Alex Rivera | Logout

What's so special about file descriptor 3 on linux?

Asked 2010-08-20T22:24:48.633
21

I'm working on a server application that's going to work on Linux and Mac OS X. It goes like this:

  • start main application
  • fork of the controller process
  • call lock_down() in the controller process
  • terminate main application
  • the controller process then forks again, creating a worker process
  • eventually the controller keeps forking more worker processes

I can log using several of methods (e.g. syslog or a file) but right now I'm pondering about syslog. The "funny" thing is that no syslog output is ever seen in the controller process unless I include the #ifdef section below.

The worker processes logs flawlessly in Mac OS X and linux with or without the ifdef'ed section below. The controller also logs flawlessly in Mac OS X without the #ifdef'ed section, but on linux the ifdef is needed if I want to see any output into syslog (or the log file for that matter) from the controller process.

So, why is that?

static int
lock_down(void)
{
    struct rlimit rl;
    unsigned int n;
    int fd0;
    int fd1;
    int fd2;

    // Reset file mode mask
    umask(0);

    // change the working directory
    if ((chdir("/")) < 0)
        return EXIT_FAILURE;

    // close any and all open file descriptors
    if (getrlimit(RLIMIT_NOFILE, &rl))
        return EXIT_FAILURE;
    if (RLIM_INFINITY == rl.rlim_max)
        rl.rlim_max = 1024;

    for (n = 0; n < rl.rlim_max; n++) {
#ifdef __linux__        
        if (3 == n) // deep magic...
            continue;
#endif
        if (close(n) && (EBADF != errno))
            return EXIT_FAILURE;
    }

    // attach file descriptors 0, 1 and 2 to /dev/null
    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup2(fd0, 1);
    fd2 = dup2(fd0, 2);
    if (0 != fd0)
        return EXIT_FAILURE;

    return EXIT_SUCCESS;
}

camh was close, but using closelog() was the idea that did the trick so the honor goe

Edit
Report

1 Answer

1

Syslog binds on a given descriptor at startup. Most of the time descriptor 3. If you close it no logs.

syslog-ng -d -v

Gives you more info about what it's doing behind the scenes.

The output should look like something like this:

binding fd 3, inetaddr: 0.0.0.0, port: 514
io.c: Preparing fd 3 for reading
io.c: Preparing fd 4 for reading
binding fd 5, unixaddr: /dev/log
io.c: listening on fd 5
answered 2010-08-20T22:44:34.333

Your Answer