То, о чем вы просите, просто невозможно. По замыслу внутреннего управления процессами 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;
}
Запустите некоторые программы в фоновом режиме, которые не требуют присутствия оболочки, выйдите из консоли, запустите ps
, выйдите из программ и посмотрите, что произойдет. Замени консоль
на все, что душе угодно.
Теперь, чтобы добиться желаемого, используйте вызов prctl ()
, как в PoC, а затем execve ()
в dwm
. И надеюсь, что dwm
wait ()
s для неопределенных детей, чтобы они не превратились в зомби.
Заключительное примечание: До сих пор не существует такого понятия, как повторное воспитание детей. Т.е. вы по-прежнему не можете произвольно назначить родителя процессу.
-L[117372][117326] [[117327] bind_address[117328]:]. [117329]port:host:hostport
указывает, что данный порт на локальном (клиентском) хосте должен быть перенаправлен на данный хост и порт на удаленной стороне. Это работает путем выделения сокета для прослушивания порта на локальной стороне, опционально привязанного к указанному [117373]bind_address[117374]. Всякий раз, когда к этому порту осуществляется соединение, оно переадресуется по защищенному каналу, а с удаленной машины осуществляется соединение с портом хоста [117375]host-порта [117376]. Переадресация портов также может быть указана в файле конфигурации. Адреса IPv6 можно указать, заключив адрес в квадратные скобки. Только [117377]суперпользователь [117378] может переадресовывать привилегированные порты. По умолчанию локальный порт привязан в соответствии с настройками [117379]GatewayPorts[117380]. Однако, для привязки соединения к определенному адресу можно использовать явный [117381]bind_address[117382]. [117383]bind_address[117384] из [117385] localhost[117386] указывает, что порт прослушивания может быть привязан только для локального использования, в то время как пустой адрес или * указывает на то, что порт должен быть доступен со всех интерфейсов.
Основная проблема здесь в следующем:
Вы не можете переадресовать [117103]5902[117104] на [117105]5902[117106] - это уже [117107]5902[117108]. Поэтому он работает, когда вы подключаетесь без [117109]ssh[117110] - потому что он уже обслужен. Если вы хотите переадресовать локальный порт на другой, то вы делаете:
Если вы хотите переадресовать локальный порт на удалённую машину, то вы делаете: