2

Here's an example code to reproduce my problem:

#include <stdio.h>
int main()
{
    char *f = "toto.txt";
    char cmd[64];

    sprintf(cmd, "nano %s", f);
    system(cmd);
    return 0;
}

If I do:

./test

Everything is fine, but if I do:

echo "blah"|./test

Nano fails:

received SIGHUP or SIGTERM

Is there a safer way to execute system commands ? I've already tried redirecting stdin.

Claudio
  • 10,614
  • 4
  • 31
  • 71
freezeeedos
  • 103
  • 4
  • AFAIK, piping is implemented by the shell (e.g., Bash), so it is not available through `system()`. – Claudio Dec 02 '13 at 14:34
  • 3
    check this http://stackoverflow.com/questions/5986544/cannot-launch-interactive-program-while-piping-to-script-in-python – Deepthought Dec 02 '13 at 14:36
  • @Claudio But he is not trying to do that... it's the program's behavior that changes depending on how OP invokes it *from the shell.* –  Dec 02 '13 at 14:36
  • 3
    The error message about SIGHUP comes from nano. You can try running nano from the shell (echo "blah" | nano somefile") and it'll still show the same message. – Dan Fego Dec 02 '13 at 14:38
  • @DanFego indeed it does. I guess I won't be using stdin, then. No big deal :) – freezeeedos Dec 02 '13 at 14:46
  • I just didn't expect the piped message to go trought system(). But as system() uses the shell, I guess it makes sense ? – freezeeedos Dec 02 '13 at 15:44

1 Answers1

1

The system'ed program inherits its stdin from the process that called system. In the case of nano (and most other text editors, I'd imagine) this is a bad thing when stdin is not the terminal.

You should be able to fix it by adding < /dev/tty to the command string.

sprintf(cmd, "nano %s < /dev/tty", f);

You could check whether stdin is a tty first, and only apply the redirection when it's needed, like this:

if(isatty(0))
    sprintf(cmd, "nano %s", f);
else
    sprintf(cmd, "nano %s < /dev/tty", f);

(You're going to get bit when your f has any shell metacharacters in it, but that's an unrelated issue...)