dgecho01.lc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /* include dgecho1 */
  2. #include "unp.h"## 1 ##src/sigio/dgecho01.c##
  3. static int sockfd;## 2 ##src/sigio/dgecho01.c##
  4. #define QSIZE 8 /* size of input queue */## 3 ##src/sigio/dgecho01.c##
  5. #define MAXDG 4096 /* maximum datagram size */## 4 ##src/sigio/dgecho01.c##
  6. typedef struct {## 5 ##src/sigio/dgecho01.c##
  7. void *dg_data; /* ptr to actual datagram */## 6 ##src/sigio/dgecho01.c##
  8. size_t dg_len; /* length of datagram */## 7 ##src/sigio/dgecho01.c##
  9. struct sockaddr *dg_sa; /* ptr to sockaddr{} w/client's address */## 8 ##src/sigio/dgecho01.c##
  10. socklen_t dg_salen; /* length of sockaddr{} */## 9 ##src/sigio/dgecho01.c##
  11. } DG;## 10 ##src/sigio/dgecho01.c##
  12. static DG dg[QSIZE]; /* the queue of datagrams to process */## 11 ##src/sigio/dgecho01.c##
  13. static long cntread[QSIZE + 1]; /* diagnostic counter */## 12 ##src/sigio/dgecho01.c##
  14. static int iget; /* next one for main loop to process */## 13 ##src/sigio/dgecho01.c##
  15. static int iput; /* next one for signal handler to read into */## 14 ##src/sigio/dgecho01.c##
  16. static int nqueue; /* #on queue for main loop to process */## 15 ##src/sigio/dgecho01.c##
  17. static socklen_t clilen; /* max length of sockaddr{} */## 16 ##src/sigio/dgecho01.c##
  18. static void sig_io(int);## 17 ##src/sigio/dgecho01.c##
  19. static void sig_hup(int);## 18 ##src/sigio/dgecho01.c##
  20. /* end dgecho1 */
  21. /* include dgecho2 */
  22. void## 19 ##src/sigio/dgecho01.c##
  23. dg_echo(int sockfd_arg, SA *pcliaddr, socklen_t clilen_arg)## 20 ##src/sigio/dgecho01.c##
  24. {## 21 ##src/sigio/dgecho01.c##
  25. int i;## 22 ##src/sigio/dgecho01.c##
  26. const int on = 1;## 23 ##src/sigio/dgecho01.c##
  27. sigset_t zeromask, newmask, oldmask;## 24 ##src/sigio/dgecho01.c##
  28. sockfd = sockfd_arg;## 25 ##src/sigio/dgecho01.c##
  29. clilen = clilen_arg;## 26 ##src/sigio/dgecho01.c##
  30. for (i = 0; i < QSIZE; i++) { /* init queue of buffers */## 27 ##src/sigio/dgecho01.c##
  31. dg[i].dg_data = Malloc(MAXDG);## 28 ##src/sigio/dgecho01.c##
  32. dg[i].dg_sa = Malloc(clilen);## 29 ##src/sigio/dgecho01.c##
  33. dg[i].dg_salen = clilen;## 30 ##src/sigio/dgecho01.c##
  34. }## 31 ##src/sigio/dgecho01.c##
  35. iget = iput = nqueue = 0;## 32 ##src/sigio/dgecho01.c##
  36. Signal(SIGHUP, sig_hup);## 33 ##src/sigio/dgecho01.c##
  37. Signal(SIGIO, sig_io);## 34 ##src/sigio/dgecho01.c##
  38. Fcntl(sockfd, F_SETOWN, getpid());## 35 ##src/sigio/dgecho01.c##
  39. Ioctl(sockfd, FIOASYNC, &on);## 36 ##src/sigio/dgecho01.c##
  40. Ioctl(sockfd, FIONBIO, &on);## 37 ##src/sigio/dgecho01.c##
  41. Sigemptyset(&zeromask); /* init three signal sets */## 38 ##src/sigio/dgecho01.c##
  42. Sigemptyset(&oldmask);## 39 ##src/sigio/dgecho01.c##
  43. Sigemptyset(&newmask);## 40 ##src/sigio/dgecho01.c##
  44. Sigaddset(&newmask, SIGIO); /* the signal we want to block */## 41 ##src/sigio/dgecho01.c##
  45. Sigprocmask(SIG_BLOCK, &newmask, &oldmask);## 42 ##src/sigio/dgecho01.c##
  46. for (;;) {## 43 ##src/sigio/dgecho01.c##
  47. while (nqueue == 0)## 44 ##src/sigio/dgecho01.c##
  48. sigsuspend(&zeromask); /* wait for a datagram to process */## 45 ##src/sigio/dgecho01.c##
  49. /* 4unblock SIGIO */## 46 ##src/sigio/dgecho01.c##
  50. Sigprocmask(SIG_SETMASK, &oldmask, NULL);## 47 ##src/sigio/dgecho01.c##
  51. Sendto(sockfd, dg[iget].dg_data, dg[iget].dg_len, 0,## 48 ##src/sigio/dgecho01.c##
  52. dg[iget].dg_sa, dg[iget].dg_salen);## 49 ##src/sigio/dgecho01.c##
  53. if (++iget >= QSIZE)## 50 ##src/sigio/dgecho01.c##
  54. iget = 0;## 51 ##src/sigio/dgecho01.c##
  55. /* 4block SIGIO */## 52 ##src/sigio/dgecho01.c##
  56. Sigprocmask(SIG_BLOCK, &newmask, &oldmask);## 53 ##src/sigio/dgecho01.c##
  57. nqueue--;## 54 ##src/sigio/dgecho01.c##
  58. }## 55 ##src/sigio/dgecho01.c##
  59. }## 56 ##src/sigio/dgecho01.c##
  60. /* end dgecho2 */
  61. /* include sig_io */
  62. static void## 57 ##src/sigio/dgecho01.c##
  63. sig_io(int signo)## 58 ##src/sigio/dgecho01.c##
  64. {## 59 ##src/sigio/dgecho01.c##
  65. ssize_t len;## 60 ##src/sigio/dgecho01.c##
  66. int nread;## 61 ##src/sigio/dgecho01.c##
  67. DG *ptr;## 62 ##src/sigio/dgecho01.c##
  68. for (nread = 0;;) {## 63 ##src/sigio/dgecho01.c##
  69. if (nqueue >= QSIZE)## 64 ##src/sigio/dgecho01.c##
  70. err_quit("receive overflow");## 65 ##src/sigio/dgecho01.c##
  71. ptr = &dg[iput];## 66 ##src/sigio/dgecho01.c##
  72. ptr->dg_salen = clilen;## 67 ##src/sigio/dgecho01.c##
  73. len = recvfrom(sockfd, ptr->dg_data, MAXDG, 0,## 68 ##src/sigio/dgecho01.c##
  74. ptr->dg_sa, &ptr->dg_salen);## 69 ##src/sigio/dgecho01.c##
  75. if (len < 0) {## 70 ##src/sigio/dgecho01.c##
  76. if (errno == EWOULDBLOCK)## 71 ##src/sigio/dgecho01.c##
  77. break; /* all done; no more queued to read */## 72 ##src/sigio/dgecho01.c##
  78. else## 73 ##src/sigio/dgecho01.c##
  79. err_sys("recvfrom error");## 74 ##src/sigio/dgecho01.c##
  80. }## 75 ##src/sigio/dgecho01.c##
  81. ptr->dg_len = len;## 76 ##src/sigio/dgecho01.c##
  82. nread++;## 77 ##src/sigio/dgecho01.c##
  83. nqueue++;## 78 ##src/sigio/dgecho01.c##
  84. if (++iput >= QSIZE)## 79 ##src/sigio/dgecho01.c##
  85. iput = 0;## 80 ##src/sigio/dgecho01.c##
  86. }## 81 ##src/sigio/dgecho01.c##
  87. cntread[nread]++; /* histogram of #datagrams read per signal */## 82 ##src/sigio/dgecho01.c##
  88. }## 83 ##src/sigio/dgecho01.c##
  89. /* end sig_io */
  90. /* include sig_hup */
  91. static void## 84 ##src/sigio/dgecho01.c##
  92. sig_hup(int signo)## 85 ##src/sigio/dgecho01.c##
  93. {## 86 ##src/sigio/dgecho01.c##
  94. int i;## 87 ##src/sigio/dgecho01.c##
  95. for (i = 0; i <= QSIZE; i++)## 88 ##src/sigio/dgecho01.c##
  96. printf("cntread[%d] = %ld\n", i, cntread[i]);## 89 ##src/sigio/dgecho01.c##
  97. }## 90 ##src/sigio/dgecho01.c##
  98. /* end sig_hup */