Приклад: zap

Програма zap, вибірково нищівна процеси, також була представлена ​​в розділі 5 у вигляді командного файлу Основним недоліком тієї версії є швидкість: програма створює так багато процесів, що виконання стає дуже повільним, що небажано, особливо для програми, яка вбиває помилкові процеси Пере писана на Сі, zap буде працювати швидше Не будемо робити всю роботу: як і раніше використовуємо ps для пошуку інформації про процес Це набагато легше, ніж отримувати інформацію з ядра, до того ж таке рішення переносимо Програма zap відкриває канал, в якому з боку уведення знаходиться ps, і зчитує дані звідти, а не з файлу Функція popen (3) аналогічна fopen, тільки першим аргументом є не імя файлу, а команда Існує і функція pclose, яка не використовується в даному прикладі

/ * Zap: інтерактивний вбивця процесів * /

#include &ltstdioh&gt

#include &ltsignalh&gt

char * progname / * Імя програми для повідомлення про помилку * / char * ps = ps-ag; / * Залежить від системи * /

main(argc,  argv) int  argc

char  *argv[]

{

FILE  *fin,  *popen() char  buf[BUFSIZ]

int pid

progname = argv[0]

if ((fin  = popen(ps, &quotr&quot))  == NULL)  {

fprintf(stderr, &quot%s: cant  run  %s\n&quot,  progname, ps) exit(1)

}

fgets (buf, sizeof buf, fin) / * Отримати заголовну рядок * / fprintf (stderr, % s, buf)

while  (fgets(buf,  sizeof buf,  fin) =  NULL)

if (argc == 1 ||  strindex(buf,  argv[1]) &gt= 0)  { buf[strlen(buf)–1]  =  \0; /*  suppress  \n  */ fprintf(stderr,  &quot%s  &quot, buf)

if  (ttyin()  ==  y)  { sscanf(buf,  &quot%d&quot,  &amppid) kill(pid,  SIGKILL)

}

}

exit(0)

}

Програма була написана з використанням ps-ag (параметр залежить від конкретної системи), 1 але до тих пір поки ви не станете привілейованим користувачем, ви зможете знищувати тільки свої власні процеси

При першому виклику fgets отримує від ps заголовну рядок (попро буйте зрозуміти, що станеться, якщо спробувати знищити «процес», відповідний цієї заголовної рядку – це корисна вправа)

Функція sscanf належить до сімейства scanf (3), що займається перетворенням формату вводу Вона конвертує не файл, а рядок Системний виклик kill посилає вказаний сигнал процесу при цьому сигнал SIGKILL, визначений у , не може бути перехоплений або проігноровано Може бути, ви памятаєте (про це йшлося в розділі 5), що чисельне значення відправленого сигналу дорівнює 9, але краще використовувати символьні константи, а не розкидати по програмі магічні числа

Якщо аргументи не задані, команда zap надає для вибору кожен рядок виведення ps Якщо ж аргумент зазначений, то zap пропонує тільки відповідні йому рядки виводу ps Функція strin- dex (s1, s2) перевіряє, чи відповідає аргумент якої частини рядка виводу ps, використовуючи strncmp (див табл 62) Функція strindex

1 Параметр-a вимагає відображення процесів всіх користувачів, а не лише то тих, що належать користувачу, запустившему ps У System V ps-a не виводить процеси, що є лідерами групи процесів, для включення їх до виведений список необхідний параметр-g В ОС гілки BSD дію параметра-g не визначено Наприклад, під FreeBSD v 44 ps не має параметра-g, але його вказівку при запуску ps повідомлень про помилку не викликає – Прямуючи науч ред

повертає позицію в s1, в якій зустрілася s2, або -1, якщо відповідність не виявлено

strindex (s, t) / * повертає індекс t в s і -1, якщо не знайдено * / char * s, * t

{

int i, n

n = strlen(t)

for  (i = 0  s[i] =  \0; i++)

if  (strncmp(s+i,  t,  n)  ==  0) return  i

return –1

}

Список найбільш часто вживаних функцій із стандартної библи набряки введення-виведення наведено в табл 64

Таблиця 64 Корисні стандартні функції ввода5вивода

Функція

Дія

fp=fopen(s,mode)

c=getc(fp) putc(c,fp) ungetc(c,fp)

scanf(fmt,a1,..)

fscanf(fp,..) sscanf(s,..) printf(fmt,a1,..) fprintf(fp,..) sprintf(s,..) fgets(s,n,fp)

fputs(s,fp) fflush(fp) fclose(fp) fp=popen(s,mode) pclose(fp) system(s)

відкрити файл s режими r, w, a для читання, запису і додавання (у разі помилки повертає NULL)

витягти символ getchar () – це getc (stdin)

вставити символ putchar () – це putc (c, stdout)

повернути символ назад у файл введення fp, за один раз не більше одного символу

читати символи з stdin в a1, .. відповідно до fmt Кожен ai має бути вказівником Повертає EOF або кількість перетворених полів

читати з файлу fp

читати з рядка s

форматувати a1, .. відповідно до fmt, виводити в stdout

виводити .. в файл fp

виводити .. в рядок s

прочитати не більше ніж n символів з fp в s У кінці файлу повертає NULL

виводити рядок s у файл fp

скинути буферізованние висновок для файлу fp

закрити файл fp

відкрити канал для команди s Див fopen

закрити канал fp

запустити команду s і чекати завершення

Вправа 611Змініть zap так, щоб можна було задавати будь-яку кількість аргументів Запропонована версія zap пропонує для вибору рядок, відповідну самій собі Чи правильно це Якщо ні, змініть програму Підказка: getpid (2) ~

Вправа 612Напишіть функцію fgrep (1), грунтуючись на strin-dex Порівняйте час виконання при складному пошуку, наприклад для 10 слів у документі Чому fgrep працює швидше ~

Джерело: Керниган Б, Пайк Р, UNIX Програмне оточення – Пер з англ – СПб: Символ-Плюс, 2003 – 416 с, Мул

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*