version 0.2.1
[fms.git] / libs / shttpd / compat_unix.c
1 /*
2  * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
3  * All rights reserved
4  *
5  * "THE BEER-WARE LICENSE" (Revision 42):
6  * Sergey Lyubka wrote this file.  As long as you retain this notice you
7  * can do whatever you want with this stuff. If we meet some day, and you think
8  * this stuff is worth it, you can buy me a beer in return.
9  */
10
11 #include "defs.h"
12
13 void 
14 set_close_on_exec(int fd)
15 {
16         (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
17 }
18
19 int
20 my_stat(const char *path, struct stat *stp)
21 {
22         return (stat(path, stp));
23 }
24
25 int
26 my_open(const char *path, int flags, int mode)
27 {
28         return (open(path, flags, mode));
29 }
30
31 int
32 my_remove(const char *path)
33 {
34         return (remove(path));
35 }
36
37 int
38 my_rename(const char *path1, const char *path2)
39 {
40         return (rename(path1, path2));
41 }
42
43 int
44 my_mkdir(const char *path, int mode)
45 {
46         return (mkdir(path, mode));
47 }
48
49 char *
50 my_getcwd(char *buffer, int maxlen)
51 {
52         return (getcwd(buffer, maxlen));
53 }
54
55 int
56 set_non_blocking_mode(int fd)
57 {
58         int     ret = -1;
59         int     flags;
60
61         if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
62                 DBG(("nonblock: fcntl(F_GETFL): %d", ERRNO));
63         } else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
64                 DBG(("nonblock: fcntl(F_SETFL): %d", ERRNO));
65         } else {
66                 ret = 0;        /* Success */
67         }
68
69         return (ret);
70 }
71
72 #ifndef NO_CGI
73 int
74 spawn_process(struct conn *c, const char *prog, char *envblk,
75                 char *envp[], int sock, const char *dir)
76 {
77         int             ret;
78         pid_t           pid;
79         const char      *p, *interp = c->ctx->options[OPT_CGI_INTERPRETER];
80
81         envblk = NULL;  /* unused */
82
83         if ((pid = vfork()) == -1) {
84
85                 ret = -1;
86                 elog(E_LOG, c, "redirect: fork: %s", strerror(errno));
87
88         } else if (pid == 0) {
89
90                 /* Child */
91
92                 (void) chdir(dir);
93                 (void) dup2(sock, 0);
94                 (void) dup2(sock, 1);
95                 (void) closesocket(sock);
96
97                 /* If error file is specified, send errors there */
98                 if (c->ctx->error_log)
99                         (void) dup2(fileno(c->ctx->error_log), 2);
100
101                 if ((p = strrchr(prog, '/')) != NULL)
102                         p++;
103                 else
104                         p = prog;
105
106                 /* Execute CGI program */
107                 if (interp == NULL) {
108                         (void) execle(p, p, NULL, envp);
109                         elog(E_FATAL, c, "redirect: exec(%s)", prog);
110                 } else {
111                         (void) execle(interp, interp, p, NULL, envp);
112                         elog(E_FATAL, c, "redirect: exec(%s %s)",
113                             interp, prog);
114                 }
115
116                 /* UNREACHED */
117                 exit(EXIT_FAILURE);
118
119         } else {
120
121                 /* Parent */
122                 ret = 0;
123                 (void) closesocket(sock);
124         }
125
126         return (ret);
127 }
128 #endif /* !NO_CGI */