この質問は以下に密接に関連しています。シェルでアプリケーションを「正しく」起動する方法しかし、もっと具体的な問題を解決しようとしています。他のプロセスの子プロセスになるようにシェルからアプリケーションを作成する方法。これは、2つのグラフィック例で意味するものです。
systemd-+-acpid
|-bash---chromium-+-chrome-sandbox---chromium-+-chrome-sandbox---nacl_helper
| | `-chromium---5*[chromium-+-{Chrome_ChildIOT}]
| | |-{Compositor}]
| | |-{HTMLParserThrea}]
| | |-{OptimizingCompi}]
| | `-3*[{v8:SweeperThrea}]]
| |-chromium
| |-chromium-+-chromium
| | |-{Chrome_ChildIOT}
| | `-{Watchdog}
| |-{AudioThread}
| |-3*[{BrowserBlocking}]
| |-{BrowserWatchdog}
| |-5*[{CachePoolWorker}]
| |-{Chrome_CacheThr}
| |-{Chrome_DBThread}
| |-{Chrome_FileThre}
| |-{Chrome_FileUser}
| |-{Chrome_HistoryT}
| |-{Chrome_IOThread}
| |-{Chrome_ProcessL}
| |-{Chrome_SafeBrow}
| |-{CrShutdownDetec}
| |-{IndexedDB}
| |-{LevelDBEnv}
| |-{NSS SSL ThreadW}
| |-{NetworkChangeNo}
| |-2*[{Proxy resolver}]
| |-{WorkerPool/1201}
| |-{WorkerPool/2059}
| |-{WorkerPool/2579}
| |-{WorkerPool/2590}
| |-{WorkerPool/2592}
| |-{WorkerPool/2608}
| |-{WorkerPool/2973}
| |-{WorkerPool/2974}
| |-{chromium}
| |-{extension_crash}
| |-{gpu-process_cra}
| |-{handle-watcher-}
| |-{inotify_reader}
| |-{ppapi_crash_upl}
| `-{renderer_crash_}
|-2*[dbus-daemon]
|-dbus-launch
|-dhcpcd
|-firefox-+-4*[{Analysis Helper}]
| |-{Cache I/O}
| |-{Cache2 I/O}
| |-{Cert Verify}
| |-3*[{DOM Worker}]
| |-{Gecko_IOThread}
| |-{HTML5 Parser}
| |-{Hang Monitor}
| |-{Image Scaler}
| |-{JS GC Helper}
| |-{JS Watchdog}
| |-{Proxy R~olution}
| |-{Socket Thread}
| |-{Timer}
| |-{URL Classifier}
| |-{gmain}
| |-{localStorage DB}
| |-{mozStorage #1}
| |-{mozStorage #2}
| |-{mozStorage #3}
| |-{mozStorage #4}
| `-{mozStorage #5}
|-gpg-agent
|-login---bash---startx---xinit-+-Xorg.bin-+-xf86-video-inte
| | `-{Xorg.bin}
| `-dwm-+-dwmstatus
| `-xterm---bash-+-bash
| `-pstree
|-systemd---(sd-pam)
|-systemd-journal
|-systemd-logind
|-systemd-udevd
|-wpa_actiond
`-wpa_supplicant
プロセスツリーでは、chromiumとfirefoxが起動時にinit
開始されますPID 1
。プロセス:dwm
weston
weston-desktop
systemd-+-acpid
|-bash---chromium-+-chrome-sandbox---chromium-+-chrome-sandbox---nacl_helper
| | `-chromium-+-3*[chromium-+-{Chrome_ChildIOT}]
| | | |-{Compositor}]
| | | |-{HTMLParserThrea}]
| | | |-{OptimizingCompi}]
| | | `-3*[{v8:SweeperThrea}]]
| | `-4*[chromium-+-{Chrome_ChildIOT}]
| | |-{CompositorRaste}]
| | |-{Compositor}]
| | |-{HTMLParserThrea}]
| | |-{OptimizingCompi}]
| | `-3*[{v8:SweeperThrea}]]
| |-{AudioThread}
| |-3*[{BrowserBlocking}]
| |-{BrowserWatchdog}
| |-5*[{CachePoolWorker}]
| |-{Chrome_CacheThr}
| |-{Chrome_DBThread}
| |-{Chrome_FileThre}
| |-{Chrome_FileUser}
| |-{Chrome_HistoryT}
| |-{Chrome_IOThread}
| |-{Chrome_ProcessL}
| |-{Chrome_SafeBrow}
| |-{Chrome_SyncThre}
| |-{CrShutdownDetec}
| |-{IndexedDB}
| |-{NSS SSL ThreadW}
| |-{NetworkChangeNo}
| |-2*[{Proxy resolver}]
| |-{WorkerPool/2315}
| |-{WorkerPool/2316}
| |-{WorkerPool/2481}
| |-{chromium}
| |-{extension_crash}
| |-{gpu-process_cra}
| |-{handle-watcher-}
| |-{inotify_reader}
| |-{renderer_crash_}
| `-{sandbox_ipc_thr}
|-2*[dbus-daemon]
|-dbus-launch
|-dhcpcd
|-gpg-agent
|-login---bash---startx---xinit-+-Xorg.bin-+-xf86-video-inte
| | `-{Xorg.bin}
| `-dwm-+-dwmstatus
| `-xterm---bash
|-login---bash---weston-launch---weston-+-Xwayland---4*[{Xwayland}]
| |-weston-desktop--+-firefox-+-firefox
| | | |-4*[{Analysis Helper}]
| | | |-{Cache2 I/O}
| | | |-{Cert Verify}
| | | |-{DNS Resolver #1}
| | | |-{DNS Resolver #2}
| | | |-2*[{DOM Worker}]
| | | |-{Gecko_IOThread}
| | | |-{HTML5 Parser}
| | | |-{Hang Monitor}
| | | |-{Image Scaler}
| | | |-{ImageDecoder #1}
| | | |-{ImageDecoder #2}
| | | |-{ImageDecoder #3}
| | | |-{JS GC Helper}
| | | |-{JS Watchdog}
| | | |-{Socket Thread}
| | | |-{Timer}
| | | |-{URL Classifier}
| | | |-{gmain}
| | | |-{localStorage DB}
| | | |-{mozStorage #1}
| | | |-{mozStorage #2}
| | | |-{mozStorage #3}
| | | |-{mozStorage #4}
| | | `-{mozStorage #5}
| | `-weston-terminal---bash---pstree
| `-weston-keyboard
|-systemd---(sd-pam)
|-systemd-journal
|-systemd-logind
|-systemd-udevd
|-tmux---bash
|-wpa_actiond
`-wpa_supplicant
考えられる解決策の1つはnsenter
fromを使用することですutil-linux
。プロセスの名前空間dwm
に入りますdwm
。これを行うより簡単な方法はありますか?
答え1
プロセスをシェルの子として開始し、他のプロセスがその親プロセスになるように「親を上書き」することはできません。
したがって、子プロセスを明示的に開始する親プロセスを使用する必要があります。
init
PID 1 は例外です。プロセスは元の親を失ったプロセスを収集するため、そのプロセスの子になる可能性があります。
init
(アップスタートでは、PID 1を共有しませんが、非常に似た役割を持つ複数のプロセスがある可能性があります。)
(また、PR_SET_CHILD_SUBREAPER in man 2 prctl
)
答え2
あなたが要求することは単に不可能です。 UnixとLinuxの設計により、内部プロセス管理は、親プロセスがinit
終了するすべてのプロセスの親プロセスになります。これは、プロセスに親がなければならず(設計上)、initが死ぬとinit
システムがシャットダウンされるため常に存在するためです。しかし、それ以上には「子育て」のプロセスのようなものはありません。
編集する
しかし:lord.garbageが指摘したように、prctl()
本当にクールで、それを使用するすべてのプログラムを移植不可能にする不思議なシステムコールがあります。私たちは気にしないと仮定します。このPR_SET_CHILD_SUBREAPER
オプションは、wait()
お子様(以前と同様)だけでなく、すべての子孫(親が早期に死亡した場合)にも使用してください。したがって、この機能を使用するプロセスは、その子孫の役割をinit
引き受けることができます。次のコードは概念証明です。
#include <sys/prctl.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int
main (int argc, const char* const argv[], char* const envp[])
{
pid_t pid;
if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) < 0) {
perror("prctl");
return 4;
}
pid = fork();
if (pid < 0) {
perror("fork");
return 4;
}
if (pid == 0) {
// child
char* const argv[] = { "/usr/bin/konsole", "-e", "/bin/bash", NULL };
if (execve("/usr/bin/konsole", argv, envp) < 0) {
perror("execve");
}
}
// parent
while (1) {
pid_t wpid;
int s;
wpid = waitpid(-1, &s, 0);
if (wpid > 0) {
printf("child with pid %u has exited\n", wpid);
}
}
return 0;
}
シェル参加を必要としない一部のプログラムをバックグラウンドで実行します。 konsoleを終了してps
プログラムを終了した後に何が起こるかを確認してください。konsole
必要なものと交換してください。
必要なものを達成するには、prctl()
PoCの呼び出しを使用してからexecve()
toを使用しますdwm
。これがdwm
wait()
非特異的な子供に効果があるので、彼らは最終的にゾンビにならないことを願っています。
最終注意事項:まだ「子育て」のようなものはありません。つまり、プロセスに親をランダムに割り当てることはできません。
答え3
プロセスを親プロセスとしてdwmプロセスに送信できるとは思いません。ただし、dwmの子プロセスでスクリーンまたはシェルを起動できる場合は、必要なプロセスをそのプロセスにリセットできます。詳細については、次のリンクを参照してください。http://monkeypatch.me/blog/move-a-running-process-to-a-new-screen-shell.html