#include #include #include #define BUF_SIZE 8192 //#define STRING(str) #str //#define BUF_FILL_FORMAT "%" STRING(BUF_SIZE) "c" #define BUF_FILL_FORMAT "%8192c" #define IPC_DIR "ipc" #define PATH_SEPARATOR "/" #define CLIENT_LOCK_PATH IPC_DIR PATH_SEPARATOR "client.lock" #define SERVER_LOCK_PATH IPC_DIR PATH_SEPARATOR "server.lock" #define SERVER_ENVIRONMENT_PATH IPC_DIR PATH_SEPARATOR "server.environment" #define SERVER_STDIN_PATH IPC_DIR PATH_SEPARATOR "server.stdin" #define SERVER_STDOUT_PATH IPC_DIR PATH_SEPARATOR "server.stdout" #define SERVER_STDERR_PATH IPC_DIR PATH_SEPARATOR "server.stderr" #define SERVER_RB "nohup ruby ./server.cgi /dev/null 2>&1 &" static int argc; static char **argv; static char **env; static FILE *fs_client_lock; static FILE *fs_server_lock; static FILE *fs_environment; static FILE *fs_stdin; static FILE *fs_stderr; static FILE *fs_stdout; static struct flock lock; static char **e; static char buf[BUF_SIZE]; static int n; static void ensure_server_running () { int ret; char *cmd; fs_server_lock = fopen (SERVER_LOCK_PATH, "w"); lock.l_type = F_WRLCK; if(fcntl (fileno (fs_server_lock), F_SETLK, &lock) == 0) { cmd = SERVER_RB; system (cmd); lock.l_type = F_UNLCK; fcntl (fileno (fs_server_lock), F_SETLKW, &lock); } } static void aquire_lock () { fs_client_lock = fopen (CLIENT_LOCK_PATH, "w"); lock.l_type = F_WRLCK; fcntl (fileno (fs_client_lock), F_SETLKW, &lock); } static void send_env () { fs_environment = fopen (SERVER_ENVIRONMENT_PATH, "w"); for (e = env; *e; e++) { fprintf (fs_environment, "%s%c", *e, '\0'); } fclose (fs_environment); } static void send_stdin () { buf[0] = n = 0; fs_stdin = fopen (SERVER_STDIN_PATH, "w"); while ((n = fscanf (stdin, BUF_FILL_FORMAT, &buf[0])) > 0) { fprintf (fs_stdin, "%*s", n, buf); } fclose (fs_stdin); } static void open_stdout_and_stderr () { fs_stdout = fopen (SERVER_STDOUT_PATH, "r"); fs_stderr = fopen (SERVER_STDERR_PATH, "r"); } static void receive_stdout () { buf[0] = n = 0; while ((n = fscanf (fs_stdout, BUF_FILL_FORMAT, &buf[0])) > 0) { fprintf (stdout, "%*s", n, buf); } fclose (fs_stdout); } static void receive_stderr () { buf[0] = n = 0; while ((n = fscanf (fs_stderr, BUF_FILL_FORMAT, &buf[0])) > 0) { fprintf (stderr, "%*s", n, buf); } fclose (fs_stderr); } static void release_lock () { lock.l_type = F_UNLCK; fcntl (fileno (fs_client_lock), F_SETLK, &lock); } int main (__argc, __argv, __env) int __argc; char **__argv; char **__env; { argc = __argc; argv = __argv; env = __env; putenv ("ACGI_SERVER=1"); ensure_server_running (); aquire_lock (); send_env (); send_stdin (); open_stdout_and_stderr (); receive_stdout (); receive_stderr (); release_lock (); return 0; }