I have the following example program:
#include <stdio.h>
int
main(int argc, char ** argv){
char buf[100];
printf("Please enter your name: ");
fflush(stdout);
gets(buf);
printf("Hello \"%s\"\n", buf);
execve("/bin/sh", 0, 0);
}
I and when I run without any pipe it works as it should and returns a sh
promt:
bash$ ./a.out
Please enter your name: warning: this program uses gets() which is unsafe.
testName
Hello "testName"
$ exit
bash$
But this does not work in a pipe, i think I know why that is, but I cannot figure out a solution. Example run bellow.
bash$ echo -e "testName\npwd" | ./a.out
Please enter your name: warning: this program uses gets() which is unsafe.
Hello "testName"
bash$
I figure this has something to do with the fact that gets
empties stdin
in such a way that /bin/sh
receives a EOF and promtly quits without an error message.
But how do I get around this (without modifying the program, if possible, and not removing gets
, if not) so that I get a promt even though I supply input through a pipe?
P.S. I am running this on a FreeBSD (4.8) machine D.S.
You can run your program without any modifications like this:
This way you ensure that your program's standard input doesn't end after what
echo
outputs. Instead,cat
continues to supply input to your program. The source of that subsequent input is your terminal since this is wherecat
reads from.Here's an example session:
Note that because shell's standard input is not connected to a terminal,
sh
thinks it is not executed interactively and hence does not display the prompt. You can type your commands normally, though.Not 100% sure of this (the precise shell being used and the OS might throw these answers a bit; I believe that FreeBSD uses GNU
bash
by default as/bin/sh
?), butsh
may be detecting that its input is not a tty.or
sh
might go into non-interactive mode like that also if called assh
, expectinglogin
will prepend a-
ontoargv[0]
for it. Setting upexecve ("/bin/sh", { "-sh", NULL}, NULL)
might convince it that it's being run as a login shell.Using
execve("/bin/sh", 0, 0);
is cruel and unusual punishment for the shell. It gives it no arguments or environment at all - not even its own program name, nor even such mandatory environment variables as PATH or HOME.