relative paths in Exec= in .desktop and .service files
simon.mcvittie at collabora.co.uk
Mon Sep 8 05:23:05 PDT 2014
On <https://bugs.freedesktop.org/show_bug.cgi?id=44030>, we've been
trying to work out what the semantics of a non-absolute Exec key in
D-Bus services should be. I would like it to be the same as in XDG
desktop entries (whatever that is), which is not currently completely
In particular, Ralf Habacker (maintainer of D-Bus on Windows) would like
D-Bus session .service files to be "relocatable", because fixed paths
like /usr are not something that exists on Windows. I would like to
avoid having the semantics of .service files on Windows and Unix be
completely different, so I would like to have something that can work on
Unix too, hence involving XDG rather than doing a Windows-specific change.
There are three cases:
1) absolute (starts with / on Unix, [/\] or [A-Za-z]:[/\] on Windows)
This is easy and obvious. Exec=/usr/bin/foo executes /usr/bin/foo,
Exec=C:\\mingw\\bin\\bar.exe executes C:\mingw\bin\bar.exe.
2) no path separator (no / on Unix, no [/\] on Windows)
For desktop entries on Unix, this is well-defined: Exec=foo searches the
PATH for foo, the same way execvp() would do.
For D-Bus services, this is not currently specified. Implementation
detail: dbus-daemon on Unix uses execv(), so it will look in its current
working directory, whatever that happens to be; dbus-daemon on Windows
fails to execute the service.
I think a reasonable behaviour would be to use execvp() on Unix and
SearchPath(NULL, "foo.exe", ...) on Windows.
3) contains a path separator but is relative
This is not currently in either specification: it is unspecified what
Exec=../bin/foo or Exec=./foo would do.
Reasonable possibilities include:
* it's relative to the directory containing the executable that is
interpreting the file, e.g. dbus-daemon[.exe], i.e. normally /usr/bin
* it's relative to the getcwd() of the process that is interpreting
the file, i.e. normally / or $HOME
* it's relative to the directory containing the file itself,
i.e. normally /usr/share/applications
(Implementation detail: whichever directory is chosen, on Unix, it
should be relatively straightforward to make Unix dbus-daemon chdir() to
it after fork() but before execvp(), since POSIX.1-2004 says chdir(2) is
async-signal-safe. That would make relative paths do the expected thing.)
More information about the dbus