1

I have a linux application written in c++. The application listens to a socket on a certain port. I implemented this using ACE Acceptor. In addition the application starts postgresql database using the init script /etc/init.d/postgresql start by calling the ACE_OS::system function.

The problem I am having is: When the application exits, the port is still occupied. When I run netstat I see that the postgres is listening to that port. (This only happens if I start postgres from the application on any given port).

Is there a way to close the port? Why does postgres listen to that port?

Shay
  • 633
  • 2
  • 11
  • 27
  • 1
    Isn't it your question actually how to stop postgres? – Michael Krelin - hacker Oct 25 '11 at 21:02
  • @MichaelKrelin-hacker, not necessarily. The app might be a command/response server which, as one of its actions, starts up the system's database. What this suggests (running as root, leaking resources to child processes, etc.) is something else. :) – pilcrow Oct 25 '11 at 21:13
  • But it says "I see postgres is listening to that port" ? – Michael Krelin - hacker Oct 25 '11 at 21:16
  • Yes, because postgres has inherited the socket that the OP's app opened. If the app also opened `/dev/null` and made a `pipe()` before starting postgres, `lsof` would show that the descendant postgres was holding `/dev/null` and a `pipe()`, too. – pilcrow Oct 25 '11 at 21:23
  • Ugh, I hope this is some system-management app, because otherwise starting postgres in your app sounds very wrong. – derobert Oct 25 '11 at 21:36

1 Answers1

3

Is there a way to close the port?

Yes. Close the socket, or set FD_CLOEXEC on the underlying file descriptor.

Or ... wrap your call to the child process (...postgresql start) with something that will close fds higher than stderr:

ACE_OS::system("perl -MPOSIX -e 'POSIX::close($_) for 3 .. sysconf(_SC_OPEN_MAX); exec @ARGV' /etc/init.d/postgresql start");

or similar. Tuck that in a script to make it look nicer.

Why does postgres listen to that port?

Your child processes (and their children) are inheriting your open file descriptors, including the socket your c++ app opens.

pilcrow
  • 56,591
  • 13
  • 94
  • 135
  • Is there a way to start the child process in a way that wont inherit the open file descriptor? – Shay Oct 25 '11 at 21:27
  • @Shay, yes. Either close the descriptor before exec'ing the child (close(the_right_fd) or FD_CLOEXEC) or loop through the fd table as the perl snippet does and hope for the best. – pilcrow Oct 25 '11 at 21:31