Patch for using fnord on MMUless machines
Erich Schubert <[email protected]> Thu, 23 Sep 2004 14:21:54 +0200
| Newsgroups | gmane.comp.web.fnord |
|---|---|
| Message-ID | <[email protected]> |
--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi,
i'm running fnord on a MMUless ARM machine. Attached is a patch
modifying fnord to
* use vfork() instead of fork()
* allocate less memory on the stack and more on the heap (mmuless
machines often have a fixed stack)
* fork as late as possible (to avoid vfork errors)
It should work the same on machines with MMU, i don't know about the
performance impacts of my changes. Using the stack might be cheaper, and
it certainly is nicer code without that extra free() at the end...
Greetings,
Erich Schubert
--
erich@(vitavonni.de|debian.org) -- GPG Key ID: 4B3A135C (o_
A polar bear is a rectangular bear after a coordinate transform. //\
Es ist besser, geliebt und verloren zu haben, V_/_
als niemals geliebt zu haben.
--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fnord-nommu-vfork.patch"
# * Avoid allocating large chunks on the stack
# * Fork as late as possible
# * use vfork - mmuless machines don't have fork()
# Erich Schubert <[email protected]>
diff -Nru fnord-1.8/httpd.c /home/eschubert/firm/uClinux/apps-gpl/fnord/httpd.c
--- fnord-1.8/httpd.c 2004-09-23 14:05:02.000000000 +0200
+++ fnord/httpd.c 2004-08-05 15:52:52.000000000 +0200
@@ -254,14 +254,15 @@
return i;
}
-static void do_cgi(const char* pathinfo,const char* const* envp) {
+static int do_cgi(const char* pathinfo,const char* const* envp, int fd0, int fd1, int df0, int df1) {
const char *method_name[]={ "?", "GET", "HEAD", "POST"};
- char cgi_env_buf[MAXHEADERLEN*2+PATH_MAX+200];
+ char *cgi_env_buf = malloc(MAXHEADERLEN*2+PATH_MAX+200);
register unsigned int en=elen(envp);
+ int pid;
char *tmp=cgi_env_buf;
char **cgi_arg;
register int i;
- char **cgi_env=(char **)alloca((CGIENVLEN+en+1)*sizeof(char *)) ;
+ char **cgi_env=(char **)malloc((CGIENVLEN+en+1)*sizeof(char *)) ;
cgi_env[0]="GATEWAY_INTERFACE=CGI/1.1";
cgi_env[1]="SERVER_PROTOCOL=HTTP/1.0";
@@ -389,7 +390,7 @@
if (args && (args[str_chr(args,'=')]==0)) {
int n=3;
for (i=0;args[i];++i) if (args[i]=='+') ++n;
- cgi_arg=alloca(n*sizeof(char*));
+ cgi_arg=malloc(n*sizeof(char*));
cgi_arg[n=1]=args;
for (i=0;args[i];++i) {
if (args[i]=='+') {
@@ -400,7 +401,7 @@
}
cgi_arg[++n]=0;
} else {
- cgi_arg=alloca(2*sizeof(char*));
+ cgi_arg=malloc(2*sizeof(char*));
cgi_arg[1]=0;
}
@@ -410,8 +411,25 @@
tmp[str_copy(tmp+1,url)+1]=0;
/* start cgi */
- execve(cgi_arg[0],cgi_arg,cgi_env);
- raise(SIGQUIT); /* gateway unavailable. */
+ if (!(pid=vfork())) {
+ close(df1);
+ close(fd0);
+
+ dup2(df0,0);
+ dup2(fd1,1);
+
+ close(df0);
+ close(fd1);
+
+ alarm(CGI_TIMEOUT);
+ execve(cgi_arg[0],cgi_arg,cgi_env);
+ raise(SIGQUIT); /* gateway unavailable. */
+ }
+ /* clean up cgi_arg, cgi_env */
+ free(cgi_env_buf);
+ free(cgi_env);
+ if (cgi_arg) free(cgi_arg);
+ return pid;
}
static void cgi_child(int sig) {
@@ -457,7 +475,7 @@
badrequest(500,"Internal Server Error","Server Resource problem.");
}
- if ((pid=fork())) {
+ if ( (pid=do_cgi(pathinfo,envp,fd[0],fd[1],df[0],df[1])) ) {
if (pid>0) {
struct pollfd pfd[2];
int nr=1;
@@ -555,19 +573,6 @@
#endif
}
}
- else {
- close(df[1]);
- close(fd[0]);
-
- dup2(df[0],0);
- dup2(fd[1],1);
-
- close(df[0]);
- close(fd[1]);
-
- alarm(CGI_TIMEOUT);
- do_cgi(pathinfo,envp);
- }
exit(0);
}
#endif
@@ -977,7 +982,7 @@
while (testurl[0]=='/') ++testurl,--ol;
ul=str_len(testurl);
if (str_diff(testurl+ol,"index.html")) return 0; /* no request for index.html */
- test=alloca(ul+1);
+ test=malloc(ul+1);
++test;
ul-=4;
byte_copy(test,ul,testurl);
@@ -1334,7 +1339,7 @@
int i;
host=header(buf,len,"Host");
if (!host) i=100; else i=str_len(host)+7;
- Buf=alloca(i);
+ Buf=malloc(i);
if (!host) {
char *ip=getenv("TCPLOCALIP");
if (!ip) ip="127.0.0.1";
@@ -1391,6 +1396,7 @@
badrequest(404,"Not Found","<title>Not Found</title>This host is not served here.");
}
}
+ free(Buf);
}
#ifdef AUTH
{
@@ -1402,15 +1408,15 @@
const char *authorization;
authorization = header(buf, len, "Authorization");
- child = fork();
- if(child < 0) {
- badrequest(500, "Internal Server Error", "Server Resource problem.");
- } else if(child == 0) {
+ child = vfork();
+ if(child == 0) {
const char *argv[5] = { auth_script, host, url, authorization, NULL };
dup2(2, 1);
execve(auth_script, argv, envp);
_exit(1);
+ } else if(child < 0) {
+ badrequest(500, "Internal Server Error", "Server Resource problem.");
} else {
int status;
pid_t childr;
--Q68bSM7Ycu6FN28Q--