В какой файловый дескриптор execve перенаправить? - PullRequest
0 голосов
/ 12 января 2020
int main (void) {

   int rc=fork();
   if(rc==0){
   close(1); //close stdout BEFORE opening my file
   open("./c.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);


   //execve "wc"
   char *cmd[3];
   cmd[0] = strdup("wc"); //file to execuable
   cmd[1]=strdup("c.c"); //first arg to command 'wc' -> c.c
   cmd[2]=NULL;

   execvp(cmd[0], cmd);
   }

Если я закрою стандартный вывод (), то вывод execve ("w c") будет в файле c.txt, но ТОЛЬКО если я закрою стандартный вывод ДО открытия () ing. Если я назову это ПОСЛЕ

open("./c.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
   close(1); 

, то -> wc: write error: Bad file descriptor.

Я прочитал, что для open () (вероятно, в моем случае для вывода wc) достигается ОС дескриптор файла от 0, и поэтому сначала он находит 1 как стандартный вывод для printf () на экран. Поэтому мне нужно закрыть его, чтобы использовать дескриптор файла из open ("./c .txt") для wc. Но если это правильно (я не знаю, где я правильно понял), тогда не имеет значения, закрываю ли я stdout до или после вызова open (), не так ли? После закрытия ОС не имеет другого FD для использования в качестве вывода. Возможно, я не совсем понимаю.

вопрос: почему сначала нужно закрыть fd1, чтобы сделать перенаправление на c .txt?

1 Ответ

2 голосов
/ 12 января 2020

Несколько принципов для установки sh вначале.

  1. stdout - это один из потоков, автоматически открываемых при запуске программы. Код запуска программы использует файловый дескриптор 1 для stdout).
  2. execve создает новый процесс с теми же дескрипторами открытого файла, что и родительский / вызывающий процесс (существуют исключения и нюансы, которые могут быть чтение из execve man page .
  3. open будет искать самый низкий доступный дескриптор файла для использования.

Ok, так что теперь к вашему коду.

Случай 1 - закрыть, открыть, выполнить

В этом случае происходит следующая последовательность событий:

  1. Программа начинается с stdout => fd 1.
  2. close(1) делает доступным fd 1.
  3. open("c.txt") возвращает 1, что эффективно перенаправляет stdout в файл .
  4. execve создает новый процесс, в котором 1 открывается и перенаправляется в файл.
  5. wc записывает в fd 1, что теперь заканчивается в файле.

Случай 2 - открыть, закрыть, выполнить

В этом случае происходит следующая последовательность событий:

  1. P rogram начинается с stdout => fd 1.
  2. open("c.txt") вызывается, но fd 1 недоступен, поэтому возвращает 2.
  3. close(1) означает, что теперь есть фактически нет stdout.
  4. execve создает новый процесс, у которого нет открытого потока на fd 1 (ie нет stdout).
  5. wc пытается записать на fd 1 и получает ошибку bad file descriptor, так как fd 1 не открыт.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...