парсинг proc / pid / cmdline для получения параметров функции - PullRequest
2 голосов
/ 10 сентября 2009

Я пытаюсь извлечь параметр, с которым было вызвано приложение, используя данные внутри cmdline.

Если я запускаю экземпляр приложения следующим образом:

myapp 1 2

, а затем введите команду myapp, и я увижу что-то вроде myapp12.

Мне нужно было извлечь эти значения, и я использовал этот кусок кода, чтобы сделать это


pid_t proc_id = getpid();

sprintf(buf,"/proc/%i/cmdline",proc_id);

FILE * pFile;
pFile = fopen (buf,"r");
if (pFile!=NULL)
{
    fread(buf,100,100,pFile);
    cout << "PID " << proc_id << endl;
    string str = buf;
    cout << buf << endl;
    size_t found=str.find_last_of("/\\");
    cout << " file: " << str.substr(found+1) << endl;

    fclose (pFile);
}

Но я получаю только имя приложения и никаких параметров ...


Обновление сопоставлено с ответом:

Хорошо, теперь у меня возникает вопрос: как прочитать файл cmdline, не останавливаясь на первом символе NULL?

fopen(cmdline, "rb")

больше ничего не делает, поэтому ...

Ответы [ 2 ]

9 голосов
/ 16 марта 2011

/usr/bin/strings /proc/1337/cmdline обычно делают работу за меня.

7 голосов
/ 10 сентября 2009

Все параметры командной строки (которые будут представлены как массив argv[]) на самом деле являются разделенными нулями строками в /proc/XXX/cmdline.

abatkin@penguin:~> hexdump -C /proc/28460/cmdline
00000000  70 65 72 6c 00 2d 65 00  31 20 77 68 69 6c 65 20  |perl.-e.1 while |
00000010  74 72 75 65 00                                    |true.|

Это объясняет, почему, когда вы cat 'ed cmdline, они все "слиплись" вместе (cat игнорировал недопустимые символы NULL) и почему ваш cout остановился после первого аргумента командной строки (имя процесса) ), поскольку он думал, что имя процесса было строкой с нулевым символом в конце, и на этом этапе прекратил поиск других символов.

Обработка аргументов командной строки

Для обработки аргументов командной строки у вас есть пара опций. Если вы просто хотите, чтобы вся командная строка представляла собой одну гигантскую строку, выполните цикл от 0 до (numRead - 2) (где numRead - количество прочитанных символов) и замените все пустые байты (curByte == 0) пробелами. Затем просто убедитесь, что последний символ также равен байту NULL (в случае, если что-то было усечено из-за буфера фиксированного размера).

Если вместо этого вам нужен массив со всеми аргументами, вам нужно быть более креативным. Одним из вариантов будет цикл от 0 до (numRead - 1), и он может содержать все байты NULL, которые вы найдете. Затем выделите массив из char* этой длины. Затем вернитесь в командную строку и установите начало каждой строки (то есть первого байта в массиве плюс каждый байт, следующий за нулевым байтом) последовательным элементам массива char*.

Просто знайте, что поскольку вы читаете в буфер фиксированного размера, все, что находится за пределами этого буфера, будет усечено. Так что помните, что что бы вы ни делали, вам, вероятно, нужно вручную убедиться, что конец последней строки заканчивается NULL, иначе большинство функций обработки строк не будут знать, где заканчивается строка, и будут продолжаться вечно.

...