practical examples use dup or dup2 - c

I know what dup / dup2 does, but I have no idea when it would be used.
Any practical examples?
Thanks.

One example use would be I/O redirection. For this you fork a child process and close the stdin or stdout file descriptors (0 and 1) and then you do a dup() on another filedescriptor of your choice which will now be mapped to the lowest available file descriptor, which is in this case 0 or 1.
Using this you can now exec any child process which is possibly unaware of your application and whenever the child writes on the stdout (or reads from stdin, whatever you configured) the data gets written on the provided filedescriptor instead.
Shells use this to implement commands with pipes, e.g. /bin/ls | more by connecting the stdout of one process to the stdin of the other.

The best scenario to understand dup and dup2 is redirection.
First thing we need to know is that the system has 3 default file ids(or variables indicating output or input sources) that deals with the input and output. They are stdin, stdout, stderr, in integers they are 0,1,2. Most of the functions like fprintf or cout are directly output to stdout.
If we want to redirect the output, one way is give, for example, fprintf function more arguments indicating in and out.
However, there is a more elegant way: we can overwrite the default file ids to make them pointing to the file we want to receive the output. dup and dup2 exactly work in this situation.
Let's start with one simple example now: suppose we want to redirect the output of fprintf to a txt file named "chinaisbetter.txt". First of all we need to open this file
int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);
Then we want stdout to point to "chinaisbetter.txt" by using dup function:
dup2(fw,1);
Now stdout(1) points to the descriptor of "chinaisbetter.txt" even though it's still 1, but the output is redirected now.
Then you can use printf as normal, but the results will be in the txt file instead of showing directly on the screen:
printf("Are you kidding me? \n");
PS:
This just gives a intuitive explanation, you may need to check the manpage or detailed information. Actually, we say "copy" here, they are not copying everything.
The file id here is referring to the handler of the file. The file descriptor mentioned above is a struct the records file's information.

When you are curious about POSIX functions, especially those that seem to duplicate themselves, it's generally good to check the standard itself. At the bottom you will usually see examples, as well as reasoning behind the implementation (and existence) of both.
In this case:
The following sections are informative.
Examples
Redirecting Standard Output to a File
The following example closes standard output for the current processes, re-assigns standard output to go to the file referenced by pfd, and closes the original file descriptor to clean up.
#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...
Redirecting Error Messages
The following example redirects messages from stderr to stdout.
#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...
Application Usage
None.
Rationale
The dup() and dup2() functions are redundant. Their services are also provided by the fcntl() function. They have been included in this volume of IEEE Std 1003.1-2001 primarily for historical reasons, since many existing applications use them.
While the brief code segment shown is very similar in behavior to dup2(), a conforming implementation based on other functions defined in this volume of IEEE Std 1003.1-2001 is significantly more complex. Least obvious is the possible effect of a signal-catching function that could be invoked between steps and allocate or deallocate file descriptors. This could be avoided by blocking signals.
The dup2() function is not marked obsolescent because it presents a type-safe version of functionality provided in a type-unsafe version by fcntl(). It is used in the POSIX Ada binding.
The dup2() function is not intended for use in critical regions as a synchronization mechanism.
In the description of [EBADF], the case of fildes being out of range is covered by the given case of fildes not being valid. The descriptions for fildes and fildes2 are different because the only kind of invalidity that is relevant for fildes2 is whether it is out of range; that is, it does not matter whether fildes2 refers to an open file when the dup2() call is made.
Future Directions
None.
See also
close(), fcntl(), open(), the Base Definitions volume of IEEE Std 1003.1-2001, <unistd.h>
Change History
First released in Issue 1. Derived from Issue 1 of the SVID.

One practical example is redirecting output messages to some other stream like some log file. Here is a sample code for I/O redirection.
Please refer to original post here
#include <stdio.h>
main()
{
int fd;
fpos_t pos;
printf("stdout, ");
fflush(stdout);
fgetpos(stdout, &pos);
fd = dup(fileno(stdout));
freopen("stdout.out", "w", stdout);
f();
fflush(stdout);
dup2(fd, fileno(stdout));
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos); /* for C9X */
printf("stdout again\n");
}
f()
{
printf("stdout in f()");
}

I/O redirection in the shell would most likely be implemented using dup2/fcnlt system calls.
We can easily emulate the $program 2>&1 > logfile.log type of redirection using the dup2 function.
The program below redirects both stdout and stderr .i.e emulates behavior of $program 2>&1 > output using the dup2.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int
main(void){
int close_this_fd;
dup2(close_this_fd = open("output", O_WRONLY), 1);
dup2(1,2);
close(close_this_fd);
fprintf(stdout, "standard output\n");
fprintf(stderr, "standard error\n");
fflush(stdout);
sleep(100); //sleep to examine the filedes in /proc/pid/fd level.
return;
}
vagrant#precise64:/vagrant/advC$ ./a.out
^Z
[2]+ Stopped ./a.out
vagrant#precise64:/vagrant/advC$ cat output
standard error
standard output
vagrant#precise64:/vagrant/advC$ ll /proc/2761/fd
total 0
dr-x------ 2 vagrant vagrant 0 Jun 20 22:07 ./
dr-xr-xr-x 8 vagrant vagrant 0 Jun 20 22:07 ../
lrwx------ 1 vagrant vagrant 64 Jun 20 22:07 0 -> /dev/pts/0
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 1 -> /vagrant/advC/output
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 2 -> /vagrant/advC/output

Related

posix_spawn pipe dmesg to python script

I've got several USB to 422 adapters in my test system. I've used FTProg to give each adapter a specific name: Sensor1, Sensor2, etc. They will all be plugged in at power on. I don't want to hard code each adapter to a specific ttyUSBx. I want the drivers to figure out which tty it needs to use. I'm developing in C for a linux system. My first thought was to something like this in my startup code.
system("dmesg | find_usb.py");
The python script would find the devices since each one has a unique Product Description. Then using the usb tree to associate each device with its ttyUSBx. The script would then create /tmp/USBDevs which would just be a simple device:tty pairing that would be easy for the C code to search.
I've been told...DoN't UsE sYsTeM...use posix_spawn(). But I'm having problems getting the output of dmesg piped to my python script. This isn't working
char *my_args[] = {"dmesg", "|", "find_usb.py", NULL};
pid_t pid;
int status;
status = posix_spawn(&pid, "/bin/dmesg", NULL, NULL, my_args, NULL);
if(status == 0){
if(waitpid(pid, &status, 0) != -1);{
printf("posix_spawn exited: %i", status);
}
I've been trying to figure out how to do this with posix_spawn_file_actions(), but I'm not allowed to hit the peak of the 'Ballmer Curve' at work.
Thanks in advance
Instead of using /dev/ttyUSB* devices, write udev rules to generate named symlinks to the devices. For a brief how-to, see here. Basically, you'll have an udev rule for each device, ending with say SYMLINK+=Sensor-name, and in your program, use /dev/Sensor-name for each sensor. (I do recommend using Sensor- prefix, noting the initial Capital letter, as all device names are currently lowercase. This avoids any clashes with existing devices.)
These symlinks will then only exist when the matching device is plugged in, and will point to the correct device (/dev/ttyUSB* in this case). When the device is removed, udev automagically deletes the symlink also. Just make sure your udev rule identifies the device precisely (not just vendor:device, but serial number also). I'd expect the rule to look something like
SUBSYSTEM=="tty", ATTRS{idVendor}=="VVVV", ATTRS{idProduct}=="PPPP", ATTRS{serial}=="SSSSSSSS", SYMLINK+="Sensor-name"
where VVVV is the USB Vendor ID (four hexadecimal digits), PPPP is the USB Product ID (four hexadecimal digits), and SSSSSSSS is the serial number string. You can see these values using e.g. udevadm info -a -n /dev/ttyUSB* when the device is plugged in.
If you still insist on parsing dmesg output, using your own script is a good idea.
You could use FILE *handle = popen("dmesg | find_usb.py", "r"); and read from handle like it was a file. When complete, close the handle using int exitstatus = pclose(handle);. See man popen and man pclose for the details, and man 2 wait for the WIFEXITED(), WEXITSTATUS(), WIFSIGNALED(), WTERMSIG() macros you'll need to use to examine exitstatus (although in your case, I suppose you can just ignore any errors).
If you do want to use posix_spawn() (or roughly equivalently, fork() and execvp()), you'd need to set up at least one pipe (to read the output of the spawned command) – two if you spawn/fork+exec both dmesg and your Python script –, and that gets a bit more complicated. See man pipe for details on that. Personally, I would rewrite the Python script so that it executes dmesg itself internally, and only outputs the device name(s). With posix_spawn(), you'd init a posix_file_actions_t, with three actions: _adddup2() to duplicate the write end of the pipe to STDOUT_FILENO, and two _addclose()s to close both ends of the pipe. However, I myself prefer to use fork() and exec() instead, somewhat similar to the example by Glärbo in this answer.

Exec function in c is not returning -1 when it should

I am using an execv function to run a program called code.x.
code.x has a part where it guarantees its failure by Assertion.
My code that runs execl is:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
int main()
{
pid_t pid;
char *args[] = { "./code.x",NULL };
pid = fork();
if (pid > 0) {
wait(NULL);
printf("%s\n", strerror(errno));
printf("done\n");
}
else if (pid == 0) {
printf("%s\n", strerror(errno));
execv(args[0], args);
printf("should fail");
}
else {
printf("forkfail");
}
return 1;
}
the code prints
Success
code.x: code.c:15: main: Assertion '0 == 1' failed.
Success
done
"should fail" is never printed and WEXITSTATUS(status) shows that the exit status is 0.
The exec family of functions replace the calling process with a new program in its initial state loaded from an executable file. They can only fail if this replacement fails, e.g. due to the requested file not existing or the invoking user not having permissions to access/execute it.
If an assertion failure in the program ./code.x you're invoking happens, this is long past the point where execv could have failed; at this point, the original program state where execv was performed no longer exists, because it was already replaced. The parent process will see it exit via a wait-family function, and can inspect the status reported by the wait-family function to determine why it exited.
exec* functions succeed if the program starts running. Your program did start running.
An assertion failure causes the program to abort, exit with a signal. The Linux manual page wait(2) explains that:
WEXITSTATUS(wstatus)
returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as
the argument for a return statement in main(). This macro should be employed only if WIFEXITED returned true.
If you didn't check that WIFEXITED(status) is true, then WEXITSTATUS(status) is garbage.
Instead, check WIFSIGNALED(status) and if true, get the signal - WTERMSIG(status), which should equal to SIGABRT.
execv successfully did its job. The process ./code.x executed, then exited because of an assertiong.
The exec family of functions don't care about the process's return value. Once the process starts, the calling process is effectively terminated and gone.
Exec will only return if for some reason the process couldn't be started at all. Specifically, only these errors (taken from the man page) will cause exec to return and set errno to one of these values:
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
EACCES Search permission is denied on a component of the path prefix of filename or the name of a script interpreter. (See also path_resolution(7).)
EACCES The file or a script interpreter is not a regular file.
EACCES Execute permission is denied for the file or a script or ELF interpreter.
EACCES The filesystem is mounted noexec.
EAGAIN (since Linux 3.1)
Having changed its real UID using one of the set*uid() calls, the caller was—and is now still—above its RLIMIT_NPROC resource limit (see
setrlimit(2)). For a more detailed explanation of this error, see NOTES.
EFAULT filename or one of the pointers in the vectors argv or envp points outside your accessible address space.
EINVAL An ELF executable had more than one PT_INTERP segment (i.e., tried to name more than one interpreter).
EIO An I/O error occurred.
EISDIR An ELF interpreter was a directory.
ELIBBAD An ELF interpreter was not in a recognized format.
ELOOP Too many symbolic links were encountered in resolving filename or the name of a script or ELF interpreter.
ELOOP The maximum recursion limit was reached during recursive script interpretation (see "Interpreter scripts", above). Before Linux 3.8, the
error produced for this case was ENOEXEC.
EMFILE The per-process limit on the number of open file descriptors has been reached.
ENAMETOOLONG filename is too long.
ENFILE The system-wide limit on the total number of open files has been reached.
ENOENT The file filename or a script or ELF interpreter does not exist, or a shared library needed for the file or interpreter cannot be found.
ENOEXEC An executable is not in a recognized format, is for the wrong architecture, or has some other format error that means it cannot be executed.
ENOMEM Insufficient kernel memory was available.
ENOTDIR A component of the path prefix of filename or a script or ELF interpreter is not a directory.
EPERM The filesystem is mounted nosuid, the user is not the superuser, and the file has the set-user-ID or set-group-ID bit set.
EPERM The process is being traced, the user is not the superuser and the file has the set-user-ID or set-group-ID bit set.
EPERM A "capability-dumb" applications would not obtain the full set of permitted capabilities granted by the executable file. See capabilities(7).
ETXTBSY The specified executable was open for writing by one or more processes.
The Exec function family replaces the existing process image with a new process image. This is why it is required to fork before spawning another process, because the currently running process is completely replaced, this includes the program counter, which keeps track of the next instruction to execute.
printf("should fail");
is never excecuted because the instant you called execv(args[0], args), the program counter was moved to execute args[0], thus leaving behind the execution path that would have resulted in that print statement.
Exec returns -1 on the condition that it encountered an error while replacing the image, and has absolutely no relation to the return value of the program being executed. This is because the two processes, after Exec is called, are not coordinating with each other at all. Remember: the fork() command created a new address space, which means that these processes are now running in separate domains on separate executables.
Some documentation may be of help:
http://man7.org/linux/man-pages/man3/exec.3.html
Hope this helped.

Read from a file which is being actively written to

I have two programs: one (program1) writes to a file continuously, and I want the other program (program2) to read the file continuously. What is happening is that my second program is only reading up to the data point which was written when the second code was executed and stops instead of continuously reading.
Is there any way to achieve the thing?
Basically, I want the output of program1 to be used as the input of program2. Is there any way to read and write in RAM instead of file as disk read costs more time.
Code 2:
#include <stdio.h>
int main(){
FILE *fptr;
fptr = fopen("gbbct1.seq","r");
char c;
c = fgetc(fptr);
while (c != EOF){
printf("%c", c);
c = fgetc(fptr);
}
}
I am looking for platform independent approach. If that's not possible, I would like to know for Linux platform. I don't need to preserve the data once read. I don't want to block program1.
The most basic version of your code needs to reset the file stream status when it encounters EOF and then sleep for a while. For example, assuming POSIX and using only the simplest (most ubiquitous) functions:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
const char filename[] = "gbbct1.seq";
FILE *fptr = fopen(filename, "r");
if (fptr == 0)
{
fprintf(stderr, "failed to open file '%s' for reading\b", filename);
exit(EXIT_FAILURE);
}
while (1)
{
int c;
while ((c = fgetc(fptr)) != EOF)
fputc(c, stdout);
clearerr(fptr);
sleep(1);
}
/*NOTREACHED*/
return EXIT_FAILURE;
}
The sleep() function sleeps for an integral number of seconds; if you want sub-second sleeps, you can consider usleep(),
nanosleep(), timer_create() and relatives, etc.
I have a program I call dribbler (because it dribbles data to its output):
Usage: dribbler [-hlntV][-s nap.time][-r std.dev][-f outfile][-i infile][-m message][-o openstr][-F format]
-V Print version information and exit
-f outfile Write to named file (dribbler.out)
-h Print this help message and exit
-i infile Read lines from input file
-l Loop back to start of input file on EOF
-m message Write message on each line of output
-n Number lines read from input file
-o openstr Flags passed to fopen() (a+)
-s nap.time Sleep for given interval between writes (1.000 second)
-r std.dev Randomize the time (Gaussian around nap.time with std.dev)
-t Write to standard output instead of file
-F format Printf format to use instead of %zu
I used:
$ dribbler -s 3 -r 1.3 -f gbbct1.seq &
[1] 81129
$
to write to the control file that program2 is coded to read. I then ran program2 on it, and it produced the outputs as it proceeded.
It's hard to show the time sequence on SO. I have another program (the story of my life) called tstamp which reads lines of input and prints them with a timestamp prefixed to the line:
Usage: tstamp [-hV][-f num][-F format]
-f num Number of fractional digits (0, 3, 6, 9)
-h Print this help message and exit
-F fmt Time format (strftime(3)) to use
-V Print version information and exit
I tried modifying program2.c to set line buffered mode on my Mac (macOS Sierra 10.12.5, GCC 7.1.0), by adding the line below before the while loop in program2.c, but it was effectively ignored, somewhat to my surprise and chagrin:
setvbuf(fptr, 0, _IOLBF, 0);
So, I rewrote the while loop as:
while ((c = fgetc(fptr)) != EOF)
{
fputc(c, stdout);
if (c == '\n')
fflush(stdout);
}
Then I was able to run dribbler in the background, and program2 | tstamp -f 3 to get output like:
$ program2 | tstamp -f 3
2017-06-03 23:52:44.836: 0: message written to file
2017-06-03 23:52:44.836: 1: message written to file
2017-06-03 23:52:44.836: 2: message written to file
2017-06-03 23:52:44.836: 3: message written to file
[…more similar lines with the same time stamp…]
2017-06-03 23:52:44.836: 22: message written to file
2017-06-03 23:52:44.836: 23: message written to file
2017-06-03 23:52:44.836: 24: message written to file
2017-06-03 23:52:44.836: 25: message written to file
2017-06-03 23:52:50.859: 26: message written to file
2017-06-03 23:52:54.866: 27: message written to file
2017-06-03 23:52:58.880: 28: message written to file
2017-06-03 23:53:02.888: 29: message written to file
2017-06-03 23:53:05.902: 30: message written to file
2017-06-03 23:53:07.907: 31: message written to file
2017-06-03 23:53:09.913: 32: message written to file
2017-06-03 23:53:12.925: 33: message written to file
2017-06-03 23:53:14.935: 34: message written to file
2017-06-03 23:53:15.938: 35: message written to file
2017-06-03 23:53:19.954: 36: message written to file
2017-06-03 23:53:21.964: 37: message written to file
2017-06-03 23:53:23.972: 38: message written to file
^C
$ kill %1
[1]+ Terminated: 15 dribbler -s 3 -r 1.3 -f gbbct1.seq
$
You can see that I'd had dribbler running for a while when I started program2 (it got modified and recompiled — part of my chagrin), so there was quite a lot of date to read immediately (hence the multiple lines with the timestamp 2017-06-03 23:52:44.836:), but then it was waiting on dribbler to write more, and as you can see, it sometimes waited nearly 6 seconds between lines, and other times about 1 second, and various intervals in between. The gaps are made more uniform by program2 sleeping for a second at a time. (Yes, I wrote these tools to help answer questions on SO — but dribbler and tstamp both pre-date this question by months.)
I have two programs: one (program1) writes to a file continuously, and I want the other program (program2) to read the file continuously.
What happens then is platform-specific. BTW, the mere ability to run several programs at once (in several processes) is provided by the operating system (and is not defined in, since outside of, the C11 standard). Read Operating Systems : Three Easy Pieces (freely downloadable chapters).
IIRC, on Windows (that I don't know and never used) that is not allowed to happen (one of the programs would be blocked or would have its file open fail).
However, if on Linux with a native local file system (such as Ext4), you could consider using inotify(7) facilities (which won't work with remote file systems à la NFS, and probably won't work on FAT filesystems like e.g. some USB key; but you need to check).
Basically, I want the output of program1 to be used as the input of program2. Is there any way to read and write in RAM instead of file as disk read costs more time.
(I am supposing you wrote both program1 and program2, or at least have their source code and can modify it)
BTW, application programs don't read directly from RAM; they work in virtual memory and each process has its own virtual address space. See this answer.
You surely want to have some inter-process communications, which are provided by your operating system.
On Linux there are many ways of doing that (you should read Advanced Linux Programming whose chapters are freely downloadable). I suggest considering some fifo(7), or some pipe(7) (if both running programs can be started from a common process), or some unix(7) sockets.
You surely need to multiplex for I/O (in both processes) e.g. by having some event loop around a poll(2).
Windows also has inter-process communication facilities. But I don't know them.
(I strongly recommend to spend a few days reading, notably Advanced Linux Programming or some other similar book, before writing a single line of code. You lack an overall picture on OSes and on Linux)
I would recommend using a pipe(7), or else some named fifo(7), or else some unix(7) socket. You could then write code portable on all POSIX systems. I don't recommend to use a file and inotify(7) (which is complex and Linux specific). See also popen(3).
You might find some framework libraries (e.g. Glib from GTK, QtCore, POCO, libevent, 0mq) to help you write portable code able to run on many platforms.

open system call - Linux

Trying to open tty port using open system call. HOw do i know if this port is being used by another application in case the open system call returns -1?
DO not find error codes for the same.
a call to open() won't give you an error if the file is already open.
Howerver, you can try to analyze the output of the linux lsofcommand:
lsof /dev/ttyS0
It will return information about the processes that opened the given file (in this case: /dev/ttyS0).
(I've tested this a few times so I'm not sure about it, but lsof seems to return 0 if the file is opened by a process and return 1 if no process has opened it. This could be an indication, however I would suggest you really analyze the output of the command itself)
#include <errno.h>
#include <stdio.h>
#include <strcing.h>
int main()
{
if(open("/dev/ttyS0", O_RDWR))
printf("errno = %s\n", strerror(errno));
return errno;
}
see this link in order to figure out what the error code is.

Start a process in the background in Linux with C

I am trying to do something a little weird here. I need to start a process, logcat, from a deamon that will run in the background and print to the terminal without taking control of stdin. It is for logging so ideally logcat will print log messages while still allowing the user to input standard commands and initialize programs from the shell. Here is the code for the daemon I have so far. The program, logcat, starts and shows log messages but I cannot enter any commands into stdin as it appears that the program has taken control of stdin.
int main ( int argc, char** argv, char** env )
{
int fd;
if ((fd = open("/dev/console", O_RDWR)) < 0) {
fd = open("/dev/null", O_RDWR);
}
printf("THIS IS A TEST\n");
dup2(1, fd);
dup2(2, fd);
pid_t childpid = fork();
if(childpid == -1) {
perror("Failed to fork, logcat not starting");
return 1;
}
if(childpid == 0) {
//this is the child, exec logcat
setsid();
int execReturn = execl("/system/bin/logcat", "logcat", (char *) 0);
} else {
//this is the parent do nothing
close(fd);
return 0;
}
close(fd);
return 0;
}
Thanks
The 'logcat' command seems to be for Android development - that might explain the odd location of the command.
The key operation that you must fix is to ensure that you close your current standard input (the terminal) and open /dev/null/ for the input device:
close(0);
if ((fd = open("/dev/null", O_RDONLY)) != 0)
...error - failed to open /dev/null!
This means that your daemonized child process will not read anything from the terminal.
What I think you want to do is:
Run your launcher program from a command line, which will have standard input, standard output and standard error connected to 'the terminal'.
Inside your program, you want to replace the standard input so it comes from /dev/null.
You want to leave standard output alone - you want logcat to write to the current standard output.
You probably want to leave standard error alone too.
At some point in the proceedings, you do your daemonization properly (borrowing the link from #bstpierre's answer), making sure that the terminal you are connected to is not your controlling terminal, so that interrupts and hangups sent to the terminal don't affect your daemon. The plumbing is simpler than what you have set up - you should deal with standard input and leave standard output and standard error unchanged (instead of changing the outputs and leaving the input unchanged).
Now, you might want the output to go to /dev/console; if so, then it is reasonable to revise the code to open /dev/console. However, it is not reasonable to fall back on /dev/null if you can't open /dev/console; your program should report an error and fail (because there is no point in having logcat writing to /dev/null!). Make sure you open the console with the O_NOCTTY flag so it does not become the controlling terminal for the daemon.
The final comment I'd make is:
Are you sure you want random text appearing over your terminal or console when it is in use for other things?
I don't much like it when that happens.
See also: SO 958249
How to Daemonize in Linux [dead link]
How to Daemonize in Linux [wayback machine archive of the above]
gist on github -- code taken from link above
Executive summary:
One of the things I keep running across is Linux daemons that don’t properly daemonize themselves. To properly daemonize, the following steps must be followed.
The fork() call is used to create a separate process.
The setsid() call is used to detach the process from the parent (normally a shell).
The file mask should be reset.
The current directory should be changed to something benign.
The standard files (stdin,stdout and stderr) need to be reopened.
Failure to do any of these steps will lead to a daemon process that can misbehave. The typical symptoms are as follows.
Starting the daemon and then logging out will cause the terminal to hang. This is particularly nasty with ssh.
The directory from which the daemon was launched remains locked.
Spurious output appears in the shell from which the daemon was started.
There is special purposed function for this in glibc:
#include <unistd.h>
...
/* We are in the parent, yet */
daemon(0,0);
/* Now we are in the child */
...
More details here http://linux.die.net/man/3/daemon

Resources