X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-sysdeps.c;h=de3a18cb97f9fa7c0b305ad24da007cd965b6245;hb=bb8dd7fec5389db4df9b5e8863974149e8a650dc;hp=7f779600590fd5c440b816a6a27515dd0be1c605;hpb=cf4c8dbfa84136c44a18b65168ca599baec45d3a;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 7f77960..de3a18c 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -1,4 +1,4 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-sysdeps.c Wrappers around system/libc features shared between UNIX and Windows (internal to D-Bus implementation) * * Copyright (C) 2002, 2003, 2006 Red Hat, Inc. @@ -18,38 +18,43 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +#include #include "dbus-internals.h" #include "dbus-sysdeps.h" #include "dbus-threads.h" #include "dbus-protocol.h" #include "dbus-string.h" #include "dbus-list.h" +#include "dbus-misc.h" /* NOTE: If you include any unix/windows-specific headers here, you are probably doing something * wrong and should be putting some code in dbus-sysdeps-unix.c or dbus-sysdeps-win.c. * * These are the standard ANSI C headers... */ +#if HAVE_LOCALE_H #include +#endif #include #include #include -/* This is UNIX-specific (on windows it's just in stdlib.h I believe) - * but OK since the same stuff does exist on Windows in stdlib.h - * and covered by a configure check. - */ #ifdef HAVE_ERRNO_H #include #endif -_DBUS_DEFINE_GLOBAL_LOCK (win_fds); -_DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache); -_DBUS_DEFINE_GLOBAL_LOCK (system_users); +#ifdef DBUS_WIN + #include +#elif (defined __APPLE__) +# include +# define environ (*_NSGetEnviron()) +#else +extern char **environ; +#endif /** * @defgroup DBusSysdeps Internal system-dependent API @@ -88,6 +93,8 @@ _dbus_abort (void) } /** + * @ingroup DBusMisc + * * Wrapper for setenv(). If the value is #NULL, unsets * the environment variable. * @@ -96,13 +103,16 @@ _dbus_abort (void) * we can not rely on internal implementation details of * the underlying libc library. * + * This function is not thread-safe, because altering the environment + * in Unix is not thread-safe in general. + * * @param varname name of environment variable - * @param value value of environment variable - * @returns #TRUE on success. + * @param value value of environment variable, or #NULL to unset + * @returns #TRUE on success, #FALSE if not enough memory. */ dbus_bool_t -_dbus_setenv (const char *varname, - const char *value) +dbus_setenv (const char *varname, + const char *value) { _dbus_assert (varname != NULL); @@ -174,66 +184,34 @@ _dbus_setenv (const char *varname, const char* _dbus_getenv (const char *varname) { + /* Don't respect any environment variables if the current process is + * setuid. This is the equivalent of glibc's __secure_getenv(). + */ + if (_dbus_check_setuid ()) + return NULL; return getenv (varname); } -/* - * init a pipe instance. - * - * @param pipe the pipe - * @param fd the file descriptor to init from - */ -void -_dbus_pipe_init (DBusPipe *pipe, - int fd) -{ - pipe->fd_or_handle = fd; -} - -/** - * init a pipe with stdout - * - * @param pipe the pipe - */ -void -_dbus_pipe_init_stdout (DBusPipe *pipe) -{ - _dbus_pipe_init (pipe, 1); -} - /** - * check if a pipe is valid; pipes can be set invalid, similar to - * a -1 file descriptor. + * Wrapper for clearenv(). * - * @param pipe the pipe instance - * @returns #FALSE if pipe is not valid + * @returns #TRUE on success. */ dbus_bool_t -_dbus_pipe_is_valid(DBusPipe *pipe) +_dbus_clearenv (void) { - return pipe->fd_or_handle >= 0; -} + dbus_bool_t rc = TRUE; -/** - * Check if a pipe is stdout or stderr. - * - * @param pipe the pipe instance - * @returns #TRUE if pipe is one of the standard out/err channels - */ -dbus_bool_t -_dbus_pipe_is_stdout_or_stderr (DBusPipe *pipe) -{ - return pipe->fd_or_handle == 1 || pipe->fd_or_handle == 2; -} +#ifdef HAVE_CLEARENV + if (clearenv () != 0) + rc = FALSE; +#else -/** - * Initializes a pipe to an invalid value. - * @param pipe the pipe - */ -void -_dbus_pipe_invalidate (DBusPipe *pipe) -{ - pipe->fd_or_handle = -1; + if (environ != NULL) + environ[0] = NULL; +#endif + + return rc; } /** @@ -441,45 +419,6 @@ _dbus_string_append_uint (DBusString *str, return TRUE; } -#ifdef DBUS_BUILD_TESTS -/** - * Appends a double to a DBusString. - * - * @param str the string - * @param value the floating point value - * @returns #FALSE if not enough memory or other failure. - */ -dbus_bool_t -_dbus_string_append_double (DBusString *str, - double value) -{ -#define MAX_DOUBLE_LEN 64 /* this is completely made up :-/ */ - int orig_len; - char *buf; - int i; - - orig_len = _dbus_string_get_length (str); - - if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN)) - return FALSE; - - buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN); - - snprintf (buf, MAX_LONG_LEN, "%g", value); - - i = 0; - while (*buf) - { - ++buf; - ++i; - } - - _dbus_string_shorten (str, MAX_DOUBLE_LEN - i); - - return TRUE; -} -#endif /* DBUS_BUILD_TESTS */ - /** * Parses an integer contained in a DBusString. Either return parameter * may be #NULL if you aren't interested in it. The integer is parsed @@ -506,7 +445,7 @@ _dbus_string_parse_int (const DBusString *str, _dbus_string_get_length (str) - start); end = NULL; - errno = 0; + _dbus_set_errno_to_zero (); v = strtol (p, &end, 0); if (end == NULL || end == p || errno != 0) return FALSE; @@ -545,7 +484,7 @@ _dbus_string_parse_uint (const DBusString *str, _dbus_string_get_length (str) - start); end = NULL; - errno = 0; + _dbus_set_errno_to_zero (); v = strtoul (p, &end, 0); if (end == NULL || end == p || errno != 0) return FALSE; @@ -558,213 +497,6 @@ _dbus_string_parse_uint (const DBusString *str, return TRUE; } -#ifdef DBUS_BUILD_TESTS -static dbus_bool_t -ascii_isspace (char c) -{ - return (c == ' ' || - c == '\f' || - c == '\n' || - c == '\r' || - c == '\t' || - c == '\v'); -} -#endif /* DBUS_BUILD_TESTS */ - -#ifdef DBUS_BUILD_TESTS -static dbus_bool_t -ascii_isdigit (char c) -{ - return c >= '0' && c <= '9'; -} -#endif /* DBUS_BUILD_TESTS */ - -#ifdef DBUS_BUILD_TESTS -static dbus_bool_t -ascii_isxdigit (char c) -{ - return (ascii_isdigit (c) || - (c >= 'a' && c <= 'f') || - (c >= 'A' && c <= 'F')); -} -#endif /* DBUS_BUILD_TESTS */ - -#ifdef DBUS_BUILD_TESTS -/* Calls strtod in a locale-independent fashion, by looking at - * the locale data and patching the decimal comma to a point. - * - * Relicensed from glib. - */ -static double -ascii_strtod (const char *nptr, - char **endptr) -{ - /* FIXME: The Win32 C library's strtod() doesn't handle hex. - * Presumably many Unixes don't either. - */ - - char *fail_pos; - double val; - struct lconv *locale_data; - const char *decimal_point; - int decimal_point_len; - const char *p, *decimal_point_pos; - const char *end = NULL; /* Silence gcc */ - - fail_pos = NULL; - - locale_data = localeconv (); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen (decimal_point); - - _dbus_assert (decimal_point_len != 0); - - decimal_point_pos = NULL; - if (decimal_point[0] != '.' || - decimal_point[1] != 0) - { - p = nptr; - /* Skip leading space */ - while (ascii_isspace (*p)) - p++; - - /* Skip leading optional sign */ - if (*p == '+' || *p == '-') - p++; - - if (p[0] == '0' && - (p[1] == 'x' || p[1] == 'X')) - { - p += 2; - /* HEX - find the (optional) decimal point */ - - while (ascii_isxdigit (*p)) - p++; - - if (*p == '.') - { - decimal_point_pos = p++; - - while (ascii_isxdigit (*p)) - p++; - - if (*p == 'p' || *p == 'P') - p++; - if (*p == '+' || *p == '-') - p++; - while (ascii_isdigit (*p)) - p++; - end = p; - } - } - else - { - while (ascii_isdigit (*p)) - p++; - - if (*p == '.') - { - decimal_point_pos = p++; - - while (ascii_isdigit (*p)) - p++; - - if (*p == 'e' || *p == 'E') - p++; - if (*p == '+' || *p == '-') - p++; - while (ascii_isdigit (*p)) - p++; - end = p; - } - } - /* For the other cases, we need not convert the decimal point */ - } - - /* Set errno to zero, so that we can distinguish zero results - and underflows */ - errno = 0; - - if (decimal_point_pos) - { - char *copy, *c; - - /* We need to convert the '.' to the locale specific decimal point */ - copy = dbus_malloc (end - nptr + 1 + decimal_point_len); - - c = copy; - memcpy (c, nptr, decimal_point_pos - nptr); - c += decimal_point_pos - nptr; - memcpy (c, decimal_point, decimal_point_len); - c += decimal_point_len; - memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); - c += end - (decimal_point_pos + 1); - *c = 0; - - val = strtod (copy, &fail_pos); - - if (fail_pos) - { - if (fail_pos > decimal_point_pos) - fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1); - else - fail_pos = (char *)nptr + (fail_pos - copy); - } - - dbus_free (copy); - - } - else - val = strtod (nptr, &fail_pos); - - if (endptr) - *endptr = fail_pos; - - return val; -} -#endif /* DBUS_BUILD_TESTS */ - -#ifdef DBUS_BUILD_TESTS -/** - * Parses a floating point number contained in a DBusString. Either - * return parameter may be #NULL if you aren't interested in it. The - * integer is parsed and stored in value_return. Return parameters are - * not initialized if the function returns #FALSE. - * - * @param str the string - * @param start the byte index of the start of the float - * @param value_return return location of the float value or #NULL - * @param end_return return location of the end of the float, or #NULL - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_string_parse_double (const DBusString *str, - int start, - double *value_return, - int *end_return) -{ - double v; - const char *p; - char *end; - - p = _dbus_string_get_const_data_len (str, start, - _dbus_string_get_length (str) - start); - - end = NULL; - errno = 0; - v = ascii_strtod (p, &end); - if (end == NULL || end == p || errno != 0) - return FALSE; - - if (value_return) - *value_return = v; - if (end_return) - *end_return = start + (end - p); - - return TRUE; -} -#endif /* DBUS_BUILD_TESTS */ - /** @} */ /* DBusString group */ /** @@ -783,7 +515,7 @@ _dbus_generate_pseudorandom_bytes_buffer (char *buffer, _dbus_verbose ("Falling back to pseudorandom for %d bytes\n", n_bytes); - _dbus_get_current_time (NULL, &tv_usec); + _dbus_get_real_time (NULL, &tv_usec); srand (tv_usec); i = 0; @@ -869,8 +601,8 @@ _dbus_generate_random_ascii (DBusString *str, } /** - * Converts a UNIX or Windows errno - * into a #DBusError name. + * Converts a UNIX errno, or Windows errno or WinSock error value into + * a #DBusError name. * * @todo should cover more errnos, specifically those * from open(). @@ -889,10 +621,16 @@ _dbus_error_from_errno (int error_number) #ifdef EPROTONOSUPPORT case EPROTONOSUPPORT: return DBUS_ERROR_NOT_SUPPORTED; +#elif defined(WSAEPROTONOSUPPORT) + case WSAEPROTONOSUPPORT: + return DBUS_ERROR_NOT_SUPPORTED; #endif #ifdef EAFNOSUPPORT case EAFNOSUPPORT: return DBUS_ERROR_NOT_SUPPORTED; +#elif defined(WSAEAFNOSUPPORT) + case WSAEAFNOSUPPORT: + return DBUS_ERROR_NOT_SUPPORTED; #endif #ifdef ENFILE case ENFILE: @@ -918,41 +656,33 @@ _dbus_error_from_errno (int error_number) case ENOMEM: return DBUS_ERROR_NO_MEMORY; #endif -#ifdef EINVAL - case EINVAL: - return DBUS_ERROR_FAILED; -#endif -#ifdef EBADF - case EBADF: - return DBUS_ERROR_FAILED; -#endif -#ifdef EFAULT - case EFAULT: - return DBUS_ERROR_FAILED; -#endif -#ifdef ENOTSOCK - case ENOTSOCK: - return DBUS_ERROR_FAILED; -#endif -#ifdef EISCONN - case EISCONN: - return DBUS_ERROR_FAILED; -#endif #ifdef ECONNREFUSED case ECONNREFUSED: return DBUS_ERROR_NO_SERVER; +#elif defined(WSAECONNREFUSED) + case WSAECONNREFUSED: + return DBUS_ERROR_NO_SERVER; #endif #ifdef ETIMEDOUT case ETIMEDOUT: return DBUS_ERROR_TIMEOUT; +#elif defined(WSAETIMEDOUT) + case WSAETIMEDOUT: + return DBUS_ERROR_TIMEOUT; #endif #ifdef ENETUNREACH case ENETUNREACH: return DBUS_ERROR_NO_NETWORK; +#elif defined(WSAENETUNREACH) + case WSAENETUNREACH: + return DBUS_ERROR_NO_NETWORK; #endif #ifdef EADDRINUSE case EADDRINUSE: return DBUS_ERROR_ADDRESS_IN_USE; +#elif defined(WSAEADDRINUSE) + case WSAEADDRINUSE: + return DBUS_ERROR_ADDRESS_IN_USE; #endif #ifdef EEXIST case EEXIST: @@ -967,6 +697,80 @@ _dbus_error_from_errno (int error_number) return DBUS_ERROR_FAILED; } +/** + * Converts the current system errno value into a #DBusError name. + * + * @returns an error name + */ +const char* +_dbus_error_from_system_errno (void) +{ + return _dbus_error_from_errno (errno); +} + +/** + * Assign 0 to the global errno variable + */ +void +_dbus_set_errno_to_zero (void) +{ +#ifdef DBUS_WINCE + SetLastError (0); +#else + errno = 0; +#endif +} + +/** + * See if errno is set + * @returns #TRUE if errno is not 0 + */ +dbus_bool_t +_dbus_get_is_errno_nonzero (void) +{ + return errno != 0; +} + +/** + * See if errno is ENOMEM + * @returns #TRUE if errno == ENOMEM + */ +dbus_bool_t +_dbus_get_is_errno_enomem (void) +{ + return errno == ENOMEM; +} + +/** + * See if errno is EINTR + * @returns #TRUE if errno == EINTR + */ +dbus_bool_t +_dbus_get_is_errno_eintr (void) +{ + return errno == EINTR; +} + +/** + * See if errno is EPIPE + * @returns #TRUE if errno == EPIPE + */ +dbus_bool_t +_dbus_get_is_errno_epipe (void) +{ + return errno == EPIPE; +} + +/** + * Get error message from errno + * @returns _dbus_strerror(errno) + */ +const char* +_dbus_strerror_from_errno (void) +{ + return _dbus_strerror (errno); +} + /** @} end of sysdeps */ /* tests in dbus-sysdeps-util.c */