You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Ralf S. Engelschall" <rs...@engelschall.com> on 1998/05/21 14:04:42 UTC
[PATCH] Spawning-stuff in mod_rewrite for Win32 with pinfo (FOR BEN!)
The below patch is the best solution I found to repair the spawning-stuff in
mod_rewrite for Win32 with pinfo. I _HAVEN'T TESTED IT_ because I cannot test
it (currently not even a useable Windows NT). I've created it blindly
extracting the relevant parts from ap_call_exec() which should only be
relavant for mod_rewrite.
Background:
The "RewriteMap ... prg:/path/to/program" directive spawns /path/to/program
once at startup and communicates with it via STDIN/STDOUT. In principle
ap_open_piped_log() should be used but this doesn't work correctly for really
reading _AND_ writing to a program even when I patch http_log.c to make STDOUT
available. The communication loops and we have not the time to make such a big
change. On the other hand the old mechanism needs to exec() the child
manually. Here the other modules use ap_call_exec() which does a lot of
horrible hacking for Win32, EMX, etc. This also cannot be used by mod_rewrite
because it assumes to have a request_rec to operate on. But the RewriteMap
program is run at startup only one (and not started in the middle of
requests), there is no such request_rec available. And third, to make
RewriteMap programs available to Win32 the new pinfo stuff should be used.
ARGL, what an ugly situation I was forced into...
Workaround:
I looked at the rewritemap_program_child() where the pinfo stuff was still not
used and tried to place there the minimal stuff from ap_call_exec() which
should be needed to make Win32 happy.
NOT IT'S YOUR TURN, BEN: I cannot test it. You have to test it for us, please.
Or at least review it in theory. When you want to test it, you could use
a ruleset like
RewriteEngine on
RewriteLog logs/rewrite_log
RewriteLogLevel 9
RewriteMap test prg:/path/to/test.pl
RewriteRule ^/foo/(.*)$ /foo/${test:$1|$1} [R,L]
and a test.pl with
#!/sw/bin/perl
$|++;
while (<STDIN>) {
$url = $_;
$url =~ s|\n$||;
print STDOUT $url . '/fucking_win32_stuff/' . "\n";
}
This should redirect any /foo/ URLs to a simular one with
/fucking_win32_stuff/ appended.
Greetings,
Ralf S. Engelschall
rse@engelschall.com
www.engelschall.com
Index: mod_rewrite.c
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/modules/standard/mod_rewrite.c,v
retrieving revision 1.106
diff -u -r1.106 mod_rewrite.c
--- mod_rewrite.c 1998/05/21 10:48:35 1.106
+++ mod_rewrite.c 1998/05/21 11:51:44
@@ -3127,6 +3127,7 @@
rewrite_server_conf *conf;
FILE *fpin;
FILE *fpout;
+ FILE *fperr;
array_header *rewritemaps;
rewritemap_entry *entries;
rewritemap_entry *map;
@@ -3154,16 +3155,18 @@
continue;
fpin = NULL;
fpout = NULL;
- rc = spawn_child(p, rewritemap_program_child, (void *)map->datafile,
- kill_after_timeout, &fpin, &fpout);
+ rc = ap_spawn_child_err(p, rewritemap_program_child,
+ (void *)map->datafile, kill_after_timeout,
+ &fpin, &fpout, &fperr);
if (rc == 0 || fpin == NULL || fpout == NULL) {
- perror("spawn_child");
+ perror("ap_spawn_child");
fprintf(stderr, "mod_rewrite: "
"could not fork child for RewriteMap process\n");
exit(1);
}
map->fpin = fileno(fpin);
map->fpout = fileno(fpout);
+ map->fperr = fileno(fperr);
}
return;
}
@@ -3173,17 +3176,48 @@
{
int child_pid = 1;
+ /*
+ * Prepare for exec
+ */
ap_cleanup_for_exec();
#ifdef SIGHUP
signal(SIGHUP, SIG_IGN);
#endif
+
+ /*
+ * Exec() the child program
+ */
#if defined(WIN32)
- child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH,
- "/c", (char *)cmd, NULL);
+ /* MS Windows */
+ {
+ char *pCommand;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ pCommand = strcat("CMD.EXE", " /C ", cmd, NULL);
+
+ memset(&si, 0, sizeof(si));
+ memset(&pi, 0, sizeof(pi));
+
+ si.cb = sizeof(si);
+ si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
+ si.wShowWindow = SW_HIDE;
+ si.hStdInput = pinfo->hPipeInputRead;
+ si.hStdOutput = pinfo->hPipeOutputWrite;
+ si.hStdError = pinfo->hPipeErrorWrite;
+
+ if (CreateProcess(NULL, pCommand, NULL, NULL, TRUE, 0,
+ environ, NULL, &si, &pi)) {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ child_pid = pi.dwProcessId;
+ }
+ }
#elif defined(__EMX__)
- /* OS/2 needs a '/' */
+ /* IBM OS/2 */
execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
+ /* Standard Unix */
execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
return(child_pid);
Index: mod_rewrite.h
===================================================================
RCS file: /e/apache/REPOS/apache-1.3/src/modules/standard/mod_rewrite.h,v
retrieving revision 1.51
diff -u -r1.51 mod_rewrite.h
--- mod_rewrite.h 1998/05/20 15:34:27 1.51
+++ mod_rewrite.h 1998/05/21 11:34:39
@@ -252,6 +252,7 @@
int type; /* the type of the map */
int fpin; /* in file pointer for program maps */
int fpout; /* out file pointer for program maps */
+ int fperr; /* err file pointer for program maps */
char *(*func)(request_rec *, /* function pointer for internal maps */
char *);
} rewritemap_entry;