Added NameList method handling, small improvemnets and cleanups
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-util-unix.c
index 6e09245..6265e2b 100644 (file)
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
 #include <grp.h>
 #include <sys/socket.h>
 #include <dirent.h>
 #include <sys/un.h>
+
+#ifdef HAVE_SYSLOG_H
 #include <syslog.h>
+#endif
 
 #ifdef HAVE_SYS_SYSLIMITS_H
 #include <sys/syslimits.h>
 #endif
 
+#include "sd-daemon.h"
+
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
@@ -120,6 +128,7 @@ _dbus_become_daemon (const DBusString *pidfile,
             dup2 (dev_null_fd, 2);
           else
             _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
+          close (dev_null_fd);
         }
 
       if (!keep_umask)
@@ -251,8 +260,8 @@ _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
       DBusString pid;
       int bytes;
 
-      _dbus_verbose ("writing our pid to pipe %"PRIuPTR"\n",
-                     print_pid_pipe->fd_or_handle);
+      _dbus_verbose ("writing our pid to pipe %d\n",
+                     print_pid_pipe->fd);
       
       if (!_dbus_string_init (&pid))
         {
@@ -369,11 +378,72 @@ _dbus_change_to_daemon_user  (const char    *user,
 }
 #endif /* !HAVE_LIBAUDIT */
 
-void 
-_dbus_init_system_log (void)
+
+/**
+ * Attempt to ensure that the current process can open
+ * at least @limit file descriptors.
+ *
+ * If @limit is lower than the current, it will not be
+ * lowered.  No error is returned if the request can
+ * not be satisfied.
+ *
+ * @limit Number of file descriptors
+ */
+void
+_dbus_request_file_descriptor_limit (unsigned int limit)
 {
-  openlog ("dbus", LOG_PID, LOG_DAEMON);
+#ifdef HAVE_SETRLIMIT
+  struct rlimit lim;
+  struct rlimit target_lim;
+
+  /* No point to doing this practically speaking
+   * if we're not uid 0.  We expect the system
+   * bus to use this before we change UID, and
+   * the session bus takes the Linux default
+   * of 1024 for both cur and max.
+   */
+  if (getuid () != 0)
+    return;
+
+  if (getrlimit (RLIMIT_NOFILE, &lim) < 0)
+    return;
+
+  if (lim.rlim_cur >= limit)
+    return;
+
+  /* Ignore "maximum limit", assume we have the "superuser"
+   * privileges.  On Linux this is CAP_SYS_RESOURCE.
+   */
+  target_lim.rlim_cur = target_lim.rlim_max = limit;
+  /* Also ignore errors; if we fail, we will at least work
+   * up to whatever limit we had, which seems better than
+   * just outright aborting.
+   *
+   * However, in the future we should probably log this so OS builders
+   * have a chance to notice any misconfiguration like dbus-daemon
+   * being started without CAP_SYS_RESOURCE.
+   */
+  setrlimit (RLIMIT_NOFILE, &target_lim);
+#endif
 }
+
+void
+_dbus_init_system_log (dbus_bool_t is_daemon)
+{
+#ifdef HAVE_SYSLOG_H
+  int logopts = LOG_PID;
+
+#if HAVE_DECL_LOG_PERROR
+#ifdef HAVE_SYSTEMD
+  if (!is_daemon || sd_booted () <= 0)
+#endif
+    logopts |= LOG_PERROR;
+#endif
+
+  openlog ("dbus", logopts, LOG_DAEMON);
+#endif
+}
+
 /**
  * Log a message to the system log file (e.g. syslog on Unix).
  *
@@ -407,6 +477,8 @@ _dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...)
 void
 _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args)
 {
+  va_list tmp;
+#ifdef HAVE_SYSLOG_H
   int flags;
   switch (severity)
     {
@@ -423,7 +495,21 @@ _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args
         return;
     }
 
-  vsyslog (flags, msg, args);
+  DBUS_VA_COPY (tmp, args);
+  vsyslog (flags, msg, tmp);
+  va_end (tmp);
+#endif
+
+#if !defined(HAVE_SYSLOG_H) || !HAVE_DECL_LOG_PERROR
+    {
+      /* vsyslog() won't write to stderr, so we'd better do it */
+      DBUS_VA_COPY (tmp, args);
+      fprintf (stderr, "dbus[" DBUS_PID_FORMAT "]: ", _dbus_getpid ());
+      vfprintf (stderr, msg, tmp);
+      fputc ('\n', stderr);
+      va_end (tmp);
+    }
+#endif
 
   if (severity == DBUS_SYSTEM_LOG_FATAL)
     exit (1);
@@ -470,7 +556,7 @@ _dbus_user_at_console (const char *username,
                        DBusError  *error)
 {
 
-  DBusString f;
+  DBusString u, f;
   dbus_bool_t result;
 
   result = FALSE;
@@ -486,8 +572,9 @@ _dbus_user_at_console (const char *username,
       goto out;
     }
 
+  _dbus_string_init_const (&u, username);
 
-  if (!_dbus_string_append (&f, username))
+  if (!_dbus_concat_dir_and_file (&f, &u))
     {
       _DBUS_SET_OOM (error);
       goto out;
@@ -1005,11 +1092,11 @@ string_squash_nonprintable (DBusString *str)
   
   for (i = 0; i < len; i++)
     {
-         unsigned char c = (unsigned char) buf[i];
+      unsigned char c = (unsigned char) buf[i];
       if (c == '\0')
-        c = ' ';
+        buf[i] = ' ';
       else if (c < 0x20 || c > 127)
-        c = '?';
+        buf[i] = '?';
     }
 }
 
@@ -1079,10 +1166,10 @@ _dbus_command_for_pid (unsigned long  pid,
     goto fail;
   
   string_squash_nonprintable (&cmdline);  
-  
+
   if (!_dbus_string_copy (&cmdline, 0, str, _dbus_string_get_length (str)))
     goto oom;
-  
+
   _dbus_string_free (&cmdline);  
   _dbus_string_free (&path);
   return TRUE;