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