Категории
Самые читаемые
RUSBOOK.SU » Компьютеры и Интернет » Программирование » Программирование для Linux. Профессиональный подход - Марк Митчелл

Программирование для Linux. Профессиональный подход - Марк Митчелл

Читать онлайн Программирование для Linux. Профессиональный подход - Марк Митчелл

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 35 36 37 38 39 40 41 42 43 ... 77
Перейти на страницу:

Например, программа, представленная в листинге 7.2, с помощью файла /proc/self определяет свой идентификатор процесса (это делается лишь в демонстрационных целях, гораздо проще пользоваться функцией getpid(), описанной в разделе 3.1.1, "Идентификаторы процессов"). Для чтения содержимого символической ссылки вызывается функция readlink() (описана в разделе 8.11, "Функция readlink(): чтение символических ссылок").

Листинг 7.2. (get-pid.c) Получение идентификатора процесса из файла /proc/self

#include <stdio.h>

#include <sys/types.h>

#include <unistd.h>

/* Определение идентификатора вызывающего процесса

   на основании символической ссылки /proc/self. */

pid_t get_pid_from_proc_self() {

 char target[32];

 int pid;

 /* Чтение содержимого символической ссылки. */

 readlink("/proc/self", target, sizeof(target));

 /* Адресатом ссылки является каталог, имя которого соответствует

    идентификатору процесса. */

 sscanf(target, "%d", &pid);

 return (pid_t)pid;

}

int main() {

 printf("/proc/self reports process id %dn",

  (int)get_pid_from_proc_self());

 printf("getpid() reports process id %dn", (int)getpid());

 return 0;

}

7.2.2. Список аргументов процесса

Файл cmdline в файловой системе /proc содержит список аргументов процесса (см. раздел 2.1.1. "Список аргументов"). Этот список представлен одной строкой, в которой аргументы отделяются друг от друга нулевыми символами. Большинство функций работы со строками предполагает, что нулевым символом оканчивается вся строка, поэтому они не смогут правильно обработать файл cmdline.

В листинге 2.1 приводилась программа, которая отображала переданный ей список аргументов. Теперь, когда мы узнали назначение файлов cmdline файловой системы /proc, можно написать программу, отображающую список аргументов другого процесса. Ее текст показан в листинге 7.3. Поскольку в строке файла cmdline может содержаться несколько нулевых символов, ее длину нельзя определить с помощью функции strlen() (она лишь подсчитывает число символов, пока не встретится нулевой символ). Приходится полагаться на функцию read(), которая возвращает число прочитанных байтов.

Листинг 7.3. (print-arg-list.c) Отображение списка аргументов указанного процесса

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>

/* Вывод списка аргументов (по одному в строке) процесса

   с заданным идентификатором. */

void print_process_arg_list(pid_t pid) {

 int fd;

 char filename[24];

 char arg_list[1024];

 size_t length;

 char* next_arg;

 /* Определение полного имени файла cmdline

    для заданного процесса. */

 snprintf(filename, sizeof(filename), "/proc/%d/cmdline",

  (int)pid);

 /* Чтение содержимого файла. */

 fd = open(filename, O_RDONLY);

 length = read(fd, arg_list, sizeof(arg_list));

 close(fd);

 /* Функция read() не помещает в конец текста нулевой символ,

    поэтому его приходится добавлять отдельно. */

 arg_list[length] = '';

 /* Перебор аргументов. Аргументы отделяются друг от друга

    нулевыми символами. */

 next_arg = arg_list;

 while (next_arg < arg_list + length) {

  /* Вывод аргументов. Каждый из них оканчивается нулевым

     символом и потому интерпретируется как обычная строка. */

  printf("%sn", next_arg);

  /* Переход к следующем аргументу. Поскольку каждый аргумент

     заканчивается нулевым символом, функция strlen() вычисляет

     длину отдельного аргумента, а не всего списка. */

  next_arg += strlen(next_arg) + 1;

 }

}

int main(int argc, char* argv[]) {

 pid_t pid = (pid_t)atoi(argv[1]);

 print_process_arg_list(pid);

 return 0;

}

Предположим, к примеру, что номер процесса системного демона syslogd равен 372.

% ps 372

 PID TTY STAT TIME COMMAND

 372 ?   S    0:00 syslogd -m 0

% ./print-arg-list 372

syslogd

-m

0

В данном случае программа print-arg-list, сообщает о том, что демон syslogd вызван с аргументами -m 0.

7.2.3. Переменные среды процесса

Файл environ содержит список переменных среды, в которой работает процесс (см. раздел 2.1.6, "Среда выполнения"). Как и в случае файла cmdline, элементы списка разделяются нулевыми символами. Формат элемента таков: ПЕРЕМЕННАЯ=значение.

Представленная в листинге 7.4 программа является обобщением программы, которая была показана в листинге 2.3. В данном случае программа принимает в командной строке идентификатор процесса и отображает список его переменных среды, извлекаемый из файловой системы /proc.

Листинг 7.4. (print-environment.c) Отображение переменных среды процесса

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>

/* Вывод переменных среды (по одной в строке) процесса

   с заданным идентификатором. */

void print_process_environment(pid_t pid) {

 int fd;

 char filename[24];

 char environment[8192];

 size_t length;

 char* next_var;

 /* Определение полного имени файла environ

    для заданного процесса. */

 snprintf(filename, sizeof(filename), "/proc/%d/environ",

  (int)pid);

 /* Чтение содержимого файла. */

 fd = open(filename, O_RDONLY);

 length = read(fd, environment, sizeof (environment));

 close(fd);

 /* Функция read() не помещает в конец текста нулевой символ,

    поэтому его приходится добавлять отдельно. */

 environment[length] = ' ';

 /* Перебор переменных. Элементы списка отделяются друг от друга

    нулевыми символами. */

 next_var = environment;

 while (next_var < environment + length) {

  /* Вывод элементов списка. Каждый из них оканчивается нулевым

     символом и потому интерпретируется как обычная строка. */

  printf("%sn", next_var);

  /* Переход к следующей переменной. Поскольку каждый элемент

     списка заканчивается нулевым символом, функция strlen()

     вычисляет длину отдельного элемента, а не всего списка. */

  next_var += strlen(next_var) + 1;

 }

}

int main(int argc, char* argv[]) {

 pid_t pid = (pid_t)atoi(argv[1]);

 print_process_environment(pid);

 return 0;

}

7.2.4. Исполняемый файл процесса

Файл exe указывает на исполняемый файл процесса. В разделе 2.1.1, "Список аргументов", говорилось о том, что имя исполняемого файла обычно передается в качестве первого элемента списка аргументов. Но это лишь распространенное соглашение. Программу можно запустить с произвольным списком аргументов. Файл exe файловой системы /proc — это более надежный способ узнать, какой исполняемый файл запущен процессом.

Во многих программах путь ко вспомогательным файлам задан относительно исполняемого файла, поэтому важно знать, где именно он находится. Функция get_executable_path() в листинге 7.5 определяет путевое имя текущего исполняемого файла, проверяя символическую ссылку /proc/self/exe.

Листинг 7.5. (get-exe-path.c) Определение путевого имени текущего исполняемого файла

#include <limits.h>

#include <stdio.h>

#include <string.h>

#include <unistd.h>

/* Нахождение путевого имени текущего исполняемого файла.

   путевое имя помещается в строку BUFFER, длина которой

   равна LEN. Возвращается число символов в имени либо

   -1 в случае ошибки. */

size_t get_executable_path(char* buffer, size_t len) {

 char* path_end;

 /* чтение содержимого символической ссылки /proc/self/exe. */

 if (readlink("/proc/self/exe", buffer, len) <= 0)

  return -1;

 /* Нахождение последней косой черты, отделяющей путевое имя. */

 path_end = strrchr(buffer, '/');

 if (path_end == NULL)

  return -1;

 /* Переход к символу, стоящему за последней косой чертой. */

1 ... 35 36 37 38 39 40 41 42 43 ... 77
Перейти на страницу:
На этой странице вы можете бесплатно скачать Программирование для Linux. Профессиональный подход - Марк Митчелл торрент бесплатно.
Комментарии
Открыть боковую панель
Комментарии
Сергій
Сергій 25.01.2024 - 17:17
"Убийство миссис Спэнлоу" от Агаты Кристи – это великолепный детектив, который завораживает с первой страницы и держит в напряжении до последнего момента. Кристи, как всегда, мастерски строит