1
     pid_t pid;
     pid=fork();
     if (pid == 0)
     {
         //child process.
         execl("/opt/bin/version.out", "version.out > /tmp/version",0);
         _exit(0);
     }
     else
     {
         // this is parent, wait for child to finish.
         waitpid(pid, NULL, 0);
         verDir("/tmp/version");
     }

With the above c++ code, I am trying to create a child process, execute command /opt/bin/version.out and redirect the output to /tmp/version, but it doesn't create /tmp/version at all, any error with above syntax? is execl() and waitpid() syntax correct? Thanks.

vivekian2
  • 3,795
  • 9
  • 35
  • 41
rodee
  • 3,233
  • 5
  • 34
  • 70

4 Answers4

2

The '>' redirection is not valid in execl as it is a shell command....

Try to look at Running a script from execl() for an example of how to invoke a shell to do your execution....

If you want to avoid the shell invokation, you will have to do a 'dup' call to close the stderr/stdout in the chiled process and open it to the file -- you can see an example here; fork, pipe exec and dub2

Or in your child process, you can force the output to a specific file, by closing the stdout and reopen it as the file, like this;

 if (pid == 0)
     {
         //child process.
         close(1);
         creat("/tmp/version",0644); // this will create a new stdout
         close(2);
         dup(1);   // this will make stderr to also go to the same file.....

         execl("/opt/bin/version.out", "version.out",0);
         perror("execl didn't work"); // print out the error if execl failed...
         _exit(0);
     }.....
Community
  • 1
  • 1
Soren
  • 14,402
  • 4
  • 41
  • 67
  • Thanks Soren, have few questions: I don't want stderr to go into /tmp/version, so do I still need dup(1) ? and what does close(2) do ? _exit(0) will always exit with return value 0? I want to check the status in parent, so don't want to return 0 all the time. – rodee Apr 14 '14 at 23:05
  • 1
    If you dont want stderr to go to the same file, then you either leave out the close(2);dup(1); or you make it go to a different file, using creat(...) instead of dup, or make it go to /dev/null by using a sequence of close(2); open("/dev/null",1); – Soren Apr 14 '14 at 23:13
  • How do I revert this to get the stdout back on screen? – rodee Apr 16 '14 at 03:00
1

Redirection is a shell function, not a kernel function. You could run your command through the shell:

execl("/bin/sh", "sh", "-c", "/opt/bin/version.out > /tmp/version", (char *)NULL);

As an easier alternative, you could use popen() to run /opt/bin/version.out and read its output directly into your program. You would not have to use /tmp/version in this case.

FILE *version = popen("/opt/bin/version.out", "r");
... read from version ...
pclose(version);
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
0

Instead of doing the redirection in the argument of execl (which is incorrect), it should be done as part of a dup2 call.

Here is a code snippet on how to redirect to a a file instead of stdout without any error checking.

 int fd = open ("/tmp/version", O_CREAT|O_WRONLY|O_TRUNC); 
 dup2(fd, STDOUT_FILENO); 
 close(fd); 

Now, you can launch your binary using execl

 execl("/opt/bin/version.out","version.out", (char*)0); 

Do please add appropriate error checking for existence of a file and access permissions.

vivekian2
  • 3,795
  • 9
  • 35
  • 41
-2

You will need to run it in a shell:

execl("/bin/sh", "sh", "-c", "/opt/bin/version.out > /tmp/version", (char*)NULL);

You should also be checking the return value of execl for errors.

dma
  • 1,758
  • 10
  • 25