diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index efaebfd94..ef351749f 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1708,9 +1708,10 @@ main (int argc, char **argv ) opt.running_detached = 1; } - if (chdir("/")) + if (gnupg_chdir (gnupg_daemon_rootdir ())) { - log_error ("chdir to / failed: %s\n", strerror (errno)); + log_error ("chdir to '%s' failed: %s\n", + gnupg_daemon_rootdir (), strerror (errno)); exit (1); } diff --git a/common/homedir.c b/common/homedir.c index fce6d44be..a30e8dc76 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -433,6 +433,34 @@ gnupg_default_homedir_p (void) } +/* Return the directory name used by daemons for their current working + * directory. */ +const char * +gnupg_daemon_rootdir (void) +{ +#ifdef HAVE_W32_SYSTEM + static char *name; + + if (!name) + { + char path[MAX_PATH]; + size_t n; + + n = GetSystemDirectoryA (path, sizeof path); + if (!n || n >= sizeof path) + name = xstrdup ("/"); /* Error - use the curret top dir instead. */ + else + name = xstrdup (path); + } + + return name; + +#else /*!HAVE_W32_SYSTEM*/ + return "/"; +#endif /*!HAVE_W32_SYSTEM*/ +} + + /* Helper for gnupg-socketdir. This is a global function, so that * gpgconf can use it for its --create-socketdir command. If * SKIP_CHECKS is set permission checks etc. are not done. The diff --git a/common/sysutils.c b/common/sysutils.c index 1aa2e5314..e90010c44 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -796,6 +796,15 @@ gnupg_mkdir (const char *name, const char *modestr) } +/* A simple wrapper around chdir. NAME is expected to be utf8 + * encoded. */ +int +gnupg_chdir (const char *name) +{ + return chdir (name); +} + + /* A wrapper around chmod which takes a string for the mode argument. This makes it easier to handle the mode argument which is not defined on all systems. The format of the modestring is the same diff --git a/common/sysutils.h b/common/sysutils.h index e93ea2b1c..009b14b4a 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -65,7 +65,8 @@ void gnupg_allow_set_foregound_window (pid_t pid); int gnupg_remove (const char *fname); gpg_error_t gnupg_rename_file (const char *oldname, const char *newname, int *block_signals); -int gnupg_mkdir (const char *name, const char *modestr); +int gnupg_mkdir (const char *name, const char *modestr); +int gnupg_chdir (const char *name); int gnupg_chmod (const char *name, const char *modestr); char *gnupg_mkdtemp (char *template); int gnupg_setenv (const char *name, const char *value, int overwrite); diff --git a/common/util.h b/common/util.h index 5b712d3e9..c6d19c64b 100644 --- a/common/util.h +++ b/common/util.h @@ -235,6 +235,7 @@ const char *default_homedir (void); void gnupg_set_homedir (const char *newdir); const char *gnupg_homedir (void); int gnupg_default_homedir_p (void); +const char *gnupg_daemon_rootdir (void); const char *gnupg_socketdir (void); const char *gnupg_sysconfdir (void); const char *gnupg_bindir (void); diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 6eabca9c3..436c8080b 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -1351,11 +1351,13 @@ main (int argc, char **argv) log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED); opt.running_detached = 1; - if (chdir("/")) + if (gnupg_chdir (gnupg_daemon_rootdir ())) { - log_error ("chdir to / failed: %s\n", strerror (errno)); + log_error ("chdir to '%s' failed: %s\n", + gnupg_daemon_rootdir (), strerror (errno)); dirmngr_exit (1); } + } #endif diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 26e89dd8d..bf3f42a0e 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -908,9 +908,10 @@ main (int argc, char **argv ) sigaction (SIGPIPE, &sa, NULL); } - if (chdir("/")) + if (gnupg_chdir (gnupg_daemon_rootdir ())) { - log_error ("chdir to / failed: %s\n", strerror (errno)); + log_error ("chdir to '%s' failed: %s\n", + gnupg_daemon_rootdir (), strerror (errno)); exit (1); }