Как я могу реализовать 'мишень' программно в C?

  • булева алгебра
  • теория множеств
  • дискретная математика
12
задан robottobor 19 November 2009 в 09:20
поделиться

4 ответа

Вы можете popen () программу tee.

Или вы можете fork () и pipe stdout через дочерний процесс, такой как этот (адаптированный из реальной живой программы, которую я написал, поэтому он работает!):

void tee(const char* fname) {
    int pipe_fd[2];
    check(pipe(pipe_fd));
    const pid_t pid = fork();
    check(pid);
    if(!pid) { // our log child
        close(pipe_fd[1]); // Close unused write end
        FILE* logFile = fname? fopen(fname,"a"): NULL;
        if(fname && !logFile)
            fprintf(stderr,"cannot open log file \"%s\": %d (%s)\n",fname,errno,strerror(errno));
        char ch;
        while(read(pipe_fd[0],&ch,1) > 0) {
            //### any timestamp logic or whatever here
            putchar(ch);
            if(logFile)
                fputc(ch,logFile);
            if('\n'==ch) {
                fflush(stdout);
                if(logFile)
                    fflush(logFile);
            }
        }
        putchar('\n');
        close(pipe_fd[0]);
        if(logFile)
            fclose(logFile);
        exit(EXIT_SUCCESS);
    } else {
        close(pipe_fd[0]); // Close unused read end
        // redirect stdout and stderr
        dup2(pipe_fd[1],STDOUT_FILENO);  
        dup2(pipe_fd[1],STDERR_FILENO);  
        close(pipe_fd[1]);  
    }
}
7
ответ дан 2 December 2019 в 21:03
поделиться

Вы можете использовать forkpty () с exec () для выполнения отслеживаемая программа с ее параметрами. forkpty () возвращает дескриптор файла, который перенаправляется в программы stdin и stdout. Все, что записывается в файловый дескриптор, является вводом программы. Все, что написано программой, можно прочитать из файлового дескриптора.

Вторая часть - прочитать в цикле вывод программы и записать его в файл, а также распечатать его в stdout.

Пример:

pid = forkpty(&fd, NULL, NULL, NULL);
if (pid<0)
    return -1;

if (!pid) /* Child */
{
execl("/bin/ping", "/bin/ping", "-c", "1", "-W", "1", "192.168.3.19", NULL);
}

/* Parent */
waitpid(pid, &status, 0);
return WEXITSTATUS(status);
1
ответ дан 2 December 2019 в 21:03
поделиться

Вы можете использовать pipe (2) и dup2 (2) , чтобы связать ваш стандартный выход с файловым дескриптором, из которого вы можете читать. Затем вы можете иметь отдельный поток, отслеживающий этот дескриптор файла, записывая все, что он получает, в файл журнала и исходный стандартный вывод (сохраненный avay в другом файловом дескрипторе с помощью dup2 перед подключением канала). Но вам понадобится фоновый поток.

На самом деле, я думаю, что метод popen tee, предложенный vatine, вероятно, проще и безопаснее (если вам не нужно делать что-либо дополнительно с файлом журнала, например, метки времени или кодирование или что-то в этом роде).

1
ответ дан 2 December 2019 в 21:03
поделиться

Нет тривиального способа сделать это в C. Я подозреваю, что проще всего было бы вызвать popen (3) с tee как командой и желаемым файлом журнала как arument,

-1
ответ дан 2 December 2019 в 21:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: