listen.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* posix */
  2. #include <sys/types.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <fcntl.h>
  7. #include <string.h>
  8. #include <errno.h>
  9. #include <sys/stat.h>
  10. #include <signal.h>
  11. /* socket extensions */
  12. #include <sys/uio.h>
  13. #include <sys/socket.h>
  14. #include <netinet/in.h>
  15. #include <sys/un.h>
  16. /* plan 9 */
  17. #include "lib.h"
  18. #include "sys9.h"
  19. #include "priv.h"
  20. extern int _muxsid;
  21. extern void _killmuxsid(void);
  22. /*
  23. * replace the fd with a pipe and start a process to
  24. * accept calls in. this is all to make select work.
  25. */
  26. static int
  27. listenproc(Rock *r, int fd)
  28. {
  29. Rock *nr;
  30. char *net;
  31. int cfd, nfd, dfd;
  32. int pfd[2];
  33. struct stat d;
  34. char *p;
  35. char listen[Ctlsize];
  36. char name[Ctlsize];
  37. switch(r->stype){
  38. case SOCK_DGRAM:
  39. net = "udp";
  40. break;
  41. case SOCK_STREAM:
  42. net = "tcp";
  43. break;
  44. }
  45. strcpy(listen, r->ctl);
  46. p = strrchr(listen, '/');
  47. if(p == 0)
  48. return -1;
  49. strcpy(p+1, "listen");
  50. if(pipe(pfd) < 0)
  51. return -1;
  52. /* replace fd with a pipe */
  53. nfd = dup(fd);
  54. dup2(pfd[0], fd);
  55. close(pfd[0]);
  56. fstat(fd, &d);
  57. r->inode = d.st_ino;
  58. r->dev = d.st_dev;
  59. /* start listening process */
  60. switch(fork()){
  61. case -1:
  62. close(pfd[1]);
  63. close(nfd);
  64. return -1;
  65. case 0:
  66. if(_muxsid == -1) {
  67. _RFORK(RFNOTEG);
  68. _muxsid = getpgrp();
  69. } else
  70. setpgid(getpid(), _muxsid);
  71. _RENDEZVOUS(2, _muxsid);
  72. break;
  73. default:
  74. atexit(_killmuxsid);
  75. _muxsid = _RENDEZVOUS(2, 0);
  76. close(pfd[1]);
  77. close(nfd);
  78. return 0;
  79. }
  80. /* for(fd = 0; fd < 30; fd++)
  81. if(fd != nfd && fd != pfd[1])
  82. close(fd);/**/
  83. for(;;){
  84. cfd = open(listen, O_RDWR);
  85. if(cfd < 0)
  86. break;
  87. dfd = _sock_data(cfd, net, r->domain, r->stype, r->protocol, &nr);
  88. if(dfd < 0)
  89. break;
  90. if(write(pfd[1], nr->ctl, strlen(nr->ctl)) < 0)
  91. break;
  92. if(read(pfd[1], name, sizeof(name)) <= 0)
  93. break;
  94. close(dfd);
  95. }
  96. exit(0);
  97. }
  98. int
  99. listen(fd, backlog)
  100. int fd;
  101. int backlog;
  102. {
  103. Rock *r;
  104. int n, cfd;
  105. char msg[128];
  106. struct sockaddr_in *lip;
  107. struct sockaddr_un *lunix;
  108. r = _sock_findrock(fd, 0);
  109. if(r == 0){
  110. errno = ENOTSOCK;
  111. return -1;
  112. }
  113. switch(r->domain){
  114. case PF_INET:
  115. cfd = open(r->ctl, O_RDWR);
  116. if(cfd < 0){
  117. errno = EBADF;
  118. return -1;
  119. }
  120. lip = (struct sockaddr_in*)&r->addr;
  121. if(lip->sin_port >= 0) {
  122. if(write(cfd, "bind 0", 6) < 0) {
  123. errno = EGREG;
  124. close(cfd);
  125. return -1;
  126. }
  127. snprintf(msg, sizeof msg, "announce %d",
  128. ntohs(lip->sin_port));
  129. }
  130. else
  131. strcpy(msg, "announce *");
  132. n = write(cfd, msg, strlen(msg));
  133. if(n < 0){
  134. errno = EOPNOTSUPP; /* Improve error reporting!!! */
  135. close(cfd);
  136. return -1;
  137. }
  138. close(cfd);
  139. return listenproc(r, fd);
  140. case PF_UNIX:
  141. if(r->other < 0){
  142. errno = EGREG;
  143. return -1;
  144. }
  145. lunix = (struct sockaddr_un*)&r->addr;
  146. if(_sock_srv(lunix->sun_path, r->other) < 0){
  147. _syserrno();
  148. r->other = -1;
  149. return -1;
  150. }
  151. r->other = -1;
  152. return 0;
  153. default:
  154. errno = EAFNOSUPPORT;
  155. return -1;
  156. }
  157. }