This function is to be called only by the main process! * Returns, on success, the ID (non zero) in the process table of the * newly forked procees. * */
| 277 | * newly forked procees. |
| 278 | * */ |
| 279 | int internal_fork(const struct internal_fork_params *ifpp) |
| 280 | { |
| 281 | int new_idx; |
| 282 | pid_t pid; |
| 283 | unsigned int seed; |
| 284 | |
| 285 | if (is_main==0) { |
| 286 | LM_BUG("buggy call from non-main process!!!"); |
| 287 | return -1; |
| 288 | } |
| 289 | |
| 290 | new_idx = 1; /* start from 1 as 0 (attendent) is always running */ |
| 291 | for( ; new_idx<counted_max_processes ; new_idx++) |
| 292 | if ( (pt[new_idx].flags&OSS_PROC_IS_RUNNING)==0 ) break; |
| 293 | if (new_idx==counted_max_processes) { |
| 294 | LM_BUG("no free process slot found while trying to fork again\n"); |
| 295 | return -1; |
| 296 | } |
| 297 | |
| 298 | seed = rand(); |
| 299 | |
| 300 | LM_DBG("forking new process \"%s\" on slot %d\n", ifpp->proc_desc, new_idx); |
| 301 | |
| 302 | /* set the IPC pipes */ |
| 303 | if ( (ifpp->flags & OSS_PROC_NO_IPC) ) { |
| 304 | /* advertise no IPC to the rest of the procs */ |
| 305 | pt[new_idx].ipc_pipe[0] = -1; |
| 306 | pt[new_idx].ipc_pipe[1] = -1; |
| 307 | pt[new_idx].ipc_sync_pipe[0] = -1; |
| 308 | pt[new_idx].ipc_sync_pipe[1] = -1; |
| 309 | /* NOTE: the IPC fds will remain open in the other processes, |
| 310 | * but they will not be known */ |
| 311 | } else { |
| 312 | /* activate the IPC pipes */ |
| 313 | pt[new_idx].ipc_pipe[0]=pt[new_idx].ipc_pipe_holder[0]; |
| 314 | pt[new_idx].ipc_pipe[1]=pt[new_idx].ipc_pipe_holder[1]; |
| 315 | pt[new_idx].ipc_sync_pipe[0]=pt[new_idx].ipc_sync_pipe_holder[0]; |
| 316 | pt[new_idx].ipc_sync_pipe[1]=pt[new_idx].ipc_sync_pipe_holder[1]; |
| 317 | } |
| 318 | |
| 319 | pt[new_idx].pid = 0; |
| 320 | |
| 321 | atomic_init(&pt[new_idx].startup_result, CHLD_STARTING); |
| 322 | |
| 323 | if ( (pid=fork())<0 ){ |
| 324 | LM_CRIT("cannot fork \"%s\" process (%d: %s)\n",ifpp->proc_desc, |
| 325 | errno, strerror(errno)); |
| 326 | reset_process_slot( new_idx ); |
| 327 | return -1; |
| 328 | } |
| 329 | |
| 330 | if (pid==0){ |
| 331 | const struct internal_fork_handler *cfhp; |
| 332 | /* child process */ |
| 333 | is_main = 0; /* a child is not main process */ |
| 334 | /* set uid */ |
| 335 | process_no = new_idx; |
| 336 | /* set attributes, pid etc */ |