Why should I use fork() to daemonize my process? - c++

According to my purpose, I just want to let my process be running in the background. Then I could write normal program and run it with the following command:
nohup myprogram 1>2 2>/dev/null &
Then this program will be running in the background, just like as a daemon.
With this way, I do not need to call fork() for running in background.
So my question is what is the difference to run program in background with the above command between using fork() function?

TL;DR the fork() call is not needed, it just helps providing a nice UI for the users of the program.
A daemon uses fork() to create a duplicate of it. The child process then keeps running (in the background). The parent process may produce some output (status) then it exits.
Of course you can write only the child part of the program and launch it using the command line you posted:
$ nohup myprogram 1>2 2>/dev/null &
But if you write the daemon and I have to use it, I certainly prefer to use a simpler command line, without all that scaffolding needed to put the program in background and ensure its output doesn't make it stop and so on:
$ myprogram # there is no need for anything else

Related

How to Run one Process Twice with shell script?

If I have an executable, what is the correct way to run it twice with shell script ?
The process to be executed twice is using shared memory for message passing and shared semaphores
using simply
./a
./a
will run one process and other process can't run until first process stops and therefore no communication between two processes takes place
what is the right way to run one executable twice in parallel fashion ?
As #SamVarshavchik said, use an ampersand to run a process in the background, so the other one can run concurrently:
./a &
./a
or
./a & ./a
If, as your comments imply, the second process needs to be in the background because the first process is interactive, you can do:
{ sleep 10; ./second; } &
./first
Alternatively, you can start each process with its own Terminal:
xterm -e "./first" &
xterm -e "./second" &
At first, instead of bash hacking, it would be better to rewrite your app and make it fork() on start. But in general, if you want to bring the first process to foreground you can use an fg command:
./a &
./a &
fg 1

How to know if a SIGHUP signal has been handled?

I have a python script who sends a SIGHUP signal to another process, unrelated with my script (not a child, not alterable). When the process receives the SIGHUP, it starts a "light restart", reloading configuration file and updating information.
The "restart" doesn't stop the process, so I can't wait for an exit code. I know I can look at the process log file to know if the signal is handled, but that's too heavy and too slow for the script flow.
I would like to know if I can use another method to be warned that the SIGHUP have been received by my process?
The inotify-tools C library may solve your problem. Its installation gives you access to new commands: inotifywait and inotifywatch.
Let's say you have this /tmp/foo.bar file. You can start watching for any read access on this file with the following command:
inotifywait --event access /tmp/foo.bar
Then, do a cat /tmp/foo.bar and the program will return.
As I said, it's a C library and I guess there are other language implementations of it. So feel free to not use this Bash example and write you own program using this library.

Netcat on remote machine using ssh

I was trying to run netcat by using ssh and seems that my code always fails in my C code. Here are the commands which I am executing using system() in this order.
system("ssh machine 'nc -l 61001|dd bs=64M of=temp' &")
system("/bin/dd if=filename bs=64M|nc IP_address 61001")
I noticed that the first command works correctly as the temp file is created on the remote machine. The second dd command fails and states that 0 bytes has been written on the remote machine. These commands work correctly when executed from the terminal, but fail as soon as I put it in system() calls in C.
Short answer:
a & disown (instead of just &) should do.
Explanation:
system() spawns a shell that just executes one command and then exits. The & tells the shell to fork the command into background (means, it doesn't wait for its completion), but it's still part of the session and process group of the shell. When the group leader (the shell) exits, all children are killed. The disown causes the shell to start new process group, the child process is now owned by init (the first process in the system).
"Real" answer:
This is about programming. You are forking processes like crazy to accomplish something a C program could easily do using builtin library calls (except for the ssh but there are better ways, too). Go read on BSD sockets.

How to find the state(blocking or non-blocking) of a particular shell command?

For example,if i use system() command from a c program to invoke a shell command whether it will complete the shell command and then it'll proceed with program or it'll do both concurrently
what are all the various methods available to find this information ?
You can use fork() or exec() for non-blocking, but a system() call is blocking. This means it will wait for your shell command to finish prior to resuming executing of your C program.
Note if you want it to return right away, you can issue your system command with an & behind it and your C program will run concurrently.
Sequential Example:
system("long_script.sh");
Concurrent Example:
system("long_script.sh &");

Make child process spawned with system() keep running after parent gets kill signals and exits

In a Linux/C++ library I'm launching a process via the system() call,
system("nohup processName > /dev/null&");
This seems to work fine with a simple test application that exits on it's own, but if I use this from inside of a Nodejs/V8 extension which gets a kill signal, the child process gets killed. I did find that running,
system("sudo nohup processName > /dev/null&");
With the sudoers file set up to not require a password manages to make this run even when the parent process (node) exits. Is there someway to entirely detach the child process so signals sent to the parent and the parent exiting have no effect on the child anymore? Preferably within the system() call and not something that requires getting the process ID and doing something with it.
The procedure to detach from the parent process is simple: Run the command under setsid (so it starts in a new session), redirecting standard input, output and error to /dev/null (or somewhere else, as appropriate), in background of a subshell. Because system() starts a new shell, it is equivalent to such a subshell, so
system("setsid COMMAND </dev/null >/dev/null 2>/dev/null &");
does exactly what is needed. In a shell script, the equivalent is
( setsid COMMAND </dev/null >/dev/null 2>/dev/null & )
(Shell scripts need a subshell, because otherwise the COMMAND would be under job control for the current shell. That is not important when using system(), because it starts a new shell just for the command anyway; the shell will exit when the command exits.)
The redirections are necessary to make sure the COMMAND has no open descriptors to the current terminal. (When the terminal closes, a TERM signal is sent to all such processes.) This means standard input, standard output, and standard error all must be redirected. The above redirections work in both Bash and POSIX shells, but might not work in ancient versions of /bin/sh. In particular, it should work in all Linux distros.
setsid starts a new session; the COMMAND becoming the process group leader for its own process group. Signals can be directed to either a single process, or to all processes in a process group. Termination signals are usually sent to entire process groups (since an application may technically consist of multiple related processes). Starting a new session makes sure COMMAND does not get killed if the process group the parent proces belongs to is killed by a process-group wide signal.
My guess is that the whole process group is being killed. You could try setpgid in the child to start a new process group. The first step should be to get rid of system and use fork and execve or posix_spawn.