summaryrefslogtreecommitdiff
path: root/core/fork_server.c
diff options
context:
space:
mode:
authorUnbit <info@unbit.it>2014-05-06 17:57:37 +0200
committerUnbit <info@unbit.it>2014-05-06 17:57:37 +0200
commit246e106d8551ca95c2f1850695d432b78e892d8b (patch)
tree564bbd2e9789e4ca8ec151a7dd0424d95fc9c3af /core/fork_server.c
parente983fae9a40f966dbdeb9392db55bab118460dad (diff)
downloaduwsgi-246e106d8551ca95c2f1850695d432b78e892d8b.tar.gz
added support for on_demand and config pipe in fork-server mode
Diffstat (limited to 'core/fork_server.c')
-rw-r--r--core/fork_server.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/core/fork_server.c b/core/fork_server.c
index d08a1e4e..e88b1284 100644
--- a/core/fork_server.c
+++ b/core/fork_server.c
@@ -14,11 +14,15 @@ from now on, we can consider the new child as a full-featured vassal
*/
+#define VASSAL_HAS_CONFIG 0x02
+#define VASSAL_HAS_ON_DEMAND 0x04
+
static void parse_argv_hook(uint16_t item, char *value, uint16_t vlen, void *data) {
struct uwsgi_string_list **usl = (struct uwsgi_string_list **) data;
uwsgi_string_new_list(usl, uwsgi_concat2n(value, vlen, "", 0));
}
+
void uwsgi_fork_server(char *socket) {
// map fd 0 to /dev/null to avoid mess
uwsgi_remap_fd(0, "/dev/null");
@@ -49,7 +53,7 @@ void uwsgi_fork_server(char *socket) {
// we only read 4 bytes header
ssize_t len = uwsgi_recv_cred_and_fds(client_fd, hbuf, remains, &ppid, &uid, &gid, fds, &fds_count);
uwsgi_log("RET = %d %d %d %d fds:%d\n", len, ppid, uid, gid, fds_count);
- if (len <= 0) {
+ if (len <= 0 || fds_count < 1) {
uwsgi_error("uwsgi_fork_server()/recvmsg()");
goto end;
}
@@ -89,15 +93,46 @@ void uwsgi_fork_server(char *socket) {
goto end;
}
else {
- // close everything excluded the passed fds and client_fd
+ // close everything excluded 0,1,2, the passed fds and client_fd
// set EMPEROR_FD and FD_CONFIG env vars
char *uef = uwsgi_num2str(fds[0]);
if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
- uwsgi_error("setenv()");
+ uwsgi_error("uwsgi_fork_server()/setenv()");
exit(1);
}
free(uef);
+
+ int pipe_config = -1;
+ int on_demand = -1;
+
+ if (uh->modifier2 & VASSAL_HAS_CONFIG && fds_count > 1) {
+ pipe_config = fds[1];
+ char *uef = uwsgi_num2str(pipe_config);
+ if (setenv("UWSGI_EMPEROR_FD_CONFIG", uef, 1)) {
+ uwsgi_error("uwsgi_fork_server()/setenv()");
+ exit(1);
+ }
+ free(uef);
+ }
+
+ if (uh->modifier2 & VASSAL_HAS_ON_DEMAND && fds_count > 1) {
+ if (pipe_config > -1) {
+ if (fds_count > 2) {
+ on_demand = fds[2];
+ }
+ }
+ else {
+ on_demand = fds[1];
+ }
+ }
// dup the on_demand socket to 0 and close it
+ if (on_demand > -1) {
+ if (dup2(on_demand, 0) < 0) {
+ uwsgi_error("uwsgi_fork_server()/dup2()");
+ exit(1);
+ }
+ close(on_demand);
+ }
// now fork again and die
pid_t new_pid = fork();