Bug 1205109

Summary: emacs cannot reach XDG_RUNTIME_DIR
Product: [openSUSE] openSUSE Distribution Reporter: Zim Tsui <zimtsui>
Component: OtherAssignee: Dr. Werner Fink <werner>
Status: RESOLVED FIXED QA Contact: E-mail List <qa-bugs>
Severity: Minor    
Priority: P5 - None CC: zimtsui
Version: Leap 15.4   
Target Milestone: ---   
Hardware: All   
OS: openSUSE Leap 15.4   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Bug Depends on:    
Bug Blocks: 1205169    
Attachments: /usr/bin/emacs modified shell script

Description Zim Tsui 2022-11-06 16:41:26 UTC
# Description

Emacs checks whether environment variable `XDG_RUNTIME_DIR` exists to determine where a certain socket file should be placed. If `XDG_RUNTIME_DIR` doesn't exist, emacs will fallback to some other location. See <https://git.savannah.gnu.org/cgit/emacs.git/tree/lib-src/emacsclient.c?h=emacs-27.2#n1393>

`sudo` defaults to unset all environment variables and set some certain ones. So any program run by `sudo` should miss `XDG_RUNTIME_DIR` in its environment.

If I run `sudo emacs-nox`, everything goes expectedly. But if I run `sudo emacs`, emacs prompts `Unable to set up transient service directory: XDG_RUNTIME_DIR "/run/user/0" not available: No such file or directory`.

# Possible reason

The binary `/usr/bin/emacs` is not built from emacs source, but made by the SUSE package maintainer. The binary checks whether it's run in terminal or X to determine whether it should exec `emacs-nox` or `emacs-x11`.

The `/usr/bin/emacs` binary defines an environment variable `XDG_RUNTIME_DIR` as `/run/user/<USER_ID>` arbitrarily. But `/run/user/0` doesn't exist because it  should be created by `/etc/profile` in a login shell. And `sudo` doesn't spawn a new login shell.

# Reproduction

1. Install `emacs` and `emcas-nox` from zypper, and don't install `emacs-x11`.
1. Restart your computer and don't login as root in any tty, but login as a regular user.
1. `sudo emacs`
1. Quit emacs.
1. You will see the prompt.

# Versions

openSUSE Leap 15.4
Emacs 27.2
Sudo 1.9.9
Comment 1 Dr. Werner Fink 2022-11-07 08:19:55 UTC
Created attachment 862687 [details]
/usr/bin/emacs modified shell script

(In reply to Zim Tsui from comment #0)

> # Possible reason
> 
> The binary `/usr/bin/emacs` is not built from emacs source, but made by the
> SUSE package maintainer. The binary checks whether it's run in terminal or X
> to determine whether it should exec `emacs-nox` or `emacs-x11`.

/usr/bin/emacs is a shell script and not a binary which enables to switch between emacs-x11, emacs-gtk, or emacs-nox.  Abd indeed this script also tries to provide a connection to the dbus API if not given.

> 
> The `/usr/bin/emacs` binary defines an environment variable
> `XDG_RUNTIME_DIR` as `/run/user/<USER_ID>` arbitrarily. But `/run/user/0`
> doesn't exist because it  should be created by `/etc/profile` in a login
> shell. And `sudo` doesn't spawn a new login shell.

The /run/user/<USER_ID> will not be created by the login shell but by the systemd pam module pam_systemd(.so) -> `man 8 pam_systemd'

Give the attached shell script as a replacement of /usr/bin/emacs a try and report if this does work for you.
Comment 2 Zim Tsui 2022-11-07 13:34:53 UTC
(In reply to Dr. Werner Fink from comment #1)
> Give the attached shell script as a replacement of /usr/bin/emacs a try and
> report if this does work for you.

I tried that but it doesn't work.

Your substitute script simply replaces `UID` with `EUID`. This is redundant because `sudo` already handles that well. Try the below as regular user:

```shell
$ sudo sh -c "echo \$UID"
0
$ sudo sh -c "echo \$EUID"
0
```

The key point is that the directory `/run/user/0` doesn't exist if you have never logged in as root since boot.

`su -` or `sudo -i` simply emulates a login shell, but actually doesn't create a new session. See <https://github.com/systemd/systemd/issues/7451#issuecomment-346787237>

A possible solution is doing nothing about the environment. Since emacs has its own logic about handling the absence of environment variables, why interfere it?
Comment 3 Dr. Werner Fink 2022-11-07 14:10:09 UTC
(In reply to Zim Tsui from comment #2)
> (In reply to Dr. Werner Fink from comment #1)
> > Give the attached shell script as a replacement of /usr/bin/emacs a try and
> > report if this does work for you.
> 
> I tried that but it doesn't work.
> 
> Your substitute script simply replaces `UID` with `EUID`. This is redundant
> because `sudo` already handles that well. Try the below as regular user:
> 
> ```shell
> $ sudo sh -c "echo \$UID"
> 0
> $ sudo sh -c "echo \$EUID"
> 0
> ```

The aim is to replace XDG_RUNTIME_DIR to the correct one

> 
> The key point is that the directory `/run/user/0` doesn't exist if you have
> never logged in as root since boot.
> 
> `su -` or `sudo -i` simply emulates a login shell, but actually doesn't
> create a new session. See
> <https://github.com/systemd/systemd/issues/7451#issuecomment-346787237>
> 
> A possible solution is doing nothing about the environment. Since emacs has
> its own logic about handling the absence of environment variables, why
> interfere it?

just try 

   sudo /usr/bin/emacs-nox

and then try with installed emacs-x11

   sudo /usr/bin/emacs-gtk

and see what happens ... I see e.g.

 XDG_RUNTIME_DIR (/run/user/223) is not owned by us (uid 0), but by uid 223! (This could e.g. happen if you try to connect to a non-root PulseAudio as a root user, over the native protocol. Don't do that.)

that is the exported XDG variables will be taken by user root.
Comment 4 Zim Tsui 2022-11-07 18:14:22 UTC
(In reply to Dr. Werner Fink from comment #3)
> just try 
> 
>    sudo /usr/bin/emacs-nox
> 
> and then try with installed emacs-x11
> 
>    sudo /usr/bin/emacs-gtk
> 
> and see what happens ... I see e.g.

If I run `sudo emacs-nox` directly, no errors occurred.

Only if I run `sudo emacs`, it prints errors.

This is because the script `/usr/bin/emacs` set the variable `XDG_RUNTIME_DIR` to `/run/user/0` when I run `sudo emacs`, while the directory `/run/user/0` doesn't exist.

The reason why `/run/user/0` doesn't exist is that `sudo` doesn't create a new real session to login as root(UID:0), it merely SIMULATES a login shell. The systemd is not aware of someone loging in as root, and will not create the directory `/run/user/0`.

> The aim is to replace XDG_RUNTIME_DIR to the correct one

The variable `XDG_RUNTIME_DIR` should be managed only by systemd rather than by user scripts, because only systemd knows what to do else with the variable, such as creating the corresponding directories. It's dangerous to set the XDG_ variables manually.

The simplist solution to this issue is not to set the XDG variables in `/usr/bin/emacs`, as if the variables are not set when `emacs-nox` is run directly.
Comment 5 Dr. Werner Fink 2022-11-08 07:17:52 UTC
(In reply to Zim Tsui from comment #4)
> (In reply to Dr. Werner Fink from comment #3)
> > just try 
> > 
> >    sudo /usr/bin/emacs-nox
> > 
> > and then try with installed emacs-x11
> > 
> >    sudo /usr/bin/emacs-gtk
> > 
> > and see what happens ... I see e.g.
> 
> If I run `sudo emacs-nox` directly, no errors occurred.

I've asked for emacs-gtk not for emacs-nox, please install the package emacs-x11 and then retry with 

  EMACS_TOOLKIT=gtk sudo emacs

> 
> Only if I run `sudo emacs`, it prints errors.
> 
> This is because the script `/usr/bin/emacs` set the variable
> `XDG_RUNTIME_DIR` to `/run/user/0` when I run `sudo emacs`, while the
> directory `/run/user/0` doesn't exist.
> 
> The reason why `/run/user/0` doesn't exist is that `sudo` doesn't create a
> new real session to login as root(UID:0), it merely SIMULATES a login shell.
> The systemd is not aware of someone loging in as root, and will not create
> the directory `/run/user/0`.

I'm aware of, nevertheless the question is how to solve the problem for the most emacs users out there. And the x11/gtk version of GNU Emacs is with dbus support.  And this script exists e.g. for ssh connections.

> 
> > The aim is to replace XDG_RUNTIME_DIR to the correct one
> 
> The variable `XDG_RUNTIME_DIR` should be managed only by systemd rather than
> by user scripts, because only systemd knows what to do else with the
> variable, such as creating the corresponding directories. It's dangerous to
> set the XDG_ variables manually.

This managment does currently not happen.

> 
> The simplist solution to this issue is not to set the XDG variables in
> `/usr/bin/emacs`, as if the variables are not set when `emacs-nox` is run
> directly.

That is a corner case ... I'm interested to solve it also for emacs with dbus support.
Comment 6 Zim Tsui 2022-11-08 11:04:18 UTC
(In reply to Dr. Werner Fink from comment #5)
> I've asked for emacs-gtk not for emacs-nox, please install the package
> emacs-x11 and then retry with 
> 
>   EMACS_TOOLKIT=gtk sudo emacs
> 

After trying what you said, more bugs appear. (=。=')

If I run `sudo emacs`, 

- An error happened.
- A terminal emacs is open.
- The open emacs's process name is `emacs-gtk`.
- There is an additional process `dbus-run-session`.

If I run `EMACS_TOOLKIT=gtk sudo emacs`, 

- An error happened.
- A terminal emacs is open.
- The open emacs's process name is `emacs-gtk`.
- There is an additional process `dbus-run-session`.

If I run `sudo emacs-x11`, 

- No errors happened.
- A terminal emacs is open.
- The open emacs's process name is `emacs-x11`.

If I run `sudo emacs-gtk`, 

- No errors happened.
- A terminal emacs is open.
- The open emacs's process name is `emacs-gtk`.

If I switch to root via `su -`, and then run `emacs`

- An error happened.
- An X emacs is open.
- The open emacs's process name is `emacs-gtk`.
- There is an additional process `dbus-run-session`.

It's difficult to describe all the behavior, why not reproduce that by your self?
Comment 7 Dr. Werner Fink 2022-11-08 13:47:45 UTC
(In reply to Zim Tsui from comment #6)
> (In reply to Dr. Werner Fink from comment #5)

> It's difficult to describe all the behavior, why not reproduce that by your
> self?

Because I've less problem as I work often as root and therefore /run/user/0
simply exists
Comment 8 Dr. Werner Fink 2022-11-08 13:50:05 UTC
Btw:

I see for

  sudo emacs-gtk
  XDG_RUNTIME_DIR (/run/user/223) is not owned by us (uid 0), but by uid 223! (This could e.g. happen if you try to connect to a non-root PulseAudio as a root user, over the native protocol. Don't do that.)

this is an error I guess
Comment 9 Zim Tsui 2022-11-08 20:12:05 UTC
(In reply to Dr. Werner Fink from comment #8)
> Btw:
> 
> I see for
> 
>   sudo emacs-gtk
>   XDG_RUNTIME_DIR (/run/user/223) is not owned by us (uid 0), but by uid
> 223! (This could e.g. happen if you try to connect to a non-root PulseAudio
> as a root user, over the native protocol. Don't do that.)
> 
> this is an error I guess

`XDG_RUNTIME_DIR` is always resolved to `/run/user/0`, because the script `/usr/bin/emacs` set `XDG_RUNTIME_DIR` to `/run/user/$UID`, where UID and EUID both equal 0 within `sudo`. It has nothing to do with the regular user.

Besides, I'm not asking for help, I'm simply reporting a bug, because I seldom use Emacs.
Comment 10 OBSbugzilla Bot 2022-11-09 15:35:02 UTC
This is an autogenerated message for OBS integration:
This bug (1205109) was mentioned in
https://build.opensuse.org/request/show/1034852 Factory / emacs
Comment 11 Dr. Werner Fink 2022-12-01 14:20:38 UTC
should be done for now