#include <string.h>
#include <signal.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <ctype.h>
#include <sys/socket.h>
return;
}
+void daemonize () {
+ const char *devnull = "/dev/null";
+
+ /* Fork once to ensure we aren't the process group leader */
+ int i = fork ();
+ if (i < 0) {
+ fprintf (stderr, "Unable to fork\n");
+ _exit (1);
+ }
+
+ /* Exit if we are the parent */
+ if (i > 0)
+ _exit (0); /* parent exits */
+
+ /* Start a new session */
+ setsid ();
+
+ /* Fork again so the session group leader exits */
+ i = fork ();
+ if (i < 0) {
+ fprintf (stderr, "Unable to fork\n");
+ _exit (1);
+ }
+
+ /* Exit if we are the parent */
+ if (i > 0)
+ _exit (0); /* parent exits */
+
+ if (chdir ("/") <0) {
+ fprintf (stderr, "Unable to chdir /\n");
+ _exit (1);
+ }
+
+ /* Now close all FDs and reopen the 3 stdxxx to /dev/null */
+ for (i = getdtablesize () - 1; i >= 0; i--)
+ close (i);
+
+ i = open (devnull, O_RDWR);
+ if (i == -1) {
+ fprintf (stderr, "Unable to open /dev/null\n");
+ _exit (1);
+ }
+ i = open (devnull, O_RDONLY);
+ if (i != 0) {
+ dup2 (i, 0);
+ close (i);
+ }
+ i = open (devnull, O_WRONLY);
+ if (i != 1) {
+ dup2 (i, 1);
+ close (i);
+ }
+ i = open (devnull, O_WRONLY);
+ if (i != 2) {
+ dup2 (i, 2);
+ close (i);
+ }
+}
+
+
+
int main(int argc, char* argv[]) {
/* Server */
/* General */
int retval;
- /* Daemon Process */
- pid_t daemon_pid;
-
xml_init();
/* Parse arguments */
}
}
+ /* Daemonize before we start opening sockets, as this closes FDs */
+ if (!foreground)
+ daemonize();
+
+ if (pidfile != NULL) {
+ /* Attempt to open pidfile and write PID */
+ FILE* pidf = fopen(pidfile, "w");
+ if (pidf) {
+ fprintf(pidf, "%d\n", getpid());
+ fclose(pidf);
+ } else {
+ /* Warn on failure */
+ guacd_log_error("Could not write PID file: %s", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+
/* Set up logging prefix */
strncpy(log_prefix, basename(argv[0]), sizeof(log_prefix));
+ /* Open log as early as we can */
+ openlog(NULL, LOG_PID, LOG_DAEMON);
/* Get addresses for binding */
if ((retval = getaddrinfo(listen_address, listen_port, &hints, &addresses))) {
exit(EXIT_FAILURE);
}
- if (!foreground) {
-
- /* Fork into background */
- daemon_pid = fork();
-
- /* If error, fail */
- if (daemon_pid == -1) {
- guacd_log_error("Error forking daemon process: %s", strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- /* If parent, write PID file and exit */
- else if (daemon_pid != 0) {
-
- if (pidfile != NULL) {
-
- /* Attempt to open pidfile and write PID */
- FILE* pidf = fopen(pidfile, "w");
- if (pidf) {
- fprintf(pidf, "%d\n", daemon_pid);
- fclose(pidf);
- }
-
- /* Warn on failure */
- else {
- guacd_log_error("Could not write PID file: %s", strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- }
-
- exit(EXIT_SUCCESS);
- }
- }
-
- /* Open log */
- openlog(NULL, LOG_PID, LOG_DAEMON);
-
/* Ignore SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
guacd_log_info("Could not set handler for SIGPIPE to ignore. SIGPIPE may cause termination of the daemon.");