LINUX.ORG.RU

Parent / child relationship

 


0

1

Обычная тривиальная задачка — хочу, чтобы родитель общался с потомком через UNIX сокет. Потомок, разумеется, делает execvp, чтобы не тащить за собой весь мусор из памяти родителя. И вот смотрю я на этот кошмар из

parent:
  socketpair

child:
  close(parent)
  dup2
  execv

parent:
  close(child)
  .. do stuff ..

и думаю — а никто ничего проще не придумал что-ли? Я могу выставить наружу сокет для чайлдов, конечно, но это уже какая-то наркомания по-моему.

P.S. C, конечно же.

★☆

Последнее исправление: kirk_johnson (всего исправлений: 1)

parent:

pipe
close(pipe_fd[1])
fork

child:

close(pipe_fd[0])
set_env('PIPE_FD', pipe_fd[1]);
execv

Можно вместо setenv просто через параметр передать

zaz ★★★★
()
Ответ на: комментарий от kirk_johnson

Почему таже ? 2 вызова у парента перед форком (pipe + close) и 1 вызов (close) у чайлда перед execv и все

zaz ★★★★
()
Ответ на: комментарий от zaz

Почему таже ? 2 вызова у парента перед форком (pipe + close) и 1 вызов (close) у чайлда перед execv и все

Потому что мы опять делаем кучу файловых дескрипторов и неочевидными методами их распихиваем :)

kirk_johnson ★☆
() автор топика

А что, для тебя это сложно? Ну оберни в my_popen и используй его. Нормальным людям тут как-бы нужна гибкость, кому-то нужны пайпы, кому-то все дескриптры ребёнка закрыть, кому-то открыть в логфайлы и т.д.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

А что, для тебя это сложно? Ну оберни в my_popen и используй его. Нормальным людям тут как-бы нужна гибкость, кому-то нужны пайпы, кому-то все дескриптры ребёнка закрыть, кому-то открыть в логфайлы и т.д.

Нет, для меня это не сложно. Но выглядит довольно ущербно. Особенно чудно это выглядит в свете того, что O_CLOEXEC до сих пор не является дефолтной опцией %) И для верности многие до сих пор используют чудную функцию closefrom().

kirk_johnson ★☆
() автор топика

Потомок, разумеется, делает execvp, чтобы не тащить за собой весь мусор из памяти родителя.

Не надо копить мусор.

а никто ничего проще не придумал что-ли?

Куда уж проще.

А вообще, кажется, что ты поныть пришел.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Не надо копить мусор.

Я не хочу eventloop с таймерами в потомке. Нет, серьезно. Файловые дескрипторы с flock'ами тоже не лучшие кандидаты.

kirk_johnson ★☆
() автор топика
Последнее исправление: kirk_johnson (всего исправлений: 1)
Ответ на: комментарий от kirk_johnson

Но выглядит довольно ущербно

Только для тех кто не хочет думать и разбираться в API, а хочет кнопку «за*бись».

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от slovazap

Только для тех кто не хочет думать и разбираться в API, а хочет кнопку «за*бись».

Да нет, я с этим API разобрался ещё лет 15 назад. Лучше оно от этого не стало.

kirk_johnson ★☆
() автор топика
Ответ на: комментарий от tailgunner

Интересно. А придумай идеальный API для этой задачи?

Я бы сделал API, который просто позволяет запустить новую копию процесса, которая сразу регистрирует тебе pipe/socket/whatever нужного типа и отдает их оба в клиенты. Без вот этого вот cleanup -> fork -> execvp -> find-the-goddamn-descriptor. Серьезно, одна из самых популярных задач, а все до сих пор одно и то же каждый раз пишут.

kirk_johnson ★☆
() автор топика

Обычная тривиальная задачка — хочу, чтобы родитель общался с потомком через UNIX сокет

Ничего обычного в ней нет, нормальные люди используют в такой ситуации пайпы

annulen ★★★★★
()
Ответ на: комментарий от annulen

Ничего обычного в ней нет, нормальные люди используют в такой ситуации пайпы

Чо, правда? А если мне все-таки нужно двустороннее общение с разбивкой на сообщения?

kirk_johnson ★☆
() автор топика

dup2
close(child)

Most probably, я чего-то не понимаю, но зачем это? Нельзя просто передать в exec'нутый процесс номер child?

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Most probably, я чего-то не понимаю, но зачем это? Нельзя просто передать в exec'нутый процесс номер child?

dup2 здесь чтобы можно было сделать closefrom(). Потому что никто не гарантирует, что все библиотеки используют O_ClOEXEC.

kirk_johnson ★☆
() автор топика
Ответ на: комментарий от kirk_johnson

Я просил протип функции, а не рассуждения, как хорошо она должна делать.

int run_child(const char *path, const char *argv[]) 
? Ну так напиши. Ты уже написал в топике больше текста.

А если мне все-таки нужно двустороннее общение с разбивкой на сообщения?

...то тебе нужно что-то необычное.

tailgunner ★★★★★
()
Ответ на: комментарий от kirk_johnson

Вопрос был «что», а не «как». Впрочем, забей.

tailgunner ★★★★★
()
Ответ на: комментарий от kirk_johnson

Чо, правда? А если мне все-таки нужно двустороннее общение с разбивкой на сообщения?

Для двусторонней передачи данных между процессами я использую очереди сообщений (message queue). В «Линуксе» наибольший размер одного сообщения равен 8 КБ, наибольшее количество сообщений в очереди равно 10. Для обмена сообщениями процессам нужно лишь знать имя очереди в виде строки. Все работает без видимых задержек.

Enthusiast ★★★
()
Ответ на: комментарий от Enthusiast

Для двусторонней передачи данных между процессами я использую очереди сообщений (message queue). В «Линуксе» наибольший размер одного сообщения равен 8 КБ, наибольшее количество сообщений в очереди равно 10. Для обмена сообщениями процессам нужно лишь знать имя очереди в виде строки. Все работает без видимых задержек.

Я портанул imsg из openbsd. Довольно годная штука.

kirk_johnson ★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.