Запустите графический интерфейс Python из программы C, работающей с пользователем root

Я сделал программу C, которая в какой-то момент вызывает свой графический интерфейс python.

При запуске C и Python на моем рабочем столе с помощью sudo это работает, потому что sudo выполняет программу C от имени моего пользователя.

Но я создал модуль systemd для запуска кода C при загрузке, поэтому он выполняется пользователем root, а затем я не могу заставить его отображать графический интерфейс Python на моем рабочем столе, потому что я получаю WARNING **: Could not open X display.

Код C наблюдает за двоичным файлом с помощью inotify и выполняет некоторую работу, когда двоичный файл открыт, и открывает графический интерфейс Python с помощью простого вызова system.

Код C должен быть выполнен с привилегиями root, но графический интерфейс python может быть запущен как обычный пользователь и, когда ему это нужно, возможно, с помощью polkit для его получения. Просто нужно написать некоторые вещи в файле xml, расположенном в /var/lib.

Есть идеи, как я могу это сделать?


person codiaf    schedule 18.06.2013    source источник


Ответы (1)


Причина, по которой он работает, когда вы запускаете его первым способом, заключается в том, что переменная окружения DISPLAY уже установлена ​​до того, как вы запустите программу C, и она будет унаследована подпроцессами.

Если вы запускаете программу C при загрузке, переменная DISPLAY (вероятно) не будет установлена, поэтому вам нужно будет установить ее перед запуском подпроцесса с помощью чего-то вроде...

#include <stdlib.h>

setenv("DISPLAY", something, 1);
// Now launch the Python script

Хитрость заключается в том, что поставить для something. Это должно быть то, что вы получаете, когда выполняете echo $DISPLAY из обычного сеанса X11, предполагая, что программа C работает в той же системе, что и ваш сеанс X11.

Вам придется либо жестко запрограммировать значение, которое работает, либо найти какой-то способ передать правильное значение программе на C.


Обновить

Что касается проблем с разрешениями — одним из простых решений было бы поместить xhost +root в ~/.xsession, предполагая, что вы доверяете root.

В противном случае вы можете заставить скрипт Python работать как ваш UID. Вы можете сделать правильный fork-exec и вызвать setuid(2) в дочернем процессе до вызов exec(), или вы можете вызвать os.setuid() в верхней части вашего Скрипт Python.

person Aya    schedule 18.06.2013
comment
Дисплей может быть жестко запрограммирован на :0, но это не сработает, если я не сделаю xhost + раньше, и я не могу выполнить эту команду из кода C, потому что она работает с правами root? - person codiaf; 18.06.2013
comment
Если вы запускаете команду от имени root, вы также сможете указать ей использовать вашу X-авторизацию. Перед вызовом system() для запуска приложения установите для переменной среды XAUTHORITY значение /pathto/user/homedir/.Xauthority. Этого должно быть достаточно вместо использования команды xhost. - person This isn't my real name; 18.06.2013
comment
Я попробовал смесь того, что вы, ребята, сказали. Я создал пользователя с идентификатором 627 и дал ему разрешение с помощью xhost +SI:localuser:username, then on the python code I set os.setuid(627)` поверх кода, поэтому, когда я пишу print(os.getuid()), я получаю правильный 627. Появляется все то же сообщение. У идеи Эдельсона есть проблема, заключающаяся в том, что я не знаю, какой пользователь увидит графический интерфейс Python. - person codiaf; 19.06.2013
comment
@user712533 ​​user712533 ​​TBH, я не особенно знаком с системой разрешений X11, но даже если вы можете заставить ее работать, кажется немного хакерским иметь процесс демона, работающий от имени пользователя root, порождающий графический интерфейс направленный на какой-то произвольный сеанс X11. Что делать, если нет зарегистрированных пользователей, или что, если вы хотите, чтобы графический интерфейс был виден нескольким пользователям? Более гибкий подход состоял бы в том, чтобы «заинтересованные» пользователи сами запускали программу X11 и выполняли IPC с процессом демона. - person Aya; 19.06.2013