| 84 | |
| 85 | |
| 86 | ngx_pid_t |
| 87 | ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, |
| 88 | char *name, ngx_int_t respawn) |
| 89 | { |
| 90 | u_long on; |
| 91 | ngx_pid_t pid; |
| 92 | ngx_int_t s; |
| 93 | |
| 94 | if (respawn >= 0) { |
| 95 | s = respawn; |
| 96 | |
| 97 | } else { |
| 98 | for (s = 0; s < ngx_last_process; s++) { |
| 99 | if (ngx_processes[s].pid == -1) { |
| 100 | break; |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | if (s == NGX_MAX_PROCESSES) { |
| 105 | ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
| 106 | "no more than %d processes can be spawned", |
| 107 | NGX_MAX_PROCESSES); |
| 108 | return NGX_INVALID_PID; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | |
| 113 | if (respawn != NGX_PROCESS_DETACHED) { |
| 114 | |
| 115 | /* Solaris 9 still has no AF_LOCAL */ |
| 116 | |
| 117 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1) |
| 118 | { |
| 119 | ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, |
| 120 | "socketpair() failed while spawning \"%s\"", name); |
| 121 | return NGX_INVALID_PID; |
| 122 | } |
| 123 | |
| 124 | ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, |
| 125 | "channel %d:%d", |
| 126 | ngx_processes[s].channel[0], |
| 127 | ngx_processes[s].channel[1]); |
| 128 | |
| 129 | if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) { |
| 130 | ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, |
| 131 | ngx_nonblocking_n " failed while spawning \"%s\"", |
| 132 | name); |
| 133 | ngx_close_channel(ngx_processes[s].channel, cycle->log); |
| 134 | return NGX_INVALID_PID; |
| 135 | } |
| 136 | |
| 137 | if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) { |
| 138 | ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, |
| 139 | ngx_nonblocking_n " failed while spawning \"%s\"", |
| 140 | name); |
| 141 | ngx_close_channel(ngx_processes[s].channel, cycle->log); |
| 142 | return NGX_INVALID_PID; |
| 143 | } |
no test coverage detected