5
5
#include <stdio.h>
6
6
#include <string.h>
7
7
#include <sys/epoll.h>
8
+ #include <signal.h>
8
9
#include <unistd.h>
9
10
#include <sys/stat.h>
10
11
#include <unistd.h>
@@ -30,9 +31,16 @@ char file_types[MAXFILETYPES][2][64] = {
30
31
thread_pool * pool = NULL ;
31
32
int get_line (int fd , char * buf , int size );
32
33
34
+ void send_nosignal (int fd , char * buf , size_t size )
35
+ {
36
+ if (send (fd , buf , size , MSG_NOSIGNAL ) < 0 )
37
+ perror ("send" );
38
+ }
39
+
33
40
void * malloc_specific_data ()
34
41
{
35
42
int * id = (int * )pthread_getspecific (buf_id );
43
+ if ((* id ) == MAX_SPECIFIC_DATA ) return NULL ;
36
44
++ (* id );
37
45
return pthread_getspecific (buf_key [(* id )- 1 ]);
38
46
}
@@ -75,7 +83,7 @@ void cat(int fd, const char *filename)
75
83
fgets (buf , MAX_SPECIFIC_DATA_SIZE , resource );
76
84
while (!feof (resource ))
77
85
{
78
- send (fd , buf , strlen (buf ), 0 );
86
+ send_nosignal (fd , buf , strlen (buf ));
79
87
fgets (buf , MAX_SPECIFIC_DATA_SIZE , resource );
80
88
}
81
89
fclose (resource );
@@ -91,11 +99,11 @@ void cat_bytes(int fd, const char *filename)
91
99
FILE * resource = fopen (filename , "rb" );
92
100
char * buf = malloc_specific_data ();
93
101
size_t n ;
94
- n = fread (buf , 1 , 1024 , resource );
102
+ n = fread (buf , 1 , MAX_SPECIFIC_DATA_SIZE , resource );
95
103
while (!feof (resource ))
96
104
{
97
- send (fd , buf , n , 0 );
98
- n = fread (buf , 1 , 1024 , resource );
105
+ send_nosignal (fd , buf , n );
106
+ n = fread (buf , 1 , MAX_SPECIFIC_DATA_SIZE , resource );
99
107
}
100
108
fclose (resource );
101
109
}
@@ -104,13 +112,13 @@ const char* get_filetype(char *buf, const char *filename)
104
112
{
105
113
char * tmp = malloc_specific_data ();
106
114
int i = 0 ;
107
- while (filename [i ]!= '\0' && filename [i ]!= '.' ) ++ i ;
115
+ while (filename [i ]!= '\0' && filename [i ]!= '.' && i < MAX_SPECIFIC_DATA_SIZE - 2 ) ++ i ;
108
116
if (filename [i ] == '\0' ) strcpy (buf , "text/html" );
109
117
else
110
118
{
111
119
int j = 0 ;
112
120
++ i ;
113
- while (filename [i ]!= '\0' )
121
+ while (filename [i ]!= '\0' && i < MAX_SPECIFIC_DATA_SIZE - 1 )
114
122
tmp [j ++ ]= filename [i ++ ];
115
123
tmp [j ]= '\0' ;
116
124
for (i = 0 ; i < MAXFILETYPES ; ++ i )
@@ -128,15 +136,15 @@ void unimplemented(int fd)
128
136
char * buf = malloc_specific_data ();
129
137
discard_headers (fd , buf );
130
138
sprintf (buf , "HTTP/1.0 501 Method Not Implemented\r\n" );
131
- send (fd , buf , strlen (buf ), 0 );
139
+ send_nosignal (fd , buf , strlen (buf ));
132
140
sprintf (buf , SERV_STRING );
133
- send (fd , buf , strlen (buf ), 0 );
141
+ send_nosignal (fd , buf , strlen (buf ));
134
142
sprintf (buf , "Content-Type: text/html\r\n" );
135
- send (fd , buf , strlen (buf ), 0 );
143
+ send_nosignal (fd , buf , strlen (buf ));
136
144
sprintf (buf , "Connection: closed\r\n" );
137
- send (fd , buf , strlen (buf ), 0 );
145
+ send_nosignal (fd , buf , strlen (buf ));
138
146
sprintf (buf , "\r\n" );
139
- send (fd , buf , strlen (buf ), 0 );
147
+ send_nosignal (fd , buf , strlen (buf ));
140
148
char * filename = malloc_specific_data ();
141
149
sprintf (filename , "%s/501.html" ,PATH );
142
150
cat (fd , filename );
@@ -147,15 +155,15 @@ void not_found(int fd)
147
155
char * buf = malloc_specific_data ();
148
156
discard_headers (fd , buf );
149
157
sprintf (buf , "HTTP/1.0 404 NOTFOUND\r\n" );
150
- send (fd , buf , strlen (buf ), 0 );
158
+ send_nosignal (fd , buf , strlen (buf ));
151
159
sprintf (buf , SERV_STRING );
152
- send (fd , buf , strlen (buf ), 0 );
160
+ send_nosignal (fd , buf , strlen (buf ));
153
161
sprintf (buf , "Content-Type: text/html\r\n" );
154
- send (fd , buf , strlen (buf ), 0 );
162
+ send_nosignal (fd , buf , strlen (buf ));
155
163
sprintf (buf , "Connection: closed\r\n" );
156
- send (fd , buf , strlen (buf ), 0 );
164
+ send_nosignal (fd , buf , strlen (buf ));
157
165
sprintf (buf , "\r\n" );
158
- send (fd , buf , strlen (buf ), 0 );
166
+ send_nosignal (fd , buf , strlen (buf ));
159
167
char * filename = malloc_specific_data ();
160
168
sprintf (filename , "%s/404.html" ,PATH );
161
169
cat (fd , filename );
@@ -167,15 +175,15 @@ void respond_ok(int fd, const char *filename)
167
175
discard_headers (fd , buf );
168
176
char * ft = malloc_specific_data ();
169
177
sprintf (buf , "HTTP/1.0 200 OK\r\n" );
170
- send (fd , buf , strlen (buf ), 0 );
178
+ send_nosignal (fd , buf , strlen (buf ));
171
179
sprintf (buf , SERV_STRING );
172
- send (fd , buf , strlen (buf ), 0 );
180
+ send_nosignal (fd , buf , strlen (buf ));
173
181
sprintf (buf , "Content-Type: %s\r\n" , get_filetype (ft , filename ));
174
- send (fd , buf , strlen (buf ), 0 );
182
+ send_nosignal (fd , buf , strlen (buf ));
175
183
sprintf (buf , "Connection: closed\r\n" );
176
- send (fd , buf , strlen (buf ), 0 );
184
+ send_nosignal (fd , buf , strlen (buf ));
177
185
sprintf (buf , "\r\n" );
178
- send (fd , buf , strlen (buf ), 0 );
186
+ send_nosignal (fd , buf , strlen (buf ));
179
187
//cat(fd, filename);
180
188
if (strcmp (ft , "image/jpeg" ) == 0 )
181
189
cat_bytes (fd , filename );
@@ -185,7 +193,6 @@ void respond_ok(int fd, const char *filename)
185
193
186
194
void * accept_request (void * arg )
187
195
{
188
- printf ("start accept request\n" );
189
196
pthread_once (& buf_once , buf_init_once );
190
197
/* init thread-specific data */
191
198
for (int i = 0 ; i < MAX_SPECIFIC_DATA ; ++ i )
@@ -256,6 +263,10 @@ void *accept_request(void *arg)
256
263
respond_ok (clifd , path );
257
264
}
258
265
printf ("connection terminated\n" );
266
+ {
267
+ int * k = pthread_getspecific (buf_id );
268
+ * k = 0 ;
269
+ }
259
270
close (clifd );
260
271
return NULL ;
261
272
}
@@ -289,13 +300,20 @@ int get_line(int fd, char *buf, int size)
289
300
buf [i ] = '\0' ;
290
301
return i ;
291
302
}
303
+
292
304
int main (int argc , char * * argv )
293
305
{
294
306
if (argc != 3 )
295
307
{
296
308
fprintf (stderr , "usage: %s <directory> <port>" , argv [0 ]);
297
309
exit (0 );
298
310
}
311
+ sigset_t signal_mask ;
312
+ sigemptyset (& signal_mask );
313
+ sigaddset (& signal_mask , SIGPIPE );
314
+ if (pthread_sigmask (SIG_BLOCK , & signal_mask , NULL ) == -1 )
315
+ perror ("SIGPIPE" );
316
+
299
317
strcpy (PATH , argv [1 ]);
300
318
int pathlen = strlen (PATH );
301
319
if (PATH [pathlen - 1 ] == '/' )
@@ -363,11 +381,8 @@ int main(int argc, char **argv)
363
381
}
364
382
else if (events [i ].events & EPOLLIN )
365
383
{
366
- printf ("EPOLLIN accepted\n" );
367
384
int clifd = events [i ].data .fd ;
368
- printf ("before add task\n" );
369
385
pool_add_task (pool , accept_request , (void * )& clifd );
370
- printf ("after add task" );
371
386
epoll_ctl (epfd , EPOLL_CTL_DEL , clifd , NULL );
372
387
}
373
388
}
0 commit comments