LINUX.ORG.RU

Убить процесс по его гуи-окну (теория)

 , ,


0

3

Сразу скажу: это как-то реализовано в крупных DE, но я не знаю как и знать не хочу - так что просьба туда не смотреть. Вопрос о том, как должно быть правильно (вне зависимости от того как уже где-то сделано). Возможно, тема не для desktop а для dev, не знаю.

Так вот, простая ситуация - гуи-прога зависла и юзер хочет её завершить. Или не зависла даже, но юзер всё равно хочет её завершить именно аварийным способом. При этом считаем что механизм запуска этой проги тоже у нас в руках, а так же мы можем в умеренных рамках патчить X-server и ядро (хотя лучше без ядра). Но требовать что-то от самой проги свыше дефолтного X11 протокола нельзя (т.е. оно должно работать со всем существующим софтом без патчей).

Проблема разделяется на две: 1) сопоставить окно и pid, 2) найти все побочные pid-ы проги (у неё могут быть подпроцессы) которые тоже надо убить.

Что касается первого, то варианта вижу два:

  1. при открывании коннекта к иксам с помощью ядра узнавать кто вызвал connect() на той стороне и запоминать (в линуксе это getsockopt(SO_PEERCRED));

  2. запускать каждое приложение с отдельным $DISPLAY либо Xauthority, запоминать запущеный pid и где-то хранить таблицу соответствия.

У обоих вариантов есть минус: открыть коннект может один процесс а потом так или иначе отдать сокет другому, иногда совсем другому. В случае первого варианта будет ещё чуть сложнее распознать мультипроцесс приложения. Во втором - схема слишком муторная.

Теперь о втором, варианты такие:

  1. запоминать только один pid и с ним и работать

  2. считать единым приложением то у чего одинаковый pgid (и обеспечить и его отделение при лаунче)

  3. считать единым приложением то у чего одинаковый sid (и обеспечить и его отделение при лаунче)

  4. про лаунче засовывать новый процесс в контейнер и определять по контейнеру

Минусы очевидные: первый вариант не учитывает подпроцессы (а надо?), последний - наоборот испортит возможность запустить демон (демона убьют вместе с контейнером), ну а 2-3 плохи тем что их два без чёткой разницы, и есть опасения что их некоторые могут использовать не по назначению.

Чего по-моему делать точно не нужно:

  1. искать список с помощью дерева процессов по pid+ppid (стоит кому-то в середине заверщиться как вся ветка его потомков прячется в ppid=1)

  2. трассировать всех, ловить fork() и запоминать то же дерево но без потерь (слишком накладно и вызовет конфликты с отладчиками).

И ешё вопрос: а надо ли это убивание процесса считать критичным для безопасности действием и старательно затыкать все способы спрятаться от данной системы, или же считать это всего лишь инструментом управления и считать что раз процесс хочет уйти от этого то значит так надо.

Что думаете по поводу всех поднятых вопросов?

★★★★★
Ответ на: комментарий от sergej

Это свойство может содержать что угодно, его создаёт прога (как и все остальные свойства). Или не создаёт и его вообще нет. Хотя у большинства всё-таки есть, даже у xclock который без модных тулкитов. У прокинутых по ssh там будет явно не то что нужно.

Так что в качестве подсказки для поиска сойдёт но не более. getsockopt(SO_PEERCRED) выдаёт более достоверные данные практически всех случаях.

firkax ★★★★★
() автор топика