2013-05-14 3 views
1

У меня есть следующая функцияМоя начинка функция строковое значение

void runSysCall(char *command, char *output) 
{ 

    FILE *cmdline = popen(command, "rb"); 
    size_t size = 0; 


    while(getdelim(&output, &size, 0, cmdline) != -1); 

    fclose(cmdline); 
} 

Я зову его от этой функции и то, что когда-нибудь я Возвращаться нуль.

char * getVendorOfTheProcesses() 
{ 

    char * result = 0; 
    runSysCall("cat /proc/cpuinfo | grep -i 'Model'", result); 

    printf("%s", result); 
    return "asdsd"; 
} 

Если вы напечатаете значение результата из функции, оно даст то, что предполагается распечатать.

Пожалуйста, любая помощь будет оценена по достоинству.

+1

Вероятно, вы имеете в виду 'getdelim (output, & size, 0, cmdline)'. Обязательно включите все предупреждения компилятора. –

+0

@KerrekSB - Да и нет: 'getdelim' нуждается в' char ** 'в качестве первого параметра. но 'output' - это только' char * '. – Roddy

ответ

1

Пожалуйста, измените

FILE *cmdline = popen(command, "rb"); 

к

FILE *cmdline = popen(command, "r"); 

и она работает (я тестировал - http://ideone.com/agV18s).

От http://pubs.opengroup.org/onlinepubs/009696899/functions/popen.html

Режим аргумента в POPEN() является строкой, которая определяет режим ввода/вывода:

Если режим г, при запуске дочернего процесса, его файл дескриптора STDOUT_FILENO должен быть записываемый конец трубы, а файл дескриптор fileno (поток) в вызывающем процессе, где поток представляет собой указатель потока , возвращенный popen(), должен быть читаемым концом трубы .

Если режим ж, когда дочерний процесс запускается его дескриптор файла STDIN_FILENO должен быть читаемым конец трубы, а файл дескриптор fileno (поток) в процессе вызова, где поток является указателем поток возвращенный popen(), должен быть записываемым концом трубы .

Если режим - любое другое значение, результат не определен.

Кажется, вы используете режим b, вызывающий проблему (или получение неопределенного поведения).

Также убедитесь, что все ваши указатели, чтобы избежать утечек памяти.

Также обратите внимание, что каждая итерация runSysCall перезапишет output. Таким образом, в вашем getVendorOfTheProcesses, когда вы печатаете result, вы получите null, так как это последнее, что нужно прочитать. Поэтому вам нужно убедиться, что вы добавляете каждую строку и возвращаете ее до runSysCall вместо result.

Я немного изменил свой код, чтобы включить то, что я имею в виду - http://ideone.com/QVTjiD Это просто пример, вы должны адаптировать его для своих нужд и включить управление памятью.

Чтобы убедиться, что код работает нормально (на моей машине граф был 128, вашим может отличаться), вы можете использовать что-то, как показано ниже:

$ cat /proc/cpuinfo | grep -i 'Model' | wc -l 
128 
$ ./a.out | wc -l 
128 

Надеется, что это помогает.

+0

Ваш первый идеал ошибочен: 'printf («% s », result);' пишет '(null)'! – Roddy

+0

@Roddy Это не ошибка, это то, что @Alibaba имеет. Я объяснил в более поздней половине моего ответа, почему это «null» (таким образом, недостаток в коде) и как он может быть исправлен. Также см. Второй «идеон» (http://ideone.com/QVTjiD), который показывает способ устранения проблемы. – Bill

0

Я думаю, вы не поняли, как работает getdelim. Первый параметр имеет тип char**, который он использует для возврата char *. Таким образом, ваш runSysCall должны работать точно так же: -

void runSysCall(char *command, char **output) 
{ 
    .... 
    while(getdelim(output, &size, 0, cmdline) != -1); 
    ... 
} 

Теперь, когда вы называете runSysCall второй из параметров должен быть типа char**, так что ...

char * getVendorOfTheProcesses() 
{ 
    char * result = 0; 
    runSysCall("cat /proc/cpuinfo | grep -i 'Model'", &result); 

    return result; 
} 

Обратите внимание, что указатель вернулся из getVendorOfTheProcess был malloc'd внутренним путем getdelim. Чтобы избежать утечки, вы должны free(), если после звонка getVendorOfTheProcess().

Теперь вы должны получить ожидаемые результаты.

Смежные вопросы