6

I have a very specific problem for which I am unable to find the answer after numerous searches. I have a linux program. It's job is to launch another secondary executable (via fork() and exec()) when it receives a specific message over the network. I do not have access to modify the secondary executable.

My program prints all its TTY to stdout, and I typically launch it via ./program > output.tty The problem I have is that this second executable is very verbose. It simultaneously prints to stdout while also putting the same TTY in a log file. So my output.tty file ends up containing both output streams.

How can I set things up such that the secondary executable's TTY gets redirected to /dev/null? I can't use system() because I can't afford to wait for the child process. I need to be able to fire and forget.

Thanks.

mdevico
  • 71
  • 1
  • 4
  • `exec()` a shell that calls the program and redirects it's output. – πάντα ῥεῖ Nov 18 '16 at 00:10
  • can't you use `>` redirection operator as an argument in `exec()`? – SkrewEverything Nov 18 '16 at 00:12
  • @SkrewEverything No. The redirection operator is interpreted by a shell. – πάντα ῥεῖ Nov 18 '16 at 00:14
  • The statement 'My program prints all its TTY to stdout' is difficult to parse. It prints data to stdout. Often stdout is associated with a tty. When you run the program as `./program > output.tty`, its stdout is *not* associated with a tty but with a regular file that happens the have `tty` as a suffix. It makes no sense to say "putting the same TTY in a log file". A tty is a physical device (although these days its almost certainly a pseudo-tty). Data gets written to it. – William Pursell Nov 18 '16 at 00:14
  • C is not C++ is not C! Remove the unrelated tag and follow [ask]. – too honest for this site Nov 18 '16 at 00:43
  • @πάνταῥεῖ: thanks for the suggestion. I did see in the documentation for `exec()` that there is a variation that accepts a shell script, but unfortunately my command + arguments would go over the 127 character limit for the first line. – mdevico Nov 18 '16 at 01:14

2 Answers2

11

In child process use dup2() to redirect the output to a file.

int main(int argc, const char * argv[]) {

    pid_t ch;
    ch = fork();
    int fd;
    if(ch == 0)
    {
        //child process

        fd = open("/dev/null",O_WRONLY | O_CREAT, 0666);   // open the file /dev/null
        dup2(fd, 1);                                       // replace standard output with output file
        execlp("ls", "ls",".",NULL);                       // Excecute the command
        close(fd);                                         // Close the output file 
    }

    //parent process

    return 0;
}
SkrewEverything
  • 2,393
  • 1
  • 19
  • 50
2

In the child process, before calling exec, you need to close the standard output stream.

pid_t pid =fork();
if (pid == 0) {
    close(1);
    // call exec
} else if (pid > 0) {
    // parent
}
dbush
  • 205,898
  • 23
  • 218
  • 273