summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-sysdeps.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-04-06 23:15:41 +0000
committerHavoc Pennington <hp@redhat.com>2003-04-06 23:15:41 +0000
commit856361ff5b8ce701cdb447085931d3076ee52008 (patch)
tree05aa6d44983e8eff29bc45b9dc94ff8b7998fe3c /dbus/dbus-sysdeps.c
parentc8991b0f95a3b53bc98de9e029780bbe0a0b3114 (diff)
2003-04-06 Havoc Pennington <hp@pobox.com>
* dbus/dbus-sysdeps.c (_dbus_become_daemon): write the pidfile here in the parent process, so we can return an error if it fails. Also, move some of the code into the child so the parent is less hosed if we fail midway through. * bus/bus.c (bus_context_new): move pidfile detection further up in the function, before we start overwriting sockets and such. * bus/messagebus.in: adjust this a bit, not sure if it will work. * configure.in: add --with-system-pid-file and --with-system-socket 2003-04-06 Colin Walters <walters@verbum.org> * configure.in (DBUS_SYSTEM_PID_FILE): New variable. * bus/system.conf.in: Declare a pidfile. * bus/bus.c (bus_context_new): Test for an existing pid file, and create one (if appropriate). * bus/config-parser.c (enum ElementType) [ELEMENT_PIDFILE]: New. (struct BusConfigParser) [pidfile]: New. (element_type_to_name, merge_included, start_busconfig_child) (bus_config_parser_end_element, bus_config_parser_content): Handle it. (bus_config_parser_unref): Free it. (bus_config_parser_get_pidfile): New function. * bus/config-parser.h (_dbus_write_pid_file): Prototype. * dbus/dbus-errors.h (DBUS_ERROR_PIDFILE_EXISTS): New error. * dbus/dbus-sysdeps.c (_dbus_write_pid_file): New function. * dbus/dbus-sysdeps.h: Prototype it.
Diffstat (limited to 'dbus/dbus-sysdeps.c')
-rw-r--r--dbus/dbus-sysdeps.c130
1 files changed, 102 insertions, 28 deletions
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index 7a389956..df921b17 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -1700,6 +1700,15 @@ _dbus_string_append_our_uid (DBusString *str)
return _dbus_string_append_int (str, getuid ());
}
+/**
+ * Gets our process ID
+ * @returns process ID
+ */
+unsigned long
+_dbus_getpid (void)
+{
+ return getpid ();
+}
_DBUS_DEFINE_GLOBAL_LOCK (atomic);
@@ -2930,17 +2939,17 @@ _dbus_print_backtrace (void)
/**
* Does the chdir, fork, setsid, etc. to become a daemon process.
*
+ * @param pidfile #NULL, or pidfile to create
* @param error return location for errors
* @returns #FALSE on failure
*/
dbus_bool_t
-_dbus_become_daemon (DBusError *error)
+_dbus_become_daemon (const DBusString *pidfile,
+ DBusError *error)
{
const char *s;
+ pid_t child_pid;
- /* This is so we don't prevent unmounting of devices. We divert
- * all messages to syslog
- */
if (chdir ("/") < 0)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
@@ -2948,29 +2957,7 @@ _dbus_become_daemon (DBusError *error)
return FALSE;
}
- s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
- if (s == NULL || *s == '\0')
- {
- int dev_null_fd;
-
- /* silently ignore failures here, if someone
- * doesn't have /dev/null we may as well try
- * to continue anyhow
- */
-
- dev_null_fd = open ("/dev/null", O_RDWR);
- if (dev_null_fd >= 0)
- {
- dup2 (dev_null_fd, 0);
- dup2 (dev_null_fd, 1);
- dup2 (dev_null_fd, 2);
- }
- }
-
- /* Get a predictable umask */
- umask (022);
-
- switch (fork ())
+ switch ((child_pid = fork ()))
{
case -1:
dbus_set_error (error, _dbus_error_from_errno (errno),
@@ -2978,10 +2965,41 @@ _dbus_become_daemon (DBusError *error)
return FALSE;
break;
- case 0:
+ case 0:
+ s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
+ if (s == NULL || *s == '\0')
+ {
+ int dev_null_fd;
+
+ /* silently ignore failures here, if someone
+ * doesn't have /dev/null we may as well try
+ * to continue anyhow
+ */
+
+ dev_null_fd = open ("/dev/null", O_RDWR);
+ if (dev_null_fd >= 0)
+ {
+ dup2 (dev_null_fd, 0);
+ dup2 (dev_null_fd, 1);
+ dup2 (dev_null_fd, 2);
+ }
+ }
+
+ /* Get a predictable umask */
+ umask (022);
break;
default:
+ if (pidfile)
+ {
+ if (!_dbus_write_pid_file (pidfile,
+ child_pid,
+ error))
+ {
+ kill (child_pid, SIGTERM);
+ return FALSE;
+ }
+ }
_exit (0);
break;
}
@@ -2993,6 +3011,62 @@ _dbus_become_daemon (DBusError *error)
}
/**
+ * Creates a file containing the process ID.
+ *
+ * @param filename the filename to write to
+ * @param pid our process ID
+ * @param error return location for errors
+ * @returns #FALSE on failure
+ */
+dbus_bool_t
+_dbus_write_pid_file (const DBusString *filename,
+ unsigned long pid,
+ DBusError *error)
+{
+ const char *cfilename;
+ int fd;
+ FILE *f;
+
+ cfilename = _dbus_string_get_const_data (filename);
+
+ fd = open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644);
+
+ if (fd < 0)
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to open \"%s\": %s", cfilename,
+ _dbus_strerror (errno));
+ return FALSE;
+ }
+
+ if ((f = fdopen (fd, "w")) == NULL)
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to fdopen fd %d: %s", fd, _dbus_strerror (errno));
+ close (fd);
+ return FALSE;
+ }
+
+ if (fprintf (f, "%lu\n", pid) < 0)
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to write to \"%s\": %s", cfilename,
+ _dbus_strerror (errno));
+ return FALSE;
+ }
+
+ if (fclose (f) == EOF)
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to close \"%s\": %s", cfilename,
+ _dbus_strerror (errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
* Changes the user and group the bus is running as.
*
* @param uid the new user ID