Как из программы на C (именно на C) запустить какую-либо стандартную утилиту и результат ее работы направить не в консоль, а в буфер памяти программы?
>Как из программы на C (именно на C) запустить какую-либо стандартную утилиту
>и результат ее работы направить не в консоль, а в буфер
>памяти программы?
nu zapustit' ochen' prosto: vizovami funkcii klassa 'exec...' ili 'system' (esli est' u tebia takovie)
a perenapravit' toje mojno standartnimi stredstvami... na freebsd ne znaiu a vot na windows eto bilo sdelat' prosto s pomoshiu api.
>>Как из программы на C (именно на C) запустить какую-либо стандартную утилиту
>>и результат ее работы направить не в консоль, а в буфер
>>памяти программы?
>
>
Можно выложить во временный файл (типа > /tmp/tmp), потоv его читать
Мона функцией popen() - запускает программу и возвращает FILE* дял интерфейса к ней
С помощью примерно такой функции:int my_exec(char* const cmd, char* out, int bufsize)
{ pid_t pid;
char* argv[4]; /* for child/execv() */
int len; /* for child/write() */
int stat; /* for parent/waitpid() */
int ret=-1; /* for parent return status */
int p[2]; /* pipe */
int tmp;if(!cmd)
return -1;
if(pipe(p)==-1)
return -1;
switch(pid=fork())
{ case -1:
tmp=errno;
close(p[0]);
close(p[1]);
errno=tmp;
break;
case 0: /* Child */
close(p[0]);
close(0);
close(2);
open("/dev/null", O_RDONLY);
open("/dev/null", O_WRONLY);
dup2(p[1], 1);
close(p[1]);
argv[0]="sh";
argv[1]="-c";
argv[2]=cmd;
argv[3]=NULL;
execv("/bin/sh", argv);
exit(1); /* execv() fails */
default: /* Parent */
close(p[1]);
*out='\0';
if(waitpid(pid, &stat, WUNTRACED)==pid)
{ if(WIFEXITED(stat))
{ ret=WEXITSTATUS(stat);
if(out && bufsize)
{ int len=read(p[0], out, bufsize-1);
if(len>=0)
out[len]='\0';
}
}
else if(WIFSIGNALED(stat))
ret=-2;
else if(WIFSTOPPED(stat))
{ kill(pid, SIGKILL); /* or wait more??? */
ret=-3;
}
}
close(p[0]);
}
return ret;
}Писалось это немного под другую задачу и было чуть-чуть переделано, но вроде работает. Разумеется понадобятся соответствующие заголовочники.
>
>Писалось это немного под другую задачу и было чуть-чуть переделано, но вроде
>работает. Разумеется понадобятся соответствующие заголовочники.идея верная, но реализация несколько ограничена :)
1. нет проверки ошибочных ситуаций -> в случае чего, застрелитесь отслеживать ошибочные ситуации.
2. жестко заданная последовательность "waitpid - read" -> может быть переполнение пайпа и потеря данных от клиента, равно как и просто блокировка клиента на заполненном пайпе -> deadlock.
3. waitpid может вернуть не только pid (допустим, по приходу сигнала) -> потенциальная потеря дочернего процесса в виде зомби и потеря всех данных из пайпа.
4. на stderr то-же бывает что сыплется интересная информация, а вы ее просто выкидываете в /dev/null. если уж не обрабатываете, то лучше хотя бы вообще не трогать.
5. может быть еще что-то по мелочам.// wbr
>идея верная, но реализация несколько ограничена :)
Ну я же говорю, что писалось под другую задачу и что примерно такая функция. То есть это скорее информация для размышления. :)и потом:
>1. нет проверки ошибочных ситуаций -> в случае чего, застрелитесь отслеживать ошибочные ситуации.
если ошибка произойдёт именно где-то в функции, то errno добавит информации. Конечно неплохо бы добавить пару !разных! кодов возврата...>4. на stderr то-же бывает что сыплется интересная информация, а вы ее
>просто выкидываете в /dev/null. если уж не обрабатываете, то лучше хотя
>бы вообще не трогать.
Добавить это при необходимости совсем не сложно. К тому же мне сначала показалось, что требовался только стандартный поток вывода. Sorry.А в остальном, выше я уже сказал, это просто пример вместо обычных man popen(3), man dup2(2), man pipe(2), которые разумеется тоже нужно изучить, но идея реализации бывает весьма кстати...
>Как из программы на C (именно на C) запустить какую-либо стандартную утилиту
>и результат ее работы направить не в консоль, а в буфер
>памяти программы?man popen(3)
man dup2(2)// wbr
>>Как из программы на C (именно на C) запустить какую-либо стандартную утилиту
>>и результат ее работы направить не в консоль, а в буфер
>>памяти программы?
>
>man popen(3)
>man dup2(2)++man pipe(2)
// wbr
>Как из программы на C (именно на C) запустить какую-либо стандартную утилиту
>и результат ее работы направить не в консоль, а в буфер памяти программы?Попробуй подумать над задачей. Зачем запускать из C стандартную утилиту, если для этого существует sh? Твоя главная программа должна быть на sh и организовывать взаимодействе между процессами.
Каждая программа должен заниматься только своим участком работы, процессы очень посто и удобно взаимодействуют через stdin/stdout. В последний раз я делал exec из C в MS-Windows 3.0.
это я не понял. мне в программе надо реализовать довольно большой алгоритм, который на sh не написать. в том числе проводить сложный поиск по текстовому файлу. я и планирую не писать подпрограммы для обработки текста на С, а вызывать стандартные утилиты типа grep или sed.
я эту задачу реализовал так:FILE *f;
char *command;
char buffer[1024];f = popen (command,"r");
while (1) {
if ( fgets (buffer, 1024, f) == NULL )
break;
}
pclose (f);