ptyfork.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*+-------------------------------------------------------------------------
  2. ptyfork.c
  3. ptyfork # cmd args .....
  4. open a pty, wire fd # so that we pass slave part
  5. of the pty as fd # to fork # cmd args .....
  6. Defined functions:
  7. --------------------------------------------------------------------------*/
  8. /*+:EDITS:*/
  9. /*:04-26-2000-11:16-wht@bob-RELEASE 4.42 */
  10. /*:04-06-1998-13:12-wht@gyro-creation */
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include <memory.h>
  15. #include <malloc.h>
  16. #include <time.h>
  17. #include <fcntl.h>
  18. #include <errno.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <sys/time.h>
  22. #include <signal.h>
  23. #include <termio.h>
  24. /*+-------------------------------------------------------------------------
  25. usage()
  26. --------------------------------------------------------------------------*/
  27. void
  28. usage()
  29. {
  30. fprintf(stderr,"ptyfork fd cmd [args ...]\n");
  31. exit(1);
  32. } /* end of usage */
  33. /*+-------------------------------------------------------------------------
  34. open_free_pty()
  35. --------------------------------------------------------------------------*/
  36. int
  37. open_free_pty(master,slave,pmasterfd,pslavefd)
  38. char *master;
  39. char *slave;
  40. int *pmasterfd;
  41. int *pslavefd;
  42. {
  43. int masterfd = -1;
  44. int slavefd = -1;
  45. char c1,c2;
  46. struct stat st;
  47. strcpy(master,"/dev/ptyp0");
  48. strcpy(slave,"/dev/ttyp0");
  49. printf("1st pty %s %s\n",master,slave);
  50. for(c1 = 's'; c1 >= 'p'; c1--)
  51. {
  52. master[8] = c1;
  53. master[9] = '0';
  54. if (!stat(master, &st))
  55. {
  56. slave[8] = c1;
  57. for(c2 = 0; c2 <= 15; c2++)
  58. {
  59. master[9] = (c2 < 0x0A) ? (c2 + '0') : (c2 - 10 + 'a');
  60. if (!stat(master, &st))
  61. {
  62. slave[9] = master[9];
  63. printf("pty try: %s %d %d\n",master,masterfd,slavefd);
  64. masterfd = open(master, O_RDWR);
  65. slavefd = open(slave, O_RDWR);
  66. printf("pty open: %s %d %d\n",master,masterfd,slavefd);
  67. if ((masterfd >= 0) && (slavefd >= 0))
  68. {
  69. *pmasterfd = masterfd;
  70. *pslavefd = slavefd;
  71. return(0);
  72. }
  73. close(masterfd);
  74. close(slavefd);
  75. }
  76. }
  77. }
  78. }
  79. return(-1);
  80. } /* end of open_free_pty */
  81. /*+-------------------------------------------------------------------------
  82. aggressive_fork()
  83. --------------------------------------------------------------------------*/
  84. int
  85. aggressive_fork()
  86. {
  87. int count = 5;
  88. int pid;
  89. while (count--)
  90. {
  91. if ((pid = fork()) >= 0)
  92. return (pid);
  93. }
  94. return (-1);
  95. } /* end of aggressive_fork */
  96. /*+-------------------------------------------------------------------------
  97. main(argc,argv)
  98. --------------------------------------------------------------------------*/
  99. main(argc,argv)
  100. int argc;
  101. char **argv;
  102. {
  103. int itmp;
  104. char m[128];
  105. char s[128];
  106. int masterfd,slavefd,targetfd,fdmax;
  107. char buf[512];
  108. int child = 0;
  109. struct timeval tval,*tv = &tval;
  110. #ifdef CFG_HasFdSet
  111. CFG_FDSET fdset;
  112. #else
  113. int fdset;
  114. #endif
  115. if(argc < 3)
  116. usage();
  117. if((targetfd = atoi(argv[1])) <= 0)
  118. usage();
  119. if(open_free_pty(m,s,&masterfd,&slavefd))
  120. {
  121. printf("ptyfork: cannot open pty\n");
  122. exit(2);
  123. }
  124. if((child = aggressive_fork()) > 0)
  125. {
  126. /* parent */
  127. close(slavefd);
  128. fdmax = targetfd;
  129. if(fdmax < masterfd)
  130. fdmax = masterfd;
  131. while(1)
  132. {
  133. #ifdef CFG_HasFdSet
  134. FD_ZERO(&fdset);
  135. FD_SET(targetfd, &fdset);
  136. FD_SET(masterfd, &fdset);
  137. #else
  138. fdset = 1 << targetfd;
  139. fdset |= 1 << masterfd;
  140. #endif
  141. tv->tv_sec = 10;
  142. tv->tv_usec = 0;
  143. if ((itmp = select(fdmax, &fdset, 0, 0, tv)) < 1)
  144. {
  145. if(itmp == 0)
  146. continue;
  147. break;
  148. }
  149. if(FD_ISSET(targetfd,&fdset))
  150. {
  151. errno = 0;
  152. if((itmp = read(targetfd,buf,sizeof(buf))) < 0)
  153. break;
  154. write(masterfd,buf,itmp);
  155. }
  156. if(FD_ISSET(masterfd,&fdset))
  157. {
  158. errno = 0;
  159. if((itmp = read(masterfd,buf,sizeof(buf))) < 0)
  160. break;
  161. write(targetfd,buf,itmp);
  162. }
  163. }
  164. kill(child,9);
  165. exit(1);
  166. }
  167. else if(!child)
  168. {
  169. /* child */
  170. close(targetfd);
  171. dup2(slavefd,targetfd);
  172. close(slavefd);
  173. close(masterfd);
  174. execvp(argv[2],argv + 2);
  175. perror("child exec failure");
  176. exit(255);
  177. }
  178. perror("fork");
  179. exit(1);
  180. } /* end of main */