mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 06:28:00 +02:00
2005-01-16 Havoc Pennington <hp@redhat.com>
This is about it on what can be disabled/deleted from libdbus easily, back below 150K anyhow. Deeper cuts are more work than just turning the code off as I've done here. * dbus/dbus-marshal-basic.c (_dbus_pack_int32): we don't need the signed int convenience funcs * dbus/dbus-internals.c (_dbus_verbose_real): omit when not in verbose mode * dbus/dbus-string-util.c, dbus/dbus-string.c: more breaking things out of libdbus * dbus/dbus-sysdeps.c, dbus/dbus-sysdeps-util.c: same * dbus/dbus-hash.c: purge the TWO_STRINGS crap (well, make it tests-enabled-only, though it should probably be deleted) * dbus/dbus-message-util.c: same stuff * dbus/dbus-auth-util.c: same stuff
This commit is contained in:
parent
4c1a2a760b
commit
7bf62e31a3
26 changed files with 6517 additions and 5626 deletions
24
ChangeLog
24
ChangeLog
|
|
@ -1,3 +1,27 @@
|
|||
2005-01-16 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
This is about it on what can be disabled/deleted from libdbus
|
||||
easily, back below 150K anyhow. Deeper cuts are more work than
|
||||
just turning the code off as I've done here.
|
||||
|
||||
* dbus/dbus-marshal-basic.c (_dbus_pack_int32): we don't need the
|
||||
signed int convenience funcs
|
||||
|
||||
* dbus/dbus-internals.c (_dbus_verbose_real): omit when not in
|
||||
verbose mode
|
||||
|
||||
* dbus/dbus-string-util.c, dbus/dbus-string.c: more breaking
|
||||
things out of libdbus
|
||||
|
||||
* dbus/dbus-sysdeps.c, dbus/dbus-sysdeps-util.c: same
|
||||
|
||||
* dbus/dbus-hash.c: purge the TWO_STRINGS crap (well, make it
|
||||
tests-enabled-only, though it should probably be deleted)
|
||||
|
||||
* dbus/dbus-message-util.c: same stuff
|
||||
|
||||
* dbus/dbus-auth-util.c: same stuff
|
||||
|
||||
2005-01-16 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* dbus/dbus-userdb-util.c: split out part of dbus-userdb.c
|
||||
|
|
|
|||
|
|
@ -62,15 +62,16 @@ DBUS_LIB_SOURCES= \
|
|||
dbus-marshal-validate.h \
|
||||
dbus-message.c \
|
||||
dbus-message-internal.h \
|
||||
dbus-message-private.h \
|
||||
dbus-object-tree.c \
|
||||
dbus-object-tree.h \
|
||||
dbus-pending-call.c \
|
||||
dbus-resources.c \
|
||||
dbus-resources.h \
|
||||
dbus-server.c \
|
||||
dbus-server-protected.h \
|
||||
dbus-server-debug-pipe.c \
|
||||
dbus-server-debug-pipe.h \
|
||||
dbus-server-protected.h \
|
||||
dbus-server-unix.c \
|
||||
dbus-server-unix.h \
|
||||
dbus-sha.c \
|
||||
|
|
@ -121,16 +122,18 @@ DBUS_SHARED_SOURCES= \
|
|||
### should be underscore-prefixed but don't really need
|
||||
### to be unless they move to DBUS_SHARED_SOURCES later)
|
||||
DBUS_UTIL_SOURCES= \
|
||||
dbus-auth-util.c \
|
||||
dbus-mainloop.c \
|
||||
dbus-mainloop.h \
|
||||
dbus-marshal-recursive-util.c \
|
||||
dbus-message-util.c \
|
||||
dbus-spawn.c \
|
||||
dbus-spawn.h \
|
||||
dbus-string-util.c \
|
||||
dbus-sysdeps-util.c \
|
||||
dbus-sysdeps-util.h \
|
||||
dbus-test.c \
|
||||
dbus-test.h \
|
||||
dbus-userdb-util.c \
|
||||
dbus-userdb-util.h
|
||||
dbus-userdb-util.c
|
||||
|
||||
libdbus_1_la_SOURCES= \
|
||||
$(DBUS_LIB_SOURCES) \
|
||||
|
|
|
|||
169
dbus/dbus-auth-util.c
Normal file
169
dbus/dbus-auth-util.c
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-auth-util.c Would be in dbus-auth.c, but only used for tests/bus
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004 Red Hat Inc.
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#include "dbus-internals.h"
|
||||
#include "dbus-test.h"
|
||||
#include "dbus-auth.h"
|
||||
|
||||
/**
|
||||
* @addtogroup DBusAuth
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
#include "dbus-test.h"
|
||||
#include "dbus-auth-script.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static dbus_bool_t
|
||||
process_test_subdir (const DBusString *test_base_dir,
|
||||
const char *subdir)
|
||||
{
|
||||
DBusString test_directory;
|
||||
DBusString filename;
|
||||
DBusDirIter *dir;
|
||||
dbus_bool_t retval;
|
||||
DBusError error;
|
||||
|
||||
retval = FALSE;
|
||||
dir = NULL;
|
||||
|
||||
if (!_dbus_string_init (&test_directory))
|
||||
_dbus_assert_not_reached ("didn't allocate test_directory\n");
|
||||
|
||||
_dbus_string_init_const (&filename, subdir);
|
||||
|
||||
if (!_dbus_string_copy (test_base_dir, 0,
|
||||
&test_directory, 0))
|
||||
_dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
|
||||
|
||||
if (!_dbus_concat_dir_and_file (&test_directory, &filename))
|
||||
_dbus_assert_not_reached ("couldn't allocate full path");
|
||||
|
||||
_dbus_string_free (&filename);
|
||||
if (!_dbus_string_init (&filename))
|
||||
_dbus_assert_not_reached ("didn't allocate filename string\n");
|
||||
|
||||
dbus_error_init (&error);
|
||||
dir = _dbus_directory_open (&test_directory, &error);
|
||||
if (dir == NULL)
|
||||
{
|
||||
_dbus_warn ("Could not open %s: %s\n",
|
||||
_dbus_string_get_const_data (&test_directory),
|
||||
error.message);
|
||||
dbus_error_free (&error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
printf ("Testing %s:\n", subdir);
|
||||
|
||||
next:
|
||||
while (_dbus_directory_get_next_file (dir, &filename, &error))
|
||||
{
|
||||
DBusString full_path;
|
||||
|
||||
if (!_dbus_string_init (&full_path))
|
||||
_dbus_assert_not_reached ("couldn't init string");
|
||||
|
||||
if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
|
||||
_dbus_assert_not_reached ("couldn't copy dir to full_path");
|
||||
|
||||
if (!_dbus_concat_dir_and_file (&full_path, &filename))
|
||||
_dbus_assert_not_reached ("couldn't concat file to dir");
|
||||
|
||||
if (!_dbus_string_ends_with_c_str (&filename, ".auth-script"))
|
||||
{
|
||||
_dbus_verbose ("Skipping non-.auth-script file %s\n",
|
||||
_dbus_string_get_const_data (&filename));
|
||||
_dbus_string_free (&full_path);
|
||||
goto next;
|
||||
}
|
||||
|
||||
printf (" %s\n", _dbus_string_get_const_data (&filename));
|
||||
|
||||
if (!_dbus_auth_script_run (&full_path))
|
||||
{
|
||||
_dbus_string_free (&full_path);
|
||||
goto failed;
|
||||
}
|
||||
else
|
||||
_dbus_string_free (&full_path);
|
||||
}
|
||||
|
||||
if (dbus_error_is_set (&error))
|
||||
{
|
||||
_dbus_warn ("Could not get next file in %s: %s\n",
|
||||
_dbus_string_get_const_data (&test_directory), error.message);
|
||||
dbus_error_free (&error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
failed:
|
||||
|
||||
if (dir)
|
||||
_dbus_directory_close (dir);
|
||||
_dbus_string_free (&test_directory);
|
||||
_dbus_string_free (&filename);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
process_test_dirs (const char *test_data_dir)
|
||||
{
|
||||
DBusString test_directory;
|
||||
dbus_bool_t retval;
|
||||
|
||||
retval = FALSE;
|
||||
|
||||
_dbus_string_init_const (&test_directory, test_data_dir);
|
||||
|
||||
if (!process_test_subdir (&test_directory, "auth"))
|
||||
goto failed;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
failed:
|
||||
|
||||
_dbus_string_free (&test_directory);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
_dbus_auth_test (const char *test_data_dir)
|
||||
{
|
||||
|
||||
if (test_data_dir == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (!process_test_dirs (test_data_dir))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
137
dbus/dbus-auth.c
137
dbus/dbus-auth.c
|
|
@ -2392,139 +2392,4 @@ _dbus_auth_set_context (DBusAuth *auth,
|
|||
|
||||
/** @} */
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
#include "dbus-test.h"
|
||||
#include "dbus-auth-script.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static dbus_bool_t
|
||||
process_test_subdir (const DBusString *test_base_dir,
|
||||
const char *subdir)
|
||||
{
|
||||
DBusString test_directory;
|
||||
DBusString filename;
|
||||
DBusDirIter *dir;
|
||||
dbus_bool_t retval;
|
||||
DBusError error;
|
||||
|
||||
retval = FALSE;
|
||||
dir = NULL;
|
||||
|
||||
if (!_dbus_string_init (&test_directory))
|
||||
_dbus_assert_not_reached ("didn't allocate test_directory\n");
|
||||
|
||||
_dbus_string_init_const (&filename, subdir);
|
||||
|
||||
if (!_dbus_string_copy (test_base_dir, 0,
|
||||
&test_directory, 0))
|
||||
_dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
|
||||
|
||||
if (!_dbus_concat_dir_and_file (&test_directory, &filename))
|
||||
_dbus_assert_not_reached ("couldn't allocate full path");
|
||||
|
||||
_dbus_string_free (&filename);
|
||||
if (!_dbus_string_init (&filename))
|
||||
_dbus_assert_not_reached ("didn't allocate filename string\n");
|
||||
|
||||
dbus_error_init (&error);
|
||||
dir = _dbus_directory_open (&test_directory, &error);
|
||||
if (dir == NULL)
|
||||
{
|
||||
_dbus_warn ("Could not open %s: %s\n",
|
||||
_dbus_string_get_const_data (&test_directory),
|
||||
error.message);
|
||||
dbus_error_free (&error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
printf ("Testing %s:\n", subdir);
|
||||
|
||||
next:
|
||||
while (_dbus_directory_get_next_file (dir, &filename, &error))
|
||||
{
|
||||
DBusString full_path;
|
||||
|
||||
if (!_dbus_string_init (&full_path))
|
||||
_dbus_assert_not_reached ("couldn't init string");
|
||||
|
||||
if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
|
||||
_dbus_assert_not_reached ("couldn't copy dir to full_path");
|
||||
|
||||
if (!_dbus_concat_dir_and_file (&full_path, &filename))
|
||||
_dbus_assert_not_reached ("couldn't concat file to dir");
|
||||
|
||||
if (!_dbus_string_ends_with_c_str (&filename, ".auth-script"))
|
||||
{
|
||||
_dbus_verbose ("Skipping non-.auth-script file %s\n",
|
||||
_dbus_string_get_const_data (&filename));
|
||||
_dbus_string_free (&full_path);
|
||||
goto next;
|
||||
}
|
||||
|
||||
printf (" %s\n", _dbus_string_get_const_data (&filename));
|
||||
|
||||
if (!_dbus_auth_script_run (&full_path))
|
||||
{
|
||||
_dbus_string_free (&full_path);
|
||||
goto failed;
|
||||
}
|
||||
else
|
||||
_dbus_string_free (&full_path);
|
||||
}
|
||||
|
||||
if (dbus_error_is_set (&error))
|
||||
{
|
||||
_dbus_warn ("Could not get next file in %s: %s\n",
|
||||
_dbus_string_get_const_data (&test_directory), error.message);
|
||||
dbus_error_free (&error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
failed:
|
||||
|
||||
if (dir)
|
||||
_dbus_directory_close (dir);
|
||||
_dbus_string_free (&test_directory);
|
||||
_dbus_string_free (&filename);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
process_test_dirs (const char *test_data_dir)
|
||||
{
|
||||
DBusString test_directory;
|
||||
dbus_bool_t retval;
|
||||
|
||||
retval = FALSE;
|
||||
|
||||
_dbus_string_init_const (&test_directory, test_data_dir);
|
||||
|
||||
if (!process_test_subdir (&test_directory, "auth"))
|
||||
goto failed;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
failed:
|
||||
|
||||
_dbus_string_free (&test_directory);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
_dbus_auth_test (const char *test_data_dir)
|
||||
{
|
||||
|
||||
if (test_data_dir == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (!process_test_dirs (test_data_dir))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
/* tests in dbus-auth-util.c */
|
||||
|
|
|
|||
|
|
@ -231,13 +231,17 @@ static DBusHashEntry* find_string_function (DBusHashTable *table,
|
|||
dbus_bool_t create_if_not_found,
|
||||
DBusHashEntry ***bucket,
|
||||
DBusPreallocatedHash *preallocated);
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
static DBusHashEntry* find_two_strings_function (DBusHashTable *table,
|
||||
void *key,
|
||||
dbus_bool_t create_if_not_found,
|
||||
DBusHashEntry ***bucket,
|
||||
DBusPreallocatedHash *preallocated);
|
||||
#endif
|
||||
static unsigned int string_hash (const char *str);
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
static unsigned int two_strings_hash (const char *str);
|
||||
#endif
|
||||
static void rebuild_table (DBusHashTable *table);
|
||||
static DBusHashEntry* alloc_entry (DBusHashTable *table);
|
||||
static void remove_entry (DBusHashTable *table,
|
||||
|
|
@ -330,7 +334,9 @@ _dbus_hash_table_new (DBusHashType type,
|
|||
table->find_function = find_string_function;
|
||||
break;
|
||||
case DBUS_HASH_TWO_STRINGS:
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
table->find_function = find_two_strings_function;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
_dbus_assert_not_reached ("Unknown hash table type");
|
||||
|
|
@ -696,6 +702,7 @@ _dbus_hash_iter_get_string_key (DBusHashIter *iter)
|
|||
return real->entry->key;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Gets the key for the current entry.
|
||||
* Only works for hash tables of type #DBUS_HASH_TWO_STRINGS
|
||||
|
|
@ -713,6 +720,7 @@ _dbus_hash_iter_get_two_strings_key (DBusHashIter *iter)
|
|||
|
||||
return real->entry->key;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* A low-level but efficient interface for manipulating the hash
|
||||
|
|
@ -849,6 +857,7 @@ string_hash (const char *str)
|
|||
return h;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/* This hashes a memory block with two nul-terminated strings
|
||||
* in it, used in dbus-object-registry.c at the moment.
|
||||
*/
|
||||
|
|
@ -867,6 +876,7 @@ two_strings_hash (const char *str)
|
|||
|
||||
return h;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/** Key comparison function */
|
||||
typedef int (* KeyCompareFunc) (const void *key_a, const void *key_b);
|
||||
|
|
@ -928,6 +938,7 @@ find_string_function (DBusHashTable *table,
|
|||
preallocated);
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
static int
|
||||
two_strings_cmp (const char *a,
|
||||
const char *b)
|
||||
|
|
@ -945,7 +956,9 @@ two_strings_cmp (const char *a,
|
|||
|
||||
return strcmp (a + len_a + 1, b + len_b + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
static DBusHashEntry*
|
||||
find_two_strings_function (DBusHashTable *table,
|
||||
void *key,
|
||||
|
|
@ -961,6 +974,7 @@ find_two_strings_function (DBusHashTable *table,
|
|||
(KeyCompareFunc) two_strings_cmp, create_if_not_found, bucket,
|
||||
preallocated);
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
static DBusHashEntry*
|
||||
find_direct_function (DBusHashTable *table,
|
||||
|
|
@ -1077,7 +1091,12 @@ rebuild_table (DBusHashTable *table)
|
|||
idx = string_hash (entry->key) & table->mask;
|
||||
break;
|
||||
case DBUS_HASH_TWO_STRINGS:
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
idx = two_strings_hash (entry->key) & table->mask;
|
||||
#else
|
||||
idx = 0;
|
||||
_dbus_assert_not_reached ("two-strings is not enabled");
|
||||
#endif
|
||||
break;
|
||||
case DBUS_HASH_INT:
|
||||
case DBUS_HASH_ULONG:
|
||||
|
|
@ -1127,6 +1146,7 @@ _dbus_hash_table_lookup_string (DBusHashTable *table,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Looks up the value for a given string in a hash table
|
||||
* of type #DBUS_HASH_TWO_STRINGS. Returns %NULL if the value
|
||||
|
|
@ -1151,6 +1171,7 @@ _dbus_hash_table_lookup_two_strings (DBusHashTable *table,
|
|||
else
|
||||
return NULL;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* Looks up the value for a given integer in a hash table
|
||||
|
|
@ -1258,6 +1279,7 @@ _dbus_hash_table_remove_string (DBusHashTable *table,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Removes the hash entry for the given key. If no hash entry
|
||||
* for the key exists, does nothing.
|
||||
|
|
@ -1285,6 +1307,7 @@ _dbus_hash_table_remove_two_strings (DBusHashTable *table,
|
|||
else
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* Removes the hash entry for the given key. If no hash entry
|
||||
|
|
@ -1407,6 +1430,7 @@ _dbus_hash_table_insert_string (DBusHashTable *table,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Creates a hash entry with the given key and value.
|
||||
* The key and value are not copied; they are stored
|
||||
|
|
@ -1447,6 +1471,7 @@ _dbus_hash_table_insert_two_strings (DBusHashTable *table,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* Creates a hash entry with the given key and value.
|
||||
|
|
|
|||
|
|
@ -174,6 +174,8 @@ _dbus_warn (const char *format,
|
|||
va_end (args);
|
||||
}
|
||||
|
||||
#ifdef DBUS_ENABLE_VERBOSE_MODE
|
||||
|
||||
static dbus_bool_t verbose_initted = FALSE;
|
||||
|
||||
/**
|
||||
|
|
@ -238,6 +240,8 @@ _dbus_verbose_reset_real (void)
|
|||
verbose_initted = FALSE;
|
||||
}
|
||||
|
||||
#endif /* DBUS_ENABLE_VERBOSE_MODE */
|
||||
|
||||
/**
|
||||
* Duplicates a string. Result must be freed with
|
||||
* dbus_free(). Returns #NULL if memory allocation fails.
|
||||
|
|
@ -354,6 +358,7 @@ _dbus_string_array_contains (const char **array,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Returns a string describing the given name.
|
||||
*
|
||||
|
|
@ -387,6 +392,7 @@ _dbus_header_field_to_string (int header_field)
|
|||
return "unknown";
|
||||
}
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
#ifndef DBUS_DISABLE_CHECKS
|
||||
/** String used in _dbus_return_if_fail macro */
|
||||
|
|
|
|||
|
|
@ -39,9 +39,6 @@ DBUS_BEGIN_DECLS
|
|||
|
||||
void _dbus_warn (const char *format,
|
||||
...) _DBUS_GNUC_PRINTF (1, 2);
|
||||
void _dbus_verbose_real (const char *format,
|
||||
...) _DBUS_GNUC_PRINTF (1, 2);
|
||||
void _dbus_verbose_reset_real (void);
|
||||
|
||||
#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
||||
#define _DBUS_FUNCTION_NAME __func__
|
||||
|
|
@ -79,6 +76,11 @@ void _dbus_verbose_reset_real (void);
|
|||
#endif
|
||||
|
||||
#ifdef DBUS_ENABLE_VERBOSE_MODE
|
||||
|
||||
void _dbus_verbose_real (const char *format,
|
||||
...) _DBUS_GNUC_PRINTF (1, 2);
|
||||
void _dbus_verbose_reset_real (void);
|
||||
|
||||
# define _dbus_verbose _dbus_verbose_real
|
||||
# define _dbus_verbose_reset _dbus_verbose_reset_real
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ link_before (DBusList **list,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
static void
|
||||
link_after (DBusList **list,
|
||||
DBusList *after_this_link,
|
||||
|
|
@ -145,6 +146,7 @@ link_after (DBusList **list,
|
|||
link->next->prev = link;
|
||||
}
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
@ -313,6 +315,7 @@ _dbus_list_prepend_link (DBusList **list,
|
|||
link_before (list, *list, link);
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Inserts data into the list before the given existing link.
|
||||
*
|
||||
|
|
@ -341,7 +344,9 @@ _dbus_list_insert_before (DBusList **list,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Inserts data into the list after the given existing link.
|
||||
*
|
||||
|
|
@ -370,6 +375,7 @@ _dbus_list_insert_after (DBusList **list,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* Inserts a link into the list before the given existing link.
|
||||
|
|
@ -389,6 +395,7 @@ _dbus_list_insert_before_link (DBusList **list,
|
|||
link_before (list, before_this_link, link);
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Inserts a link into the list after the given existing link.
|
||||
*
|
||||
|
|
@ -406,6 +413,7 @@ _dbus_list_insert_after_link (DBusList **list,
|
|||
else
|
||||
link_after (list, after_this_link, link);
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* Removes a value from the list. Only removes the
|
||||
|
|
@ -690,6 +698,7 @@ _dbus_list_pop_last (DBusList **list)
|
|||
return data;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Removes the last link in the list and returns it. This is a
|
||||
* constant-time operation.
|
||||
|
|
@ -710,6 +719,7 @@ _dbus_list_pop_last_link (DBusList **list)
|
|||
|
||||
return link;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* Copies a list. This is a linear-time operation. If there isn't
|
||||
|
|
|
|||
|
|
@ -88,21 +88,6 @@ _dbus_pack_uint32 (dbus_uint32_t value,
|
|||
pack_4_octets (value, byte_order, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a 32 bit signed integer into a data pointer.
|
||||
*
|
||||
* @param value the value
|
||||
* @param byte_order the byte order to use
|
||||
* @param data the data pointer
|
||||
*/
|
||||
void
|
||||
_dbus_pack_int32 (dbus_int32_t value,
|
||||
int byte_order,
|
||||
unsigned char *data)
|
||||
{
|
||||
pack_4_octets ((dbus_uint32_t) value, byte_order, data);
|
||||
}
|
||||
|
||||
#ifndef DBUS_HAVE_INT64
|
||||
/* from ORBit */
|
||||
static void
|
||||
|
|
@ -183,20 +168,6 @@ _dbus_unpack_uint32 (int byte_order,
|
|||
}
|
||||
#endif /* _dbus_unpack_uint32 */
|
||||
|
||||
/**
|
||||
* Unpacks a 32 bit signed integer from a data pointer
|
||||
*
|
||||
* @param byte_order The byte order to use
|
||||
* @param data the data pointer
|
||||
* @returns the integer
|
||||
*/
|
||||
dbus_int32_t
|
||||
_dbus_unpack_int32 (int byte_order,
|
||||
const unsigned char *data)
|
||||
{
|
||||
return (dbus_int32_t) _dbus_unpack_uint32 (byte_order, data);
|
||||
}
|
||||
|
||||
static void
|
||||
set_4_octets (DBusString *str,
|
||||
int offset,
|
||||
|
|
|
|||
|
|
@ -152,11 +152,6 @@ typedef union
|
|||
DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(data)))
|
||||
#endif
|
||||
|
||||
void _dbus_pack_int32 (dbus_int32_t value,
|
||||
int byte_order,
|
||||
unsigned char *data);
|
||||
dbus_int32_t _dbus_unpack_int32 (int byte_order,
|
||||
const unsigned char *data);
|
||||
void _dbus_pack_uint32 (dbus_uint32_t value,
|
||||
int byte_order,
|
||||
unsigned char *data);
|
||||
|
|
|
|||
2963
dbus/dbus-marshal-recursive-util.c
Normal file
2963
dbus/dbus-marshal-recursive-util.c
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -335,6 +335,115 @@ append_string_field (DBusString *dest,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Parses a basic type defined by type contained in a DBusString. The
|
||||
* end_return parameter may be #NULL if you aren't interested in it. The
|
||||
* type is parsed and stored in value_return. Return parameters are not
|
||||
* initialized if the function returns #FALSE.
|
||||
*
|
||||
* @param str the string
|
||||
* @param type the type of the basic type
|
||||
* @param start the byte index of the start of the type
|
||||
* @param value_return return location of the value or #NULL
|
||||
* @param end_return return location of the end of the type, or #NULL
|
||||
* @returns #TRUE on success
|
||||
*/
|
||||
static dbus_bool_t
|
||||
_dbus_string_parse_basic_type (const DBusString *str,
|
||||
char type,
|
||||
int start,
|
||||
void *value,
|
||||
int *end_return)
|
||||
{
|
||||
int end = start;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
{
|
||||
int len = _dbus_string_get_length (str) - start;
|
||||
if (len >= 5 && _dbus_string_find_to (str, start, start + 5, "false", NULL))
|
||||
{
|
||||
end += 5;
|
||||
*(unsigned char *) value = TRUE;
|
||||
}
|
||||
else if (len >= 4 && _dbus_string_find_to (str, start, start + 4, "true", NULL))
|
||||
{
|
||||
end += 4;
|
||||
*(unsigned char *) value = FALSE;
|
||||
}
|
||||
else
|
||||
_dbus_warn ("could not parse BOOLEAN\n");
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_BYTE:
|
||||
{
|
||||
long val = 0;
|
||||
|
||||
if (_dbus_string_get_byte (str, start) == '\'' &&
|
||||
_dbus_string_get_length (str) >= start + 4 &&
|
||||
_dbus_string_get_byte (str, start + 1) == '\\' &&
|
||||
_dbus_string_get_byte (str, start + 2) == '\'' &&
|
||||
_dbus_string_get_byte (str, start + 3) == '\'')
|
||||
{
|
||||
val = '\'';
|
||||
end += 4;
|
||||
}
|
||||
else if (_dbus_string_get_byte (str, start) == '\'' &&
|
||||
_dbus_string_get_length (str) >= start + 3 &&
|
||||
_dbus_string_get_byte (str, start + 2) == '\'')
|
||||
{
|
||||
val = _dbus_string_get_byte (str, start + 1);
|
||||
end += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_dbus_string_parse_int (str, start, &val, &end))
|
||||
_dbus_warn ("Failed to parse integer for BYTE\n");
|
||||
}
|
||||
|
||||
if (val > 255)
|
||||
_dbus_warn ("A byte must be in range 0-255 not %ld\n", val);
|
||||
|
||||
*(unsigned char *) value = val;
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_INT32:
|
||||
{
|
||||
long val;
|
||||
if (_dbus_string_parse_int (str, start, &val, &end))
|
||||
*(dbus_int32_t *)value = val;
|
||||
break;
|
||||
}
|
||||
case DBUS_TYPE_UINT32:
|
||||
{
|
||||
unsigned long val;
|
||||
if (_dbus_string_parse_uint (str, start, &val, &end))
|
||||
*(dbus_uint32_t *)value = val;
|
||||
break;
|
||||
}
|
||||
#ifdef DBUS_HAVE_INT64
|
||||
case DBUS_TYPE_INT64:
|
||||
case DBUS_TYPE_UINT64:
|
||||
/* use stroll oull */
|
||||
_dbus_assert_not_reached ("string -> [u]int64 not supported yet");
|
||||
break;
|
||||
#endif /* DBUS_HAVE_INT64 */
|
||||
case DBUS_TYPE_DOUBLE:
|
||||
_dbus_string_parse_double (str, start, value, &end);
|
||||
break;
|
||||
default:
|
||||
_dbus_assert_not_reached ("not a basic type");
|
||||
break;
|
||||
}
|
||||
if (end_return)
|
||||
*end_return = end;
|
||||
|
||||
return end != start;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
static dbus_bool_t
|
||||
parse_basic_type (DBusString *src, char type,
|
||||
DBusString *dest, dbus_bool_t *unalign,
|
||||
|
|
|
|||
|
|
@ -71,4 +71,4 @@ long _dbus_message_loader_get_max_message_size (DBusMessageLoader
|
|||
|
||||
DBUS_END_DECLS
|
||||
|
||||
#endif /* DBUS_MESSAGE_H */
|
||||
#endif /* DBUS_MESSAGE_INTERNAL_H */
|
||||
|
|
|
|||
119
dbus/dbus-message-private.h
Normal file
119
dbus/dbus-message-private.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-message-private.h header shared between dbus-message.c and dbus-message-util.c
|
||||
*
|
||||
* Copyright (C) 2005 Red Hat Inc.
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef DBUS_MESSAGE_PRIVATE_H
|
||||
#define DBUS_MESSAGE_PRIVATE_H
|
||||
|
||||
#include <dbus/dbus-message.h>
|
||||
#include <dbus/dbus-message-internal.h>
|
||||
#include <dbus/dbus-string.h>
|
||||
#include <dbus/dbus-dataslot.h>
|
||||
#include <dbus/dbus-marshal-header.h>
|
||||
|
||||
DBUS_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* @addtogroup DBusMessageInternals
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef DBusMessageLoader
|
||||
*
|
||||
* The DBusMessageLoader object encapsulates the process of converting
|
||||
* a byte stream into a series of DBusMessage. It buffers the incoming
|
||||
* bytes as efficiently as possible, and generates a queue of
|
||||
* messages. DBusMessageLoader is typically used as part of a
|
||||
* DBusTransport implementation. The DBusTransport then hands off
|
||||
* the loaded messages to a DBusConnection, making the messages
|
||||
* visible to the application.
|
||||
*
|
||||
* @todo write tests for break-loader that a) randomly delete header
|
||||
* fields and b) set string fields to zero-length and other funky
|
||||
* values.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation details of DBusMessageLoader.
|
||||
* All members are private.
|
||||
*/
|
||||
struct DBusMessageLoader
|
||||
{
|
||||
int refcount; /**< Reference count. */
|
||||
|
||||
DBusString data; /**< Buffered data */
|
||||
|
||||
DBusList *messages; /**< Complete messages. */
|
||||
|
||||
long max_message_size; /**< Maximum size of a message */
|
||||
|
||||
unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */
|
||||
|
||||
unsigned int corrupted : 1; /**< We got broken data, and are no longer working */
|
||||
};
|
||||
|
||||
|
||||
/** How many bits are in the changed_stamp used to validate iterators */
|
||||
#define CHANGED_STAMP_BITS 21
|
||||
|
||||
/**
|
||||
* @brief Internals of DBusMessage
|
||||
*
|
||||
* Object representing a message received from or to be sent to
|
||||
* another application. This is an opaque object, all members
|
||||
* are private.
|
||||
*/
|
||||
struct DBusMessage
|
||||
{
|
||||
DBusAtomic refcount; /**< Reference count */
|
||||
|
||||
DBusHeader header; /**< Header network data and associated cache */
|
||||
|
||||
DBusString body; /**< Body network data. */
|
||||
|
||||
char byte_order; /**< Message byte order. */
|
||||
|
||||
unsigned int locked : 1; /**< Message being sent, no modifications allowed. */
|
||||
|
||||
DBusList *size_counters; /**< 0-N DBusCounter used to track message size. */
|
||||
long size_counter_delta; /**< Size we incremented the size counters by. */
|
||||
|
||||
dbus_uint32_t changed_stamp : CHANGED_STAMP_BITS; /**< Incremented when iterators are invalidated. */
|
||||
|
||||
DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
|
||||
|
||||
#ifndef DBUS_DISABLE_CHECKS
|
||||
int generation; /**< _dbus_current_generation when message was created */
|
||||
#endif
|
||||
};
|
||||
|
||||
dbus_bool_t _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
|
||||
DBusError *error,
|
||||
int first_arg_type,
|
||||
va_list var_args);
|
||||
|
||||
/** @} */
|
||||
|
||||
DBUS_END_DECLS
|
||||
|
||||
#endif /* DBUS_MESSAGE_H */
|
||||
1309
dbus/dbus-message-util.c
Normal file
1309
dbus/dbus-message-util.c
Normal file
File diff suppressed because it is too large
Load diff
1382
dbus/dbus-message.c
1382
dbus/dbus-message.c
File diff suppressed because it is too large
Load diff
|
|
@ -53,6 +53,62 @@ typedef struct
|
|||
unsigned int align_offset : 3; /**< str - align_offset is the actual malloc block */
|
||||
} DBusRealString;
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup DBusStringInternals DBusString implementation details
|
||||
* @ingroup DBusInternals
|
||||
* @brief DBusString implementation details
|
||||
*
|
||||
* The guts of DBusString.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the maximum max length (and thus also the maximum length)
|
||||
* of a DBusString
|
||||
*/
|
||||
#define _DBUS_STRING_MAX_MAX_LENGTH (_DBUS_INT_MAX - _DBUS_STRING_ALLOCATION_PADDING)
|
||||
|
||||
/**
|
||||
* Checks a bunch of assertions about a string object
|
||||
*
|
||||
* @param real the DBusRealString
|
||||
*/
|
||||
#define DBUS_GENERIC_STRING_PREAMBLE(real) _dbus_assert ((real) != NULL); _dbus_assert (!(real)->invalid); _dbus_assert ((real)->len >= 0); _dbus_assert ((real)->allocated >= 0); _dbus_assert ((real)->max_length >= 0); _dbus_assert ((real)->len <= ((real)->allocated - _DBUS_STRING_ALLOCATION_PADDING)); _dbus_assert ((real)->len <= (real)->max_length)
|
||||
|
||||
/**
|
||||
* Checks assertions about a string object that needs to be
|
||||
* modifiable - may not be locked or const. Also declares
|
||||
* the "real" variable pointing to DBusRealString.
|
||||
* @param str the string
|
||||
*/
|
||||
#define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
|
||||
DBUS_GENERIC_STRING_PREAMBLE (real); \
|
||||
_dbus_assert (!(real)->constant); \
|
||||
_dbus_assert (!(real)->locked)
|
||||
|
||||
/**
|
||||
* Checks assertions about a string object that may be locked but
|
||||
* can't be const. i.e. a string object that we can free. Also
|
||||
* declares the "real" variable pointing to DBusRealString.
|
||||
*
|
||||
* @param str the string
|
||||
*/
|
||||
#define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
|
||||
DBUS_GENERIC_STRING_PREAMBLE (real); \
|
||||
_dbus_assert (!(real)->constant)
|
||||
|
||||
/**
|
||||
* Checks assertions about a string that may be const or locked. Also
|
||||
* declares the "real" variable pointing to DBusRealString.
|
||||
* @param str the string.
|
||||
*/
|
||||
#define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
|
||||
DBUS_GENERIC_STRING_PREAMBLE (real)
|
||||
|
||||
/** @} */
|
||||
|
||||
DBUS_END_DECLS
|
||||
|
||||
#endif /* DBUS_STRING_PRIVATE_H */
|
||||
|
|
|
|||
727
dbus/dbus-string-util.c
Normal file
727
dbus/dbus-string-util.c
Normal file
|
|
@ -0,0 +1,727 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-string-util.c Would be in dbus-string.c, but not used in libdbus
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dbus-internals.h"
|
||||
#include "dbus-string.h"
|
||||
#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
|
||||
#include "dbus-string-private.h"
|
||||
|
||||
/**
|
||||
* @addtogroup DBusString
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copies the contents of a DBusString into a different
|
||||
* buffer. The resulting buffer will be nul-terminated.
|
||||
*
|
||||
* @param str a string
|
||||
* @param buffer a C buffer to copy data to
|
||||
* @param avail_len maximum length of C buffer
|
||||
*/
|
||||
void
|
||||
_dbus_string_copy_to_buffer (const DBusString *str,
|
||||
char *buffer,
|
||||
int avail_len)
|
||||
{
|
||||
int copy_len;
|
||||
DBUS_CONST_STRING_PREAMBLE (str);
|
||||
|
||||
_dbus_assert (avail_len >= 0);
|
||||
|
||||
copy_len = MIN (avail_len, real->len+1);
|
||||
memcpy (buffer, real->str, copy_len);
|
||||
if (avail_len > 0 && avail_len == copy_len)
|
||||
buffer[avail_len-1] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a string ends with the given suffix
|
||||
*
|
||||
* @todo memcmp might make this faster.
|
||||
*
|
||||
* @param a the string
|
||||
* @param c_str the C-style string
|
||||
* @returns #TRUE if the string ends with the suffix
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_string_ends_with_c_str (const DBusString *a,
|
||||
const char *c_str)
|
||||
{
|
||||
const unsigned char *ap;
|
||||
const unsigned char *bp;
|
||||
const unsigned char *a_end;
|
||||
unsigned long c_str_len;
|
||||
const DBusRealString *real_a = (const DBusRealString*) a;
|
||||
DBUS_GENERIC_STRING_PREAMBLE (real_a);
|
||||
_dbus_assert (c_str != NULL);
|
||||
|
||||
c_str_len = strlen (c_str);
|
||||
if (((unsigned long)real_a->len) < c_str_len)
|
||||
return FALSE;
|
||||
|
||||
ap = real_a->str + (real_a->len - c_str_len);
|
||||
bp = (const unsigned char*) c_str;
|
||||
a_end = real_a->str + real_a->len;
|
||||
while (ap != a_end)
|
||||
{
|
||||
if (*ap != *bp)
|
||||
return FALSE;
|
||||
|
||||
++ap;
|
||||
++bp;
|
||||
}
|
||||
|
||||
_dbus_assert (*ap == '\0');
|
||||
_dbus_assert (*bp == '\0');
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the given byte scanning backward from the given start.
|
||||
* Sets *found to -1 if the byte is not found.
|
||||
*
|
||||
* @param str the string
|
||||
* @param start the place to start scanning (will not find the byte at this point)
|
||||
* @param byte the byte to find
|
||||
* @param found return location for where it was found
|
||||
* @returns #TRUE if found
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_string_find_byte_backward (const DBusString *str,
|
||||
int start,
|
||||
unsigned char byte,
|
||||
int *found)
|
||||
{
|
||||
int i;
|
||||
DBUS_CONST_STRING_PREAMBLE (str);
|
||||
_dbus_assert (start <= real->len);
|
||||
_dbus_assert (start >= 0);
|
||||
_dbus_assert (found != NULL);
|
||||
|
||||
i = start - 1;
|
||||
while (i >= 0)
|
||||
{
|
||||
if (real->str[i] == byte)
|
||||
break;
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
if (found)
|
||||
*found = i;
|
||||
|
||||
return i >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips whitespace from start, storing the first non-whitespace in *end.
|
||||
* (whitespace is space, tab, newline, CR).
|
||||
*
|
||||
* @param str the string
|
||||
* @param start where to start
|
||||
* @param end where to store the first non-whitespace byte index
|
||||
*/
|
||||
void
|
||||
_dbus_string_skip_white (const DBusString *str,
|
||||
int start,
|
||||
int *end)
|
||||
{
|
||||
int i;
|
||||
DBUS_CONST_STRING_PREAMBLE (str);
|
||||
_dbus_assert (start <= real->len);
|
||||
_dbus_assert (start >= 0);
|
||||
|
||||
i = start;
|
||||
while (i < real->len)
|
||||
{
|
||||
if (!(real->str[i] == ' ' ||
|
||||
real->str[i] == '\n' ||
|
||||
real->str[i] == '\r' ||
|
||||
real->str[i] == '\t'))
|
||||
break;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
_dbus_assert (i == real->len || !(real->str[i] == ' ' ||
|
||||
real->str[i] == '\t'));
|
||||
|
||||
if (end)
|
||||
*end = i;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
#include "dbus-test.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void
|
||||
test_max_len (DBusString *str,
|
||||
int max_len)
|
||||
{
|
||||
if (max_len > 0)
|
||||
{
|
||||
if (!_dbus_string_set_length (str, max_len - 1))
|
||||
_dbus_assert_not_reached ("setting len to one less than max should have worked");
|
||||
}
|
||||
|
||||
if (!_dbus_string_set_length (str, max_len))
|
||||
_dbus_assert_not_reached ("setting len to max len should have worked");
|
||||
|
||||
if (_dbus_string_set_length (str, max_len + 1))
|
||||
_dbus_assert_not_reached ("setting len to one more than max len should not have worked");
|
||||
|
||||
if (!_dbus_string_set_length (str, 0))
|
||||
_dbus_assert_not_reached ("setting len to zero should have worked");
|
||||
}
|
||||
|
||||
static void
|
||||
test_hex_roundtrip (const unsigned char *data,
|
||||
int len)
|
||||
{
|
||||
DBusString orig;
|
||||
DBusString encoded;
|
||||
DBusString decoded;
|
||||
int end;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (data);
|
||||
|
||||
if (!_dbus_string_init (&orig))
|
||||
_dbus_assert_not_reached ("could not init string");
|
||||
|
||||
if (!_dbus_string_init (&encoded))
|
||||
_dbus_assert_not_reached ("could not init string");
|
||||
|
||||
if (!_dbus_string_init (&decoded))
|
||||
_dbus_assert_not_reached ("could not init string");
|
||||
|
||||
if (!_dbus_string_append_len (&orig, data, len))
|
||||
_dbus_assert_not_reached ("couldn't append orig data");
|
||||
|
||||
if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
|
||||
_dbus_assert_not_reached ("could not encode");
|
||||
|
||||
if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
|
||||
_dbus_assert_not_reached ("could not decode");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&encoded) == end);
|
||||
|
||||
if (!_dbus_string_equal (&orig, &decoded))
|
||||
{
|
||||
const char *s;
|
||||
|
||||
printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
|
||||
_dbus_string_get_length (&orig),
|
||||
_dbus_string_get_length (&encoded),
|
||||
_dbus_string_get_length (&decoded));
|
||||
printf ("Original: %s\n", data);
|
||||
s = _dbus_string_get_const_data (&decoded);
|
||||
printf ("Decoded: %s\n", s);
|
||||
_dbus_assert_not_reached ("original string not the same as string decoded from hex");
|
||||
}
|
||||
|
||||
_dbus_string_free (&orig);
|
||||
_dbus_string_free (&encoded);
|
||||
_dbus_string_free (&decoded);
|
||||
}
|
||||
|
||||
typedef void (* TestRoundtripFunc) (const unsigned char *data,
|
||||
int len);
|
||||
static void
|
||||
test_roundtrips (TestRoundtripFunc func)
|
||||
{
|
||||
(* func) ("Hello this is a string\n", -1);
|
||||
(* func) ("Hello this is a string\n1", -1);
|
||||
(* func) ("Hello this is a string\n12", -1);
|
||||
(* func) ("Hello this is a string\n123", -1);
|
||||
(* func) ("Hello this is a string\n1234", -1);
|
||||
(* func) ("Hello this is a string\n12345", -1);
|
||||
(* func) ("", 0);
|
||||
(* func) ("1", 1);
|
||||
(* func) ("12", 2);
|
||||
(* func) ("123", 3);
|
||||
(* func) ("1234", 4);
|
||||
(* func) ("12345", 5);
|
||||
(* func) ("", 1);
|
||||
(* func) ("1", 2);
|
||||
(* func) ("12", 3);
|
||||
(* func) ("123", 4);
|
||||
(* func) ("1234", 5);
|
||||
(* func) ("12345", 6);
|
||||
{
|
||||
unsigned char buf[512];
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < _DBUS_N_ELEMENTS (buf))
|
||||
{
|
||||
buf[i] = i;
|
||||
++i;
|
||||
}
|
||||
i = 0;
|
||||
while (i < _DBUS_N_ELEMENTS (buf))
|
||||
{
|
||||
(* func) (buf, i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/* The max length thing is sort of a historical artifact
|
||||
* from a feature that turned out to be dumb; perhaps
|
||||
* we should purge it entirely. The problem with
|
||||
* the feature is that it looks like memory allocation
|
||||
* failure, but is not a transient or resolvable failure.
|
||||
*/
|
||||
static void
|
||||
set_max_length (DBusString *str,
|
||||
int max_length)
|
||||
{
|
||||
DBusRealString *real;
|
||||
|
||||
real = (DBusRealString*) str;
|
||||
|
||||
real->max_length = max_length;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* @ingroup DBusStringInternals
|
||||
* Unit test for DBusString.
|
||||
*
|
||||
* @todo Need to write tests for _dbus_string_copy() and
|
||||
* _dbus_string_move() moving to/from each of start/middle/end of a
|
||||
* string. Also need tests for _dbus_string_move_len ()
|
||||
*
|
||||
* @returns #TRUE on success.
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_string_test (void)
|
||||
{
|
||||
DBusString str;
|
||||
DBusString other;
|
||||
int i, end;
|
||||
long v;
|
||||
double d;
|
||||
int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 };
|
||||
char *s;
|
||||
dbus_unichar_t ch;
|
||||
|
||||
i = 0;
|
||||
while (i < _DBUS_N_ELEMENTS (lens))
|
||||
{
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
set_max_length (&str, lens[i]);
|
||||
|
||||
test_max_len (&str, lens[i]);
|
||||
_dbus_string_free (&str);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Test shortening and setting length */
|
||||
i = 0;
|
||||
while (i < _DBUS_N_ELEMENTS (lens))
|
||||
{
|
||||
int j;
|
||||
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
set_max_length (&str, lens[i]);
|
||||
|
||||
if (!_dbus_string_set_length (&str, lens[i]))
|
||||
_dbus_assert_not_reached ("failed to set string length");
|
||||
|
||||
j = lens[i];
|
||||
while (j > 0)
|
||||
{
|
||||
_dbus_assert (_dbus_string_get_length (&str) == j);
|
||||
if (j > 0)
|
||||
{
|
||||
_dbus_string_shorten (&str, 1);
|
||||
_dbus_assert (_dbus_string_get_length (&str) == (j - 1));
|
||||
}
|
||||
--j;
|
||||
}
|
||||
|
||||
_dbus_string_free (&str);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Test appending data */
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
i = 0;
|
||||
while (i < 10)
|
||||
{
|
||||
if (!_dbus_string_append (&str, "a"))
|
||||
_dbus_assert_not_reached ("failed to append string to string\n");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
|
||||
|
||||
if (!_dbus_string_append_byte (&str, 'b'))
|
||||
_dbus_assert_not_reached ("failed to append byte to string\n");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
_dbus_string_free (&str);
|
||||
|
||||
/* Check steal_data */
|
||||
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
if (!_dbus_string_append (&str, "Hello World"))
|
||||
_dbus_assert_not_reached ("could not append to string");
|
||||
|
||||
i = _dbus_string_get_length (&str);
|
||||
|
||||
if (!_dbus_string_steal_data (&str, &s))
|
||||
_dbus_assert_not_reached ("failed to steal data");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == 0);
|
||||
_dbus_assert (((int)strlen (s)) == i);
|
||||
|
||||
dbus_free (s);
|
||||
|
||||
/* Check move */
|
||||
|
||||
if (!_dbus_string_append (&str, "Hello World"))
|
||||
_dbus_assert_not_reached ("could not append to string");
|
||||
|
||||
i = _dbus_string_get_length (&str);
|
||||
|
||||
if (!_dbus_string_init (&other))
|
||||
_dbus_assert_not_reached ("could not init string");
|
||||
|
||||
if (!_dbus_string_move (&str, 0, &other, 0))
|
||||
_dbus_assert_not_reached ("could not move");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == 0);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i);
|
||||
|
||||
if (!_dbus_string_append (&str, "Hello World"))
|
||||
_dbus_assert_not_reached ("could not append to string");
|
||||
|
||||
if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
|
||||
_dbus_assert_not_reached ("could not move");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == 0);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i * 2);
|
||||
|
||||
if (!_dbus_string_append (&str, "Hello World"))
|
||||
_dbus_assert_not_reached ("could not append to string");
|
||||
|
||||
if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
|
||||
_dbus_assert_not_reached ("could not move");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == 0);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i * 3);
|
||||
|
||||
_dbus_string_free (&other);
|
||||
|
||||
/* Check copy */
|
||||
|
||||
if (!_dbus_string_append (&str, "Hello World"))
|
||||
_dbus_assert_not_reached ("could not append to string");
|
||||
|
||||
i = _dbus_string_get_length (&str);
|
||||
|
||||
if (!_dbus_string_init (&other))
|
||||
_dbus_assert_not_reached ("could not init string");
|
||||
|
||||
if (!_dbus_string_copy (&str, 0, &other, 0))
|
||||
_dbus_assert_not_reached ("could not copy");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == i);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i);
|
||||
|
||||
if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
|
||||
_dbus_assert_not_reached ("could not copy");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == i);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i * 2);
|
||||
_dbus_assert (_dbus_string_equal_c_str (&other,
|
||||
"Hello WorldHello World"));
|
||||
|
||||
if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
|
||||
_dbus_assert_not_reached ("could not copy");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == i);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i * 3);
|
||||
_dbus_assert (_dbus_string_equal_c_str (&other,
|
||||
"Hello WorldHello WorldHello World"));
|
||||
|
||||
_dbus_string_free (&str);
|
||||
_dbus_string_free (&other);
|
||||
|
||||
/* Check replace */
|
||||
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
if (!_dbus_string_append (&str, "Hello World"))
|
||||
_dbus_assert_not_reached ("could not append to string");
|
||||
|
||||
i = _dbus_string_get_length (&str);
|
||||
|
||||
if (!_dbus_string_init (&other))
|
||||
_dbus_assert_not_reached ("could not init string");
|
||||
|
||||
if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
|
||||
&other, 0, _dbus_string_get_length (&other)))
|
||||
_dbus_assert_not_reached ("could not replace");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == i);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i);
|
||||
_dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
|
||||
|
||||
if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
|
||||
&other, 5, 1))
|
||||
_dbus_assert_not_reached ("could not replace center space");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == i);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
|
||||
_dbus_assert (_dbus_string_equal_c_str (&other,
|
||||
"HelloHello WorldWorld"));
|
||||
|
||||
|
||||
if (!_dbus_string_replace_len (&str, 1, 1,
|
||||
&other,
|
||||
_dbus_string_get_length (&other) - 1,
|
||||
1))
|
||||
_dbus_assert_not_reached ("could not replace end character");
|
||||
|
||||
_dbus_assert (_dbus_string_get_length (&str) == i);
|
||||
_dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
|
||||
_dbus_assert (_dbus_string_equal_c_str (&other,
|
||||
"HelloHello WorldWorle"));
|
||||
|
||||
_dbus_string_free (&str);
|
||||
_dbus_string_free (&other);
|
||||
|
||||
/* Check append/get unichar */
|
||||
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
ch = 0;
|
||||
if (!_dbus_string_append_unichar (&str, 0xfffc))
|
||||
_dbus_assert_not_reached ("failed to append unichar");
|
||||
|
||||
_dbus_string_get_unichar (&str, 0, &ch, &i);
|
||||
|
||||
_dbus_assert (ch == 0xfffc);
|
||||
_dbus_assert (i == _dbus_string_get_length (&str));
|
||||
|
||||
_dbus_string_free (&str);
|
||||
|
||||
/* Check insert/set/get byte */
|
||||
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
if (!_dbus_string_append (&str, "Hello"))
|
||||
_dbus_assert_not_reached ("failed to append Hello");
|
||||
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
|
||||
|
||||
_dbus_string_set_byte (&str, 1, 'q');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
|
||||
|
||||
if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
|
||||
_dbus_assert_not_reached ("can't insert byte");
|
||||
|
||||
if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
|
||||
_dbus_assert_not_reached ("can't insert byte");
|
||||
|
||||
if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
|
||||
_dbus_assert_not_reached ("can't insert byte");
|
||||
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
|
||||
_dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
|
||||
|
||||
_dbus_string_free (&str);
|
||||
|
||||
/* Check append/parse int/double */
|
||||
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
if (!_dbus_string_append_int (&str, 27))
|
||||
_dbus_assert_not_reached ("failed to append int");
|
||||
|
||||
i = _dbus_string_get_length (&str);
|
||||
|
||||
if (!_dbus_string_parse_int (&str, 0, &v, &end))
|
||||
_dbus_assert_not_reached ("failed to parse int");
|
||||
|
||||
_dbus_assert (v == 27);
|
||||
_dbus_assert (end == i);
|
||||
|
||||
_dbus_string_free (&str);
|
||||
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
if (!_dbus_string_append_double (&str, 50.3))
|
||||
_dbus_assert_not_reached ("failed to append float");
|
||||
|
||||
i = _dbus_string_get_length (&str);
|
||||
|
||||
if (!_dbus_string_parse_double (&str, 0, &d, &end))
|
||||
_dbus_assert_not_reached ("failed to parse float");
|
||||
|
||||
_dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
|
||||
_dbus_assert (end == i);
|
||||
|
||||
_dbus_string_free (&str);
|
||||
|
||||
/* Test find */
|
||||
if (!_dbus_string_init (&str))
|
||||
_dbus_assert_not_reached ("failed to init string");
|
||||
|
||||
if (!_dbus_string_append (&str, "Hello"))
|
||||
_dbus_assert_not_reached ("couldn't append to string");
|
||||
|
||||
if (!_dbus_string_find (&str, 0, "He", &i))
|
||||
_dbus_assert_not_reached ("didn't find 'He'");
|
||||
_dbus_assert (i == 0);
|
||||
|
||||
if (!_dbus_string_find (&str, 0, "Hello", &i))
|
||||
_dbus_assert_not_reached ("didn't find 'Hello'");
|
||||
_dbus_assert (i == 0);
|
||||
|
||||
if (!_dbus_string_find (&str, 0, "ello", &i))
|
||||
_dbus_assert_not_reached ("didn't find 'ello'");
|
||||
_dbus_assert (i == 1);
|
||||
|
||||
if (!_dbus_string_find (&str, 0, "lo", &i))
|
||||
_dbus_assert_not_reached ("didn't find 'lo'");
|
||||
_dbus_assert (i == 3);
|
||||
|
||||
if (!_dbus_string_find (&str, 2, "lo", &i))
|
||||
_dbus_assert_not_reached ("didn't find 'lo'");
|
||||
_dbus_assert (i == 3);
|
||||
|
||||
if (_dbus_string_find (&str, 4, "lo", &i))
|
||||
_dbus_assert_not_reached ("did find 'lo'");
|
||||
|
||||
if (!_dbus_string_find (&str, 0, "l", &i))
|
||||
_dbus_assert_not_reached ("didn't find 'l'");
|
||||
_dbus_assert (i == 2);
|
||||
|
||||
if (!_dbus_string_find (&str, 0, "H", &i))
|
||||
_dbus_assert_not_reached ("didn't find 'H'");
|
||||
_dbus_assert (i == 0);
|
||||
|
||||
if (!_dbus_string_find (&str, 0, "", &i))
|
||||
_dbus_assert_not_reached ("didn't find ''");
|
||||
_dbus_assert (i == 0);
|
||||
|
||||
if (_dbus_string_find (&str, 0, "Hello!", NULL))
|
||||
_dbus_assert_not_reached ("Did find 'Hello!'");
|
||||
|
||||
if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
|
||||
_dbus_assert_not_reached ("Did find 'Oh, Hello'");
|
||||
|
||||
if (_dbus_string_find (&str, 0, "ill", NULL))
|
||||
_dbus_assert_not_reached ("Did find 'ill'");
|
||||
|
||||
if (_dbus_string_find (&str, 0, "q", NULL))
|
||||
_dbus_assert_not_reached ("Did find 'q'");
|
||||
|
||||
if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
|
||||
_dbus_assert_not_reached ("Didn't find 'He'");
|
||||
|
||||
if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
|
||||
_dbus_assert_not_reached ("Did find 'Hello'");
|
||||
|
||||
if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
|
||||
_dbus_assert_not_reached ("Did not find 'H'");
|
||||
_dbus_assert (i == 0);
|
||||
|
||||
if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
|
||||
_dbus_assert_not_reached ("Did not find 'o'");
|
||||
_dbus_assert (i == _dbus_string_get_length (&str) - 1);
|
||||
|
||||
if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
|
||||
_dbus_assert_not_reached ("Did find 'o'");
|
||||
_dbus_assert (i == -1);
|
||||
|
||||
if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
|
||||
_dbus_assert_not_reached ("Did find 'e'");
|
||||
_dbus_assert (i == -1);
|
||||
|
||||
if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
|
||||
_dbus_assert_not_reached ("Didn't find 'e'");
|
||||
_dbus_assert (i == 1);
|
||||
|
||||
_dbus_string_free (&str);
|
||||
|
||||
/* Hex encoding */
|
||||
_dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
|
||||
if (!_dbus_string_init (&other))
|
||||
_dbus_assert_not_reached ("could not init string");
|
||||
|
||||
if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
|
||||
_dbus_assert_not_reached ("deccoded bogus hex string with no error");
|
||||
|
||||
_dbus_assert (end == 8);
|
||||
|
||||
_dbus_string_free (&other);
|
||||
|
||||
test_roundtrips (test_hex_roundtrip);
|
||||
|
||||
_dbus_string_free (&str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -54,6 +54,7 @@ struct DBusString
|
|||
* to inline non-exported symbols across files in the library.
|
||||
* Note that these break type safety (due to the casts)
|
||||
*/
|
||||
#define _dbus_string_get_data(s) ((char*)(((DBusString*)(s))->dummy1))
|
||||
#define _dbus_string_get_length(s) (((DBusString*)(s))->dummy2)
|
||||
#define _dbus_string_set_byte(s, i, b) ((((unsigned char*)(((DBusString*)(s))->dummy1))[(i)]) = (unsigned char) (b))
|
||||
#define _dbus_string_get_byte(s, i) (((const unsigned char*)(((DBusString*)(s))->dummy1))[(i)])
|
||||
|
|
@ -71,7 +72,9 @@ dbus_bool_t _dbus_string_init_preallocated (DBusString *str,
|
|||
int allocate_size);
|
||||
void _dbus_string_free (DBusString *str);
|
||||
void _dbus_string_lock (DBusString *str);
|
||||
#ifndef _dbus_string_get_data
|
||||
char* _dbus_string_get_data (DBusString *str);
|
||||
#endif /* _dbus_string_get_data */
|
||||
#ifndef _dbus_string_get_const_data
|
||||
const char* _dbus_string_get_const_data (const DBusString *str);
|
||||
#endif /* _dbus_string_get_const_data */
|
||||
|
|
@ -205,11 +208,6 @@ dbus_bool_t _dbus_string_parse_double (const DBusString *str,
|
|||
int start,
|
||||
double *value,
|
||||
int *end_return);
|
||||
dbus_bool_t _dbus_string_parse_basic_type (const DBusString *str,
|
||||
char type,
|
||||
int start,
|
||||
void *value,
|
||||
int *end_return);
|
||||
dbus_bool_t _dbus_string_find (const DBusString *str,
|
||||
int start,
|
||||
const char *substr,
|
||||
|
|
|
|||
871
dbus/dbus-sysdeps-util.c
Normal file
871
dbus/dbus-sysdeps-util.c
Normal file
|
|
@ -0,0 +1,871 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-sysdeps-util.c Would be in dbus-sysdeps.c, but not used in libdbus
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
|
||||
* Copyright (C) 2003 CodeFactory AB
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#include "dbus-sysdeps.h"
|
||||
#include "dbus-internals.h"
|
||||
#include "dbus-protocol.h"
|
||||
#include "dbus-string.h"
|
||||
#define DBUS_USERDB_INCLUDES_PRIVATE 1
|
||||
#include "dbus-userdb.h"
|
||||
#include "dbus-test.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <grp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup DBusInternalsUtils
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Does the chdir, fork, setsid, etc. to become a daemon process.
|
||||
*
|
||||
* @param pidfile #NULL, or pidfile to create
|
||||
* @param print_pid_fd file descriptor to print pid to, or -1 for none
|
||||
* @param error return location for errors
|
||||
* @returns #FALSE on failure
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_become_daemon (const DBusString *pidfile,
|
||||
int print_pid_fd,
|
||||
DBusError *error)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a file containing the process ID.
|
||||
*
|
||||
* @param filename the filename to write to
|
||||
* @param pid our process ID
|
||||
* @param error return location for errors
|
||||
* @returns #FALSE on failure
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_write_pid_file (const DBusString *filename,
|
||||
unsigned long pid,
|
||||
DBusError *error)
|
||||
{
|
||||
const char *cfilename;
|
||||
int fd;
|
||||
FILE *f;
|
||||
|
||||
cfilename = _dbus_string_get_const_data (filename);
|
||||
|
||||
fd = open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to open \"%s\": %s", cfilename,
|
||||
_dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((f = fdopen (fd, "w")) == NULL)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to fdopen fd %d: %s", fd, _dbus_strerror (errno));
|
||||
close (fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (fprintf (f, "%lu\n", pid) < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to write to \"%s\": %s", cfilename,
|
||||
_dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (fclose (f) == EOF)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to close \"%s\": %s", cfilename,
|
||||
_dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the user and group the bus is running as.
|
||||
*
|
||||
* @param uid the new user ID
|
||||
* @param gid the new group ID
|
||||
* @param error return location for errors
|
||||
* @returns #FALSE on failure
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_change_identity (dbus_uid_t uid,
|
||||
dbus_gid_t gid,
|
||||
DBusError *error)
|
||||
{
|
||||
/* setgroups() only works if we are a privileged process,
|
||||
* so we don't return error on failure; the only possible
|
||||
* failure is that we don't have perms to do it.
|
||||
* FIXME not sure this is right, maybe if setuid()
|
||||
* is going to work then setgroups() should also work.
|
||||
*/
|
||||
if (setgroups (0, NULL) < 0)
|
||||
_dbus_warn ("Failed to drop supplementary groups: %s\n",
|
||||
_dbus_strerror (errno));
|
||||
|
||||
/* Set GID first, or the setuid may remove our permission
|
||||
* to change the GID
|
||||
*/
|
||||
if (setgid (gid) < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to set GID to %lu: %s", gid,
|
||||
_dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (setuid (uid) < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to set UID to %lu: %s", uid,
|
||||
_dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Installs a UNIX signal handler
|
||||
*
|
||||
* @param sig the signal to handle
|
||||
* @param handler the handler
|
||||
*/
|
||||
void
|
||||
_dbus_set_signal_handler (int sig,
|
||||
DBusSignalHandler handler)
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t empty_mask;
|
||||
|
||||
sigemptyset (&empty_mask);
|
||||
act.sa_handler = handler;
|
||||
act.sa_mask = empty_mask;
|
||||
act.sa_flags = 0;
|
||||
sigaction (sig, &act, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a directory; Directory must be empty
|
||||
*
|
||||
* @param filename directory filename
|
||||
* @param error initialized error object
|
||||
* @returns #TRUE on success
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_delete_directory (const DBusString *filename,
|
||||
DBusError *error)
|
||||
{
|
||||
const char *filename_c;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
filename_c = _dbus_string_get_const_data (filename);
|
||||
|
||||
if (rmdir (filename_c) != 0)
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"Failed to remove directory %s: %s\n",
|
||||
filename_c, _dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Checks if a file exists
|
||||
*
|
||||
* @param file full path to the file
|
||||
* @returns #TRUE if file exists
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_file_exists (const char *file)
|
||||
{
|
||||
return (access (file, F_OK) == 0);
|
||||
}
|
||||
|
||||
/** Checks if user is at the console
|
||||
*
|
||||
* @param username user to check
|
||||
* @param error return location for errors
|
||||
* @returns #TRUE is the user is at the consolei and there are no errors
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_user_at_console (const char *username,
|
||||
DBusError *error)
|
||||
{
|
||||
|
||||
DBusString f;
|
||||
dbus_bool_t result;
|
||||
|
||||
result = FALSE;
|
||||
if (!_dbus_string_init (&f))
|
||||
{
|
||||
_DBUS_SET_OOM (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_dbus_string_append (&f, DBUS_CONSOLE_DIR))
|
||||
{
|
||||
_DBUS_SET_OOM (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
if (!_dbus_string_append (&f, username))
|
||||
{
|
||||
_DBUS_SET_OOM (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = _dbus_file_exists (_dbus_string_get_const_data (&f));
|
||||
|
||||
out:
|
||||
_dbus_string_free (&f);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the filename is an absolute path
|
||||
*
|
||||
* @param filename the filename
|
||||
* @returns #TRUE if an absolute path
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_path_is_absolute (const DBusString *filename)
|
||||
{
|
||||
if (_dbus_string_get_length (filename) > 0)
|
||||
return _dbus_string_get_byte (filename, 0) == '/';
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* stat() wrapper.
|
||||
*
|
||||
* @param filename the filename to stat
|
||||
* @param statbuf the stat info to fill in
|
||||
* @param error return location for error
|
||||
* @returns #FALSE if error was set
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_stat (const DBusString *filename,
|
||||
DBusStat *statbuf,
|
||||
DBusError *error)
|
||||
{
|
||||
const char *filename_c;
|
||||
struct stat sb;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
filename_c = _dbus_string_get_const_data (filename);
|
||||
|
||||
if (stat (filename_c, &sb) < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"%s", _dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
statbuf->mode = sb.st_mode;
|
||||
statbuf->nlink = sb.st_nlink;
|
||||
statbuf->uid = sb.st_uid;
|
||||
statbuf->gid = sb.st_gid;
|
||||
statbuf->size = sb.st_size;
|
||||
statbuf->atime = sb.st_atime;
|
||||
statbuf->mtime = sb.st_mtime;
|
||||
statbuf->ctime = sb.st_ctime;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internals of directory iterator
|
||||
*/
|
||||
struct DBusDirIter
|
||||
{
|
||||
DIR *d; /**< The DIR* from opendir() */
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Open a directory to iterate over.
|
||||
*
|
||||
* @param filename the directory name
|
||||
* @param error exception return object or #NULL
|
||||
* @returns new iterator, or #NULL on error
|
||||
*/
|
||||
DBusDirIter*
|
||||
_dbus_directory_open (const DBusString *filename,
|
||||
DBusError *error)
|
||||
{
|
||||
DIR *d;
|
||||
DBusDirIter *iter;
|
||||
const char *filename_c;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
filename_c = _dbus_string_get_const_data (filename);
|
||||
|
||||
d = opendir (filename_c);
|
||||
if (d == NULL)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to read directory \"%s\": %s",
|
||||
filename_c,
|
||||
_dbus_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
iter = dbus_new0 (DBusDirIter, 1);
|
||||
if (iter == NULL)
|
||||
{
|
||||
closedir (d);
|
||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
|
||||
"Could not allocate memory for directory iterator");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iter->d = d;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @todo for thread safety, I think we have to use
|
||||
* readdir_r(). (GLib has the same issue, should file a bug.)
|
||||
*
|
||||
* @param iter the iterator
|
||||
* @param filename string to be set to the next file in the dir
|
||||
* @param error return location for error
|
||||
* @returns #TRUE if filename was filled in with a new filename
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_directory_get_next_file (DBusDirIter *iter,
|
||||
DBusString *filename,
|
||||
DBusError *error)
|
||||
{
|
||||
struct dirent *ent;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
again:
|
||||
errno = 0;
|
||||
ent = readdir (iter->d);
|
||||
if (ent == NULL)
|
||||
{
|
||||
if (errno != 0)
|
||||
dbus_set_error (error,
|
||||
_dbus_error_from_errno (errno),
|
||||
"%s", _dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
else if (ent->d_name[0] == '.' &&
|
||||
(ent->d_name[1] == '\0' ||
|
||||
(ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
|
||||
goto again;
|
||||
else
|
||||
{
|
||||
_dbus_string_set_length (filename, 0);
|
||||
if (!_dbus_string_append (filename, ent->d_name))
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
|
||||
"No memory to read directory entry");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a directory iteration.
|
||||
*/
|
||||
void
|
||||
_dbus_directory_close (DBusDirIter *iter)
|
||||
{
|
||||
closedir (iter->d);
|
||||
dbus_free (iter);
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
fill_user_info_from_group (struct group *g,
|
||||
DBusGroupInfo *info,
|
||||
DBusError *error)
|
||||
{
|
||||
_dbus_assert (g->gr_name != NULL);
|
||||
|
||||
info->gid = g->gr_gid;
|
||||
info->groupname = _dbus_strdup (g->gr_name);
|
||||
|
||||
/* info->members = dbus_strdupv (g->gr_mem) */
|
||||
|
||||
if (info->groupname == NULL)
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
fill_group_info (DBusGroupInfo *info,
|
||||
dbus_gid_t gid,
|
||||
const DBusString *groupname,
|
||||
DBusError *error)
|
||||
{
|
||||
const char *group_c_str;
|
||||
|
||||
_dbus_assert (groupname != NULL || gid != DBUS_GID_UNSET);
|
||||
_dbus_assert (groupname == NULL || gid == DBUS_GID_UNSET);
|
||||
|
||||
if (groupname)
|
||||
group_c_str = _dbus_string_get_const_data (groupname);
|
||||
else
|
||||
group_c_str = NULL;
|
||||
|
||||
/* For now assuming that the getgrnam() and getgrgid() flavors
|
||||
* always correspond to the pwnam flavors, if not we have
|
||||
* to add more configure checks.
|
||||
*/
|
||||
|
||||
#if defined (HAVE_POSIX_GETPWNAME_R) || defined (HAVE_NONPOSIX_GETPWNAME_R)
|
||||
{
|
||||
struct group *g;
|
||||
int result;
|
||||
char buf[1024];
|
||||
struct group g_str;
|
||||
|
||||
g = NULL;
|
||||
#ifdef HAVE_POSIX_GETPWNAME_R
|
||||
|
||||
if (group_c_str)
|
||||
result = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf),
|
||||
&g);
|
||||
else
|
||||
result = getgrgid_r (gid, &g_str, buf, sizeof (buf),
|
||||
&g);
|
||||
#else
|
||||
p = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf));
|
||||
result = 0;
|
||||
#endif /* !HAVE_POSIX_GETPWNAME_R */
|
||||
if (result == 0 && g == &g_str)
|
||||
{
|
||||
return fill_user_info_from_group (g, info, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Group %s unknown or failed to look it up\n",
|
||||
group_c_str ? group_c_str : "???");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#else /* ! HAVE_GETPWNAM_R */
|
||||
{
|
||||
/* I guess we're screwed on thread safety here */
|
||||
struct group *g;
|
||||
|
||||
g = getgrnam (group_c_str);
|
||||
|
||||
if (g != NULL)
|
||||
{
|
||||
return fill_user_info_from_group (g, info, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Group %s unknown or failed to look it up\n",
|
||||
group_c_str ? group_c_str : "???");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif /* ! HAVE_GETPWNAM_R */
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the given DBusGroupInfo struct
|
||||
* with information about the given group name.
|
||||
*
|
||||
* @param info the group info struct
|
||||
* @param groupname name of group
|
||||
* @param error the error return
|
||||
* @returns #FALSE if error is set
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_group_info_fill (DBusGroupInfo *info,
|
||||
const DBusString *groupname,
|
||||
DBusError *error)
|
||||
{
|
||||
return fill_group_info (info, DBUS_GID_UNSET,
|
||||
groupname, error);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the given DBusGroupInfo struct
|
||||
* with information about the given group ID.
|
||||
*
|
||||
* @param info the group info struct
|
||||
* @param gid group ID
|
||||
* @param error the error return
|
||||
* @returns #FALSE if error is set
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_group_info_fill_gid (DBusGroupInfo *info,
|
||||
dbus_gid_t gid,
|
||||
DBusError *error)
|
||||
{
|
||||
return fill_group_info (info, gid, NULL, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the members of info (but not info itself).
|
||||
*
|
||||
* @param info the group info
|
||||
*/
|
||||
void
|
||||
_dbus_group_info_free (DBusGroupInfo *info)
|
||||
{
|
||||
dbus_free (info->groupname);
|
||||
}
|
||||
|
||||
/** @} */ /* End of DBusInternalsUtils functions */
|
||||
|
||||
/**
|
||||
* @addtogroup DBusString
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* Get the directory name from a complete filename
|
||||
* @param filename the filename
|
||||
* @param dirname string to append directory name to
|
||||
* @returns #FALSE if no memory
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_string_get_dirname (const DBusString *filename,
|
||||
DBusString *dirname)
|
||||
{
|
||||
int sep;
|
||||
|
||||
_dbus_assert (filename != dirname);
|
||||
_dbus_assert (filename != NULL);
|
||||
_dbus_assert (dirname != NULL);
|
||||
|
||||
/* Ignore any separators on the end */
|
||||
sep = _dbus_string_get_length (filename);
|
||||
if (sep == 0)
|
||||
return _dbus_string_append (dirname, "."); /* empty string passed in */
|
||||
|
||||
while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
|
||||
--sep;
|
||||
|
||||
_dbus_assert (sep >= 0);
|
||||
|
||||
if (sep == 0)
|
||||
return _dbus_string_append (dirname, "/");
|
||||
|
||||
/* Now find the previous separator */
|
||||
_dbus_string_find_byte_backward (filename, sep, '/', &sep);
|
||||
if (sep < 0)
|
||||
return _dbus_string_append (dirname, ".");
|
||||
|
||||
/* skip multiple separators */
|
||||
while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
|
||||
--sep;
|
||||
|
||||
_dbus_assert (sep >= 0);
|
||||
|
||||
if (sep == 0 &&
|
||||
_dbus_string_get_byte (filename, 0) == '/')
|
||||
return _dbus_string_append (dirname, "/");
|
||||
else
|
||||
return _dbus_string_copy_len (filename, 0, sep - 0,
|
||||
dirname, _dbus_string_get_length (dirname));
|
||||
}
|
||||
/** @} */ /* DBusString stuff */
|
||||
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
#include <stdlib.h>
|
||||
static void
|
||||
check_dirname (const char *filename,
|
||||
const char *dirname)
|
||||
{
|
||||
DBusString f, d;
|
||||
|
||||
_dbus_string_init_const (&f, filename);
|
||||
|
||||
if (!_dbus_string_init (&d))
|
||||
_dbus_assert_not_reached ("no memory");
|
||||
|
||||
if (!_dbus_string_get_dirname (&f, &d))
|
||||
_dbus_assert_not_reached ("no memory");
|
||||
|
||||
if (!_dbus_string_equal_c_str (&d, dirname))
|
||||
{
|
||||
_dbus_warn ("For filename \"%s\" got dirname \"%s\" and expected \"%s\"\n",
|
||||
filename,
|
||||
_dbus_string_get_const_data (&d),
|
||||
dirname);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
_dbus_string_free (&d);
|
||||
}
|
||||
|
||||
static void
|
||||
check_path_absolute (const char *path,
|
||||
dbus_bool_t expected)
|
||||
{
|
||||
DBusString p;
|
||||
|
||||
_dbus_string_init_const (&p, path);
|
||||
|
||||
if (_dbus_path_is_absolute (&p) != expected)
|
||||
{
|
||||
_dbus_warn ("For path \"%s\" expected absolute = %d got %d\n",
|
||||
path, expected, _dbus_path_is_absolute (&p));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit test for dbus-sysdeps.c.
|
||||
*
|
||||
* @returns #TRUE on success.
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_sysdeps_test (void)
|
||||
{
|
||||
DBusString str;
|
||||
double val;
|
||||
int pos;
|
||||
|
||||
check_dirname ("foo", ".");
|
||||
check_dirname ("foo/bar", "foo");
|
||||
check_dirname ("foo//bar", "foo");
|
||||
check_dirname ("foo///bar", "foo");
|
||||
check_dirname ("foo/bar/", "foo");
|
||||
check_dirname ("foo//bar/", "foo");
|
||||
check_dirname ("foo///bar/", "foo");
|
||||
check_dirname ("foo/bar//", "foo");
|
||||
check_dirname ("foo//bar////", "foo");
|
||||
check_dirname ("foo///bar///////", "foo");
|
||||
check_dirname ("/foo", "/");
|
||||
check_dirname ("////foo", "/");
|
||||
check_dirname ("/foo/bar", "/foo");
|
||||
check_dirname ("/foo//bar", "/foo");
|
||||
check_dirname ("/foo///bar", "/foo");
|
||||
check_dirname ("/", "/");
|
||||
check_dirname ("///", "/");
|
||||
check_dirname ("", ".");
|
||||
|
||||
|
||||
_dbus_string_init_const (&str, "3.5");
|
||||
if (!_dbus_string_parse_double (&str,
|
||||
0, &val, &pos))
|
||||
{
|
||||
_dbus_warn ("Failed to parse double");
|
||||
exit (1);
|
||||
}
|
||||
if (ABS(3.5 - val) > 1e-6)
|
||||
{
|
||||
_dbus_warn ("Failed to parse 3.5 correctly, got: %f", val);
|
||||
exit (1);
|
||||
}
|
||||
if (pos != 3)
|
||||
{
|
||||
_dbus_warn ("_dbus_string_parse_double of \"3.5\" returned wrong position %d", pos);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
_dbus_string_init_const (&str, "0xff");
|
||||
if (!_dbus_string_parse_double (&str,
|
||||
0, &val, &pos))
|
||||
{
|
||||
_dbus_warn ("Failed to parse double");
|
||||
exit (1);
|
||||
}
|
||||
if (ABS (0xff - val) > 1e-6)
|
||||
{
|
||||
_dbus_warn ("Failed to parse 0xff correctly, got: %f\n", val);
|
||||
exit (1);
|
||||
}
|
||||
if (pos != 4)
|
||||
{
|
||||
_dbus_warn ("_dbus_string_parse_double of \"0xff\" returned wrong position %d", pos);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
check_path_absolute ("/", TRUE);
|
||||
check_path_absolute ("/foo", TRUE);
|
||||
check_path_absolute ("", FALSE);
|
||||
check_path_absolute ("foo", FALSE);
|
||||
check_path_absolute ("foo/bar", FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
|
@ -1628,149 +1628,6 @@ _dbus_user_info_free (DBusUserInfo *info)
|
|||
dbus_free (info->homedir);
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
fill_user_info_from_group (struct group *g,
|
||||
DBusGroupInfo *info,
|
||||
DBusError *error)
|
||||
{
|
||||
_dbus_assert (g->gr_name != NULL);
|
||||
|
||||
info->gid = g->gr_gid;
|
||||
info->groupname = _dbus_strdup (g->gr_name);
|
||||
|
||||
/* info->members = dbus_strdupv (g->gr_mem) */
|
||||
|
||||
if (info->groupname == NULL)
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
fill_group_info (DBusGroupInfo *info,
|
||||
dbus_gid_t gid,
|
||||
const DBusString *groupname,
|
||||
DBusError *error)
|
||||
{
|
||||
const char *group_c_str;
|
||||
|
||||
_dbus_assert (groupname != NULL || gid != DBUS_GID_UNSET);
|
||||
_dbus_assert (groupname == NULL || gid == DBUS_GID_UNSET);
|
||||
|
||||
if (groupname)
|
||||
group_c_str = _dbus_string_get_const_data (groupname);
|
||||
else
|
||||
group_c_str = NULL;
|
||||
|
||||
/* For now assuming that the getgrnam() and getgrgid() flavors
|
||||
* always correspond to the pwnam flavors, if not we have
|
||||
* to add more configure checks.
|
||||
*/
|
||||
|
||||
#if defined (HAVE_POSIX_GETPWNAME_R) || defined (HAVE_NONPOSIX_GETPWNAME_R)
|
||||
{
|
||||
struct group *g;
|
||||
int result;
|
||||
char buf[1024];
|
||||
struct group g_str;
|
||||
|
||||
g = NULL;
|
||||
#ifdef HAVE_POSIX_GETPWNAME_R
|
||||
|
||||
if (group_c_str)
|
||||
result = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf),
|
||||
&g);
|
||||
else
|
||||
result = getgrgid_r (gid, &g_str, buf, sizeof (buf),
|
||||
&g);
|
||||
#else
|
||||
p = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf));
|
||||
result = 0;
|
||||
#endif /* !HAVE_POSIX_GETPWNAME_R */
|
||||
if (result == 0 && g == &g_str)
|
||||
{
|
||||
return fill_user_info_from_group (g, info, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Group %s unknown or failed to look it up\n",
|
||||
group_c_str ? group_c_str : "???");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#else /* ! HAVE_GETPWNAM_R */
|
||||
{
|
||||
/* I guess we're screwed on thread safety here */
|
||||
struct group *g;
|
||||
|
||||
g = getgrnam (group_c_str);
|
||||
|
||||
if (g != NULL)
|
||||
{
|
||||
return fill_user_info_from_group (g, info, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Group %s unknown or failed to look it up\n",
|
||||
group_c_str ? group_c_str : "???");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif /* ! HAVE_GETPWNAM_R */
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the given DBusGroupInfo struct
|
||||
* with information about the given group name.
|
||||
*
|
||||
* @param info the group info struct
|
||||
* @param groupname name of group
|
||||
* @param error the error return
|
||||
* @returns #FALSE if error is set
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_group_info_fill (DBusGroupInfo *info,
|
||||
const DBusString *groupname,
|
||||
DBusError *error)
|
||||
{
|
||||
return fill_group_info (info, DBUS_GID_UNSET,
|
||||
groupname, error);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the given DBusGroupInfo struct
|
||||
* with information about the given group ID.
|
||||
*
|
||||
* @param info the group info struct
|
||||
* @param gid group ID
|
||||
* @param error the error return
|
||||
* @returns #FALSE if error is set
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_group_info_fill_gid (DBusGroupInfo *info,
|
||||
dbus_gid_t gid,
|
||||
DBusError *error)
|
||||
{
|
||||
return fill_group_info (info, gid, NULL, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the members of info (but not info itself).
|
||||
*
|
||||
* @param info the group info
|
||||
*/
|
||||
void
|
||||
_dbus_group_info_free (DBusGroupInfo *info)
|
||||
{
|
||||
dbus_free (info->groupname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets fields in DBusCredentials to DBUS_PID_UNSET,
|
||||
* DBUS_UID_UNSET, DBUS_GID_UNSET.
|
||||
|
|
@ -1849,6 +1706,7 @@ _dbus_getuid (void)
|
|||
return getuid ();
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/** Gets our GID
|
||||
* @returns process GID
|
||||
*/
|
||||
|
|
@ -1857,6 +1715,7 @@ _dbus_getgid (void)
|
|||
{
|
||||
return getgid ();
|
||||
}
|
||||
#endif
|
||||
|
||||
_DBUS_DEFINE_GLOBAL_LOCK (atomic);
|
||||
|
||||
|
|
@ -2467,118 +2326,6 @@ _dbus_concat_dir_and_file (DBusString *dir,
|
|||
_dbus_string_get_length (dir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Internals of directory iterator
|
||||
*/
|
||||
struct DBusDirIter
|
||||
{
|
||||
DIR *d; /**< The DIR* from opendir() */
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Open a directory to iterate over.
|
||||
*
|
||||
* @param filename the directory name
|
||||
* @param error exception return object or #NULL
|
||||
* @returns new iterator, or #NULL on error
|
||||
*/
|
||||
DBusDirIter*
|
||||
_dbus_directory_open (const DBusString *filename,
|
||||
DBusError *error)
|
||||
{
|
||||
DIR *d;
|
||||
DBusDirIter *iter;
|
||||
const char *filename_c;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
filename_c = _dbus_string_get_const_data (filename);
|
||||
|
||||
d = opendir (filename_c);
|
||||
if (d == NULL)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Failed to read directory \"%s\": %s",
|
||||
filename_c,
|
||||
_dbus_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
iter = dbus_new0 (DBusDirIter, 1);
|
||||
if (iter == NULL)
|
||||
{
|
||||
closedir (d);
|
||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
|
||||
"Could not allocate memory for directory iterator");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iter->d = d;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @todo for thread safety, I think we have to use
|
||||
* readdir_r(). (GLib has the same issue, should file a bug.)
|
||||
*
|
||||
* @param iter the iterator
|
||||
* @param filename string to be set to the next file in the dir
|
||||
* @param error return location for error
|
||||
* @returns #TRUE if filename was filled in with a new filename
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_directory_get_next_file (DBusDirIter *iter,
|
||||
DBusString *filename,
|
||||
DBusError *error)
|
||||
{
|
||||
struct dirent *ent;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
again:
|
||||
errno = 0;
|
||||
ent = readdir (iter->d);
|
||||
if (ent == NULL)
|
||||
{
|
||||
if (errno != 0)
|
||||
dbus_set_error (error,
|
||||
_dbus_error_from_errno (errno),
|
||||
"%s", _dbus_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
else if (ent->d_name[0] == '.' &&
|
||||
(ent->d_name[1] == '\0' ||
|
||||
(ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
|
||||
goto again;
|
||||
else
|
||||
{
|
||||
_dbus_string_set_length (filename, 0);
|
||||
if (!_dbus_string_append (filename, ent->d_name))
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
|
||||
"No memory to read directory entry");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a directory iteration.
|
||||
*/
|
||||
void
|
||||
_dbus_directory_close (DBusDirIter *iter)
|
||||
{
|
||||
closedir (iter->d);
|
||||
dbus_free (iter);
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
pseudorandom_generate_random_bytes (DBusString *str,
|
||||
int n_bytes)
|
||||
|
|
@ -2858,62 +2605,6 @@ _dbus_exit (int code)
|
|||
_exit (code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a full-duplex pipe (as in socketpair()).
|
||||
* Sets both ends of the pipe nonblocking.
|
||||
*
|
||||
* @param fd1 return location for one end
|
||||
* @param fd2 return location for the other end
|
||||
* @param blocking #TRUE if pipe should be blocking
|
||||
* @param error error return
|
||||
* @returns #FALSE on failure (if error is set)
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_full_duplex_pipe (int *fd1,
|
||||
int *fd2,
|
||||
dbus_bool_t blocking,
|
||||
DBusError *error)
|
||||
{
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
int fds[2];
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Could not create full-duplex pipe");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!blocking &&
|
||||
(!_dbus_set_fd_nonblocking (fds[0], NULL) ||
|
||||
!_dbus_set_fd_nonblocking (fds[1], NULL)))
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Could not set full-duplex pipe nonblocking");
|
||||
|
||||
close (fds[0]);
|
||||
close (fds[1]);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*fd1 = fds[0];
|
||||
*fd2 = fds[1];
|
||||
|
||||
_dbus_verbose ("full-duplex pipe %d <-> %d\n",
|
||||
*fd1, *fd2);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
_dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"_dbus_full_duplex_pipe() not implemented on this OS");
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a file descriptor.
|
||||
*
|
||||
|
|
@ -3055,6 +2746,67 @@ _dbus_parse_uid (const DBusString *uid_str,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a full-duplex pipe (as in socketpair()).
|
||||
* Sets both ends of the pipe nonblocking.
|
||||
*
|
||||
* @todo libdbus only uses this for the debug-pipe server, so in
|
||||
* principle it could be in dbus-sysdeps-util.c, except that
|
||||
* dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
|
||||
* debug-pipe server is used.
|
||||
*
|
||||
* @param fd1 return location for one end
|
||||
* @param fd2 return location for the other end
|
||||
* @param blocking #TRUE if pipe should be blocking
|
||||
* @param error error return
|
||||
* @returns #FALSE on failure (if error is set)
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_full_duplex_pipe (int *fd1,
|
||||
int *fd2,
|
||||
dbus_bool_t blocking,
|
||||
DBusError *error)
|
||||
{
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
int fds[2];
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Could not create full-duplex pipe");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!blocking &&
|
||||
(!_dbus_set_fd_nonblocking (fds[0], NULL) ||
|
||||
!_dbus_set_fd_nonblocking (fds[1], NULL)))
|
||||
{
|
||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||
"Could not set full-duplex pipe nonblocking");
|
||||
|
||||
close (fds[0]);
|
||||
close (fds[1]);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*fd1 = fds[0];
|
||||
*fd2 = fds[1];
|
||||
|
||||
_dbus_verbose ("full-duplex pipe %d <-> %d\n",
|
||||
*fd1, *fd2);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
_dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"_dbus_full_duplex_pipe() not implemented on this OS");
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} end of sysdeps */
|
||||
|
||||
/* tests in dbus-sysdeps-util.c */
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if the UID sent in is the console user
|
||||
*
|
||||
|
|
|
|||
|
|
@ -442,6 +442,7 @@ _dbus_user_database_new (void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
/**
|
||||
* Increments refcount of user database.
|
||||
* @param db the database
|
||||
|
|
@ -456,6 +457,7 @@ _dbus_user_database_ref (DBusUserDatabase *db)
|
|||
|
||||
return db;
|
||||
}
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
|
||||
/**
|
||||
* Decrements refcount of user database.
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ trace 'reachable' through hardcoded function calls, if a function is
|
|||
called only through a vtable, it won't be marked reachable (and
|
||||
neither will its children in the call graph).
|
||||
|
||||
Also, the sizes mentioned are more or less completely bogus.
|
||||
|
||||
"""
|
||||
|
||||
print "The following are hardcoded in as vtable roots: %s" % vtable_roots
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue