signal handling to cleanup on SIGINT and SIGTERM, followup

This commit is contained in:
Yang Tse 2009-12-13 03:45:32 +00:00
Родитель 303f74c740
Коммит 6e9a484ea6
1 изменённых файлов: 60 добавлений и 43 удалений

Просмотреть файл

@ -407,9 +407,12 @@ static int ProcessRequest(struct httprequest *req)
req->rcmd = RCMD_STREAM; req->rcmd = RCMD_STREAM;
} }
else if(1 == sscanf(cmd, "pipe: %d", &num)) { else if(1 == sscanf(cmd, "pipe: %d", &num)) {
logmsg("instructed to allow a pipe size %d", num); logmsg("instructed to allow a pipe size of %d", num);
req->pipe = num-1; /* decrease by one since we don't count the if(num < 0)
first request in this number */ logmsg("negative pipe size ignored");
else if(num > 0)
req->pipe = num-1; /* decrease by one since we don't count the
first request in this number */
} }
else if(1 == sscanf(cmd, "skip: %d", &num)) { else if(1 == sscanf(cmd, "skip: %d", &num)) {
logmsg("instructed to skip this number of bytes %d", num); logmsg("instructed to skip this number of bytes %d", num);
@ -457,7 +460,7 @@ static int ProcessRequest(struct httprequest *req)
if(!end) { if(!end) {
/* we don't have a complete request yet! */ /* we don't have a complete request yet! */
logmsg("ProcessRequest returned without a complete request"); logmsg("ProcessRequest returned without a complete request");
return 0; return 0; /* not complete yet */
} }
logmsg("ProcessRequest found a complete request"); logmsg("ProcessRequest found a complete request");
@ -478,6 +481,9 @@ static int ProcessRequest(struct httprequest *req)
*/ */
do { do {
if(got_exit_signal)
return 1; /* done */
if((req->cl==0) && curlx_strnequal("Content-Length:", line, 15)) { if((req->cl==0) && curlx_strnequal("Content-Length:", line, 15)) {
/* If we don't ignore content-length, we read it and we read the whole /* If we don't ignore content-length, we read it and we read the whole
request including the body before we return. If we've been told to request including the body before we return. If we've been told to
@ -508,6 +514,7 @@ static int ProcessRequest(struct httprequest *req)
line = strchr(line, '\n'); line = strchr(line, '\n');
if(line) if(line)
line++; line++;
} while(line); } while(line);
if(!req->auth && strstr(req->reqbuf, "Authorization:")) { if(!req->auth && strstr(req->reqbuf, "Authorization:")) {
@ -565,6 +572,8 @@ static int ProcessRequest(struct httprequest *req)
} }
while(req->pipe) { while(req->pipe) {
if(got_exit_signal)
return 1; /* done */
/* scan for more header ends within this chunk */ /* scan for more header ends within this chunk */
line = &req->reqbuf[req->checkindex]; line = &req->reqbuf[req->checkindex];
end = strstr(line, END_OF_HEADERS); end = strstr(line, END_OF_HEADERS);
@ -574,13 +583,12 @@ static int ProcessRequest(struct httprequest *req)
req->pipe--; req->pipe--;
} }
/* If authentication is required and no auth was provided, end now. This /* If authentication is required and no auth was provided, end now. This
makes the server NOT wait for PUT/POST data and you can then make the makes the server NOT wait for PUT/POST data and you can then make the
test case send a rejection before any such data has been sent. Test case test case send a rejection before any such data has been sent. Test case
154 uses this.*/ 154 uses this.*/
if(req->auth_req && !req->auth) if(req->auth_req && !req->auth)
return 1; return 1; /* done */
if(req->cl > 0) { if(req->cl > 0) {
if(req->cl <= req->offset - (end - req->reqbuf) - strlen(END_OF_HEADERS)) if(req->cl <= req->offset - (end - req->reqbuf) - strlen(END_OF_HEADERS))
@ -626,37 +634,37 @@ static void storerequest(char *reqbuf, ssize_t totalsize)
do { do {
written = (ssize_t)fwrite((void *) &reqbuf[totalsize-writeleft], written = (ssize_t)fwrite((void *) &reqbuf[totalsize-writeleft],
1, (size_t)writeleft, dump); 1, (size_t)writeleft, dump);
if(got_exit_signal) { if(got_exit_signal)
res = fclose(dump); goto storerequest_cleanup;
return; if(written > 0)
}
if (written > 0)
writeleft -= written; writeleft -= written;
} while ((writeleft > 0) && ((error = ERRNO) == EINTR)); } while ((writeleft > 0) && ((error = ERRNO) == EINTR));
if (writeleft > 0) { if(writeleft == 0)
logmsg("Wrote request (%zd bytes) input to " REQUEST_DUMP, totalsize);
else if(writeleft > 0) {
logmsg("Error writing file %s error: %d %s", logmsg("Error writing file %s error: %d %s",
REQUEST_DUMP, error, strerror(error)); REQUEST_DUMP, error, strerror(error));
logmsg("Wrote only (%zd bytes) of (%zd bytes) request input to %s", logmsg("Wrote only (%zd bytes) of (%zd bytes) request input to %s",
totalsize-writeleft, totalsize, REQUEST_DUMP); totalsize-writeleft, totalsize, REQUEST_DUMP);
} }
storerequest_cleanup:
do { do {
res = fclose(dump); res = fclose(dump);
} while(res && ((error = ERRNO) == EINTR)); } while(res && ((error = ERRNO) == EINTR));
if(res) if(res)
logmsg("Error closing file %s error: %d %s", logmsg("Error closing file %s error: %d %s",
REQUEST_DUMP, error, strerror(error)); REQUEST_DUMP, error, strerror(error));
if(!writeleft)
logmsg("Wrote request (%zd bytes) input to " REQUEST_DUMP,
totalsize);
} }
/* return 0 on success, non-zero on failure */ /* return 0 on success, non-zero on failure */
static int get_request(curl_socket_t sock, struct httprequest *req) static int get_request(curl_socket_t sock, struct httprequest *req)
{ {
int error;
int fail = 0; int fail = 0;
int done_processing = 0;
char *reqbuf = req->reqbuf; char *reqbuf = req->reqbuf;
ssize_t got = 0; ssize_t got = 0;
@ -688,7 +696,7 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
/*** end of httprequest init ***/ /*** end of httprequest init ***/
while (req->offset < REQBUFSIZ-1) { while(!done_processing && (req->offset < REQBUFSIZ-1)) {
if(pipereq_length && pipereq) { if(pipereq_length && pipereq) {
memmove(reqbuf, pipereq, pipereq_length); memmove(reqbuf, pipereq, pipereq_length);
got = pipereq_length; got = pipereq_length;
@ -705,17 +713,20 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
} }
if(got_exit_signal) if(got_exit_signal)
return 1; return 1;
if (got <= 0) { if(got == 0) {
if (got < 0) {
logmsg("recv() returned error: %d", SOCKERRNO);
return DOCNUMBER_INTERNAL;
}
logmsg("Connection closed by client"); logmsg("Connection closed by client");
fail = 1;
}
else if(got < 0) {
error = SOCKERRNO;
logmsg("recv() returned error: (%d) %s", error, strerror(error));
fail = 1;
}
if(fail) {
/* dump the request received so far to the external file */
reqbuf[req->offset] = '\0'; reqbuf[req->offset] = '\0';
/* dump the request receivied so far to the external file */
storerequest(reqbuf, req->offset); storerequest(reqbuf, req->offset);
return DOCNUMBER_INTERNAL; return 1;
} }
logmsg("Read %zd bytes", got); logmsg("Read %zd bytes", got);
@ -723,12 +734,13 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
req->offset += (int)got; req->offset += (int)got;
reqbuf[req->offset] = '\0'; reqbuf[req->offset] = '\0';
if(ProcessRequest(req)) { done_processing = ProcessRequest(req);
if(req->pipe--) { if(got_exit_signal)
logmsg("Waiting for another piped request"); return 1;
continue; if(done_processing && req->pipe) {
} logmsg("Waiting for another piped request");
break; done_processing = 0;
req->pipe--;
} }
} }
@ -749,7 +761,6 @@ static int get_request(curl_socket_t sock, struct httprequest *req)
/* dump the request to an external file */ /* dump the request to an external file */
storerequest(reqbuf, req->pipelining ? req->checkindex : req->offset); storerequest(reqbuf, req->pipelining ? req->checkindex : req->offset);
if(got_exit_signal) if(got_exit_signal)
return 1; return 1;
@ -789,7 +800,7 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
for (;;) { for (;;) {
written = swrite(sock, STREAMTHIS, count); written = swrite(sock, STREAMTHIS, count);
if(got_exit_signal) if(got_exit_signal)
break; return -1;
if(written != (ssize_t)count) { if(written != (ssize_t)count) {
logmsg("Stopped streaming"); logmsg("Stopped streaming");
break; break;
@ -863,6 +874,9 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
fclose(stream); fclose(stream);
} }
if(got_exit_signal)
return -1;
/* re-open the same file again */ /* re-open the same file again */
stream=fopen(filename, "rb"); stream=fopen(filename, "rb");
if(!stream) { if(!stream) {
@ -882,15 +896,6 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
if(got_exit_signal) if(got_exit_signal)
return -1; return -1;
dump = fopen(RESPONSE_DUMP, "ab"); /* b is for windows-preparing */
if(!dump) {
error = ERRNO;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Error opening file: %s", RESPONSE_DUMP);
logmsg("couldn't create logfile: " RESPONSE_DUMP);
return -1;
}
/* If the word 'swsclose' is present anywhere in the reply chunk, the /* If the word 'swsclose' is present anywhere in the reply chunk, the
connection will be closed after the data has been sent to the requesting connection will be closed after the data has been sent to the requesting
client... */ client... */
@ -905,6 +910,14 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
else else
prevbounce = FALSE; prevbounce = FALSE;
dump = fopen(RESPONSE_DUMP, "ab"); /* b is for windows-preparing */
if(!dump) {
error = ERRNO;
logmsg("fopen() failed with error: %d %s", error, strerror(error));
logmsg("Error opening file: %s", RESPONSE_DUMP);
logmsg("couldn't create logfile: " RESPONSE_DUMP);
return -1;
}
responsesize = count; responsesize = count;
do { do {
@ -924,6 +937,8 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
} }
/* write to file as well */ /* write to file as well */
fwrite(buffer, 1, written, dump); fwrite(buffer, 1, written, dump);
if(got_exit_signal)
break;
count -= written; count -= written;
buffer += written; buffer += written;
@ -936,6 +951,9 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
logmsg("Error closing file %s error: %d %s", logmsg("Error closing file %s error: %d %s",
RESPONSE_DUMP, error, strerror(error)); RESPONSE_DUMP, error, strerror(error));
if(got_exit_signal)
return -1;
if(sendfailure) { if(sendfailure) {
logmsg("Sending response failed. Only (%zu bytes) of (%zu bytes) were sent", logmsg("Sending response failed. Only (%zu bytes) of (%zu bytes) were sent",
responsesize-count, responsesize); responsesize-count, responsesize);
@ -1223,7 +1241,6 @@ int main(int argc, char *argv[])
} }
send_doc(msgsock, &req); send_doc(msgsock, &req);
if(got_exit_signal) if(got_exit_signal)
break; break;