X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-sysdeps-util-unix.c;h=631c199f46cd6ac8e2991c137d87a179e0ade7b2;hb=7d9239c9c78cb6d0b9c282376fcf3cda1de23209;hp=a8891b452c55f66f67242ce1a8581265f9ef009a;hpb=6f9077ee870ad02119facf83d1293301b4535c3b;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index a8891b4..631c199 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -42,16 +42,24 @@ #include #include #include +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif #include #include #include #include + +#ifdef HAVE_SYSLOG_H #include +#endif #ifdef HAVE_SYS_SYSLIMITS_H #include #endif +#include "sd-daemon.h" + #ifndef O_BINARY #define O_BINARY 0 #endif @@ -115,11 +123,12 @@ _dbus_become_daemon (const DBusString *pidfile, dup2 (dev_null_fd, 0); dup2 (dev_null_fd, 1); - s = _dbus_config_debug_output (); + 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"); + 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,18 +378,77 @@ _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 @p limit file descriptors. + * + * If @p limit is lower than the current, it will not be + * lowered. No error is returned if the request can + * not be satisfied. + * + * @param limit number of file descriptors + */ +void +_dbus_request_file_descriptor_limit (unsigned int limit) +{ +#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) { - openlog ("dbus", LOG_PID, LOG_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). * * @param severity a severity value * @param msg a printf-style format string - * @param args arguments for the format string - * */ void _dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...) @@ -407,6 +475,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) { @@ -418,11 +488,26 @@ _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args break; case DBUS_SYSTEM_LOG_FATAL: flags = LOG_DAEMON|LOG_CRIT; + break; default: 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); @@ -469,7 +554,7 @@ _dbus_user_at_console (const char *username, DBusError *error) { - DBusString f; + DBusString u, f; dbus_bool_t result; result = FALSE; @@ -485,8 +570,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; @@ -607,54 +693,14 @@ _dbus_directory_open (const DBusString *filename, return iter; } -/* Calculate the required buffer size (in bytes) for directory - * entries read from the given directory handle. Return -1 if this - * this cannot be done. - * - * If you use autoconf, include fpathconf and dirfd in your - * AC_CHECK_FUNCS list. Otherwise use some other method to detect - * and use them where available. - */ -static dbus_bool_t -dirent_buf_size(DIR * dirp, size_t *size) -{ - long name_max; -# if defined(HAVE_FPATHCONF) && defined(_PC_NAME_MAX) -# if defined(HAVE_DIRFD) - name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); -# elif defined(HAVE_DDFD) - name_max = fpathconf(dirp->dd_fd, _PC_NAME_MAX); -# else - name_max = fpathconf(dirp->__dd_fd, _PC_NAME_MAX); -# endif /* HAVE_DIRFD */ - if (name_max == -1) -# if defined(NAME_MAX) - name_max = NAME_MAX; -# else - return FALSE; -# endif -# elif defined(MAXNAMELEN) - name_max = MAXNAMELEN; -# else -# if defined(NAME_MAX) - name_max = NAME_MAX; -# else -# error "buffer size for readdir_r cannot be determined" -# endif -# endif - if (size) - *size = (size_t)offsetof(struct dirent, d_name) + name_max + 1; - else - return FALSE; - - return TRUE; -} - /** * Get next file in the directory. Will not return "." or ".." on * UNIX. If an error occurs, the contents of "filename" are * undefined. The error is never set if the function succeeds. * + * This function is not re-entrant, and not necessarily thread-safe. + * Only use it for test code or single-threaded utilities. + * * @param iter the iterator * @param filename string to be set to the next file in the dir * @param error return location for error @@ -665,37 +711,24 @@ _dbus_directory_get_next_file (DBusDirIter *iter, DBusString *filename, DBusError *error) { - struct dirent *d, *ent; - size_t buf_size; + struct dirent *ent; int err; _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - if (!dirent_buf_size (iter->d, &buf_size)) - { - dbus_set_error (error, DBUS_ERROR_FAILED, - "Can't calculate buffer size when reading directory"); - return FALSE; - } - - d = (struct dirent *)dbus_malloc (buf_size); - if (!d) - { - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, - "No memory to read directory entry"); - return FALSE; - } again: - err = readdir_r (iter->d, d, &ent); - if (err || !ent) + errno = 0; + ent = readdir (iter->d); + + if (!ent) { + err = errno; + if (err != 0) dbus_set_error (error, _dbus_error_from_errno (err), "%s", _dbus_strerror (err)); - dbus_free (d); return FALSE; } else if (ent->d_name[0] == '.' && @@ -709,12 +742,10 @@ _dbus_directory_get_next_file (DBusDirIter *iter, { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, "No memory to read directory entry"); - dbus_free (d); return FALSE; } else { - dbus_free (d); return TRUE; } } @@ -1059,11 +1090,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] = '?'; } } @@ -1133,10 +1164,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; @@ -1147,3 +1178,180 @@ fail: _dbus_string_free (&path); return FALSE; } + +/* + * replaces the term DBUS_PREFIX in configure_time_path by the + * current dbus installation directory. On unix this function is a noop + * + * @param configure_time_path + * @return real path + */ +const char * +_dbus_replace_install_prefix (const char *configure_time_path) +{ + return configure_time_path; +} + +#define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" +#define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services" + +/** + * Returns the standard directories for a session bus to look for service + * activation files + * + * On UNIX this should be the standard xdg freedesktop.org data directories: + * + * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share} + * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share} + * + * and + * + * DBUS_DATADIR + * + * @param dirs the directory list we are returning + * @returns #FALSE on OOM + */ + +dbus_bool_t +_dbus_get_standard_session_servicedirs (DBusList **dirs) +{ + const char *xdg_data_home; + const char *xdg_data_dirs; + DBusString servicedir_path; + + if (!_dbus_string_init (&servicedir_path)) + return FALSE; + + xdg_data_home = _dbus_getenv ("XDG_DATA_HOME"); + xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); + + if (xdg_data_home != NULL) + { + if (!_dbus_string_append (&servicedir_path, xdg_data_home)) + goto oom; + } + else + { + const DBusString *homedir; + DBusString local_share; + + if (!_dbus_homedir_from_current_process (&homedir)) + goto oom; + + if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir))) + goto oom; + + _dbus_string_init_const (&local_share, "/.local/share"); + if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share)) + goto oom; + } + + if (!_dbus_string_append (&servicedir_path, ":")) + goto oom; + + if (xdg_data_dirs != NULL) + { + if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) + goto oom; + + if (!_dbus_string_append (&servicedir_path, ":")) + goto oom; + } + else + { + if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) + goto oom; + } + + /* + * add configured datadir to defaults + * this may be the same as an xdg dir + * however the config parser should take + * care of duplicates + */ + if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR)) + goto oom; + + if (!_dbus_split_paths_and_append (&servicedir_path, + DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, + dirs)) + goto oom; + + _dbus_string_free (&servicedir_path); + return TRUE; + + oom: + _dbus_string_free (&servicedir_path); + return FALSE; +} + + +/** + * Returns the standard directories for a system bus to look for service + * activation files + * + * On UNIX this should be the standard xdg freedesktop.org data directories: + * + * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share} + * + * and + * + * DBUS_DATADIR + * + * On Windows there is no system bus and this function can return nothing. + * + * @param dirs the directory list we are returning + * @returns #FALSE on OOM + */ + +dbus_bool_t +_dbus_get_standard_system_servicedirs (DBusList **dirs) +{ + /* + * DBUS_DATADIR may be the same as one of the standard directories. However, + * the config parser should take care of the duplicates. + * + * Also, append /lib as counterpart of /usr/share on the root + * directory (the root directory does not know /share), in order to + * facilitate early boot system bus activation where /usr might not + * be available. + */ + static const char standard_search_path[] = + "/usr/local/share:" + "/usr/share:" + DBUS_DATADIR ":" + "/lib"; + DBusString servicedir_path; + + _dbus_string_init_const (&servicedir_path, standard_search_path); + + return _dbus_split_paths_and_append (&servicedir_path, + DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, + dirs); +} + +/** + * Append the absolute path of the system.conf file + * (there is no system bus on Windows so this can just + * return FALSE and print a warning or something) + * + * @param str the string to append to + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_append_system_config_file (DBusString *str) +{ + return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE); +} + +/** + * Append the absolute path of the session.conf file. + * + * @param str the string to append to + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_append_session_config_file (DBusString *str) +{ + return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE); +}