Relative paths in .desktop, .service files' Exec= lines

Simon McVittie simon.mcvittie at
Thu Jun 23 17:54:51 UTC 2016

On 23/06/16 17:53, Allison Lortie wrote:
> On Mon, Jun 20, 2016, at 13:24, Simon McVittie wrote:
>> One subtlety of the phrasing is that a single .desktop or .service file
>> might be visible in more than one directory thanks to symlinks, hard
>> links or bind mounts. Thiago's phrasing makes it specific that it is the
>> directory that actually appeared in the .desktop or .service search path
>> that matters, and not any of the same file's other apparent locations.
> It must be this way, at least for hardlinks, since there is no way to
> tell which one is the "real" one.

Right. The same is true for bind mounts, I think.

> I don't think we should be speaking
> about search paths, though, because it may confuse the issue.  What
> happens, for example, if my homedir contains a symlink to a desktop file
> in /usr/share/applications?

What I had intended, and the way I had interpreted Thiago's meaning, is
"the easiest thing": the relative path is relative to wherever we happen
to have found it, so in this case your home directory.

And, yes, that could conceivably break things sometimes, particularly in
the case where you have a .desktop file on ~/Desktop or something - I
hadn't thought about that case.

> Reading "search path" here makes me think
> that maybe I need to be more intelligent about how I treat this: do you
> really intend for me to check if the destination of the symlink is in
> one of the standard directories and proceed accordingly?  This is a
> no-go.

No, that's not what I meant. I was wrongly assuming that .desktop file
consumers always find them via $XDG_DATA_DIRS/applications - that's what
I meant by "search path" - and not thinking about the case where you
have a .desktop file in some random other directory like ~/Desktop, and
double-click on it in a file manager or on the desktop.

(D-Bus doesn't have this case, it only cares about .service files in
$XDG_DATA_DIRS/dbus-1/services or the analogous search path for

> On the other hand, what we are doing here very much might break the
> previously working behaviour of making symlinks from
> /usr/share/applications into the user's home directory.

Right, that's a valid concern.

> On the other other hand, if we follow this all the way down the rabbit
> hole, we may get into weird situations whereby we're canonicalising
> symlinks in situations where /usr is a symlink to /mnt/usr or something
> equally awful, in which case we might end up at the wrong result.

Indeed. I specifically don't want to do that.

> For
> that reason, I think we should limit any resolution step here to direct
> inspection of the desktop file in question for being a symlink, itself,
> and not attempt a full canonicalisation.

OK. So are you thinking of something like this pseudocode?

    path = $HOME/Desktop/dconf-editor.desktop   # or something

    data = load(path)
    working_directory = data["Path"]
    argv = split(data["Exec"])

    if argv[0] is absolute:
        execv(argv[0], argv)
    else if argv[0] contains a path separator:
        if lstat(path) says it's a symlink:
            link_target = readlink(path)
            # assume join() is syntax-only manipulation like
            # Python os.path.join, and does not look at the disk
            reference = join(dirname(path), link_target)
            reference = path

        argv[0] = join(dirname(reference), argv[0])
        execv(argv[0], argv)
        # normal shell-style PATH search
        execvp(argv[0], argv)

(I'm not sure how best to represent that not-really-canonicalization as
spec text, which is why I wrote this as pseudocode for discussion instead.)

> I strongly suggest that this case is resolved relative to the directory
> in which we found the actual file.

OK, not a problem.

Simon McVittie
Collabora Ltd. <>

More information about the xdg mailing list