разбор proc/pid/cmdline для получения параметров функции

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

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

мое приложение 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")

больше ничего не делает...


person André Moreira    schedule 10.09.2009    source источник
comment
После борьбы с этим сегодня я хотел отметить, что мне пришлось использовать: fread(buf,1,100,pFile); (размер = 1, количество = длина буфера).   -  person opello    schedule 20.04.2011


Ответы (2)


Все параметры командной строки (которые будут представлены как массив 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 вводили cmdline, все они "склеивались" вместе (cat игнорировались недопустимые символы NULL) и почему ваш cout останавливался после первого аргумента командной строки (имя процесса), так как считал, что имя процесса равно нулю. -terminated строка и прекратил поиск дополнительных символов в этот момент.

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

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

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

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

person Adam Batkin    schedule 10.09.2009
comment
Я это уже видел ;) Проблема с read или fread в том, что они останавливаются на первом NULL и не получают остальные параметры... как мне это обойти? Ваше здоровье - person André Moreira; 10.09.2009
comment
read и fread не останавливаются, останавливается cout (или, возможно, конструкция string из буфера, не уверен). Проверьте возвращаемое значение из вашего fread, и вы поймете, что я имею в виду. - person Adam Batkin; 10.09.2009
comment
Адам, это моя благодарность тебе за твою помощь. У меня был синдром программиста, и я хотел уничтожить клавишу выхода ;). Ваше предложение попало в точку. Еще раз спасибо ;) - person André Moreira; 11.09.2009

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

person PypeBros    schedule 16.03.2011