[cdev] Утилита ps

Grigoriy A. Sitkarev sitkarev на komitex.ru
Пт Мар 19 22:55:22 MSK 2010


1. Обработка ошибок сделана на мой взгляд не верно.

У вас fopen(3) может вернуть NULL потому что такой процесс уже 
завершился - в промежутке между чтением записи из каталога и открытием 
файла /proc/<PID>/cmdline. В таком случае вы сделать ничего не можете, 
вам надо просто перейти к следующей записи в каталоге и всё. Но 
завершать здесь программу пожалуй не надо.

Аналогично при открытии /proc/<PID>/stat.

2. Вы не разобрались с функцией fscanf(3). Вам бы надо было прочитать 
man-страницы по каждой из библиотечных функций, которые вы используете.

Вы пытаетесь идти посимвольно с помощью fscanf(3) это нехорошо, хотя и 
работает (если уж хотите ходить посимвольно то для этого есть getc(3)). 
Я бы на вашем месте вообще целиком бы считывал файлы в буфер и разбирал 
потом как строку. Так было бы проще.

Например, выдрать имя процесса, находящееся между двух скобок где-то в 
буфере-строке buf:

char *b;
char buf[1024];
char pname[NAME_MAX];

...

while ((dp = readdir(dirh)) != NULL) {
	...
	b = strchr(buf, '(');
	if (!b)
		continue;
	ptr = ++b;
	b = strchr(b, ')');
	if (!b)
		continue;
	/* Terminate with zero.  */
	*b++ = 0;
	/* String in ptr is a process name. */
	strncpy(pname, ptr, sizeof(pname));
	...
}

Что-то в таком духе (надо проверить).

Вы можете в fscanf(3) в форматной строке несколько символов задавать и 
читать в несколько переменных. Никто не запрещает. Посмотрите, в списке 
было это, поройтесь в архивах.

3. В /proc/<PID>/cmdline аргументы, которые были переданы с командной 
строки разделены нулём, т.е. символом, который обозначает в Си 
завершение строки. Поэтому вам надо их там особым образом все прочитать 
поля.

$ hexdump -c /proc/self/cmdline
0000000   h   e   x   d   u   m   p  \0   -   c  \0   /   p   r   o   c
0000010   /   s   e   l   f   /   c   m   d   l   i   n   e  \0
000001e

Кроме того, это строки, задаваемые пользователем. А пользователь может 
быть очень коварным, и может туда засунуть всё что угодно, и символ 
табуляции и переноса каретки и т.д. По идее, все непечатные символы надо 
  оттуда убрать (экранировать).

4. Что вам вернул getpwuid(3) вы не проверяете. Надо это делать 
обязательно потому что никто не гарантирует что для данного UID найдётся 
запись учётная с именем.

Я думаю что вам ещё нужно потрудиться. Задел неплохой есть.

--
Г.А.


Malkov Stanislav пишет:
> 
> Здравствуйте, спасибо за комментарии. Сделали что могли.





Подробная информация о списке рассылки cdev