Какой процесс принимает Ctrl + C при передаче дескриптора файла STDIN?

Во-первых, извините, что я не смог привести сокращенный пример. На данный момент это было выше моих сил. Особенно мои коды, которые передают файловые дескрипторы, работали не совсем корректно. Я думаю, что у меня есть только хорошее понимание того, как код работает на высоком уровне.

По сути, вопрос заключается в том, если в следующем сложном примере конечный пользователь вводит Ctrl + C, какой процесс получает SIGINT и как это происходит.

Приложение работает в интерфейсе командной строки (CLI, в дальнейшем). Пользователь запускает клиент, который фактически отправляет команду на сервер, распечатывает некоторые ответы и завершает работу. Сервер по запросу находит подходящий рабочий исполняемый файл и fork-and-exec исполняемый файл и ожидает его. Затем сервер формирует ответ и отправляет его обратно клиенту.

Однако есть некоторые сложности. Клиент запускает сервер, если серверный процесс еще не запущен — на каждого пользователя приходится один серверный процесс. Когда сервер отмечен fork-and-exec, в строке сразу после fork() будет следующее:

if (pid == 0) {
  daemon(0, 0);
  // do more set up and exec
}

Другая сложность, которая может быть более важной, заключается в том, что когда клиент отправляет запрос через сокет unix (который выглядит как @server_name), клиент отправляет три файловых дескриптора для стандартного ввода-вывода, используя такие методы, как этот .

Когда сервер получает исполняемый файл рабочего процесса, сервер перенаправляет стандартный ввод-вывод рабочего процесса на три файловых дескриптора, полученных от клиента:

// just after fork(), in the child process' code
auto new_fd = fcntl(received_fd, F_DUPFD_CLOEXEC, 3);
dup2(new_fd, channel); // channel seems to be 0, 1, or 2

Этот фрагмент кода выполняется для всех трех файловых дескрипторов соответственно. (Исполняемый рабочий файл снова создает кучу процессов, но не передает fork-and-exec своим потомкам.)

Вопрос в том, что произойдет, если конечный пользователь введет STDIN в терминал. Я подумал, что оболочка Ctrl + C берет его, генерирует и отправляет Bash процессам, которые имеют определенный идентификатор сеанса, возможно, такой же, как прямой дочерний процесс оболочки bash или сам: клиент, в примере.

Однако похоже, что рабочий исполняемый файл получает сигнал, и я не могу подтвердить, получает ли клиент сигнал. Я не думаю, что серверный процесс получает сигнал, но не могу это подтвердить. Как такое могло произойти?

Если SIGINT сначала берет Bash и доставляет его каким-либо процессам, я подумал, что сервер был отсоединен от Ctrl+C (то есть Bash) и не имеет ничего общего с процессом bash. Я думал, что сервер и, следовательно, рабочие процессы имеют разные идентификаторы сеанса, и это выглядело так, когда я запускал команду daemon(0, 0).

Понятно, что пользовательский ввод с клавиатуры (ps -o или yes и т. д.) может быть доставлен в рабочий процесс. Я не уверен, как no можно доставить в рабочий процесс, просто эффективно разделив стандартный ввод. Я хотел бы понять, как это работает.

%P.S.Спасибо за ответы и комментарии! Ответ был действительно полезным. Звучало так, будто клиент должен получить сигнал, а рабочий процесс должен быть остановлен другим механизмом. Исходя из этого, я мог глубже изучить код. Оказалось, что клиент действительно ловит сигнал и умирает. Это разрывает соединение сокета. Сервер определяет, когда fd сломан, и сигнализирует соответствующему рабочему процессу. Поэтому рабочий процесс выглядел как получение сигнала от терминала.

Какой бы процесс ни выполнял чтение, он получит прерывание ctrl-C

stark 19.02.2023 20:41

@stark Я не думаю, что это правильно.

Joseph Sible-Reinstate Monica 20.02.2023 02:11
Конечные и Readonly классы в PHP
Конечные и Readonly классы в PHP
В прошлом, когда вы не хотели, чтобы другие классы расширяли определенный класс, вы могли пометить его как final.
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
БЭМ: Конвенция об именовании CSS
БЭМ: Конвенция об именовании CSS
Я часто вижу беспорядочный код CSS, особенно если проект большой. Кроме того, я совершал эту ошибку в профессиональных или личных проектах и...
Революционная веб-разработка ServiceNow
Революционная веб-разработка ServiceNow
В быстро развивающемся мире веб-разработки ServiceNow для достижения успеха крайне важно оставаться на вершине последних тенденций и технологий. По...
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Заголовок веб-страницы играет наиболее важную роль в SEO, он помогает поисковой системе понять, о чем ваш сайт.
Конфигурация Jest в angular
Конфигурация Jest в angular
В этой статье я рассказываю обо всех необходимых шагах, которые нужно выполнить при настройке jest в angular.
0
2
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сигнал отправляет не Bash, а драйвер tty. Он отправляет его в группу процессов переднего плана, то есть все процессы в группе переднего плана получают его.

Другие вопросы по теме