Logo Search packages:      
Sourcecode: dbus version File versions

dbus_bool_t _dbus_become_daemon ( const DBusString pidfile,
int  print_pid_fd,
DBusError error 
)

Does the chdir, fork, setsid, etc. to become a daemon process.

Parameters:
pidfile NULL, or pidfile to create
print_pid_fd file descriptor to print pid to, or -1 for none
error return location for errors
Returns:
FALSE on failure

Definition at line 3142 of file dbus-sysdeps.c.

References _dbus_assert_not_reached, _dbus_error_from_errno(), _dbus_getenv(), _dbus_getpid(), _dbus_strerror(), _dbus_string_append(), _dbus_string_append_int(), _dbus_string_free(), _dbus_string_get_length(), _dbus_string_init(), _dbus_write(), _dbus_write_pid_file(), dbus_set_error(), FALSE, NULL, and TRUE.

{
  const char *s;
  pid_t child_pid;
  int dev_null_fd;

  _dbus_verbose ("Becoming a daemon...\n");

  _dbus_verbose ("chdir to /\n");
  if (chdir ("/") < 0)
    {
      dbus_set_error (error, DBUS_ERROR_FAILED,
                      "Could not chdir() to root directory");
      return FALSE;
    }

  _dbus_verbose ("forking...\n");
  switch ((child_pid = fork ()))
    {
    case -1:
      _dbus_verbose ("fork failed\n");
      dbus_set_error (error, _dbus_error_from_errno (errno),
                      "Failed to fork daemon: %s", _dbus_strerror (errno));
      return FALSE;
      break;

    case 0:
      _dbus_verbose ("in child, closing std file descriptors\n");

      /* silently ignore failures here, if someone
       * doesn't have /dev/null we may as well try
       * to continue anyhow
       */
      
      dev_null_fd = open ("/dev/null", O_RDWR);
      if (dev_null_fd >= 0)
        {
          dup2 (dev_null_fd, 0);
          dup2 (dev_null_fd, 1);
          
          s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
          if (s == NULL || *s == '\0')
            dup2 (dev_null_fd, 2);
          else
            _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
        }

      /* Get a predictable umask */
      _dbus_verbose ("setting umask\n");
      umask (022);
      break;

    default:
      if (pidfile)
        {
          _dbus_verbose ("parent writing pid file\n");
          if (!_dbus_write_pid_file (pidfile,
                                     child_pid,
                                     error))
            {
              _dbus_verbose ("pid file write failed, killing child\n");
              kill (child_pid, SIGTERM);
              return FALSE;
            }
        }

      /* Write PID if requested */
      if (print_pid_fd >= 0)
      {
        DBusString pid;
        int bytes;
        
        if (!_dbus_string_init (&pid))
          {
            _DBUS_SET_OOM (error);
              kill (child_pid, SIGTERM);
            return FALSE;
          }
        
        if (!_dbus_string_append_int (&pid, _dbus_getpid ()) ||
            !_dbus_string_append (&pid, "\n"))
          {
            _dbus_string_free (&pid);
            _DBUS_SET_OOM (error);
              kill (child_pid, SIGTERM);
            return FALSE;
          }
        
        bytes = _dbus_string_get_length (&pid);
        if (_dbus_write (print_pid_fd, &pid, 0, bytes) != bytes)
          {
            dbus_set_error (error, DBUS_ERROR_FAILED,
                        "Printing message bus PID: %s\n",
                        _dbus_strerror (errno));
            _dbus_string_free (&pid);
              kill (child_pid, SIGTERM);
            return FALSE;
          }
        
        _dbus_string_free (&pid);
      }
      _dbus_verbose ("parent exiting\n");
      _exit (0);
      break;
    }

  _dbus_verbose ("calling setsid()\n");
  if (setsid () == -1)
    _dbus_assert_not_reached ("setsid() failed");
  
  return TRUE;
}


Generated by  Doxygen 1.6.0   Back to index