summaryrefslogtreecommitdiff
blob: 2ae7f610bd45930a68010c580b2b4aa89252f3b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
From 7f5104b242e6b36e6143183b14582d362763ff2a Mon Sep 17 00:00:00 2001
From: Gilles Dartiguelongue <eva@gentoo.org>
Date: Tue, 2 Nov 2010 23:16:51 +0100
Subject: [PATCH 2/6] daemonize so that the boot process can continue

Gentoo bug: #236701

Originally from: Dan Nicholson <dbn.lists@gmail.com>

Fork gdm-binary, except when -nodaemon is used
 
gdm-binary now forks and the parent terminates, except when the
-nodaemon or --nodaemon options are used. This provides compatibility
with xdm. Fixes bug #550170.

---
 daemon/main.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/daemon/main.c b/daemon/main.c
index 5b8d66b..191b6e3 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -513,6 +513,56 @@ is_debug_set (void)
         return debug;
 }
 
+static void
+dup_dev_null (int fd, int flags)
+{
+        int nullfd;
+        int dupfd;
+
+        VE_IGNORE_EINTR (nullfd = open ("/dev/null", flags));
+        if (G_UNLIKELY (nullfd < 0)) {
+                gdm_fail (_("Cannot open /dev/null: %s!"),
+                          strerror (errno));
+                exit (EXIT_FAILURE);
+        }
+
+        VE_IGNORE_EINTR (dupfd = dup2 (nullfd, fd));
+        if (G_UNLIKELY (dupfd < 0)) {
+                gdm_fail (_("Cannot duplicate /dev/null: %s!"),
+                          strerror (errno));
+                exit (EXIT_FAILURE);
+        }
+
+        VE_IGNORE_EINTR (close (nullfd));
+}
+
+static void
+daemonify (void)
+{
+        pid_t pid;
+
+        pid = fork ();
+
+        /* terminate the parent */
+        if (pid > 0)
+                exit (EXIT_SUCCESS);
+
+        if (G_UNLIKELY (pid < 0)) {
+                gdm_fail (_("fork () failed: %s!"), strerror (errno));
+                exit (EXIT_FAILURE);
+        }
+
+        if (G_UNLIKELY (setsid () < 0)) {
+                gdm_fail (_("setsid () failed: %s!"), strerror (errno));
+                exit (EXIT_FAILURE);
+        }
+
+        /* reopen stdin, stdout, stderr with /dev/null */
+        dup_dev_null (STDIN_FILENO, O_RDONLY);
+        dup_dev_null (STDOUT_FILENO, O_RDWR);
+        dup_dev_null (STDERR_FILENO, O_RDWR);
+}
+
 int
 main (int    argc,
       char **argv)
@@ -523,14 +573,17 @@ main (int    argc,
         DBusGConnection    *connection;
         GError             *error;
         int                 ret;
+        int                 i;
         gboolean            res;
         gboolean            xdmcp_enabled;
         GdmSignalHandler   *signal_handler;
         static gboolean     do_timed_exit    = FALSE;
         static gboolean     print_version    = FALSE;
         static gboolean     fatal_warnings   = FALSE;
+        static gboolean     no_daemon        = FALSE;
         static GOptionEntry entries []   = {
                 { "fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &fatal_warnings, N_("Make all warnings fatal"), NULL },
+                { "nodaemon", 0, 0, G_OPTION_ARG_NONE, &no_daemon, N_("Do not fork into the background"), NULL },
                 { "timed-exit", 0, 0, G_OPTION_ARG_NONE, &do_timed_exit, N_("Exit after a time (for debugging)"), NULL },
                 { "version", 0, 0, G_OPTION_ARG_NONE, &print_version, N_("Print GDM version"), NULL },
 
@@ -547,6 +600,14 @@ main (int    argc,
 
         g_type_init ();
 
+        /* preprocess the arguments to support the xdm style
+         * -nodaemon option
+         */
+        for (i = 0; i < argc; i++) {
+                if (strcmp (argv[i], "-nodaemon") == 0)
+                        argv[i] = "--nodaemon";
+        }
+
         context = g_option_context_new (_("GNOME Display Manager"));
         g_option_context_add_main_entries (context, entries, NULL);
         g_option_context_set_ignore_unknown_options (context, TRUE);
@@ -617,6 +678,9 @@ main (int    argc,
                 exit (-1);
         }
 
+        if (no_daemon == FALSE)
+                daemonify ();
+
         /* pid file */
         delete_pid ();
         write_pid ();
-- 
1.7.3.1