开发者

execv, select and read

开发者 https://www.devze.com 2023-01-16 08:21 出处:网络
I am creating a child-parent fork() to be able to communicate with a shell(/bin/sh) from the parent through a pipe.

I am creating a child-parent fork() to be able to communicate with a shell(/bin/sh) from the parent through a pipe.

The problem is: In a parent I set a select() on a child output, but it unblocks only when the process is finished! So when I run say ps it's okay. but when I run /bin/sh it does not output until shell exits. But I want to read it's output!

for(;;) {
se开发者_如何学Clect(PARENT_READ+1,&sh,NULL,NULL,NULL); // This unblocks only when shell exits!
if (FD_ISSET(PARENT_READ,&sh)) {
   while (n = read (PARENT_READ, &buf,30)) {
       buf[30]='\0';
       printf("C: %s\n",buf);
   };
};
}

The answer is somewhere in the field of disabling buffering of pipes?


A lot of programs change their behavior depending on whether or not they think they're talking to a terminal (tty), and the shell definitely does this this. Also, the default C streams stdout and stderr are probably unbuffered if stdout is a tty, and fully buffered otherwise - that means that they don't flush until the internal buffer is full, the program explicitly flushes them, or the program ends.

To work around this problem, you have to make your program pretend to be a terminal. To do this, you can use your system's pseudo-terminal APIs (try man 7 pty). The end result is a pair of file descriptors that sort-of work like a pipe.

Also, as an aside, when select unblocks, you should read exactly once from the triggered file descriptor. If you read more than once, which is possible with the loop you've got there, you risk blocking again on subsequent reads, unless you've got your FD in non-blocking mode.

However, I have to ask: why do you need to interact with the shell in this way? Is it possible to, say, just run a shell script, or use "/bin/sh -c your_command_here" instead? There are relatively few programs that actually need a real terminal to work correctly - the main ones are programs that prompt for a password, like ssh, su or sudo.

0

精彩评论

暂无评论...
验证码 换一张
取 消