int read_from_pipe(request * req) { int bytes_read, bytes_to_read = BUFFER_SIZE - (req->header_end - req->buffer); if (bytes_to_read == 0) { /* buffer full */ if (req->cgi_status == CGI_PARSE) { /* got+parsed header */ req->cgi_status = CGI_BUFFER; *req->header_end = '\0'; /* points to end of read data */ /* Could the above statement overwrite data??? No, because req->header_end points to where new data should begin, not where old data is. */ return process_cgi_header(req); /* cgi_status will change */ } req->status = PIPE_WRITE; return 1; } bytes_read = read(req->data_fd, req->header_end, bytes_to_read); if (bytes_read == -1) { if (errno == EINTR) return 1; else if (errno == EWOULDBLOCK || errno == EAGAIN) return -1; /* request blocked at the pipe level, but keep going */ else { req->status = DEAD; log_error_doc(req); perror("pipe read"); return 0; } } else if (bytes_read == 0) { /* eof, write rest of buffer */ req->status = PIPE_WRITE; if (req->cgi_status == CGI_PARSE) { /* hasn't processed header yet */ req->cgi_status = CGI_DONE; *req->header_end = '\0'; /* points to end of read data */ return process_cgi_header(req); /* cgi_status will change */ } req->cgi_status = CGI_DONE; return 1; } req->header_end += bytes_read; return 1; }
int read_from_pipe(request * req) { off_t bytes_read; /* signed */ off_t bytes_to_read; /* unsigned */ /* XXX really? */ bytes_to_read = BUFFER_SIZE - (req->header_end - req->buffer - 1); if (bytes_to_read == 0) { /* buffer full */ if (req->cgi_status == CGI_PARSE) { /* got+parsed header */ req->cgi_status = CGI_BUFFER; *req->header_end = '\0'; /* points to end of read data */ /* Could the above statement overwrite data??? No, because req->header_end points to where new data should begin, not where old data is. */ return process_cgi_header(req); /* cgi_status will change */ } req->status = PIPE_WRITE; return 1; } bytes_read = read(req->data_fd, req->header_end, bytes_to_read); #ifdef FASCIST_LOGGING if (bytes_read > 0) { *(req->header_end + bytes_read) = '\0'; fprintf(stderr, "pipe.c - read %d bytes: \"%s\"\n", bytes_read, req->header_end); } else fprintf(stderr, "pipe.c - read %d bytes\n", bytes_read); fprintf(stderr, "status, cgi_status: %d, %d\n", req->status, req->cgi_status); #endif if (bytes_read == -1) { if (errno == EINTR) return 1; else if (errno == EWOULDBLOCK || errno == EAGAIN) return -1; /* request blocked at the pipe level, but keep going */ else { req->status = DEAD; log_error_doc(req); perror("pipe read"); return 0; } } *(req->header_end + bytes_read) = '\0'; if (bytes_read == 0) { /* eof, write rest of buffer */ req->status = PIPE_WRITE; if (req->cgi_status == CGI_PARSE) { /* hasn't processed header yet */ req->cgi_status = CGI_DONE; *req->header_end = '\0'; /* points to end of read data */ return process_cgi_header(req); /* cgi_status will change */ } req->cgi_status = CGI_DONE; return 1; } req->header_end += bytes_read; if (req->cgi_status != CGI_PARSE) return write_from_pipe(req); /* why not try and flush the buffer now? */ else { char *c, *buf; buf = req->header_line; c = strstr(buf, "\n\r\n"); if (c == NULL) { c = strstr(buf, "\n\n"); if (c == NULL) { return 1; } } req->cgi_status = CGI_DONE; *req->header_end = '\0'; /* points to end of read data */ return process_cgi_header(req); /* cgi_status will change */ } return 1; }