Как использовать fork в C? - PullRequest
2 голосов
/ 01 мая 2020

Вот полный код:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
    char *command, *infile, *outfile;
    int wstatus;

    command = argv[1];
    infile = argv[2];
    outfile = argv[3];

    if (fork()) {
        wait(&wstatus);
        printf("Exit status: %d\n", WEXITSTATUS(wstatus));
    }
    else {
        close(0);
        open(infile, O_RDONLY);
        close(1);
        open(outfile, O_CREAT|O_TRUNC|O_WRONLY, 0644);
        execlp(command, command, NULL);

    }

    return 0;
}


Этот код должен выполнить и выполнить c команду с обоими перенаправлениями stdin и stdout, затем дождитесь его завершения и получите printf WEXITSTATUS(wstatus). например, ./allredir hexdump out_of_ls dump_file.

Итак, я все понимаю до fork(). Но у меня есть следующие вопросы:

  1. Насколько я понимаю, fork() клонирует процесс, однако я не понимаю, как он выполняет команду, потому что execlp должен делать это и никогда не кодировать достигает этой части.
  2. Я не понимаю, как работает execlp. Почему мы посылаем ему команду дважды (execlp(command, command, NULL);)?
  3. Как execlp знает, куда перенаправить вывод, если мы не пропустим outfile в никуда.
  4. Почему нам даже нужен infile, если команда уже передана в качестве другого аргумента?

Спасибо за ваши ответы заранее.

1 Ответ

3 голосов
/ 01 мая 2020
  1. Насколько я понимаю, fork () клонирует процесс, однако я не понимаю, как он выполняет команду, потому что execlp должен это делать, а код никогда не достигает этой части.

Fork возвращает pid дочернего элемента в родительском пространстве и 0 в новом пространстве процесса. Процесс son делает вызов execlp.

if (fork()) { 
    /* Parent process waits for child process */
}
else {
    /* Son process */
    execlp(command, command, NULL);
}

Я не понимаю, как работает execlp. Почему мы посылаем ему команду дважды (execlp (команда, команда, NULL);)?

Чтение execlp man-страница и this thread

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


Как execlp знает, куда перенаправить вывод, если мы никуда не пропускаем outfile.

Перенаправление происходит раньше, закрывая дескрипторы файлов stdin и stdout. И перенаправление происходит путем открытия файлов, файловые дескрипторы которых будут содержать записи 0 и 1.

else {
    /* redirecting stdin */
    close(0); 
    open(infile, O_RDONLY);  

    /* redirecting stdout */
    close(1); 
    open(outfile, O_CREAT|O_TRUNC|O_WRONLY, 0644);

    execlp(command, command, NULL);
}

Зачем нам нужен infile, если команда уже передана в качестве другого аргумента?

Мы не можем сказать, что делает ваша программа, не увидев аргумент, переданный как команда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...