|
|
|
@ -1,11 +1,14 @@ |
|
|
|
|
#include <sys/types.h> |
|
|
|
|
#include <sys/time.h> |
|
|
|
|
#include <sys/stat.h> |
|
|
|
|
|
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <errno.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
#include <fcntl.h> |
|
|
|
|
|
|
|
|
|
#include "config.h" |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_PWD_H |
|
|
|
@ -35,7 +38,7 @@ typedef int socklen_t; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_UN_H |
|
|
|
|
int fcgi_spawn_connection(char *appPath, unsigned short port, const char *unixsocket, int child_count) { |
|
|
|
|
int fcgi_spawn_connection(char *appPath, unsigned short port, const char *unixsocket, int child_count, int pid_fd) { |
|
|
|
|
int fcgi_fd; |
|
|
|
|
int socket_type, status; |
|
|
|
|
struct timeval tv = { 0, 100 * 1000 }; |
|
|
|
@ -159,6 +162,19 @@ int fcgi_spawn_connection(char *appPath, unsigned short port, const char *unixso |
|
|
|
|
fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n",
|
|
|
|
|
__FILE__, __LINE__, |
|
|
|
|
child); |
|
|
|
|
|
|
|
|
|
/* write pid file */ |
|
|
|
|
if (pid_fd != -1) { |
|
|
|
|
/* assume a 32bit pid_t */ |
|
|
|
|
char pidbuf[12]; |
|
|
|
|
|
|
|
|
|
snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child); |
|
|
|
|
|
|
|
|
|
write(pid_fd, pidbuf, strlen(pidbuf)); |
|
|
|
|
close(pid_fd); |
|
|
|
|
pid_fd = -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
case -1: |
|
|
|
|
break; |
|
|
|
@ -208,6 +224,7 @@ void show_help () { |
|
|
|
|
" -p <port> bind to tcp-port\n" \
|
|
|
|
|
" -s <path> bind to unix-domain socket\n" \
|
|
|
|
|
" -C <childs> (PHP only) numbers of childs to spawn (default 5)\n" \
|
|
|
|
|
" -P <path> name of PID-file for spawed process\n" \
|
|
|
|
|
" -v show version\n" \
|
|
|
|
|
" -h show this help\n" \
|
|
|
|
|
"(root only)\n" \
|
|
|
|
@ -220,14 +237,16 @@ void show_help () { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv) { |
|
|
|
|
char *fcgi_app = NULL, *changeroot = NULL, *username = NULL, *groupname = NULL, *unixsocket = NULL; |
|
|
|
|
char *fcgi_app = NULL, *changeroot = NULL, *username = NULL,
|
|
|
|
|
*groupname = NULL, *unixsocket = NULL, *pid_file = NULL; |
|
|
|
|
unsigned short port = 0; |
|
|
|
|
int child_count = 5; |
|
|
|
|
int i_am_root, o; |
|
|
|
|
int pid_fd = -1; |
|
|
|
|
|
|
|
|
|
i_am_root = (getuid() == 0); |
|
|
|
|
|
|
|
|
|
while(-1 != (o = getopt(argc, argv, "c:f:g:hp:u:vC:s:"))) { |
|
|
|
|
while(-1 != (o = getopt(argc, argv, "c:f:g:hp:u:vC:s:P:"))) { |
|
|
|
|
switch(o) { |
|
|
|
|
case 'f': fcgi_app = optarg; break; |
|
|
|
|
case 'p': port = strtol(optarg, NULL, 10);/* port */ break; |
|
|
|
@ -236,6 +255,7 @@ int main(int argc, char **argv) { |
|
|
|
|
case 'c': if (i_am_root) { changeroot = optarg; }/* chroot() */ break; |
|
|
|
|
case 'u': if (i_am_root) { username = optarg; } /* set user */ break; |
|
|
|
|
case 'g': if (i_am_root) { groupname = optarg; } /* set group */ break; |
|
|
|
|
case 'P': pid_file = optarg; /* PID file */ break; |
|
|
|
|
case 'v': show_version(); return 0; |
|
|
|
|
case 'h': show_help(); return 0; |
|
|
|
|
default:
|
|
|
|
@ -276,6 +296,46 @@ int main(int argc, char **argv) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pid_file &&
|
|
|
|
|
(-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) { |
|
|
|
|
struct stat st; |
|
|
|
|
if (errno != EEXIST) { |
|
|
|
|
fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
|
|
|
|
|
__FILE__, __LINE__, |
|
|
|
|
pid_file, strerror(errno)); |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ok, file exists */ |
|
|
|
|
|
|
|
|
|
if (0 != stat(pid_file, &st)) { |
|
|
|
|
fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n",
|
|
|
|
|
__FILE__, __LINE__, |
|
|
|
|
pid_file, strerror(errno)); |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* is it a regular file ? */ |
|
|
|
|
|
|
|
|
|
if (!S_ISREG(st.st_mode)) { |
|
|
|
|
fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n",
|
|
|
|
|
__FILE__, __LINE__, |
|
|
|
|
pid_file); |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) { |
|
|
|
|
fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
|
|
|
|
|
__FILE__, __LINE__, |
|
|
|
|
pid_file, strerror(errno)); |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (i_am_root) { |
|
|
|
|
struct group *grp = NULL; |
|
|
|
|
struct passwd *pwd = NULL; |
|
|
|
@ -337,7 +397,7 @@ int main(int argc, char **argv) { |
|
|
|
|
if (username) setuid(pwd->pw_uid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return fcgi_spawn_connection(fcgi_app, port, unixsocket, child_count); |
|
|
|
|
return fcgi_spawn_connection(fcgi_app, port, unixsocket, child_count, pid_fd); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
int main() { |
|
|
|
|