fielding 97/07/14 04:29:00
Modified: src CHANGES alloc.c buff.h http_protocol.c http_protocol.h mod_cgi.c util_script.c util_script.h Log: Removed "Make cgi unbuffered" changes of 1997/07/06 Revision Changes Path 1.335 +0 -3 apache/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache/src/CHANGES,v retrieving revision 1.334 retrieving revision 1.335 diff -C3 -r1.334 -r1.335 *** CHANGES 1997/07/14 08:50:25 1.334 --- CHANGES 1997/07/14 11:28:54 1.335 *************** *** 37,45 **** *) mod_status: PID field of "dead" child slots no longer displays main httpd process's PID. - *) CGI: Add a select() loop so that CGI scripts don't have to be - nph in order to be "unbuffered". [Sameer Parekh] - *) Makefile.nt added - to build all the bits from the command line: nmake -f Makefile.nt Doesn't yet work properly. [Ben Laurie] --- 37,42 ---- 1.39 +0 -192 apache/src/alloc.c Index: alloc.c =================================================================== RCS file: /export/home/cvs/apache/src/alloc.c,v retrieving revision 1.38 retrieving revision 1.39 diff -C3 -r1.38 -r1.39 *** alloc.c 1997/07/13 19:01:07 1.38 --- alloc.c 1997/07/14 11:28:54 1.39 *************** *** 1060,1257 **** #define enc_pipe(fds) pipe(fds) #endif /* WIN32 */ - - API_EXPORT(int) spawn_child_err_buff (pool *p, int (*func)(void *), void *data, - enum kill_conditions kill_how, - BUFF **pipe_in, BUFF **pipe_out, BUFF **pipe_err) - { - int pid; - int in_fds[2]; - int out_fds[2]; - int err_fds[2]; - int save_errno; - - block_alarms(); - - if (pipe_in && enc_pipe (in_fds) < 0) - { - save_errno = errno; - unblock_alarms(); - errno = save_errno; - return 0; - } - - if (pipe_out && enc_pipe (out_fds) < 0) { - save_errno = errno; - if (pipe_in) { - close (in_fds[0]); close (in_fds[1]); - } - unblock_alarms(); - errno = save_errno; - return 0; - } - - if (pipe_err && enc_pipe (err_fds) < 0) { - save_errno = errno; - if (pipe_in) { - close (in_fds[0]); close (in_fds[1]); - } - if (pipe_out) { - close (out_fds[0]); close (out_fds[1]); - } - unblock_alarms(); - errno = save_errno; - return 0; - } - - #ifdef WIN32 - - { - HANDLE thread_handle; - int hStdIn, hStdOut, hStdErr; - int old_priority; - - (void)acquire_mutex(spawn_mutex); - thread_handle = GetCurrentThread(); /* doesn't need to be closed */ - old_priority = GetThreadPriority(thread_handle); - SetThreadPriority(thread_handle, THREAD_PRIORITY_HIGHEST); - /* Now do the right thing with your pipes */ - if(pipe_in) - { - hStdIn = dup(fileno(stdin)); - dup2(in_fds[0], fileno(stdin)); - close(in_fds[0]); - } - if(pipe_out) - { - hStdOut = dup(fileno(stdout)); - dup2(out_fds[1], fileno(stdout)); - close(out_fds[1]); - } - if(pipe_err) - { - hStdErr = dup(fileno(stderr)); - dup2(err_fds[1], fileno(stderr)); - close(err_fds[1]); - } - - pid = (*func)(data); - if(!pid) - { - save_errno = errno; - close(in_fds[1]); - close(out_fds[0]); - close(err_fds[0]); - } - - /* restore the original stdin, stdout and stderr */ - if(pipe_in) - dup2(hStdIn, fileno(stdin)); - if(pipe_out) - dup2(hStdOut, fileno(stdout)); - if(pipe_err) - dup2(hStdErr, fileno(stderr)); - - if(pid) - { - note_subprocess(p, pid, kill_how); - if(pipe_in) - { - *pipe_in = bcreate(p, B_WR); - bpushfd(*pipe_in, in_fds[1], in_fds[1]); - } - if(pipe_out) - { - *pipe_out = bcreate(p, B_RD); - bpushfd(*pipe_out, out_fds[0], out_fds[0]); - } - if(pipe_err) - { - *pipe_err = bcreate(p, B_RD); - bpushfd(*pipe_err, err_fds[0], err_fds[0]); - } - } - SetThreadPriority(thread_handle, old_priority); - (void)release_mutex(spawn_mutex); - /* - * go on to the end of the function, where you can - * unblock alarms and return the pid - */ - - } - #else - - if ((pid = fork()) < 0) { - save_errno = errno; - if (pipe_in) { - close (in_fds[0]); close (in_fds[1]); - } - if (pipe_out) { - close (out_fds[0]); close (out_fds[1]); - } - if (pipe_err) { - close (err_fds[0]); close (err_fds[1]); - } - unblock_alarms(); - errno = save_errno; - return 0; - } - - if (!pid) { - /* Child process */ - - if (pipe_out) { - close (out_fds[0]); - dup2 (out_fds[1], STDOUT_FILENO); - close (out_fds[1]); - } - - if (pipe_in) { - close (in_fds[1]); - dup2 (in_fds[0], STDIN_FILENO); - close (in_fds[0]); - } - - if (pipe_err) { - close (err_fds[0]); - dup2 (err_fds[1], STDERR_FILENO); - close (err_fds[1]); - } - - /* HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */ - signal (SIGCHLD, SIG_DFL); /* Was that it? */ - - func (data); - exit (1); /* Should only get here if the exec in func() failed */ - } - - /* Parent process */ - - note_subprocess (p, pid, kill_how); - - if (pipe_out) { - close (out_fds[1]); - *pipe_out = bcreate(p, B_RD); - bpushfd(*pipe_out, out_fds[0], out_fds[0]); - } - - if (pipe_in) { - close (in_fds[0]); - *pipe_in = bcreate(p, B_WR); - bpushfd(*pipe_in, in_fds[1], in_fds[1]); - } - - if (pipe_err) { - close (err_fds[1]); - *pipe_err = bcreate(p, B_RD); - bpushfd(*pipe_err, err_fds[0], err_fds[0]); - } - #endif /* WIN32 */ - - unblock_alarms(); - return pid; - } - API_EXPORT(int) spawn_child_err (pool *p, int (*func)(void *), void *data, enum kill_conditions kill_how, FILE **pipe_in, FILE **pipe_out, FILE **pipe_err) --- 1060,1065 ---- 1.18 +0 -4 apache/src/buff.h Index: buff.h =================================================================== RCS file: /export/home/cvs/apache/src/buff.h,v retrieving revision 1.17 retrieving revision 1.18 diff -C3 -r1.17 -r1.18 *** buff.h 1997/07/13 19:01:08 1.17 --- buff.h 1997/07/14 11:28:54 1.18 *************** *** 155,161 **** #define bputc(c, fb) ((((fb)->flags & (B_EOUT|B_WRERR|B_WR)) != B_WR || \ (fb)->outcnt == (fb)->bufsiz) ? bflsbuf(c, (fb)) : \ ((fb)->outbase[(fb)->outcnt++] = (c), 0)) - - API_EXPORT(int) spawn_child_err_buff (pool *, int (*)(void *), void *, - enum kill_conditions, BUFF **pipe_in, BUFF **pipe_out, - BUFF **pipe_err); --- 155,157 ---- 1.136 +0 -76 apache/src/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /export/home/cvs/apache/src/http_protocol.c,v retrieving revision 1.135 retrieving revision 1.136 diff -C3 -r1.135 -r1.136 *** http_protocol.c 1997/07/14 08:50:26 1.135 --- http_protocol.c 1997/07/14 11:28:55 1.136 *************** *** 1524,1605 **** return (chunk_start + len_read); } - long send_fb_length(BUFF *fb, request_rec *r, long length) - { - char buf[IOBUFSIZE]; - long total_bytes_sent; - register int n, w, o; - conn_rec *c = r->connection; - - if (length == 0) return 0; - - total_bytes_sent = 0; - - /* Clear out the buffer */ - if(fb->incnt != 0) - { - int o; - o = bwrite(c->client, fb->inptr, fb->incnt); - fb->incnt -= o; - fb->inptr += o; - total_bytes_sent += o; - } - - /* Make unbuffered */ - fb->flags &= ~B_RD; - - while(1) - { - fd_set fds; - - bflush(c->client); - - FD_ZERO(&fds); - FD_SET(fb->fd_in, &fds); - - select(FD_SETSIZE, &fds, NULL, NULL, NULL); - - while((n = bread(fb, buf, IOBUFSIZE)) < 1 - && fb->flags & B_ERROR && errno == EINTR) - continue; - - if (n < 1) { - break; - } - o=0; - total_bytes_sent += n; - - while (n && !r->connection->aborted) { - w = bwrite(r->connection->client, &buf[o], n); - if (w > 0) { - reset_timeout(r); /* reset timeout after successful write */ - n-=w; - o+=w; - } - else if (w < 0) { - if (r->connection->aborted) - break; - else if (errno == EAGAIN) - continue; - else { - log_unixerr("send body lost connection to", - get_remote_host(r->connection, - r->per_dir_config, REMOTE_NAME), - NULL, r->server); - bsetflag(r->connection->client, B_EOUT, 1); - r->connection->aborted = 1; - break; - } - } - } - } - - kill_timeout(r); - SET_BYTES_SENT(r); - return total_bytes_sent; - } - - API_EXPORT(long) send_fb(BUFF *fb, request_rec *r) { return send_fb_length(fb, r, -1); } long send_fd(FILE *f, request_rec *r) { return send_fd_length(f, r, -1); } --- 1524,1529 ---- 1.22 +0 -3 apache/src/http_protocol.h Index: http_protocol.h =================================================================== RCS file: /export/home/cvs/apache/src/http_protocol.h,v retrieving revision 1.21 retrieving revision 1.22 diff -C3 -r1.21 -r1.22 *** http_protocol.h 1997/07/13 19:01:13 1.21 --- http_protocol.h 1997/07/14 11:28:55 1.22 *************** *** 110,118 **** long send_fd(FILE *f, request_rec *r); long send_fd_length(FILE *f, request_rec *r, long length); - - API_EXPORT(long) send_fb(BUFF *f, request_rec *r); - long send_fb_length(BUFF *f, request_rec *r, long length); /* Hmmm... could macrofy these for now, and maybe forever, though the * definitions of the macros would get a whole lot hairier. --- 110,115 ---- 1.48 +47 -31 apache/src/mod_cgi.c Index: mod_cgi.c =================================================================== RCS file: /export/home/cvs/apache/src/mod_cgi.c,v retrieving revision 1.47 retrieving revision 1.48 diff -C3 -r1.47 -r1.48 *** mod_cgi.c 1997/07/14 02:38:04 1.47 --- mod_cgi.c 1997/07/14 11:28:56 1.48 *************** *** 183,189 **** } static int log_script(request_rec *r, cgi_server_conf *conf, int ret, ! char *dbuf, char *sbuf, BUFF *script_in, BUFF *script_err) { table *hdrs_arr = r->headers_in; table_entry *hdrs = (table_entry *)hdrs_arr->elts; --- 183,189 ---- } static int log_script(request_rec *r, cgi_server_conf *conf, int ret, ! char *dbuf, char *sbuf, FILE *script_in, FILE *script_err) { table *hdrs_arr = r->headers_in; table_entry *hdrs = (table_entry *)hdrs_arr->elts; *************** *** 197,205 **** ((f = pfopen(r->pool, server_root_relative(r->pool, conf->logname), "a")) == NULL)) { /* Soak up script output */ ! while (bgets(argsbuffer, HUGE_STRING_LEN, script_in)) continue; ! while (bgets(argsbuffer, HUGE_STRING_LEN, script_err)) continue; return ret; } --- 197,205 ---- ((f = pfopen(r->pool, server_root_relative(r->pool, conf->logname), "a")) == NULL)) { /* Soak up script output */ ! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in)) continue; ! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err)) continue; return ret; } *************** *** 207,213 **** /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ fprintf(f, "%%%% [%s] %s %s%s%s %s\n", get_time(), r->method, r->uri, r->args ? "?" : "", r->args ? r->args : "", r->protocol); ! /* "%% 500 /usr/local/etc/httpd/cgi-bin" */ fprintf(f, "%%%% %d %s\n", ret, r->filename); fputs("%request\n", f); --- 207,213 ---- /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */ fprintf(f, "%%%% [%s] %s %s%s%s %s\n", get_time(), r->method, r->uri, r->args ? "?" : "", r->args ? r->args : "", r->protocol); ! /* "%% 500 /usr/local/etc/httpd/cgi-bin */ fprintf(f, "%%%% %d %s\n", ret, r->filename); fputs("%request\n", f); *************** *** 216,222 **** fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); } if ((r->method_number == M_POST || r->method_number == M_PUT) ! && *dbuf) { fprintf(f, "\n%s\n", dbuf); } --- 216,222 ---- fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); } if ((r->method_number == M_POST || r->method_number == M_PUT) ! && dbuf && *dbuf) { fprintf(f, "\n%s\n", dbuf); } *************** *** 233,259 **** fprintf(f, "%s\n", sbuf); *argsbuffer = '\0'; ! bgets(argsbuffer, HUGE_STRING_LEN, script_in); if (*argsbuffer) { fputs("%stdout\n", f); fputs(argsbuffer, f); ! while (bgets(argsbuffer, HUGE_STRING_LEN, script_in)) fputs(argsbuffer, f); fputs("\n", f); } *argsbuffer = '\0'; ! bgets(argsbuffer, HUGE_STRING_LEN, script_err); if (*argsbuffer) { fputs("%stderr\n", f); fputs(argsbuffer, f); ! while (bgets(argsbuffer, HUGE_STRING_LEN, script_err)) fputs(argsbuffer, f); fputs("\n", f); } ! bclose(script_in); ! bclose(script_err); pfclose(r->pool, f); return ret; --- 233,259 ---- fprintf(f, "%s\n", sbuf); *argsbuffer = '\0'; ! fgets(argsbuffer, HUGE_STRING_LEN-1, script_in); if (*argsbuffer) { fputs("%stdout\n", f); fputs(argsbuffer, f); ! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in)) fputs(argsbuffer, f); fputs("\n", f); } *argsbuffer = '\0'; ! fgets(argsbuffer, HUGE_STRING_LEN-1, script_err); if (*argsbuffer) { fputs("%stderr\n", f); fputs(argsbuffer, f); ! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err)) fputs(argsbuffer, f); fputs("\n", f); } ! pfclose(r->main ? r->main->pool : r->pool, script_in); ! pfclose(r->main ? r->main->pool : r->pool, script_err); pfclose(r->pool, f); return ret; *************** *** 277,282 **** --- 277,283 ---- struct cgi_child_stuff *cld = (struct cgi_child_stuff *)child_stuff; request_rec *r = cld->r; char *argv0 = cld->argv0; + int nph = cld->nph; int child_pid; #ifdef DEBUG_CGI *************** *** 311,316 **** --- 312,321 ---- if (!cld->debug) error_log2stderr (r->server); + #if !defined(__EMX__) && !defined(WIN32) + if (nph) client_to_stdout (r->connection); + #endif + /* Transumute outselves into the script. * NB only ISINDEX scripts get decoded arguments. */ *************** *** 347,353 **** { int retval, nph, dbpos = 0; char *argv0, *dbuf = NULL; ! BUFF *script_out, *script_in, *script_err; char argsbuffer[HUGE_STRING_LEN]; int is_included = !strcmp (r->protocol, "INCLUDED"); void *sconf = r->server->module_config; --- 352,358 ---- { int retval, nph, dbpos = 0; char *argv0, *dbuf = NULL; ! FILE *script_out, *script_in, *script_err; char argsbuffer[HUGE_STRING_LEN]; int is_included = !strcmp (r->protocol, "INCLUDED"); void *sconf = r->server->module_config; *************** *** 416,425 **** * waiting for free_proc_chain to cleanup in the middle of an * SSI request -djg */ ! spawn_child_err_buff (r->main ? r->main->pool : r->pool, cgi_child, ! (void *)&cld, ! kill_after_timeout, ! &script_out, &script_in, &script_err))) { log_reason ("couldn't spawn child process", r->filename, r); return SERVER_ERROR; } --- 421,435 ---- * waiting for free_proc_chain to cleanup in the middle of an * SSI request -djg */ ! spawn_child_err (r->main ? r->main->pool : r->pool, cgi_child, ! (void *)&cld, ! nph ? just_wait : kill_after_timeout, ! #if defined(__EMX__) || defined(WIN32) ! &script_out, &script_in, &script_err))) { ! #else ! &script_out, nph ? NULL : &script_in, ! &script_err))) { ! #endif log_reason ("couldn't spawn child process", r->filename, r); return SERVER_ERROR; } *************** *** 461,467 **** dbpos += dbsize; } reset_timeout(r); ! if (bwrite(script_out, argsbuffer, len_read) < (size_t)len_read) { /* silly script stopped reading, soak up remaining message */ while (get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0) --- 471,477 ---- dbpos += dbsize; } reset_timeout(r); ! if (fwrite(argsbuffer, sizeof(char), len_read, script_out) < (size_t)len_read) { /* silly script stopped reading, soak up remaining message */ while (get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0) *************** *** 470,489 **** } } ! bflush (script_out); signal (SIGPIPE, handler); kill_timeout (r); } ! bclose(script_out); /* Handle script return... */ if (script_in && !nph) { char *location, sbuf[MAX_STRING_LEN]; int ret; ! if ((ret = scan_script_header_err_buff(r, script_in, sbuf))) return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err); location = table_get (r->headers_out, "Location"); --- 480,499 ---- } } ! fflush (script_out); signal (SIGPIPE, handler); kill_timeout (r); } ! pfclose (r->main ? r->main->pool : r->pool, script_out); /* Handle script return... */ if (script_in && !nph) { char *location, sbuf[MAX_STRING_LEN]; int ret; ! if ((ret = scan_script_header_err(r, script_in, sbuf))) return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err); location = table_get (r->headers_out, "Location"); *************** *** 492,500 **** /* Soak up all the script output */ hard_timeout ("read from script", r); ! while (bgets(argsbuffer, HUGE_STRING_LEN, script_in)) continue; ! while (bgets(argsbuffer, HUGE_STRING_LEN, script_err)) continue; kill_timeout (r); --- 502,512 ---- /* Soak up all the script output */ hard_timeout ("read from script", r); ! while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_in) ! > 0) continue; ! while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err) ! > 0) continue; kill_timeout (r); *************** *** 523,542 **** send_http_header(r); if (!r->header_only) ! send_fb(script_in, r); soft_timeout("soaking script stderr", r); ! while(bgets(argsbuffer, HUGE_STRING_LEN, script_err)) ! continue; kill_timeout(r); ! ! bclose(script_in); ! bclose(script_out); } ! if (script_in && nph) { ! send_fb(script_in, r); ! #if !defined(__EMX__) && !defined(WIN32) waitpid(child_pid, (int*)0, 0); #endif } --- 535,558 ---- send_http_header(r); if (!r->header_only) ! send_fd(script_in, r); ! pfclose (r->main ? r->main->pool : r->pool, script_in); + /* Soak up stderr */ soft_timeout("soaking script stderr", r); ! while (!r->connection->aborted && ! (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err) > 0)) ! continue; kill_timeout(r); ! pfclose (r->main ? r->main->pool : r->pool, script_err); } ! if (nph) { ! #if defined(__EMX__) || defined(WIN32) ! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL) { ! bputs(argsbuffer, r->connection->client); ! } ! #else waitpid(child_pid, (int*)0, 0); #endif } 1.65 +0 -89 apache/src/util_script.c Index: util_script.c =================================================================== RCS file: /export/home/cvs/apache/src/util_script.c,v retrieving revision 1.64 retrieving revision 1.65 diff -C3 -r1.64 -r1.65 *** util_script.c 1997/07/13 19:01:16 1.64 --- util_script.c 1997/07/14 11:28:56 1.65 *************** *** 312,406 **** } } - API_EXPORT(int) scan_script_header_err_buff(request_rec *r, BUFF *fb, char *buffer) - { - char x[MAX_STRING_LEN]; - char *w, *l; - int p; - - if (buffer) *buffer = '\0'; - w = buffer ? buffer : x; - - hard_timeout ("read script header", r); - - while(1) { - - if (bgets(w, MAX_STRING_LEN-1, fb) <= 0) { - log_reason ("Premature end of script headers", r->filename, r); - return SERVER_ERROR; - } - - /* Delete terminal (CR?)LF */ - - p = strlen(w); - if (p > 0 && w[p-1] == '\n') - { - if (p > 1 && w[p-2] == '\015') w[p-2] = '\0'; - else w[p-1] = '\0'; - } - - if(w[0] == '\0') { - kill_timeout (r); - return OK; - } - - /* if we see a bogus header don't ignore it. Shout and scream */ - - if(!(l = strchr(w,':'))) { - char malformed[(sizeof MALFORMED_MESSAGE)+1+MALFORMED_HEADER_LENGTH_TO_SHOW]; - strcpy(malformed, MALFORMED_MESSAGE); - strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW); - - if (!buffer) - /* Soak up all the script output --- may save an outright kill */ - while (bgets(w, MAX_STRING_LEN-1, fb) <= 0) - continue; - - kill_timeout (r); - log_reason (malformed, r->filename, r); - return SERVER_ERROR; - } - - *l++ = '\0'; - while (*l && isspace (*l)) ++l; - - if(!strcasecmp(w,"Content-type")) { - - /* Nuke trailing whitespace */ - - char *endp = l + strlen(l) - 1; - while (endp > l && isspace(*endp)) *endp-- = '\0'; - - r->content_type = pstrdup (r->pool, l); - } - else if(!strcasecmp(w,"Status")) { - sscanf(l, "%d", &r->status); - r->status_line = pstrdup(r->pool, l); - } - else if(!strcasecmp(w,"Location")) { - table_set (r->headers_out, w, l); - } - else if(!strcasecmp(w,"Content-Length")) { - table_set (r->headers_out, w, l); - } - else if(!strcasecmp(w,"Transfer-Encoding")) { - table_set (r->headers_out, w, l); - } - - /* The HTTP specification says that it is legal to merge duplicate - * headers into one. Some browsers that support Cookies don't like - * merged headers and prefer that each Set-Cookie header is sent - * separately. Lets humour those browsers. - */ - else if(!strcasecmp(w, "Set-Cookie")) { - table_add(r->err_headers_out, w, l); - } - else { - table_merge (r->err_headers_out, w, l); - } - } - } - int scan_script_header_err(request_rec *r, FILE *f, char *buffer) { char x[MAX_STRING_LEN]; --- 312,317 ---- 1.20 +0 -1 apache/src/util_script.h Index: util_script.h =================================================================== RCS file: /export/home/cvs/apache/src/util_script.h,v retrieving revision 1.19 retrieving revision 1.20 diff -C3 -r1.19 -r1.20 *** util_script.h 1997/07/13 19:01:17 1.19 --- util_script.h 1997/07/14 11:28:56 1.20 *************** *** 64,70 **** API_EXPORT(void) add_common_vars(request_rec *r); #define scan_script_header(a1,a2) scan_script_header_err(a1,a2,NULL) int scan_script_header_err(request_rec *r, FILE *f, char *buffer); - API_EXPORT(int) scan_script_header_err_buff(request_rec *r, BUFF *f, char *buffer); void send_size(size_t size, request_rec *r); API_EXPORT(int) call_exec (request_rec *r, char *argv0, char **env, int shellcmd); --- 64,69 ----