@@ -35,10 +35,6 @@ int setsockopt(int socket, int level, int option_name, const void *option_value,
35
35
int fork ();
36
36
void exit (int status );
37
37
38
- /* this is fine because forked processes are copy on write */
39
- /* so there shouldn't be any data races */
40
- static char http_buf [8192 ];
41
-
42
38
static size_t strlen (const char * s ) {
43
39
const char * p = s ;
44
40
while (* p )
@@ -78,22 +74,20 @@ static uint16_t swap_uint16(uint16_t x) {
78
74
#define perror (s )
79
75
#endif
80
76
81
- static int tcp_listen (int port ) {
82
- static int yes = 1 ;
83
- static sockaddr_in_t addr = {AF_INET };
84
- addr .sin_port = swap_uint16 (port );
77
+ int tcp_listen (const sockaddr_in_t * addr , const void * option_value ,
78
+ socklen_t option_len ) {
85
79
int sock ;
86
80
if ((sock = socket (AF_INET , SOCK_STREAM , IPPROTO_TCP )) < 0 ||
87
- setsockopt (sock , SOL_SOCKET , SO_REUSEADDR , & yes , sizeof ( yes ) ) ||
88
- bind (sock , & addr , sizeof (addr )) || listen (sock , 10 )) {
81
+ setsockopt (sock , SOL_SOCKET , SO_REUSEADDR , option_value , option_len ) ||
82
+ bind (sock , addr , sizeof (sockaddr_in_t )) || listen (sock , 10 )) {
89
83
die ("listen" );
90
84
}
91
85
return sock ;
92
86
}
93
87
94
- static void http_consume (int clientfd ) {
88
+ static void http_consume (int clientfd , char * http_buf , size_t buf_len ) {
95
89
int n ;
96
- while ((n = read (clientfd , http_buf , sizeof ( http_buf ) )) > 0 ) {
90
+ while ((n = read (clientfd , http_buf , buf_len )) > 0 ) {
97
91
printn (http_buf , n );
98
92
const char * p = http_buf + (n - 3 );
99
93
if (n < 3 || (* p == '\n' && * (p + 1 ) == '\r' && * (p + 2 ) == '\n' )) {
@@ -125,16 +119,17 @@ static void http_drop(int clientfd) {
125
119
126
120
#define http_code (fd , x ) fprintl(fd, "HTTP/1.1 " x "\r\n\r\n" x);
127
121
128
- static int http_serve (int clientfd , const char * file_path ) {
122
+ static int http_serve (int clientfd , const char * file_path , char * http_buf ,
123
+ size_t buf_len ) {
129
124
int f , n ;
130
- http_consume (clientfd );
125
+ http_consume (clientfd , http_buf , buf_len );
131
126
if ((f = open (file_path , O_RDONLY )) < 0 ) {
132
127
perror ("open" );
133
128
http_code (clientfd , "404 Not Found" );
134
129
return 1 ;
135
130
}
136
131
fprintl (clientfd , "HTTP/1.1 200 OK\r\n\r\n" );
137
- while ((n = read (f , http_buf , sizeof ( http_buf ) )) > 0 ) {
132
+ while ((n = read (f , http_buf , buf_len )) > 0 ) {
138
133
if (write (clientfd , http_buf , n ) < 0 ) {
139
134
perror ("write" );
140
135
return 1 ;
@@ -155,7 +150,7 @@ static uint16_t string2port(const char *s) {
155
150
}
156
151
res = res * 10 + * s - '0' ;
157
152
}
158
- return res ;
153
+ return swap_uint16 ( res ) ;
159
154
}
160
155
161
156
static void usage (const char * self ) {
@@ -168,18 +163,21 @@ static void usage(const char *self) {
168
163
int main (int argc , char * argv []) {
169
164
int sock ;
170
165
uint16_t port ;
166
+ char http_buf [8192 ];
171
167
if (argc != 3 || (port = string2port (argv [1 ])) == 0 ) {
172
168
usage (argv [0 ]);
173
169
}
174
- sock = tcp_listen (port );
170
+ const int yes = 1 ;
171
+ const sockaddr_in_t addr = {AF_INET , port , 0 };
172
+ sock = tcp_listen (& addr , & yes , sizeof (yes ));
175
173
while (1 ) {
176
174
int pid , clientfd ;
177
175
if ((clientfd = accept (sock , 0 , 0 )) < 0 ) {
178
176
perror ("accept" );
179
177
} else if ((pid = fork ()) < 0 ) {
180
178
perror ("fork" );
181
179
} else if (pid == 0 ) {
182
- return http_serve (clientfd , argv [2 ]);
180
+ return http_serve (clientfd , argv [2 ], http_buf , sizeof ( http_buf ) );
183
181
}
184
182
}
185
183
return 0 ;
0 commit comments