как прекратить прослушивание порта

#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 и создало a pipe() перед запуском postgres, lsof это показало бы, что потомок postgres тоже содержал /dev/null и a pipe() .

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, и надейтесь на лучшее.