Any safe cross-platform way of writing variables into executable file? - c++

Let's say, I want to create a single-file game with one variable - 6 digit highscore. I think that the process of saving the variable would be something like this:
Main program creates datachanger.exe and dataholder.txt
Main program launches datachanger.exe
datachanger.exe is constantly checking wether main program process is still alive
Main program closes
datachanger.exe opens the dead main program, deletes last 6 symbols, inserts new ones instead
datachanger.exe launches an independent console script that kills it (suicidal maneuver) and deletes together with dataholder.txt
When script is over, it's over. We have main program with a new variable hiding inside.
I see no problem with steps #1, #4, #5 and #7. However, steps #2, #3 and #6 are problematic.
I can easily make them run with system(), but we all know the obvious downsides of this choice. CreateProcess() works only on Windows, so does GetExitCodeProcess() for the step #3. I don't know any solution besides system() for step #6, even that works reliably only on Windows.
Do I absolutely have to find out the OS user is using before the variable saving procedure?
What's the function for step #6 that works reliably and doesn't require the call of system() on Windows? Maybe it's possible to reduce the amount of steps required or simplify them?
I want to make my little games extremely user friendly.

Related

Multithreaded app has problems re-opening files - Windows taking too long to close?

I have a multithreaded app that opens a few files (read-only) and does a bunch of calculations based on data in those files. Each thread then generates some output files.
The code runs fine so long as I generate the threads and then delete them then the app exits. If, however, I try to put the thread creation/deletion into a subroutine and call it several times then the threads have problems when they try to re-open the input files. I have an if(inFile==NULL) check within each thread and sometimes that gets triggered but sometimes it just crashes. Regardless, each thread has an fclose() for each file and the threads are properly terminated so the files should always be closed before the threads are recreated.
I can create multiple threads that can open the same input files and that works fine. But if I close those threads and re-create new ones (e.g. by repeatedly calling a subroutine to create the threads) then I get errors when the threads try to re-open the input files.
The crashes are not predictable. Sometimes I can loop through the thread creation/deletion process several times, sometimes it crashes on the second time, sometimes the fourth, etc.
The only thing I can think of is that the OS (Windows 7) takes too long to close the file sometimes, so the next thread is spawned before the file is closed and then there's some kind of error due to the fact that the OS is trying to close the file while the thread is trying to open it. It seems to me that that could trigger the if(inFile==NULL) condition.
But, sometimes when the if(inFile==NULL) condition is not triggered I still get jibberish read in from the input file. So it thinks it has a good file pointer but it clearly does not.
I realize this is probably a tough question to answer but I'm stumped. So maybe someone has an idea.
Thanks in advance,
rgames

How to run multiple shell command at the same time in linux

I am trying to run multiple command in ubuntu using c++ code at the same time.
I used system() call to run multiple command but the problem with system() call is it invoke only one command at a time and rest commands are in waiting.
below I wrote my sample code, may this help you to get what I am trying to do.
major thing is I want to run all these command at a time not one by one. Please help me.
Thanks in advance.
main()
{
string command[3];
command[0]= "ls -l";
command[1]="ls";
command[2]="cat main.cpp";
for(int i=0;i<3;i++){
system(command[i].c_str());
}
}
You should read Advanced Linux Programming (a bit old, but freely available). You probably want (in the traditional way, like most shells do):
perhaps catch SIGCHLD (set the signal handler before fork, see signal(7) & signal-safety(7)...)
call fork(2) to create a new process. Be sure to check all three cases (failure with a negative returned pid_t, child with a 0 pid_t, parent with a positive pid_t). If you want to communicate with that process, use pipe(2) (read about pipe(7)...) before the fork.
in the child process, close some useless file descriptors, then run some exec function (or the underlying execve(2)) to run the needed program (e.g. /bin/ls)
call (in the parent, perhaps after having got a SIGCHLD) wait(2) or waitpid(2) or related functions.
This is very usual. Several chapters of Advanced Linux Programming are explaining it better.
There is no need to use threads in your case.
However, notice that the role of ls and cat could be accomplished with various system calls (listed in syscalls(2)...), notably read(2) & stat(2). You might not even need to run other processes. See also opendir(3) & readdir(3)
Perhaps (notably if you communicate with several processes thru several pipe(7)-s) you might want to have some event loop using poll(2) (or the older select(2)). Some libraries provide an event loop (notably all GUI widget libraries).
You have a few options (as always):
Use threads (C++ standard library implementation is good) to spawn multiple threads which each perform a system call then terminate. join on the thread list to wait for them all to terminate.
Use the *NIX fork command to spawn a new process, then within each child process use exec to execute the desired command (see here for an example of "getting the right string to the right child"). Parent process can use waitpid to determine when all children have finished running, in order to move on with the program.
Append "&" to each of your commands, which'll tell the shell to run each one in the background (specifically, system will start the process in the background then return, without waiting for the result). Not tried this, don't know if it'll work. You can't then wait for the call to terminate though (thanks PSkocik).
Just pointing out - if you run those 3 specific commands at the same time, you're unlikely to be able to read the output as they'll all print text to the terminal at the same time.
If you do require reading the output from within the program (though not mentioned in your question), this is relevant (although it doesn't use system).

c++ makefile project in eclipse - select() returns strangely fast in stdin

My Eclipse project is a C++ with makefile project. After at the end of the makefile, there is a call to the executable as if from terminal. (./myEXE)
This program is expected to accept commands from the terminal upon runtime (it is a physics simulation using MPI, with possibility to input "stop" or "stats" or "stop" commands while the simulation runs).
The input is written (not my original code) with a select() (from library sys/types, this for example) to see if there is anything readable from the stdin. The timeout option for select() makes sure MPI has time to start. After trying to read input for a while, it will check that the MPI workloads progress, and if they don't, it will raise timeout error.
Everything works like a charm when I call the makefile from terminal. It is broken when trying to run from Eclipse (shift+F9 and so on...)
It seems the problem is that stdin is always readable, thus checks on MPI before it has the possibility to initiate simulations - select() returns after <1ms.
My two main questions are therefore:
Where is Eclipse reading stdin from?
Why is it always readable?
P.S. Since the program is called via MPI in the makefile instead of directly from Eclipse, its a bit tricky to debug it all....
When select says stdin is readable, you must make sure to change its state before you call select again, otherwise it will just return immediately. Your code doesn't change its state but instead just calls select again, causing it to loop forever.
How you should fix it depends on whether stdin being closed is a fatal condition for your program. If your program must have a working stdin to continue, then if it gets an EOF while reading stdin, it should terminate, not just keep selecting blindly. If your program can continue to run usefully even without a working stdin, then it should take it out of its select set if it closes or errors. (Or stop calling select, depending on the logic.)
But you can't just ignore the case and keep running as if nothing happened.

How to stop a detached process in qt?

After starting a process with QProcess::startDetached, how can I stop it later?
Say the main program runs, then starts the detached process, which runs independently. The user closes the main program, then later opens it up again and wants to stop the process. How would I find the process and then stop it?
Is there a way I could prevent the application from the same process twice?
No, it will be decoupled from your application. You could get the the PID of it and then send a SIGSTOP on Linux, but this is platform specific and will not work without POSIX support, like with msvc. You would need to hand-craft your version therein.
Is there a way I could prevent the application from the same process twice?
Yes, by using lock file in the detached process. If that detached process happens to be written in at least partially Qt, you could use the QLockFile class.
If you happen to detach some platform specific process, then you have the same recurring issue again, for sure.
Here's the answer I figured out:
I first start the detached process that generates a unique id. That process write to a file whenever it runs (was a 1 minute timer). When it runs, it writes its id to a file. Then, if there happens to be another one that ran, if it sees a previous one ran, it just writes its id to the file and doesn't run, then, when the next one runs, it sees if its id is already in the file and if it is, it shuts itself off and clears the file, then the next run ends up running freely, being the only one running. This may end up skipping some time.
You can add a timestamp, too, as that might indicate it wasn't run recently and help with deciding whether or not to shut it down. The issue was if I just write the id to a file, when I turn the phone off, the file will say it's still running. The same applies to if it crashes.

C++ executing a bash script which terminates and restarts the current process

So here is the situation, we have a C++ datafeed client program which we run ~30 instances of with different parameters, and there are 3 scripts written to run/stop them: start.sh stop.sh and restart.sh (which runs stop.sh and then start.sh).
When there is a high volume of data the client "falls behind" real time. We test this by comparing the system time to the most recent data entry times listed. If any of the clients falls behind more than 10 minutes or so, I want to call the restart script to start all the binaries fresh so our data is as close to real time as possible.
Normally I call a script using System(script.sh), however the restart script looks up and kills the process using kill, BUT calling System() also makes the current program execution ignore SIGQUIT and SIGINT until system() returns.
On top of this if there are two concurrent executions with the same arguments they will conflict and the program will hang (this stems from establishing database connections), so I can not start the new instance until the old one is killed and I can not kill the current one if it ignores SIGQUIT.
Is there any way around this? The current state of the binary and missing some data does not matter at all if it has reached the threshold, I also can not just have the program restart itself, since if one of the instances falls behind, we want to restart all 30 of the instances (so gaps in the data are at uniform times). Is there a clean way to call a script from within C++ which hands over control and allows the script to restart the program from scratch?
FYI we are running on CentOS 6.3
Use exec() instead of system(). It will replace your process with the new one. Note there is a significant different in how exec() is called and how it behaves: system() passes its string argument to the system shell to run. exec() actually executes an executable file, and you need to supply the arguments to the process one at a time, instead of letting the shell parse them apart for you.
Here's my two cents.
Temporary solution: Use SIGKILL.
Long-term solution: Optimize your code or the general logic of your service tree, using other system calls like exec or by rewritting it to use threads.
If you want better answers maybe you should post some code and or degeneralize the issue.