The points jacwah made in his answer are basically valid.
You don't seem to be using any feature from <sys/wait.h>
so that could be dropped from your list of headers. Similarly, you aren't using <errno.h>
directly; you aren't using anything from <sys/stat.h>
; you aren't using anything from <string.h>
— so those could be dropped from your list of headers. The header <sys/types.h>
isn't needed since POSIX 2001 — officially.
Nominally, you should check that freopen()
works. There isn't going to be much of anything useful happening on the system if /dev/null
is AWOL, but maybe reporting the problem would be a useful heads up for the user. This is a very minor point.
If you were going to copy the arguments (which you're not), then it would be more appropriate to do that before modifying standard error; in fact, modifying standard error should be the last thing you do before the execvp()
, precisely so that you can report errors until the last possible moment.
There are some other points to consider when daemonizing. These do not all necessarily need to be acted on — but they are points to consider.
Should the daemon change directory to /
?
- Pro: it means that the daemon isn't blocking unmounting the file system its on, etc. This used to be an issue in the days of multiple file systems because of multiple disk drives. These days, it is far less of a concern, in general. But beware of running the daemon on a network-mounted file system (NFS or equivalent).
- Con: it means that the daemon doesn't ensure that the file system it needs is still mounted. Yes, the converse of the first problem. I have a
daemonize
program which was used to daemonize a DBMS, and it consciously has an option to specify which directory the daemonized program should have as its current directory (the default is not to change directory — like yours), and I used it to change directory to where the DBMS software was installed, precisely so that if it was a network-mounted file system, it wouldn't be unmounted while the daemon was running because the file system would be busy.
Should the daemon close open files?
- The usual answer is yes; you probably don't want any files other than than the standard ones open.
- My code provides for keeping selected file descriptors open.
Should the daemon be able to write to a log file?
- My program has command line options for each of the standard descriptors separately. The default is
/dev/null
for all three, though.
If you're opening a log file, which options are used with the open()
call.
- My code goes over the top; you can control separately
O_CREAT
, O_APPEND
, O_EXCL
, O_TRUNC
. It also ensures O_NOCTTY
.
Should the daemon ignore any signals?
Should the daemon set umask?
Should the PID of the final daemon process be reported on standard output?
I used my daemonize
in conjunction with env
to set the exact environment and in conjunction with a program similar to sudo
or su
to set the user ID and the active groups for the daemon, which gave me very precise (but not concise) control the environment of the DBMS daemon.
What you've got can easily be fixed into a workmanlike usable program by simply dropping the argument copying. The extensive list of other issues to consider doesn't prevent it being usable.