looptcp.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * Copyright (c) 1993 W. Richard Stevens. All rights reserved.
  3. * Permission to use or modify this software and its documentation only for
  4. * educational purposes and without fee is hereby granted, provided that
  5. * the above copyright notice appear in all copies. The author makes no
  6. * representations about the suitability of this software for any purpose.
  7. * It is provided "as is" without express or implied warranty.
  8. */
  9. #include "sock.h"
  10. /* Copy everything from stdin to "sockfd",
  11. * and everything from "sockfd" to stdout. */
  12. void
  13. loop_tcp(int sockfd)
  14. {
  15. int maxfdp1, nread, ntowrite, stdineof, flags;
  16. fd_set rset;
  17. if (pauseinit)
  18. sleep_us(pauseinit*1000); /* intended for server */
  19. flags = 0;
  20. stdineof = 0;
  21. FD_ZERO(&rset);
  22. maxfdp1 = sockfd + 1; /* check descriptors [0..sockfd] */
  23. for ( ; ; ) {
  24. if (stdineof == 0)
  25. FD_SET(STDIN_FILENO, &rset);
  26. FD_SET(sockfd, &rset);
  27. if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0)
  28. err_sys("select error");
  29. if (FD_ISSET(STDIN_FILENO, &rset)) { /* data to read on stdin */
  30. if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0)
  31. err_sys("read error from stdin");
  32. else if (nread == 0) { /* EOF on stdin */
  33. if (halfclose) {
  34. if (shutdown(sockfd, SHUT_WR) < 0)
  35. err_sys("shutdown() error");
  36. FD_CLR(STDIN_FILENO, &rset);
  37. stdineof = 1; /* don't read stdin anymore */
  38. continue; /* back to select() */
  39. }
  40. break; /* default: stdin EOF -> done */
  41. }
  42. if (crlf) {
  43. ntowrite = crlf_add(wbuf, writelen, rbuf, nread);
  44. if (dowrite(sockfd, wbuf, ntowrite) != ntowrite)
  45. err_sys("write error");
  46. } else {
  47. if (dowrite(sockfd, rbuf, nread) != nread)
  48. err_sys("write error");
  49. }
  50. }
  51. if (FD_ISSET(sockfd, &rset)) { /* data to read from socket */
  52. /* msgpeek = 0 or MSG_PEEK */
  53. flags = msgpeek;
  54. oncemore:
  55. if ( (nread = recv(sockfd, rbuf, readlen, flags)) < 0)
  56. err_sys("recv error");
  57. else if (nread == 0) {
  58. if (verbose)
  59. fprintf(stderr, "connection closed by peer\n");
  60. break; /* EOF, terminate */
  61. }
  62. if (crlf) {
  63. ntowrite = crlf_strip(wbuf, writelen, rbuf, nread);
  64. if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite)
  65. err_sys("writen error to stdout");
  66. } else {
  67. if (writen(STDOUT_FILENO, rbuf, nread) != nread)
  68. err_sys("writen error to stdout");
  69. }
  70. if (flags != 0) {
  71. flags = 0; /* no infinite loop */
  72. goto oncemore; /* read the message again */
  73. }
  74. }
  75. }
  76. if (pauseclose) {
  77. if (verbose)
  78. fprintf(stderr, "pausing before close\n");
  79. sleep_us(pauseclose*1000);
  80. }
  81. if (close(sockfd) < 0)
  82. err_sys("close error"); /* since SO_LINGER may be set */
  83. }