[C] Command line and file deletion
Hello, I'm actually porting my Windows software on Linux.
I coded it with the SDL so the main part of the code directly works with UNIX based system. I experiment two issues and I would like to know if you may solve them... 1. I need to re-launch my software via command line... For windows, I use ShellExecute, for Mac OSX, open with the -n flag but for linux, I have still not find a way =/ 2. For check if the new instance already run, I try to delete a file which is opened by the new instance (which will not run the same code and I don't want that a new instance start to run this code) with windows, if the file was used, remove() don't work but it seems that Linux can't do that. Also, I can't write something in it in case of crash/other thing which won't allow the new instance to say that it doesn't run anymore (and allow a other instance to do that). Sorry for my bad english Taiki |
SDL? Which language are you programming in?
|
|
Quote:
Quote:
Anyway, to delete a file, use the unlink() function (for deleting a directory, you should use the rmdir() function instead). |
I also use system() (that's why i'm looking for a command line ;)) I'm just wondering which command to use...
In fact, I want to test if the file is open somewhere. windows doesn't allow to delete a file if it's in use so I try to delete it and I test if it's still here. I would like to know if there is a way for test that (maybe with an other way) with linux/darwin... |
Quote:
Code:
#include <unistd.h> Code:
For check if the new instance already run, I try to delete a file which is opened by the new instance Most programs and games create a configuration directory .name/ under the user's home directory, and put the configuration file(s), plugins, high scores and such stuff there. You need very little code for this: Code:
#ifndef GAMEDIR Code:
#include <unistd.h> Code:
/* Flush the specified file to disk, then rename from saving to actual. Code:
FILE *output; If you had multiple simultaneous copies running, then you would have to use an unique suffix, preferably .shorthostname.pid (which is unique in a local network at any point in time; use gethostname() and getpid() to obtain the string and the PID number). The file replacement will be atomic, but in tight races some processes might see the previous one instead of the very latest one. All will see a complete file, though, never a mix. |
For the first part, you misunderstood me: I don't want to restart the soft but launch a new instance. Maybe use fork() + execlp() but it seems heavy and I don't know if they are REALLY independant.
For the second part, the file don't contain anything he's just there when the soft run a special part of the code. But the probleme is that I can't leave it and only check if it exists (in case of crash, the file won't be delete). But the idea of "block" the file seems very interesting, I'll will use it and told you if it works :) |
Quote:
Code:
pid_t child, pid; As you might guess, zombies are just children that haven't been reaped yet. It is mostly just a cosmetic issue, since the kernel will release all resources used by the process except for the PID and the exit status code. Note that the child process will inherit all variables (and open file handles) from the parent process, but otherwise it will be a different process. The two will not see any changes they make to variables after the fork. The situation may be easier to understand if you think of the child as having been magically started at the same time as the parent, has received all the same inputs and seen all the same files and times and everything as the parent process .. but that they diverge for the first time at the fork() call. Afterwards, they really are separate "programs". You can obviously fork multiple times, but make sure you fork only from the parent process. Otherwise, you get an exponential number of child processes (since each child process will fork further children); this is called a fork bomb. When testing code that does forks, run ulimit -n numberofprocesses to limit the number of processes that session (shell or terminal) can create in parallel. A smallish number like 20 is usually enough for testing; I like to do my testing using another terminal or shell. (That way, even if you happen to trigger a fork bomb, it will be limited to 20 processes, and you can kill it from another shell, for example using killall -KILL myprogname.) Any parent process can check on its children without waiting for the results, effectively just checking if anything notable has happened. Here is a full example: Code:
pid_t pid; Oh, and if you leave child processes around when the program exits, that too is okay: init (process 1, the grandparent of all processes) will adopt the children, and reap them when they exit. So any zombies too will be eventually reaped. |
I knew fork() but thanks for precision ;)
It's not exactly a child process because both process will work on there own side w/o interact with the other. If fork() allow each process to work without the other (one can be close without any impact on the other) I'll check that, i'll be back with feedback soon :) |
Quote:
Code:
pid_t pid, child1, child2; The tricky thing about this is to note that the parent process will exit immediately. It might be a good idea to first put up a small splash window, then read the configuration and fork children, and then exit. That way the user will get visual feedback immediately, and is not left waiting for some input. Because the parent process will exit, even the task manager may not realize the children are still running, and you may not get the process icon on the task bar.. So, please test if this works for you. I haven't tested this using graphical user interfaces. Specifically, I don't know how the task bar behaves when there is a delay between the original parent process starting, and the child processes starting a new window. I suspect the task manager does not show the process is still starting up. (You can fix that, of course, by waiting for the children to fully start up before exit() in the parent process. You can do that easily by using two pipes, and closing the pipe when the child has started up. A blocking read on both by the parent will wait until the child closes the pipe.) |
The only problem I can see that might trip up someone coming from Windows is leaving (and accumulating) open files. On linux anyway that's easy(-ish) to fix, a readdir loop on /proc/self/fd/, here's a really brutal demonstrator:
Code:
~/sandbox/49381$ cat opendir.cc |
In C, one could use (untested)
Code:
#define _POSIX_C_SOURCE 200809L The function generates a dynamically allocated array of the open descriptors first, then tries to close them. It will keep the standard input, standard output, and standard error descriptors open. If successful -- all descriptors except the standard ones closed successfully -- it will return zero and keep errno unchanged, otherwise it will return errno (set to describe the error). |
Thanks for these answers :)
The file management seems to work fine. For fork(), i made a big mistake and I can't check a new build after patched it so I'll be back later with news. Thanks so much for your answers Taiki |
All times are GMT -5. The time now is 01:49 PM. |