X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fproc.c;h=2c05608eb098eb313dcc085630d2cdd1d7a675dd;hb=470938bdc9149ae9c7befd0cd983f46fcc056192;hp=f7b0d9b454d741b3c88d089576ea6dbc6f2586b9;hpb=0c16b4068d625a9b9b384a9fc2a07ee3c5c762c9;p=ashd.git diff --git a/lib/proc.c b/lib/proc.c index f7b0d9b..2c05608 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #ifdef HAVE_CONFIG_H #include @@ -28,29 +30,29 @@ #include #include #include +#include -int stdmkchild(char **argv) +int stdmkchild(char **argv, void (*chinit)(void *), void *idata) { - int i; pid_t pid; int fd[2]; - if(socketpair(PF_UNIX, SOCK_DGRAM, 0, fd)) + if(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fd)) return(-1); if((pid = fork()) < 0) return(-1); if(pid == 0) { - for(i = 3; i < FD_SETSIZE; i++) { - if(i != fd[0]) - close(i); - } + if(chinit != NULL) + chinit(idata); dup2(fd[0], 0); close(fd[0]); + close(fd[1]); execvp(argv[0], argv); flog(LOG_WARNING, "could not exec child program %s: %s", argv[0], strerror(errno)); exit(127); } close(fd[0]); + fcntl(fd[1], F_SETFD, FD_CLOEXEC); return(fd[1]); } @@ -82,7 +84,7 @@ int sendfd(int sock, int fd, char *data, size_t datalen) int recvfd(int sock, char **data, size_t *datalen) { int ret, fd; - char *buf, cbuf[1024];; + char *buf, cbuf[1024]; struct msghdr msg; struct cmsghdr *cmsg; struct iovec bufvec; @@ -98,8 +100,10 @@ int recvfd(int sock, char **data, size_t *datalen) msg.msg_controllen = sizeof(cbuf); ret = recvmsg(sock, &msg, 0); - if(ret < 0) { + if(ret <= 0) { free(buf); + if(ret == 0) + errno = 0; return(-1); } @@ -119,3 +123,47 @@ int recvfd(int sock, char **data, size_t *datalen) *datalen = ret; return(fd); } + +pid_t stdforkserve(char **argv, struct hthead *req, int fd, void (*chinit)(void *), void *idata) +{ + int i; + char *ebuf, *p; + pid_t pid; + struct charvbuf args; + + if((pid = fork()) < 0) + return(-1); + if(pid == 0) { + if(chinit != NULL) + chinit(idata); + + dup2(fd, 0); + dup2(fd, 1); + close(fd); + + bufinit(args); + for(i = 0; argv[i]; i++) + bufadd(args, argv[i]); + bufadd(args, req->method); + bufadd(args, req->url); + bufadd(args, req->rest); + bufadd(args, NULL); + + for(i = 0; i < req->noheaders; i++) { + ebuf = sstrdup(req->headers[i][0]); + for(p = ebuf; *p; p++) { + if(isalnum(*p)) + *p = toupper(*p); + else + *p = '_'; + } + putenv(sprintf2("REQ_%s=%s", ebuf, req->headers[i][1])); + } + putenv(sprintf2("HTTP_VERSION=%s", req->ver)); + + execvp(args.b[0], args.b); + flog(LOG_WARNING, "could not exec child program %s: %s", argv[0], strerror(errno)); + exit(127); + } + return(pid); +}