Determine if pty has programming requesting it for input

I create pty using openpty in C, and split it between master / parent and slave / child. The child could fork / exec and pass the file descriptor to other programs. I want to enter commands to the child, but if I pass them on immediately, they will be lost. How can I tell from the parent process that someone is blocking input from stdin? I am working on SUSE 10, but I would prefer a distribution-independent solution.

Edit: The answer to this question is still interesting to me, but may not be relevant to the problem. I will take care of this later.

A simplified version of the code will be to use a source code script (some of the headers can be fixed), and add the lines

char* command = "echo 'Hello World!'\r\n", written = 0; (void)write(master, command, strlen(command)); (void)write(STDOUT_FILENO, "Sent command\r\n", 14); 

in front of a big

 for (;;) { 

mostly.

I ran csh from a script, but then noticed that the script command is unloading some garbage (as seen in vi)

 ^[[>0;115;0c 

to parent stdin. If I run the bash shell instead, nothing gets unloaded and the program simply puts the command in order.

I’m still interested to know the answer to the question asked, but it clearly has nothing to do with my problem, since something else is happening. If someone knows how to find out if pty is readable, feel free to respond.

+4
source share
2 answers

As far as I know, file descriptors cannot survive a trip to another process. However, you can share them between threads.

Regarding knowledge, when there is something to read, I would try using select with the appropriate file descriptor in the readable set.

+1
source

I noticed the same problem with losses when I write to the fd master.

Problems can be avoided by using slave fd to write. And master fd for stdin baby. In this way:

 int main(void) { int master_fd = -1; int slave_fd = -1; if( openpty( &master_fd, &slave_fd, NULL, NULL, NULL ) != -1 ) { const pid_t child_pid = fork(); if( child_pid != -1 ) { if( child_pid ) { const char command[] = "command\n"; close( master_fd ); write( slave_fd, command, strlen(command) ); close( slave_fd ); } else { close( slave_fd ); dup2( master_fd, STDIN_FILENO ); execlp( "/bin/cat", "cat", (char*)0 ); } } } return 0; } 

You can even add delays to the child process, and it still works. Thus, the parent process can exit before the child process does something:

 ~ # temp_test ~ # command cat: read error: Input/output error ~ # 

EDIT:

A slightly different example, because a printing error from a cat is embarrassing:

  if( child_pid ) { const char command[] = "command\n"; close( master_fd ); write( slave_fd, command, sizeof(command) ); close( slave_fd ); } else { char buffer[100]; ssize_t i; ssize_t len; close( slave_fd ); do { len = read( master_fd, buffer, sizeof(buffer) ); for( i = 0; i < len; i++ ) printf("%c", buffer[i] ); } while( len > 0 ); } 

And the result:

 ~ # temp_test command ~ # 
0
source

All Articles