1

I want to run execlp() from C file and write the result to some output file. I use the line:

buff = "./cgi-bin/smth";
execlp(buff, buff, "> /cgi-bin/tmp", NULL);

where smth is a compiled c script. But smth prints to stdout, and no file appears. What happens, and how to put script result to an output file?

sooobus
  • 841
  • 1
  • 9
  • 22
  • 1
    "What happens?" - you run the program `./cgi-bin/smth`, with the zeroth argument being `./cgi-bin/smth` and the first argument being `> /cgi-bin/tmp`. Exactly what you asked to happen happens. – user253751 May 25 '16 at 02:51
  • 1
    The shell does I/O redirection for you; if you're writing the 'shell', you'll have to do it for yourself. The simplest fix is to use `system("./cgi-bin/smth > /cgi-bin/tmp");` (are you sure the file shouldn't be `./cgi-bin/tmp`?). Failing that, you have to open the file in your program and arrange for standard output to go to the file — using `dup2()`, `close()` and `open()`, not in that order. – Jonathan Leffler May 25 '16 at 02:53
  • Not honoring shell-style redirections, expansions, and other shell-specific magic is what makes directly calling `exec*`-family syscalls more secure than going through `system()` when handling untrusted data. If this behaved in any way other than what you describe here, writing secure software on UNIX would be next to impossible. – Charles Duffy May 25 '16 at 02:57

1 Answers1

1

You have to handle it yourself with dup2 if using execlp. You can look at how I handle file out with execvp in comparison. I pass a flag for out redirection and then I handle it:

  if (structpipeline->option[0] == 1) { /* output redirection */    
        int length = structpipeline[i].size;
        char *filename = structpipeline->data[length - 1];
        for (int k = length - 2; k < length; k++)
            structpipeline->data[k] = '\0';    
        fd[1] = open(filename, O_WRONLY | O_CREAT, 0666);
        dup2(fd[1], STDOUT_FILENO);
        close(fd[1]);
    } /* TODO: input redirection */
    execvp(structpipeline[i].data[0], structpipeline[i].data);

See also this question Redirecting exec output to a buffer or file

Community
  • 1
  • 1
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424