|
|
a6591a |
From dc2074588d3e7b5a216cb8c0b82094157c3cf773 Mon Sep 17 00:00:00 2001
|
|
|
a6591a |
From: David King <dking@redhat.com>
|
|
|
a6591a |
Date: Mon, 25 Jun 2018 14:46:14 -0400
|
|
|
a6591a |
Subject: [PATCH] daemon: use HOME as the working directory
|
|
|
a6591a |
|
|
|
a6591a |
Session buses started as part of a systemd --user session are launched
|
|
|
a6591a |
with the current working directory being the home directory of the user.
|
|
|
a6591a |
Applications which are launched via dbus activation inherit the working
|
|
|
a6591a |
directory from the session bus dbus-daemon.
|
|
|
a6591a |
|
|
|
a6591a |
When dbus-launch is used to start dbus-daemon, as is commonly the case
|
|
|
a6591a |
with a session manager such as gnome-session, this leads to applications
|
|
|
a6591a |
having a default working directory of "/", which is undesirable (as an
|
|
|
a6591a |
example, the default directory in a GTK+ save dialog becomes "/").
|
|
|
a6591a |
|
|
|
a6591a |
As an improvement, make dbus-launch use the value of the environment
|
|
|
a6591a |
variable HOME, if it is set, as the current working directory.
|
|
|
a6591a |
|
|
|
a6591a |
Signed-off-by: David King <dking@redhat.com>
|
|
|
a6591a |
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=106987
|
|
|
a6591a |
Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1470310
|
|
|
a6591a |
---
|
|
|
a6591a |
bus/bus.c | 9 +++++++++
|
|
|
a6591a |
dbus/dbus-sysdeps-util-unix.c | 8 +++++---
|
|
|
a6591a |
dbus/dbus-sysdeps-util-win.c | 2 ++
|
|
|
a6591a |
dbus/dbus-sysdeps.h | 1 +
|
|
|
a6591a |
doc/dbus-launch.1.xml.in | 4 ++++
|
|
|
a6591a |
tools/dbus-launch.c | 22 ++++++++++++++--------
|
|
|
a6591a |
6 files changed, 35 insertions(+), 11 deletions(-)
|
|
|
a6591a |
|
|
|
a6591a |
diff --git a/bus/bus.c b/bus/bus.c
|
|
|
a6591a |
index f788e677..da2b2c1f 100644
|
|
|
a6591a |
--- a/bus/bus.c
|
|
|
a6591a |
+++ b/bus/bus.c
|
|
|
a6591a |
@@ -870,63 +870,72 @@ bus_context_new (const DBusString *config_file,
|
|
|
a6591a |
|
|
|
a6591a |
context->matchmaker = bus_matchmaker_new ();
|
|
|
a6591a |
if (context->matchmaker == NULL)
|
|
|
a6591a |
{
|
|
|
a6591a |
BUS_SET_OOM (error);
|
|
|
a6591a |
goto failed;
|
|
|
a6591a |
}
|
|
|
a6591a |
|
|
|
a6591a |
/* check user before we fork */
|
|
|
a6591a |
if (context->user != NULL)
|
|
|
a6591a |
{
|
|
|
a6591a |
if (!_dbus_verify_daemon_user (context->user))
|
|
|
a6591a |
{
|
|
|
a6591a |
dbus_set_error (error, DBUS_ERROR_FAILED,
|
|
|
a6591a |
"Could not get UID and GID for username \"%s\"",
|
|
|
a6591a |
context->user);
|
|
|
a6591a |
goto failed;
|
|
|
a6591a |
}
|
|
|
a6591a |
}
|
|
|
a6591a |
|
|
|
a6591a |
/* Now become a daemon if appropriate and write out pid file in any case */
|
|
|
a6591a |
{
|
|
|
a6591a |
DBusString u;
|
|
|
a6591a |
|
|
|
a6591a |
if (context->pidfile)
|
|
|
a6591a |
_dbus_string_init_const (&u, context->pidfile);
|
|
|
a6591a |
|
|
|
a6591a |
if (((flags & BUS_CONTEXT_FLAG_FORK_NEVER) == 0 && context->fork) ||
|
|
|
a6591a |
(flags & BUS_CONTEXT_FLAG_FORK_ALWAYS))
|
|
|
a6591a |
{
|
|
|
a6591a |
+ const char *working_dir = NULL;
|
|
|
a6591a |
+
|
|
|
a6591a |
_dbus_verbose ("Forking and becoming daemon\n");
|
|
|
a6591a |
|
|
|
a6591a |
+ if (context->type != NULL && strcmp (context->type, "session") == 0)
|
|
|
a6591a |
+ working_dir = _dbus_getenv ("HOME");
|
|
|
a6591a |
+
|
|
|
a6591a |
+ if (working_dir == NULL)
|
|
|
a6591a |
+ working_dir = "/";
|
|
|
a6591a |
+
|
|
|
a6591a |
if (!_dbus_become_daemon (context->pidfile ? &u : NULL,
|
|
|
a6591a |
+ working_dir,
|
|
|
a6591a |
print_pid_pipe,
|
|
|
a6591a |
error,
|
|
|
a6591a |
context->keep_umask))
|
|
|
a6591a |
{
|
|
|
a6591a |
_DBUS_ASSERT_ERROR_IS_SET (error);
|
|
|
a6591a |
goto failed;
|
|
|
a6591a |
}
|
|
|
a6591a |
}
|
|
|
a6591a |
else
|
|
|
a6591a |
{
|
|
|
a6591a |
_dbus_verbose ("Fork not requested\n");
|
|
|
a6591a |
|
|
|
a6591a |
/* Need to write PID file and to PID pipe for ourselves,
|
|
|
a6591a |
* not for the child process. This is a no-op if the pidfile
|
|
|
a6591a |
* is NULL and print_pid_pipe is NULL.
|
|
|
a6591a |
*/
|
|
|
a6591a |
if (!_dbus_write_pid_to_file_and_pipe (context->pidfile ? &u : NULL,
|
|
|
a6591a |
print_pid_pipe,
|
|
|
a6591a |
_dbus_getpid (),
|
|
|
a6591a |
error))
|
|
|
a6591a |
{
|
|
|
a6591a |
_DBUS_ASSERT_ERROR_IS_SET (error);
|
|
|
a6591a |
goto failed;
|
|
|
a6591a |
}
|
|
|
a6591a |
}
|
|
|
a6591a |
}
|
|
|
a6591a |
|
|
|
a6591a |
if (print_pid_pipe && _dbus_pipe_is_valid (print_pid_pipe) &&
|
|
|
a6591a |
!_dbus_pipe_is_stdout_or_stderr (print_pid_pipe))
|
|
|
a6591a |
_dbus_pipe_close (print_pid_pipe, NULL);
|
|
|
a6591a |
diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c
|
|
|
a6591a |
index 9b724cc9..30bb1441 100644
|
|
|
a6591a |
--- a/dbus/dbus-sysdeps-util-unix.c
|
|
|
a6591a |
+++ b/dbus/dbus-sysdeps-util-unix.c
|
|
|
a6591a |
@@ -49,82 +49,84 @@
|
|
|
a6591a |
#include <sys/socket.h>
|
|
|
a6591a |
#include <dirent.h>
|
|
|
a6591a |
#include <sys/un.h>
|
|
|
a6591a |
|
|
|
a6591a |
#ifdef HAVE_SYSLOG_H
|
|
|
a6591a |
#include <syslog.h>
|
|
|
a6591a |
#endif
|
|
|
a6591a |
|
|
|
a6591a |
#ifdef HAVE_SYS_SYSLIMITS_H
|
|
|
a6591a |
#include <sys/syslimits.h>
|
|
|
a6591a |
#endif
|
|
|
a6591a |
|
|
|
a6591a |
#ifdef HAVE_SYSTEMD
|
|
|
a6591a |
#include <systemd/sd-daemon.h>
|
|
|
a6591a |
#endif
|
|
|
a6591a |
|
|
|
a6591a |
#ifndef O_BINARY
|
|
|
a6591a |
#define O_BINARY 0
|
|
|
a6591a |
#endif
|
|
|
a6591a |
|
|
|
a6591a |
/**
|
|
|
a6591a |
* @addtogroup DBusInternalsUtils
|
|
|
a6591a |
* @{
|
|
|
a6591a |
*/
|
|
|
a6591a |
|
|
|
a6591a |
|
|
|
a6591a |
/**
|
|
|
a6591a |
* Does the chdir, fork, setsid, etc. to become a daemon process.
|
|
|
a6591a |
*
|
|
|
a6591a |
* @param pidfile #NULL, or pidfile to create
|
|
|
a6591a |
+ * @param working_dir directory to chdir to
|
|
|
a6591a |
* @param print_pid_pipe pipe to print daemon's pid to, or -1 for none
|
|
|
a6591a |
* @param error return location for errors
|
|
|
a6591a |
* @param keep_umask #TRUE to keep the original umask
|
|
|
a6591a |
* @returns #FALSE on failure
|
|
|
a6591a |
*/
|
|
|
a6591a |
dbus_bool_t
|
|
|
a6591a |
_dbus_become_daemon (const DBusString *pidfile,
|
|
|
a6591a |
+ const char *working_dir,
|
|
|
a6591a |
DBusPipe *print_pid_pipe,
|
|
|
a6591a |
DBusError *error,
|
|
|
a6591a |
dbus_bool_t keep_umask)
|
|
|
a6591a |
{
|
|
|
a6591a |
const char *s;
|
|
|
a6591a |
pid_t child_pid;
|
|
|
a6591a |
int dev_null_fd;
|
|
|
a6591a |
|
|
|
a6591a |
_dbus_verbose ("Becoming a daemon...\n");
|
|
|
a6591a |
|
|
|
a6591a |
- _dbus_verbose ("chdir to /\n");
|
|
|
a6591a |
- if (chdir ("/") < 0)
|
|
|
a6591a |
+ _dbus_verbose ("chdir to %s\n", working_dir);
|
|
|
a6591a |
+ if (chdir (working_dir) < 0)
|
|
|
a6591a |
{
|
|
|
a6591a |
dbus_set_error (error, DBUS_ERROR_FAILED,
|
|
|
a6591a |
- "Could not chdir() to root directory");
|
|
|
a6591a |
+ "Could not chdir() to working directory (%s)", working_dir);
|
|
|
a6591a |
return FALSE;
|
|
|
a6591a |
}
|
|
|
a6591a |
|
|
|
a6591a |
_dbus_verbose ("forking...\n");
|
|
|
a6591a |
switch ((child_pid = fork ()))
|
|
|
a6591a |
{
|
|
|
a6591a |
case -1:
|
|
|
a6591a |
_dbus_verbose ("fork failed\n");
|
|
|
a6591a |
dbus_set_error (error, _dbus_error_from_errno (errno),
|
|
|
a6591a |
"Failed to fork daemon: %s", _dbus_strerror (errno));
|
|
|
a6591a |
return FALSE;
|
|
|
a6591a |
break;
|
|
|
a6591a |
|
|
|
a6591a |
case 0:
|
|
|
a6591a |
_dbus_verbose ("in child, closing std file descriptors\n");
|
|
|
a6591a |
|
|
|
a6591a |
/* silently ignore failures here, if someone
|
|
|
a6591a |
* doesn't have /dev/null we may as well try
|
|
|
a6591a |
* to continue anyhow
|
|
|
a6591a |
*/
|
|
|
a6591a |
|
|
|
a6591a |
dev_null_fd = open ("/dev/null", O_RDWR);
|
|
|
a6591a |
if (dev_null_fd >= 0)
|
|
|
a6591a |
{
|
|
|
a6591a |
dup2 (dev_null_fd, 0);
|
|
|
a6591a |
dup2 (dev_null_fd, 1);
|
|
|
a6591a |
|
|
|
a6591a |
s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
|
|
|
a6591a |
if (s == NULL || *s == '\0')
|
|
|
a6591a |
dup2 (dev_null_fd, 2);
|
|
|
a6591a |
diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c
|
|
|
a6591a |
index 3b754dbf..bfc1cb90 100644
|
|
|
a6591a |
--- a/dbus/dbus-sysdeps-util-win.c
|
|
|
a6591a |
+++ b/dbus/dbus-sysdeps-util-win.c
|
|
|
a6591a |
@@ -27,67 +27,69 @@
|
|
|
a6591a |
#define STRSAFE_NO_DEPRECATE
|
|
|
a6591a |
|
|
|
a6591a |
#include "dbus-sysdeps.h"
|
|
|
a6591a |
#include "dbus-internals.h"
|
|
|
a6591a |
#include "dbus-protocol.h"
|
|
|
a6591a |
#include "dbus-string.h"
|
|
|
a6591a |
#include "dbus-sysdeps.h"
|
|
|
a6591a |
#include "dbus-sysdeps-win.h"
|
|
|
a6591a |
#include "dbus-sockets-win.h"
|
|
|
a6591a |
#include "dbus-memory.h"
|
|
|
a6591a |
#include "dbus-pipe.h"
|
|
|
a6591a |
|
|
|
a6591a |
#include <stdio.h>
|
|
|
a6591a |
#include <stdlib.h>
|
|
|
a6591a |
#if HAVE_ERRNO_H
|
|
|
a6591a |
#include <errno.h>
|
|
|
a6591a |
#endif
|
|
|
a6591a |
#include <winsock2.h> // WSA error codes
|
|
|
a6591a |
|
|
|
a6591a |
#ifndef DBUS_WINCE
|
|
|
a6591a |
#include <io.h>
|
|
|
a6591a |
#include <lm.h>
|
|
|
a6591a |
#include <sys/stat.h>
|
|
|
a6591a |
#endif
|
|
|
a6591a |
|
|
|
a6591a |
|
|
|
a6591a |
/**
|
|
|
a6591a |
* Does the chdir, fork, setsid, etc. to become a daemon process.
|
|
|
a6591a |
*
|
|
|
a6591a |
* @param pidfile #NULL, or pidfile to create
|
|
|
a6591a |
+ * @param working_dir directory to chdir to
|
|
|
a6591a |
* @param print_pid_pipe file descriptor to print daemon's pid to, or -1 for none
|
|
|
a6591a |
* @param error return location for errors
|
|
|
a6591a |
* @param keep_umask #TRUE to keep the original umask
|
|
|
a6591a |
* @returns #FALSE on failure
|
|
|
a6591a |
*/
|
|
|
a6591a |
dbus_bool_t
|
|
|
a6591a |
_dbus_become_daemon (const DBusString *pidfile,
|
|
|
a6591a |
+ const char *working_dir,
|
|
|
a6591a |
DBusPipe *print_pid_pipe,
|
|
|
a6591a |
DBusError *error,
|
|
|
a6591a |
dbus_bool_t keep_umask)
|
|
|
a6591a |
{
|
|
|
a6591a |
dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
|
|
|
a6591a |
"Cannot daemonize on Windows");
|
|
|
a6591a |
return FALSE;
|
|
|
a6591a |
}
|
|
|
a6591a |
|
|
|
a6591a |
/**
|
|
|
a6591a |
* Creates a file containing the process ID.
|
|
|
a6591a |
*
|
|
|
a6591a |
* @param filename the filename to write to
|
|
|
a6591a |
* @param pid our process ID
|
|
|
a6591a |
* @param error return location for errors
|
|
|
a6591a |
* @returns #FALSE on failure
|
|
|
a6591a |
*/
|
|
|
a6591a |
static dbus_bool_t
|
|
|
a6591a |
_dbus_write_pid_file (const DBusString *filename,
|
|
|
a6591a |
unsigned long pid,
|
|
|
a6591a |
DBusError *error)
|
|
|
a6591a |
{
|
|
|
a6591a |
const char *cfilename;
|
|
|
a6591a |
HANDLE hnd;
|
|
|
a6591a |
char pidstr[20];
|
|
|
a6591a |
int total;
|
|
|
a6591a |
int bytes_to_write;
|
|
|
a6591a |
|
|
|
a6591a |
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
|
|
a6591a |
|
|
|
a6591a |
diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
|
|
|
a6591a |
index 0ee45c97..e569b545 100644
|
|
|
a6591a |
--- a/dbus/dbus-sysdeps.h
|
|
|
a6591a |
+++ b/dbus/dbus-sysdeps.h
|
|
|
a6591a |
@@ -498,60 +498,61 @@ int _dbus_printf_string_upper_bound (const char *format,
|
|
|
a6591a |
va_list args);
|
|
|
a6591a |
|
|
|
a6591a |
|
|
|
a6591a |
/**
|
|
|
a6591a |
* Portable struct with stat() results
|
|
|
a6591a |
*/
|
|
|
a6591a |
typedef struct
|
|
|
a6591a |
{
|
|
|
a6591a |
unsigned long mode; /**< File mode */
|
|
|
a6591a |
unsigned long nlink; /**< Number of hard links */
|
|
|
a6591a |
dbus_uid_t uid; /**< User owning file */
|
|
|
a6591a |
dbus_gid_t gid; /**< Group owning file */
|
|
|
a6591a |
unsigned long size; /**< Size of file */
|
|
|
a6591a |
unsigned long atime; /**< Access time */
|
|
|
a6591a |
unsigned long mtime; /**< Modify time */
|
|
|
a6591a |
unsigned long ctime; /**< Creation time */
|
|
|
a6591a |
} DBusStat;
|
|
|
a6591a |
|
|
|
a6591a |
dbus_bool_t _dbus_stat (const DBusString *filename,
|
|
|
a6591a |
DBusStat *statbuf,
|
|
|
a6591a |
DBusError *error);
|
|
|
a6591a |
DBUS_PRIVATE_EXPORT
|
|
|
a6591a |
dbus_bool_t _dbus_socketpair (DBusSocket *fd1,
|
|
|
a6591a |
DBusSocket *fd2,
|
|
|
a6591a |
dbus_bool_t blocking,
|
|
|
a6591a |
DBusError *error);
|
|
|
a6591a |
|
|
|
a6591a |
void _dbus_print_backtrace (void);
|
|
|
a6591a |
|
|
|
a6591a |
dbus_bool_t _dbus_become_daemon (const DBusString *pidfile,
|
|
|
a6591a |
+ const char *working_dir,
|
|
|
a6591a |
DBusPipe *print_pid_pipe,
|
|
|
a6591a |
DBusError *error,
|
|
|
a6591a |
dbus_bool_t keep_umask);
|
|
|
a6591a |
|
|
|
a6591a |
dbus_bool_t _dbus_verify_daemon_user (const char *user);
|
|
|
a6591a |
dbus_bool_t _dbus_change_to_daemon_user (const char *user,
|
|
|
a6591a |
DBusError *error);
|
|
|
a6591a |
|
|
|
a6591a |
dbus_bool_t _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
|
|
|
a6591a |
DBusPipe *print_pid_pipe,
|
|
|
a6591a |
dbus_pid_t pid_to_write,
|
|
|
a6591a |
DBusError *error);
|
|
|
a6591a |
|
|
|
a6591a |
dbus_bool_t _dbus_command_for_pid (unsigned long pid,
|
|
|
a6591a |
DBusString *str,
|
|
|
a6591a |
int max_len,
|
|
|
a6591a |
DBusError *error);
|
|
|
a6591a |
|
|
|
a6591a |
/** A UNIX signal handler */
|
|
|
a6591a |
typedef void (* DBusSignalHandler) (int sig);
|
|
|
a6591a |
|
|
|
a6591a |
void _dbus_set_signal_handler (int sig,
|
|
|
a6591a |
DBusSignalHandler handler);
|
|
|
a6591a |
|
|
|
a6591a |
dbus_bool_t _dbus_user_at_console (const char *username,
|
|
|
a6591a |
DBusError *error);
|
|
|
a6591a |
|
|
|
a6591a |
void _dbus_init_system_log (dbus_bool_t is_daemon);
|
|
|
a6591a |
|
|
|
a6591a |
typedef enum {
|
|
|
a6591a |
diff --git a/doc/dbus-launch.1.xml.in b/doc/dbus-launch.1.xml.in
|
|
|
a6591a |
index 5135d9ca..606c65be 100644
|
|
|
a6591a |
--- a/doc/dbus-launch.1.xml.in
|
|
|
a6591a |
+++ b/doc/dbus-launch.1.xml.in
|
|
|
a6591a |
@@ -23,60 +23,64 @@
|
|
|
a6591a |
<command>dbus-launch</command>
|
|
|
a6591a |
<arg choice='opt'>--version </arg>
|
|
|
a6591a |
<arg choice='opt'>--help </arg>
|
|
|
a6591a |
<arg choice='opt'>--sh-syntax </arg>
|
|
|
a6591a |
<arg choice='opt'>--csh-syntax </arg>
|
|
|
a6591a |
<arg choice='opt'>--auto-syntax </arg>
|
|
|
a6591a |
<arg choice='opt'>--binary-syntax </arg>
|
|
|
a6591a |
<arg choice='opt'>--close-stderr </arg>
|
|
|
a6591a |
<arg choice='opt'>--exit-with-session </arg>
|
|
|
a6591a |
<arg choice='opt'>--autolaunch=<replaceable>MACHINEID</replaceable></arg>
|
|
|
a6591a |
<arg choice='opt'>--config-file=<replaceable>FILENAME</replaceable></arg>
|
|
|
a6591a |
<arg choice='opt'><replaceable>PROGRAM</replaceable></arg>
|
|
|
a6591a |
<arg choice='opt' rep='repeat'><replaceable>ARGS</replaceable></arg>
|
|
|
a6591a |
<sbr/>
|
|
|
a6591a |
</cmdsynopsis>
|
|
|
a6591a |
</refsynopsisdiv>
|
|
|
a6591a |
|
|
|
a6591a |
|
|
|
a6591a |
<refsect1 id='description'><title>DESCRIPTION</title>
|
|
|
a6591a |
<para>The <command>dbus-launch</command> command is used to start a session bus
|
|
|
a6591a |
instance of <emphasis remap='I'>dbus-daemon</emphasis> from a shell script.
|
|
|
a6591a |
It would normally be called from a user's login
|
|
|
a6591a |
scripts. Unlike the daemon itself, <command>dbus-launch</command> exits, so
|
|
|
a6591a |
backticks or the $() construct can be used to read information from
|
|
|
a6591a |
<command>dbus-launch</command>.</para>
|
|
|
a6591a |
|
|
|
a6591a |
<para>With no arguments, <command>dbus-launch</command> will launch a session bus
|
|
|
a6591a |
instance and print the address and PID of that instance to standard
|
|
|
a6591a |
output.</para>
|
|
|
a6591a |
|
|
|
a6591a |
+<para>If the environment variable HOME is set, it is used as the current
|
|
|
a6591a |
+working directory. Otherwise, the root directory (<filename>/</filename>) is
|
|
|
a6591a |
+used.</para>
|
|
|
a6591a |
+
|
|
|
a6591a |
<para>You may specify a program to be run; in this case, <command>dbus-launch</command>
|
|
|
a6591a |
will launch a session bus instance, set the appropriate environment
|
|
|
a6591a |
variables so the specified program can find the bus, and then execute the
|
|
|
a6591a |
specified program, with the specified arguments. See below for
|
|
|
a6591a |
examples.</para>
|
|
|
a6591a |
|
|
|
a6591a |
<para>If you launch a program, <command>dbus-launch</command> will not print the
|
|
|
a6591a |
information about the new bus to standard output.</para>
|
|
|
a6591a |
|
|
|
a6591a |
<para>When <command>dbus-launch</command> prints bus information to standard output, by
|
|
|
a6591a |
default it is in a simple key-value pairs format. However, you may
|
|
|
a6591a |
request several alternate syntaxes using the --sh-syntax, --csh-syntax,
|
|
|
a6591a |
--binary-syntax, or
|
|
|
a6591a |
--auto-syntax options. Several of these cause <command>dbus-launch</command> to emit shell code
|
|
|
a6591a |
to set up the environment.</para>
|
|
|
a6591a |
|
|
|
a6591a |
<para>With the --auto-syntax option, <command>dbus-launch</command> looks at the value
|
|
|
a6591a |
of the SHELL environment variable to determine which shell syntax
|
|
|
a6591a |
should be used. If SHELL ends in "csh", then csh-compatible code is
|
|
|
a6591a |
emitted; otherwise Bourne shell code is emitted. Instead of passing
|
|
|
a6591a |
--auto-syntax, you may explicitly specify a particular one by using
|
|
|
a6591a |
--sh-syntax for Bourne syntax, or --csh-syntax for csh syntax.
|
|
|
a6591a |
In scripts, it's more robust to avoid --auto-syntax and you hopefully
|
|
|
a6591a |
know which shell your script is written in.</para>
|
|
|
a6591a |
|
|
|
a6591a |
|
|
|
a6591a |
<para>See <ulink url='http://www.freedesktop.org/software/dbus/'>http://www.freedesktop.org/software/dbus/</ulink> for more information
|
|
|
a6591a |
about D-Bus. See also the man page for <emphasis remap='I'>dbus-daemon</emphasis>.</para>
|
|
|
a6591a |
|
|
|
a6591a |
</refsect1>
|
|
|
a6591a |
diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c
|
|
|
a6591a |
index 80e4a241..a956684c 100644
|
|
|
a6591a |
--- a/tools/dbus-launch.c
|
|
|
a6591a |
+++ b/tools/dbus-launch.c
|
|
|
a6591a |
@@ -592,71 +592,77 @@ kill_bus_when_session_ends (void)
|
|
|
a6591a |
/* This shouldn't happen I don't think; to avoid
|
|
|
a6591a |
* spinning on the fd forever we exit.
|
|
|
a6591a |
*/
|
|
|
a6591a |
fprintf (stderr, "dbus-launch: error reading from stdin: %s\n",
|
|
|
a6591a |
strerror (errno));
|
|
|
a6591a |
kill_bus_and_exit (0);
|
|
|
a6591a |
}
|
|
|
a6591a |
}
|
|
|
a6591a |
else if (FD_ISSET (tty_fd, &err_set))
|
|
|
a6591a |
{
|
|
|
a6591a |
verbose ("TTY has error condition\n");
|
|
|
a6591a |
|
|
|
a6591a |
kill_bus_and_exit (0);
|
|
|
a6591a |
}
|
|
|
a6591a |
}
|
|
|
a6591a |
}
|
|
|
a6591a |
}
|
|
|
a6591a |
|
|
|
a6591a |
static void
|
|
|
a6591a |
babysit (int exit_with_session,
|
|
|
a6591a |
pid_t child_pid,
|
|
|
a6591a |
int read_bus_pid_fd) /* read pid from here */
|
|
|
a6591a |
{
|
|
|
a6591a |
int ret;
|
|
|
a6591a |
int dev_null_fd;
|
|
|
a6591a |
const char *s;
|
|
|
a6591a |
|
|
|
a6591a |
verbose ("babysitting, exit_with_session = %d, child_pid = %ld, read_bus_pid_fd = %d\n",
|
|
|
a6591a |
exit_with_session, (long) child_pid, read_bus_pid_fd);
|
|
|
a6591a |
|
|
|
a6591a |
- /* We chdir ("/") since we are persistent and daemon-like, and fork
|
|
|
a6591a |
- * again so dbus-launch can reap the parent. However, we don't
|
|
|
a6591a |
- * setsid() or close fd 0 because the idea is to remain attached
|
|
|
a6591a |
- * to the tty and the X server in order to kill the message bus
|
|
|
a6591a |
- * when the session ends.
|
|
|
a6591a |
+ /* We chdir () since we are persistent and daemon-like, either to $HOME
|
|
|
a6591a |
+ * to match the behaviour of a session bus started by systemd --user, or
|
|
|
a6591a |
+ * otherwise "/". We fork again so dbus-launch can reap the parent.
|
|
|
a6591a |
+ * However, we don't setsid() or close fd 0 because the idea is to
|
|
|
a6591a |
+ * remain attached to the tty and the X server in order to kill the
|
|
|
a6591a |
+ * message bus when the session ends.
|
|
|
a6591a |
*/
|
|
|
a6591a |
|
|
|
a6591a |
- if (chdir ("/") < 0)
|
|
|
a6591a |
+ s = getenv ("HOME");
|
|
|
a6591a |
+
|
|
|
a6591a |
+ if (s == NULL || *s == '\0')
|
|
|
a6591a |
+ s = "/";
|
|
|
a6591a |
+
|
|
|
a6591a |
+ if (chdir (s) < 0)
|
|
|
a6591a |
{
|
|
|
a6591a |
- fprintf (stderr, "Could not change to root directory: %s\n",
|
|
|
a6591a |
- strerror (errno));
|
|
|
a6591a |
+ fprintf (stderr, "Could not change to working directory \"%s\": %s\n",
|
|
|
a6591a |
+ s, strerror (errno));
|
|
|
a6591a |
exit (1);
|
|
|
a6591a |
}
|
|
|
a6591a |
|
|
|
a6591a |
/* Close stdout/stderr so we don't block an "eval" or otherwise
|
|
|
a6591a |
* lock up. stdout is still chaining through to dbus-launch
|
|
|
a6591a |
* and in turn to the parent shell.
|
|
|
a6591a |
*/
|
|
|
a6591a |
dev_null_fd = open ("/dev/null", O_RDWR);
|
|
|
a6591a |
if (dev_null_fd >= 0)
|
|
|
a6591a |
{
|
|
|
a6591a |
if (!exit_with_session)
|
|
|
a6591a |
dup2 (dev_null_fd, 0);
|
|
|
a6591a |
dup2 (dev_null_fd, 1);
|
|
|
a6591a |
s = getenv ("DBUS_DEBUG_OUTPUT");
|
|
|
a6591a |
if (s == NULL || *s == '\0')
|
|
|
a6591a |
dup2 (dev_null_fd, 2);
|
|
|
a6591a |
close (dev_null_fd);
|
|
|
a6591a |
}
|
|
|
a6591a |
else
|
|
|
a6591a |
{
|
|
|
a6591a |
fprintf (stderr, "Failed to open /dev/null: %s\n",
|
|
|
a6591a |
strerror (errno));
|
|
|
a6591a |
/* continue, why not */
|
|
|
a6591a |
}
|
|
|
a6591a |
|
|
|
a6591a |
ret = fork ();
|
|
|
a6591a |
|
|
|
a6591a |
if (ret < 0)
|
|
|
a6591a |
{
|
|
|
a6591a |
fprintf (stderr, "fork() failed in babysitter: %s\n",
|
|
|
a6591a |
--
|
|
|
a6591a |
2.17.1
|
|
|
a6591a |
|