From 0c16b4068d625a9b9b384a9fc2a07ee3c5c762c9 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Tue, 16 Dec 2008 16:41:29 +0100 Subject: [PATCH] Added some process control functions to libht. --- lib/Makefile.am | 2 +- lib/proc.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/proc.h | 8 ++++ 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 lib/proc.c create mode 100644 lib/proc.h diff --git a/lib/Makefile.am b/lib/Makefile.am index d234043..30c1dee 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,4 +1,4 @@ noinst_LIBRARIES = libht.a -libht_a_SOURCES = utils.c mt.c log.c req.c +libht_a_SOURCES = utils.c mt.c log.c req.c proc.c libht_a_CFLAGS = -fPIC diff --git a/lib/proc.c b/lib/proc.c new file mode 100644 index 0000000..f7b0d9b --- /dev/null +++ b/lib/proc.c @@ -0,0 +1,121 @@ +/* + ashd - A Sane HTTP Daemon + Copyright (C) 2008 Fredrik Tolf + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include + +int stdmkchild(char **argv) +{ + int i; + pid_t pid; + int fd[2]; + + if(socketpair(PF_UNIX, SOCK_DGRAM, 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); + } + dup2(fd[0], 0); + close(fd[0]); + execvp(argv[0], argv); + flog(LOG_WARNING, "could not exec child program %s: %s", argv[0], strerror(errno)); + exit(127); + } + close(fd[0]); + return(fd[1]); +} + +int sendfd(int sock, int fd, char *data, size_t datalen) +{ + struct msghdr msg; + struct cmsghdr *cmsg; + char cmbuf[CMSG_SPACE(sizeof(int))]; + struct iovec bufvec; + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &bufvec; + msg.msg_iovlen = 1; + bufvec.iov_base = data; + bufvec.iov_len = datalen; + + msg.msg_control = cmbuf; + msg.msg_controllen = sizeof(cmbuf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + *((int *)CMSG_DATA(cmsg)) = fd; + msg.msg_controllen = cmsg->cmsg_len; + + return(sendmsg(sock, &msg, MSG_NOSIGNAL | MSG_DONTWAIT)); +} + +int recvfd(int sock, char **data, size_t *datalen) +{ + int ret, fd; + char *buf, cbuf[1024];; + struct msghdr msg; + struct cmsghdr *cmsg; + struct iovec bufvec; + + buf = smalloc(65536); + memset(&msg, 0, sizeof(msg)); + + msg.msg_iov = &bufvec; + msg.msg_iovlen = 1; + bufvec.iov_base = buf; + bufvec.iov_len = 65536; + msg.msg_control = cbuf; + msg.msg_controllen = sizeof(cbuf); + + ret = recvmsg(sock, &msg, 0); + if(ret < 0) { + free(buf); + return(-1); + } + + fd = -1; + for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if((cmsg->cmsg_level == SOL_SOCKET) && (cmsg->cmsg_type == SCM_RIGHTS)) { + fd = *((int *)CMSG_DATA(cmsg)); + } + } + if(fd < 0) { + free(buf); + errno = EPROTO; + return(-1); + } + buf = realloc(buf, ret); + *data = buf; + *datalen = ret; + return(fd); +} diff --git a/lib/proc.h b/lib/proc.h new file mode 100644 index 0000000..943e598 --- /dev/null +++ b/lib/proc.h @@ -0,0 +1,8 @@ +#ifndef _LIB_PROC_H +#define _LIB_PROC_H + +int stdmkchild(char **argv); +int sendfd(int sock, int fd, char *data, size_t datalen); +int recvfd(int sock, char **data, size_t *datalen); + +#endif -- 2.11.0