Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

/etc/pm/sleep.d/40autorandr does not work with startx/xinit sessions #39

Closed
blueyed opened this issue Dec 2, 2015 · 22 comments
Closed

Comments

@blueyed
Copy link
Contributor

blueyed commented Dec 2, 2015

When using startx / ~/.xinitrc to start X, the display detection in /etc/pm/sleep.d/40autorandr fails:

who | awk -vD="$D" '$2 ~ ":"D"(.[0-9])?$" {print $1}' | head -1

The output from who looks like this:

user   tty1         2015-12-02 13:32
@phillipberndt
Copy link
Owner

Does who --all show the information? How about w?

@phillipberndt
Copy link
Owner

@phillipberndt
Copy link
Owner

..did yesterday's commit fix the issue?

@blueyed
Copy link
Contributor Author

blueyed commented Dec 5, 2015

No, w -h looks like this for me:

user   tty1      Wed14    3days  1:11m  0.00s xinit /home/user/.xinitrc -- /usr/bin/X :0 -nolisten tcp vt1 -auth /tmp/serverauth.XXX
user   pts/3     Wed14    4:49m  7.43s  0.05s /usr/bin/python2 -c import sys; sys.path.remove(""); import neovim; neovim.start_host() /home/user/.local/opt/neovim/share/nvim/runtime/aut

I think the problem is "just" that there's no display manager that would update the utmp database with the display information.

@phillipberndt
Copy link
Owner

I have searched for portable ways to find which user "owns" an X11 session, but haven't been able to find one.. I doubt that this is generally solvable (at least, without creating potential security issues like one might do by e.g. searching for any program that is connected to the display and then su to its owner.).

@blueyed
Copy link
Contributor Author

blueyed commented Dec 5, 2015

Yeah.
What about getting the :0 out from my w -h?
But maybe after all xinit would need to be changed to also update the utmp database like other desktop managers do?

@phillipberndt
Copy link
Owner

What about getting the :0 out from my w -h?

This seems to be the best course of action, though I'm still not perfectly happy with su'ing to some user based on the output of some command that said user can influence. See the latest change.

@blueyed
Copy link
Contributor Author

blueyed commented Jan 7, 2016

FWIW, here's some adhoc method, which might be too specific, but works for me:

w -h | grep -oE '/usr/bin/X (:\S+)' | cut -d\  -f2

@phillipberndt
Copy link
Owner

That'll find any X11 session, not specifically yours, right? But in
combination with a check whether it's the only one that'd indeed be a good
fallback.

@phillipberndt
Copy link
Owner

Another thought, do you think this would work?

USERS=($(w -hu | cut -d\  -f1 | grep -vx root | sort | uniq))
if [ ${#USERS} -eq 1 ]; then
    # Obviously the session must be owned by ${USERS[1]}
fi

(I'm aware that dash does not support the array syntax, this is currently written for bash)

@blueyed
Copy link
Contributor Author

blueyed commented Jan 19, 2016

Works for me.

This does the same, using awk and only looks at tty* entries (which I'm not sure is good?!):

w -hu | awk '$2 ~ "tty.*" && $1 !~ "root" { print $1; exit }'

@phillipberndt
Copy link
Owner

Great. I'll include this as a fallback, then.

(Your variant doesn't do exactly the same; actually, checking that there isn't another user logged in was an intentional security measure.)

@blueyed
Copy link
Contributor Author

blueyed commented Jan 19, 2016

checking that there isn't another user logged in was an intentional security measure

Hmm. Isn't the idea/point to handle all logged in users?

@phillipberndt
Copy link
Owner

Hmm. Isn't the idea/point to handle all logged in users?

Sure. That works, too, if the utmp database is used correctly. If it isn't, we still lack a reliable way to determine the owner of an X11-session. We use the information to su to a user and run an executable, which is potentially dangerous, so I'd prefer to include "forgery proof" in "reliable" unless it is absolutely unavoidable not to. Since we haven't found a way to do that yet, my idea was, for the time being, to provide a fallback for the case of a single user system, where this isn't an issue.

btw, here's an awk only variant of my above approach:

w -hu | awk '/^\w+/ && $1 !~ "root" { users[$1]=$1; } ENDFILE { if(asort(users) == 1) for(u in users) print users[u]; }'

@phillipberndt
Copy link
Owner

I committed the workaround; closing this for now, though I'd still prefer to have a proper fix.

@rnav
Copy link

rnav commented Jul 28, 2016

Bumping an old one, but I did face this issue though I use SDDM. It looks like utmp is not updated, so my active login is not reflected by w/who. I've addressed this by using loginctl:

user="loginctl list-users --no-legend | cut -d' ' -f8"

@phillipberndt
Copy link
Owner

phillipberndt commented Jul 28, 2016

It'd be an option to detect whether loginctl is available and use it preferably if it is. Does this DISPLAY detection script work for you? That is, does

loginctl show-session -p Display -p Active `loginctl list-sessions --no-legend | awk '{print $1}'`

output the correct display? The SO answer however claims that this won't work with gdm.

Here's another alternative: We could search for all processes that locally run and have access to the display and check whether except for root, there's only one owning user:

for p in /proc/*; do
    [ -d $p ] || continue
    d=$(awk -v RS='\0' -F= '$1=="DISPLAY" {print $2}' $p/environ 2>/dev/null);
    if [ "$d" = ":0" ]; then # Replace :0 with $D !!
        stat -c %U $p
    fi
done | sort | uniq | grep -v root

does this work for you?

@phillipberndt phillipberndt reopened this Jul 28, 2016
@rnav
Copy link

rnav commented Jul 28, 2016

Yes, those work for me. I prefer the loginctl based approach though. Going through all the processes seems heavy -- we can perhaps use loginctl and consider other options for GDM?

@phillipberndt
Copy link
Owner

phillipberndt commented Jul 28, 2016

So do I. I wondered whether this works because we need some fail-safe in case all other detection methods fail. That was what the final w invocation was for as well (..and I thought it'd work because I foolishly assumed that noone would break POSIX compatibility.)

@rnav
Copy link

rnav commented Jul 28, 2016

Yes, I think that makes sense. I suppose a few if [ -z "$user" ]; then checks can't hurt and going through all the processes as the last resort seems better than autorandr not working at all.

phillipberndt added a commit that referenced this issue Jul 28, 2016
@phillipberndt
Copy link
Owner

I tried implementing this. Could you test if the version from the new branch works for you, please?

@rnav
Copy link

rnav commented Jul 29, 2016

This works for me with the change I mentioned in your commit. Thanks for fixing this!

phillipberndt added a commit that referenced this issue Sep 16, 2016
…th an X11 session

This is an attempt to resolve #45 and it might also be a better
alternative to #52, #44 and #39.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants