[cdev] Утилита ps
Grigoriy A. Sitkarev
sitkarev на komitex.ru
Сб Мар 20 01:31:55 MSK 2010
Тут есть некоторая неточность, я объясню в чём дело.
strncpy(3) это такая не очень хорошая функция и я обычно её заменяю на
написанную отдельно xstrncpy или safe_strncpy. Странность поведения
strncpy(3) библиотечной в следующем: если в n символах строки src
отсутствует '\0' (завершающий строку ноль) то строка в dst не будет
нуль-терминирована. Но в нашем примере мы уверены, что в
sizeof(NAME_MAX) символах будет завершающий ноль (мы его туда сами
положили). Хотя, если быть педантом, то конечно, следовало бы
принудительно её занультерминировать, потому что можно сказать что в
теории имя процесса между '(' и ')' может оказаться длинее NAME_MAX (в
какой нибудь сломаной версии или когда злоумышленник получил доступ к
/proc).
Если мы не уверены что такой нуль-терминатор есть, следовало бы
инкрементировать b после этой операции а не до. Потому что нам тогда
удобно получить длину строки, не пользуя strlen(3) т.к. указатель b уже
указывает на её конец, а адрес начала нам известен, это ptr.
/* Terminate with zero. */
*b = 0;
/* String in ptr is a process name. */
strncpy(pname, ptr, sizeof(pname));
pname[b-ptr] = 0;
++b;
или можно:
pname[b++-ptr]
Но лучше тогда:
pname[(b++)-ptr]
--
Г.А.
> Например, выдрать имя процесса, находящееся между двух скобок где-то в
> буфере-строке 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));
> ...
> }
Подробная информация о списке рассылки cdev