spawning the same program

We have a program (reader) that reads audio files in a real-time continuous stream from a sender program. If the reader gets weird we want the sender to be able to send one command that will stop the current reader and start a new one that will be able to continue reading in the files. The sender cannot access anything other than the reader (ie, it cannot run any commands on the server, etc). The reader runs on UNIX and is written in C++.

I've tried using system() to call a batch file that sleeps for a few second and then starts a new reader. It starts a new reader but the old one stays up. I've also tried exec(), which does replace the old reader with the new one but the new reader doesn't read the audio files; it just seems to sit out there doing nothing.

Is there a way to have a program basically kill itself and start a fresh version of itself that works?

Thank you.

Rather than system, use exec to invoke the startup script.

I had tried exec() and it did replace the current reader with a new reader but the new reader didn't work. It was running, but it didn't read the audio files and didn't respond to a remote shutdown like the first one can.

This is the command that I used:
execl("./Reader", (char *) NULL);

Am I missing something?

Thanks.

What did you use in the system call that worked? Another thought is to go back to system() and exit() afterwards.

I did try system() followed by exit() but the problem with using system() is that it will remain up until the program called in system() exits. So it follows this scenario using "ps -ef | grep Reader":
1) First startup - the first Reader is up
./Reader
2) Run system() followed by exit() - both Readers are up and the exit() isn't reached because it is waiting for the system() to complete
./Reader
./Reader
3) Second ./Reader exits and both are now gone since the first Reader continued and reached its own exit.

system() starts a child process. I really just want to kick off a new, separate process and exit the first process.

system() run a command line to a shell. You can put an & at the end of any command line to background it. That works even with system.

You don't seem to be passing any args to script when you invoke it, so I'm not sure why exec isn't working. You did leave off argument 0 which is the name. I thought that was a trivial problem, but maybe it's important. So try it right.
execl("./reader", "reader", NULL);
All of this assumes that you have an executable shell script. Do you? What os are you using? What is the first line of the script?

The operating system is:
SunOS grcs 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-5_10

This is the script that starts the program:
#!/usr/bin/ksh
export LD_LIBRARY_PATH=/usr/local/lib
export DLI_LOG_MSGS=DEBUG
export DLI_LOG_FILE_NAME=DLIMain.log
./Reader

I've tried calling the script:
rt = execl("./setenv1", "setenv1", (char *) NULL);
if (rt != 0)
printf("exec failure: %d\n", errno);

and I've tried calling the program directly:
rt = execl("./Reader", "Reader", (char *) NULL);
if (rt != 0)
printf("exec failure: %d\n", errno);

Neither works. The Reader is using a UDP socket to read the audio files from the sender. I don't know if that if affecting anything.

I don't know how to use & when calling exec() in C++ code.

Thanks for your help.

The & is for system, not exec.

system("/path/to/startup_script &");
exit();

Now you you will return from system while the start up script continues to run.

With exec, all that script is doing is setting the environment. Your environment should still be good. Maybe your current directory has changed. Try a full path. Also, you're right. Close the socket and any other files you opened.

A whole other approach would be have the program restart itself internally.

I have a feeling that it is the socket that is getting messed up. I'll have to look into how to close it properly and see if that makes a difference.

Thanks.

Just do close() on the socket fd.