src/dhcpcd.c
/* Returns the pid of the child, otherwise 0. */
Returns the pid of the child, otherwise 0.
Returns the pid of the child otherwise 0 .
pid_t
dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
{
#ifdef THERE_IS_NO_FORK
	eloop_timeout_delete(ctx->eloop, handle_exit_timeout, ctx);
	errno = ENOSYS;
	return 0;
#else
	pid_t pid, lpid;
	char buf = '\0';
	int sidpipe[2], fd;
	if (ctx->options & DHCPCD_DAEMONISE &&
	    !(ctx->options & (DHCPCD_DAEMONISED | DHCPCD_NOWAITIP)))
	{
		if (!dhcpcd_ipwaited(ctx))
			return 0;
	}
	if (ctx->options & DHCPCD_ONESHOT) {
		loginfox("exiting due to oneshot");
		eloop_exit(ctx->eloop, EXIT_SUCCESS);
		return 0;
	}
	eloop_timeout_delete(ctx->eloop, handle_exit_timeout, ctx);
	if (ctx->options & DHCPCD_DAEMONISED ||
	    !(ctx->options & DHCPCD_DAEMONISE))
		return 0;
	logdebugx("forking to background");
	if (pipe(sidpipe) == -1) {
		logerr("%s: pipe", __func__);
		return 0;
	}
	switch (pid = fork()) {
	case -1:
		logerr("%s: fork", __func__);
		return 0;
	case 0:
		if ((lpid = pidfile_lock(ctx->pidfile)) != 0)
			logerr("%s: pidfile_lock %d", __func__, lpid);
		setsid();
		close(sidpipe[0]);
		if (write(sidpipe[1], &buf, 1) == -1)
			logerr("%s: write", __func__);
		close(sidpipe[1]);
		if (eloop_requeue(ctx->eloop) == -1) {
			logerr("%s: eloop_requeue", __func__);
			eloop_exit(ctx->eloop, EXIT_FAILURE);
		}
		if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
			dup2(fd, STDIN_FILENO);
			dup2(fd, STDOUT_FILENO);
			dup2(fd, STDERR_FILENO);
			close(fd);
		}
		ctx->options |= DHCPCD_DAEMONISED;
		return 0;
	default:
		close(sidpipe[1]);
		if (read(sidpipe[0], &buf, 1) == -1)
			logerr("%s: read", __func__);
		close(sidpipe[0]);
		loginfox("forked to background, child pid %d", pid);
		ctx->options |= DHCPCD_FORKED;
		eloop_exit(ctx->eloop, EXIT_SUCCESS);
		return pid;
	}
#endif
}
pid_t dhcpcd_daemonise ( struct dhcpcd_ctx * ctx ) { #ifdef THERE_IS_NO_FORK eloop_timeout_delete ( ctx -> eloop , handle_exit_timeout , ctx ) ; errno = ENOSYS ; return 0 ; #else pid_t pid , lpid ; char buf = ' \0 ' ; int sidpipe [ 2 ] , fd ; if ( ctx -> options & DHCPCD_DAEMONISE && ! ( ctx -> options & ( DHCPCD_DAEMONISED | DHCPCD_NOWAITIP ) ) ) { if ( ! dhcpcd_ipwaited ( ctx ) ) return 0 ; } if ( ctx -> options & DHCPCD_ONESHOT ) { loginfox ( " " ) ; eloop_exit ( ctx -> eloop , EXIT_SUCCESS ) ; return 0 ; } eloop_timeout_delete ( ctx -> eloop , handle_exit_timeout , ctx ) ; if ( ctx -> options & DHCPCD_DAEMONISED || ! ( ctx -> options & DHCPCD_DAEMONISE ) ) return 0 ; logdebugx ( " " ) ; if ( pipe ( sidpipe ) == -1 ) { logerr ( " " , __func__ ) ; return 0 ; } switch ( pid = fork ( ) ) { case -1 : logerr ( " " , __func__ ) ; return 0 ; case 0 : if ( ( lpid = pidfile_lock ( ctx -> pidfile ) ) != 0 ) logerr ( " " , __func__ , lpid ) ; setsid ( ) ; close ( sidpipe [ 0 ] ) ; if ( write ( sidpipe [ 1 ] , & buf , 1 ) == -1 ) logerr ( " " , __func__ ) ; close ( sidpipe [ 1 ] ) ; if ( eloop_requeue ( ctx -> eloop ) == -1 ) { logerr ( " " , __func__ ) ; eloop_exit ( ctx -> eloop , EXIT_FAILURE ) ; } if ( ( fd = open ( _PATH_DEVNULL , O_RDWR , 0 ) ) != -1 ) { dup2 ( fd , STDIN_FILENO ) ; dup2 ( fd , STDOUT_FILENO ) ; dup2 ( fd , STDERR_FILENO ) ; close ( fd ) ; } ctx -> options |= DHCPCD_DAEMONISED ; return 0 ; default : close ( sidpipe [ 1 ] ) ; if ( read ( sidpipe [ 0 ] , & buf , 1 ) == -1 ) logerr ( " " , __func__ ) ; close ( sidpipe [ 0 ] ) ; loginfox ( " " , pid ) ; ctx -> options |= DHCPCD_FORKED ; eloop_exit ( ctx -> eloop , EXIT_SUCCESS ) ; return pid ; } #endif }
Returns the pid of the child, otherwise 0.
Returns the pid of the child otherwise 0 .
/* Setup a signal pipe so parent knows when to exit. */ /* Notify parent it's safe to exit as we've detached. */ /* Some polling methods don't survive after forking,
		 * so ensure we can requeue all our events. */ /* Wait for child to detach */