Question

So I have this old, nasty piece of C code that I inherited on this project from a software engineer that has moved on to greener pastures. The good news is... IT RUNS! Even better news is that it appears to be bug free.

The problem is that it was designed to run on a server with a set of start up parameters input on the command line. Now, there is a NEW requirement that this server is reconfigurable (didn't see that one coming...). Basically, if the server receives a command over UDP, it either starts this program, stops it, or restarts it with new start up parameters passed in via the UDP port.

Basically the code that I'm considering using to run the obfuscated program is something like this (sorry I don't have the actual source in front of me, it's 12:48AM and I can't sleep, so I hope the pseudo-code below will suffice):

//my "bad_process_manager"

int manage_process_of_doom() {
  while(true) {
    if (socket_has_received_data) {
      int return_val = ParsePacket(packet_buffer);
      // if statement ordering is just for demonstration, the real one isn't as ugly...
      if (packet indicates shutdown) {
        system("killall bad_process");  // process name is totally unique so I'm good?
      } else if (packet indicates restart) {
        system("killall bad_process");  // stop old configuration
        // start with new parameters that were from UDP packet...
        system("./my_bad_process -a new_param1 -b new_param2 &");
      } else {  // just start
        system("./my_bad_process -a new_param1 -b new_param2 &");
    }
  }
}

So as a result of the system() calls that I have to make, I'm wondering if there's a neater way of doing so without all the system() calls. I want to make sure that I've exhausted all possible options without having to crack open the C file. I'm afraid that actually manipulating all these values on the fly would result in having to rewrite the whole file I've inherited since it was never designed to be configurable while the program is running.

Also, in terms of starting the process, am I correct to assume that throwing the "&" in the system() call will return immediately, just like I would get control of the terminal back if I ran that line from the command line? Finally, is there a way to ensure that stderr (and maybe even stdout) gets printed to the same terminal screen that the "manager" is running on?

Thanks in advance for your help.

Was it helpful?

Solution

What you need from the server:

Ideally your server process that you're controlling should be creating some sort of PID file. Also ideally, this server process should hold an exclusive lock on the PID file as long as it is still running. This allows us to know if the PID file is still valid or the server has died.

Receive shutdown message:

Try to get a lock on the PID file, if it succeeds, you have nothing to kill (the server has died, if you proceed to the kill regardless, you may kill the wrong process), just remove the old PID file.

If the lock fails, read the PID file and do a kill() on the PID, remove the old PID file.

Receive start message:

You'll need to fork() a new process, then choose your flavor of exec() to start the new server process. The server itself should of course recreate its PID file and take a lock on it.

Receive restart message:

Same as Shutdown followed by Start.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top