2014-10-16 3 views
0

Я пытаюсь сделать что-то вроде этого:Это неправильный способ перенаправления вывода ребенка, порожденного fork и execvp?

int main(int argc, char** argv) 
{ 
    bool foo = false; 
    //parse args, check if --foo is an arg, if so mark foo true 

    if (foo) 
    { 
     //child behavior 
     while (true) { std::cout << "child" << std::endl; sleep(1); } 
    } 
    else 
    { 
     //do some parent process stuff 
     pid_t pid = fork(); 
     if(pid == 0) //spawn child 
     { 
      char* newArgv[argc+1]; 
      for (int i = 0; i < argc; ++i) newArgv[i] = argv[i]; 
      newArgv[argc] = "--foo"; //make child run child code 

      std::ostringstream oss; 
      oss << argv[0] << " >> foo.txt 2>&1"; //same binary but redir child output 
      execvp(out.str().c_str(), newArgv); 
     } 

     //more regular parent code 
    } 

    return 0; 
} 

Таким образом, в основном, бинарные нерестится себя с новым аргументом для запуска по-другому, и вывод перенаправляется (в идеале). К сожалению, в то время как это порождает два процесса, я, кажется, теряю выход ребенка, и я не уверен, почему?

+1

Да, это неправильно. Операторы перенаправления обрабатываются оболочкой, и вы не выполняете оболочку. – youdontneedtothankme

ответ

0

Что случилось с много простых:

int main(int argc, char** argv) { 
    //do some parent process stuff  
    pid_t pid = fork(); 
    if(pid == 0) //this is the child 
    { 
     //child behavior 
     while (true) { std::cout << "child" << std::endl; sleep(1); } 
    } else { 
     //more regular parent code 
    } 
    return 0; 
} 
+0

Неправильно то, что fork без exec только вилки одного потока, а некоторые потоки в родительском имеют некоторую статическую инициализацию, которая вызывает проблемы. exec обошел все эти проблемы. –

0

Вы должны установить FileDescriptor 1 пункт в foo.txt перед вызовом execv. Дочерний процесс будет использовать foo.txt в качестве стандартного вывода:

fd_t f = open("foo.txt", O_WRONLY); 
if (f != 1) 
    { 
    close(1); 
    dup2(f, 1); 
    close(f); 
    } 
execv(...); 

Любое исправление ошибок в коде выше, остается в качестве упражнения для читателя. Исправление ошибок включает, но не ограничивается этим, проверку ошибок, возвращаемых вызовами функций.

EDIT:

Если вы хотите стандартную ошибку (fildescriptor 2), чтобы идти туда, куда идет стандартный вывод, вы должны добавить это до execv:

close(2); 
dup2(1, 2); 
Смежные вопросы