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 | |
---|
80 | envblk = NULL; /* unused */ |
---|
81 | |
---|
82 | if ((pid = vfork()) == -1) { |
---|
83 | |
---|
84 | ret = -1; |
---|
85 | elog(E_LOG, c, "redirect: fork: %s", strerror(errno)); |
---|
86 | |
---|
87 | } else if (pid == 0) { |
---|
88 | |
---|
89 | /* Child */ |
---|
90 | (void) chdir(dir); |
---|
91 | (void) dup2(sock, 0); |
---|
92 | (void) dup2(sock, 1); |
---|
93 | (void) closesocket(sock); |
---|
94 | |
---|
95 | /* If error file is specified, send errors there */ |
---|
96 | if (c->ctx->error_log) |
---|
97 | (void) dup2(fileno(c->ctx->error_log), 2); |
---|
98 | |
---|
99 | /* Execute CGI program */ |
---|
100 | if (c->ctx->cgi_interpreter == NULL) { |
---|
101 | (void) execle(prog, prog, NULL, envp); |
---|
102 | elog(E_FATAL, c, "redirect: exec(%s)", prog); |
---|
103 | } else { |
---|
104 | (void) execle(c->ctx->cgi_interpreter, |
---|
105 | c->ctx->cgi_interpreter, prog, NULL, envp); |
---|
106 | elog(E_FATAL, c, "redirect: exec(%s %s)", |
---|
107 | c->ctx->cgi_interpreter, prog); |
---|
108 | } |
---|
109 | |
---|
110 | /* UNREACHED */ |
---|
111 | ret = -1; |
---|
112 | exit(EXIT_FAILURE); |
---|
113 | |
---|
114 | } else { |
---|
115 | |
---|
116 | /* Parent */ |
---|
117 | ret = 0; |
---|
118 | (void) closesocket(sock); |
---|
119 | } |
---|
120 | |
---|
121 | return (ret); |
---|
122 | } |
---|
123 | #endif /* !NO_CGI */ |
---|