summaryrefslogtreecommitdiff
path: root/src/daemon/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r--src/daemon/daemon.c129
1 files changed, 68 insertions, 61 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index c79d43a..ad35298 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -23,32 +23,38 @@ static int exit_code_pipe[2] = { -1, -1 };
int daemon_parent_pipe[2] = { -1, -1 };
-#define TERMINATE_EXIT_CODE 99
-#define TERMINATE_PARENT 98
+typedef enum {
+ TERMINATE_OK,
+ TERMINATE_ERROR,
+ TERMINATE_EXIT_CODE,
+ TERMINATE_PARENT
+} daemon_state_t;
struct daemon_t {
daemon_params_t params; /**< the parameters for creation */
- error_t error; /**< error of last start */
+ daemon_state_t state; /**< last status of the daemon */
+ wolf_error_t error; /**< error of last start */
struct pidfile_t pidfile; /**< pid/lock file of the daemon */
struct group *groupent; /**< group entry */
struct passwd *userent; /**< password entry */
};
daemon_p daemon_new( daemon_params_t params,
- error_t *error ) {
+ wolf_error_t *error ) {
daemon_p d;
d = (struct daemon_t *)malloc( sizeof ( struct daemon_t ) );
if( d == NULL ) {
- *error = ERR_OUT_OF_MEMORY;
+ *error = WOLF_ERR_OUT_OF_MEMORY;
return NULL;
}
- d->error = -1;
+ d->state = TERMINATE_ERROR;
+ d->error = WOLF_ERR_INTERNAL;
d->params = params;
if( params.daemon_name == NULL ) {
- *error = ERR_INVALID_VALUE;
+ *error = WOLF_ERR_INVALID_VALUE;
return NULL;
}
@@ -58,7 +64,7 @@ daemon_p daemon_new( daemon_params_t params,
pidfile_set_from_filename( &d->pidfile, params.pid_filename );
}
- *error = OK;
+ *error = WOLF_OK;
return d;
}
@@ -67,7 +73,7 @@ void daemon_free( daemon_p d ) {
d = NULL;
}
-static error_t close_fd( int fd ) {
+static wolf_error_t close_fd( int fd ) {
if( close( fd ) < 0 ) {
switch( errno ) {
case EBADF:
@@ -77,34 +83,34 @@ static error_t close_fd( int fd ) {
default:
LOG( log_EMERG, "Error while closing file descriptor %d: %s (%d)",
fd, strerror( errno ), errno );
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
}
- return OK;
+ return WOLF_OK;
}
-static error_t daemon_close_standard_fds( void ) {
- error_t error;
+static wolf_error_t daemon_close_standard_fds( void ) {
+ wolf_error_t error;
- if( ( error = close_fd( STDIN_FILENO ) ) != OK ) return error;
- if( ( error = close_fd( STDOUT_FILENO ) ) != OK ) return error;
- if( ( error = close_fd( STDERR_FILENO ) ) != OK ) return error;
+ if( ( error = close_fd( STDIN_FILENO ) ) != WOLF_OK ) return error;
+ if( ( error = close_fd( STDOUT_FILENO ) ) != WOLF_OK ) return error;
+ if( ( error = close_fd( STDERR_FILENO ) ) != WOLF_OK ) return error;
- return OK;
+ return WOLF_OK;
}
-static error_t daemon_close_all_fds( void ) {
+static wolf_error_t daemon_close_all_fds( void ) {
long nof_files;
int i;
- error_t error;
+ wolf_error_t error;
nof_files = sysconf( _SC_OPEN_MAX );
if( nof_files < 0 ) {
LOG( log_EMERG, "Unable to retrieve maximal number of files: %s (%d)",
strerror( errno ), errno );
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
LOG( log_DEBUG, "Closing all filedescriptors up to %ld", nof_files );
@@ -120,28 +126,28 @@ static error_t daemon_close_all_fds( void ) {
( i == exit_code_pipe[1] ) ) {
continue;
}
- if( ( error = close_fd( i ) ) != OK ) return error;
+ if( ( error = close_fd( i ) ) != WOLF_OK ) return error;
}
- return OK;
+ return WOLF_OK;
}
-static error_t open_null_fd( int must_fd, int flags ) {
+static wolf_error_t open_null_fd( int must_fd, int flags ) {
int fd;
fd = open( "/dev/null", flags );
if( fd < 0 ) {
LOG( log_EMERG, "Unable to open fd %d as /dev/null: %s (%d)",
must_fd, strerror( errno ), errno );
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
if( fd != must_fd ) {
LOG( log_EMERG, "Something is wrong with the file descriptors (expecting %d,got %d)!",
must_fd, fd );
- return ERR_PROGRAMMING;
+ return WOLF_ERR_PROGRAMMING;
}
- return OK;
+ return WOLF_OK;
}
static void atomar_write( int fd, void *data, size_t data_len ) {
@@ -174,10 +180,10 @@ atomar_read_again:
}
}
-error_t daemon_start( daemon_p d ) {
+wolf_error_t daemon_start( daemon_p d ) {
pid_t pid;
mode_t mode;
- error_t error;
+ wolf_error_t error;
int exit_code;
/* Our parent is already the init process (which has pid 1 by
@@ -186,7 +192,7 @@ error_t daemon_start( daemon_p d ) {
*/
if( getppid( ) == 1 ) {
LOG( log_EMERG, "Already running as daemon!" );
- return( d->error = ERR_PROGRAMMING );
+ return( d->error = WOLF_ERR_PROGRAMMING );
}
/* Are we starting as root? If not, bail out, we need root
@@ -197,7 +203,7 @@ error_t daemon_start( daemon_p d ) {
*/
if( geteuid( ) != 0 ) {
LOG( log_EMERG, "Unable to start daemon as not root user!" );
- return( d->error = ERR_INVALID_STATE );
+ return( d->error = WOLF_ERR_INVALID_STATE );
}
/* We fork so SIGCHLD signals get to the parent and grandfather.
@@ -223,7 +229,7 @@ error_t daemon_start( daemon_p d ) {
if( pipe( exit_code_pipe ) < 0 ) {
LOG( log_EMERG, "Unable to create exit code pipe: %s (%d)",
strerror( errno ), errno );
- return ( d->error = ERR_INTERNAL );
+ return ( d->error = WOLF_ERR_INTERNAL );
}
LOG( log_DEBUG, "Created exit code pipe (%d,%d)", exit_code_pipe[0], exit_code_pipe[1] );
@@ -234,7 +240,7 @@ error_t daemon_start( daemon_p d ) {
case -1:
/* error */
LOG( log_EMERG, "Unable to fork the first time: %s", strerror( errno ) );
- return ( d->error = ERR_INTERNAL );
+ return ( d->error = WOLF_ERR_INTERNAL );
case 0:
/* the child becomes the daemon */
@@ -249,7 +255,7 @@ error_t daemon_start( daemon_p d ) {
* code from the error pipe
*/
LOG( log_DEBUG, "Parent after first fork: child is %d", pid );
- return ( d->error = TERMINATE_EXIT_CODE );
+ return ( d->state = TERMINATE_EXIT_CODE );
}
/* second pipe communicates from the daemon back to its parent
@@ -258,7 +264,7 @@ error_t daemon_start( daemon_p d ) {
if( pipe( daemon_parent_pipe ) < 0 ) {
LOG( log_EMERG, "Unable to create parent pipe: %s (%d)",
strerror( errno ), errno );
- return ( d->error = ERR_INTERNAL );
+ return ( d->error = WOLF_ERR_INTERNAL );
}
LOG( log_DEBUG, "Created parent pipe (%d,%d)", daemon_parent_pipe[0], daemon_parent_pipe[1] );
@@ -269,7 +275,7 @@ error_t daemon_start( daemon_p d ) {
if( setsid( ) < 0 ) {
/* should actually never fail */
LOG( log_EMERG, "Starting new process group session for the parent of the daemon failed: %s", strerror( errno ) );
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
/* We fork so SIGCHLD signals get to the parent and grandfather.
@@ -296,7 +302,7 @@ error_t daemon_start( daemon_p d ) {
case -1:
/* error */
LOG( log_EMERG, "Unable to fork the second time: %s", strerror( errno ) );
- return ( d->error = ERR_INTERNAL );
+ return ( d->error = WOLF_ERR_INTERNAL );
case 0:
/* the child becomes the daemon */
@@ -306,13 +312,13 @@ error_t daemon_start( daemon_p d ) {
default:
(void)signal_install_handlers_parent( );
LOG( log_DEBUG, "Parent after second fork: child (and daemon) is %d", pid );
- return ( d->error = TERMINATE_PARENT );
+ return ( d->state = TERMINATE_PARENT );
}
/* Now install signal handlers */
- if( ( error = signal_initialize( ) ) != OK )
+ if( ( error = signal_initialize( ) ) != WOLF_OK )
return ( d->error = error );
- if( ( error = signal_install_handlers_daemon( ) ) != OK )
+ if( ( error = signal_install_handlers_daemon( ) ) != WOLF_OK )
return ( d->error = error );
/* Put the daemon in it's own process group and finally detach it
@@ -322,7 +328,7 @@ error_t daemon_start( daemon_p d ) {
if( setsid( ) < 0 ) {
/* should actually never fail */
LOG( log_EMERG, "Starting new process group for daemon session failed: %s", strerror( errno ) );
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
/* Change to the root directory for several reasons:
@@ -335,7 +341,7 @@ error_t daemon_start( daemon_p d ) {
*/
if( chdir( "/" ) < 0 ) {
LOG( log_EMERG, "Changing to root diretory failed: %s", strerror( errno ) );
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
LOG( log_DEBUG, "Changed to root directory /" );
@@ -348,11 +354,11 @@ error_t daemon_start( daemon_p d ) {
LOG( log_DEBUG, "Switched umask from %04o to %04o", mode, 0133 );
/* check if another daemon is already running, if yes, bail out */
- if( is_daemon_running( &d->pidfile, &pid, &error ) || ( error != OK ) ) {
- if( error == OK ) {
+ if( is_daemon_running( &d->pidfile, &pid, &error ) || ( error != WOLF_OK ) ) {
+ if( error == WOLF_OK ) {
LOG( log_EMERG, "Another daemon is already running with pid '%d', can't start!", pid );
}
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
/* we loose logfile and syslog file descriptors anyway, so close
@@ -362,16 +368,16 @@ error_t daemon_start( daemon_p d ) {
closelogtostderr( );
/* close all filedescriptors */
- if( daemon_close_all_fds( ) != OK )
- return ERR_INTERNAL;
+ if( daemon_close_all_fds( ) != WOLF_OK )
+ return WOLF_ERR_INTERNAL;
/* reopen the logs to the logfile and syslog (not stderr) */
reopenlogtosyslog( );
reopenlogtofile( );
/* create and lock the pidfile now, write pid of daemon into it */
- if( pidfile_create( &d->pidfile ) != OK ) {
- return ERR_INTERNAL;
+ if( pidfile_create( &d->pidfile ) != WOLF_OK ) {
+ return WOLF_ERR_INTERNAL;
}
/* Install the final permissions for new files. The reason is
@@ -399,7 +405,7 @@ error_t daemon_start( daemon_p d ) {
LOG( log_EMERG, "Unable to retrieve group information for group '%s': %s (%d)",
d->params.group_name, strerror( errno ), errno );
}
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
errno = 0;
@@ -411,19 +417,19 @@ error_t daemon_start( daemon_p d ) {
LOG( log_EMERG, "Unable to retrieve user information for user '%s': %s (%d)",
d->params.user_name, strerror( errno ), errno );
}
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
if( setgid( d->userent->pw_gid ) < 0 ) {
LOG( log_EMERG, "Setting unprivileged group failed: %s (%d)",
strerror( errno ), errno );
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
if( setuid( d->userent->pw_uid ) < 0 ) {
LOG( log_EMERG, "Setting unprivileged user failed: %s (%d)",
strerror( errno ), errno );
- return ERR_INTERNAL;
+ return WOLF_ERR_INTERNAL;
}
/* TODO: setsid and setting all groups of the user */
@@ -440,10 +446,10 @@ error_t daemon_start( daemon_p d ) {
* starting the daemon by hand still gets error messages
* on stderr.
*/
- if( ( error = daemon_close_standard_fds( ) ) != OK ) return error;
- if( ( error = open_null_fd( STDIN_FILENO, O_RDONLY ) ) != OK ) return error;
- if( ( error = open_null_fd( STDOUT_FILENO, O_WRONLY ) ) != OK ) return error;
- if( ( error = open_null_fd( STDERR_FILENO, O_WRONLY ) ) != OK ) return error;
+ if( ( error = daemon_close_standard_fds( ) ) != WOLF_OK ) return error;
+ if( ( error = open_null_fd( STDIN_FILENO, O_RDONLY ) ) != WOLF_OK ) return error;
+ if( ( error = open_null_fd( STDOUT_FILENO, O_WRONLY ) ) != WOLF_OK ) return error;
+ if( ( error = open_null_fd( STDERR_FILENO, O_WRONLY ) ) != WOLF_OK ) return error;
/* signal the grand-parent process, that he can return 0 to
* the calling shell/script
@@ -451,7 +457,8 @@ error_t daemon_start( daemon_p d ) {
exit_code = EXIT_SUCCESS;
atomar_write( exit_code_pipe[1], &exit_code, sizeof( int ) );
- return ( d->error = OK );
+ d->state = TERMINATE_OK;
+ return ( d->error = WOLF_OK );
}
NORETURN void daemon_exit( daemon_p d ) {
@@ -460,7 +467,7 @@ NORETURN void daemon_exit( daemon_p d ) {
LOG( log_DEBUG, "daemon_exit called with error %d", d->error );
- switch( d->error ) {
+ switch( d->state ) {
case TERMINATE_EXIT_CODE:
/* wait here for exit code in exit_code_pipe
* so we can return the correct exit code to
@@ -504,7 +511,7 @@ NORETURN void daemon_exit( daemon_p d ) {
/* exit code is irrelevant here.. */
exit( EXIT_SUCCESS );
- case OK:
+ case TERMINATE_OK:
/* close and unlock the pidfile here */
(void)pidfile_release( &d->pidfile );
@@ -519,8 +526,8 @@ NORETURN void daemon_exit( daemon_p d ) {
/* exit code is irrelevant here */
_exit( EXIT_SUCCESS );
-
- default:
+
+ case TERMINATE_ERROR:
/* no exit_code_pipe exists yet, we are before the
* first fork, so terminate with proper exit code
*/