This is a discussion on pseudo terminal(grantpt) problems within the comp.unix.solaris forums, part of the Solaris Operating System category; --> Hi, I am using pseudo terminals to drive an executable(sftp) from my code. I open a pseudo terminal(using grantpt) ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Hi, I am using pseudo terminals to drive an executable(sftp) from my code. I open a pseudo terminal(using grantpt) and fork. In the child the slave pty is opened and the sftp program is exec'd. The parent reads and writes to sftp by using the master file descriptor. Please see the program below. The problem is, sometimes when the parent writes to the master fd and tries to read the output from the child using the same fd, it gets whatever it just wrote. Apparently, the child did not get a chance to read it. The only way I was able to avoid this is by putting a sleep between the parent's write and select statements. Is there any other way that it can be avoided? Am I not setting any relevant terminal options/modules? Thanks, Sanjeev /************************************************** ****************** Usage : ./a.out /usr/bin/sftp <userid>@<host> <password> ************************************************** ******************/ #include <stdio.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/time.h> #include <sys/filio.h> #include <stropts.h> void wait_for_response(int fdm); fd_set readList; main(int argc, char*argv[]) { int fdm, fds, pid, nbytes, nread, count; char *slave; char Response[512]; if (argc < 4) { printf("usage: %s /usr/bin/sftp <username>@<host> <password>\n", argv[0]); exit(-1); } count = strlen(argv[3]); if( (fdm = open("/dev/ptmx", O_RDWR)) < 0 ) { perror ("Unable to get a free master pseudo tty."); exit (-1); } if (grantpt (fdm)) { perror ("grantpt"); exit (-1); } if (unlockpt(fdm)) { perror ("unlockpt"); exit (-1); } if ((pid= fork()) == 0 ) { /* child */ if (setsid() < 0) perror("setsid error"); slave = (char *) ptsname(fdm); fds = open(slave, O_RDWR); if (fds <=0){ perror("open"); exit (-1); } if(isastream(fds)) { /* Check if "fds" is a valid file descriptor */ ioctl(fds, I_PUSH, "ptem"); /* push ptem */ ioctl(fds, I_PUSH, "ldterm"); /* push ldterm*/ } close (fdm); if (dup2(fds, 0) !=0) { perror("dup2 stdin"); exit (-1); } if (dup2(fds, 1) !=1) { perror("dup2 stdout"); exit (-1); } if (dup2(fds, 2) !=2) { perror("dup2 stderr"); exit (-1); } if (fds > 2) close (fds); if(execl(argv[1], argv[1], argv[2], NULL) < 0) { perror("execl "); exit (-1); } } else if (pid >0) /*master */ { ioctl(fdm, FIONREAD,&nbytes); FD_ZERO(&readList); FD_SET(fdm,&readList); wait_for_response(fdm); if (( nread = read(fdm, Response, 512)) <= 0) { perror("read"); exit (-1); } Response[nread] = '\0'; printf("Response 1 is:%s", Response); while (strstr(Response, "password") == NULL) { wait_for_response(fdm); if (( nread = read(fdm, Response, 512)) <= 0) { perror("read"); exit (-1); } Response[nread] = '\0'; printf("Response 2 is :%s", Response); } if ((write(fdm, argv[3], count) != count)){ perror("write"); exit (-1); } if ((write(fdm, "\n", 1) != 1)){ perror("write"); exit (-1); } wait_for_response(fdm); if (( nread = read(fdm, Response, 512)) <= 0) { perror("read"); exit (-1); } Response[nread] = '\0'; printf("Reponse 3 is: %s", Response); if ((write(fdm, "put test.c\n", 11) != 11)){ perror("write"); exit (-1); } wait_for_response(fdm); if (( nread = read(fdm, Response, 512)) <= 0) { perror("read"); exit (-1); } Response[nread] = '\0'; printf("Reponse 4 is: %s", Response); if ((write(fdm, "bye\n", 4) != 4)) perror("writen"); wait_for_response(fdm); if (( nread = read(fdm, Response, 512)) <= 0) { perror("read"); exit (-1); } Response[nread] = '\0'; printf("Reponse 5 is: %s", Response); } } void wait_for_response(int fdm) { int selrc ; sleep(10); /* to avoid select returning due to our own write */ selrc = select(fdm +1, &readList,0,0, NULL); if (selrc < 1) { perror("select"); exit (-1); } } |
| |||
| sanjvkoz@yahoo.com (Sanjeev) writes: >I am using pseudo terminals to drive an executable(sftp) from my code. >I open a pseudo terminal(using grantpt) and fork. In the child the >slave pty is opened and the sftp program is exec'd. The parent reads >and writes to sftp by using the master file descriptor. Please see the >program below. >The problem is, sometimes when the parent writes to the master fd and >tries to read the output from the child using the same fd, it gets >whatever it just wrote. Apparently, the child did not get a chance to >read it. Actually, the child does get to read it but the pseudo tty echos the input. It's just like typing to a pseudo terminal; I'm not typing this in an xterm; each character that the xterm reads is send to the pseudo tty and then xterm reads back my output; when typing, the output is typically the echoed characters. >The only way I was able to avoid this is by putting a sleep between >the parent's write and select statements. You should still see all your output; it is possible that your code sends the password before sftp has switched off echo; but normally the password should not be echoed. >Is there any other way that it can be avoided? Am I not setting any >relevant terminal options/modules? Unset echo on the tty in the child. Some other small remarks: >#include <stdio.h> >#include <unistd.h> >#include <errno.h> >#include <fcntl.h> >#include <sys/ioctl.h> >#include <sys/time.h> >#include <sys/filio.h> >#include <stropts.h> Missing: #include <stdlib.h> > slave = (char *) ptsname(fdm); This case is wrong also; it the compiler from warning you that you forgot to include <stdlib.h>; not that the above code would not work as 64 bit program. > fds = open(slave, O_RDWR); > if (fds <=0){ Wrong check: should be fds < 0 Casper |
| ||||
| Casper H.S. Dik <Casper.Dik@Sun.COM> wrote in message news:<401b9eaf$0$328$e4fe514c@news.xs4all.nl>... > Unset echo on the tty in the child. > Casper, thank you for the explanation. I turned off the echo on the child and it works fine! Thanks for your other comments about the code too. Regards, Sanjeev |