#c #sockets #postgresql #port #ace
#c #сокеты #postgresql #портвейн #туз
Вопрос:
У меня есть приложение для Linux, написанное на c . Приложение прослушивает сокет на определенном порту. Я реализовал это с помощью акцептора ACE. Кроме того, приложение запускает базу данных postgresql с помощью скрипта инициализации /etc/init.d/postgresql для начала вызовите функцию ACE_OS::system .
Проблема, с которой я сталкиваюсь, заключается в следующем: когда приложение завершает работу, порт все еще занят. Когда я запускаю netstat, я вижу, что postgres прослушивает этот порт. (Это происходит только в том случае, если я запускаю postgres из приложения на любом заданном порту).
Есть ли способ закрыть порт? Почему postgres прослушивает этот порт?
Комментарии:
1. Разве это не ваш вопрос на самом деле, как остановить postgres?
2. @MichaelKrelin-хакер, не обязательно. Приложение может быть сервером команд / ответов, который в качестве одного из своих действий запускает базу данных системы. То, что это предполагает (запуск от имени root, утечка ресурсов дочерним процессам и т.д.), — это нечто другое. 🙂
3. Но в нем говорится: «Я вижу, что postgres прослушивает этот порт»?
4. Да, потому что postgres унаследовал сокет, открытый приложением OP. Если бы приложение также открылось
/dev/null
и создало apipe()
перед запуском postgres,lsof
это показало бы, что потомок postgres тоже содержал/dev/null
и apipe()
.5. Тьфу, я надеюсь, что это какое-то приложение для управления системой, потому что в противном случае запуск postgres в вашем приложении звучит очень неправильно.
Ответ №1:
Есть ли способ закрыть порт?
ДА. Закройте сокет или установите FD_CLOEXEC для базового файлового дескриптора.
Или… завершите свой вызов дочернего процесса ( ...postgresql start
) чем-то, что закроет fds выше, чем stderr:
ACE_OS::system("perl -MPOSIX -e 'POSIX::close($_) for 3 .. sysconf(_SC_OPEN_MAX); exec @ARGV' /etc/init.d/postgresql start");
или аналогичный. Добавьте это в скрипт, чтобы он выглядел лучше.
Почему postgres прослушивает этот порт?
Ваши дочерние процессы (и их дочерние процессы) наследуют ваши открытые файловые дескрипторы, включая сокет, который открывает ваше приложение на c .
Комментарии:
1. Есть ли способ запустить дочерний процесс таким образом, чтобы он не наследовал дескриптор открытого файла?
2. @Shay, да. Либо закройте дескриптор перед выполнением дочернего элемента (close(the_right_fd) или FD_CLOEXEC), либо выполните цикл по таблице fd, как это делает фрагмент perl, и надейтесь на лучшее.