From 05a4ad6994919b352b5229d0b1b0a8ebebe2a42f Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 28 Jan 2003 03:53:29 +0000 Subject: 2003-01-27 Havoc Pennington * dbus/dbus-mempool.c (time_for_size): replace printf with _dbus_verbose * dbus/dbus-message-builder.c (_dbus_message_data_load): allow empty lines; fix the SAVE_LENGTH stuff to be START_LENGTH/END_LENGTH so it actually works; couple other bugfixes * test/Makefile.am (dist-hook): add dist-hook for .message files * dbus/dbus-string.c (DBUS_STRING_COPY_PREAMBLE): source of a copy can be constant or locked. (_dbus_string_free): allow freeing a const string as documented/intended * dbus/dbus-sysdeps.c (_dbus_concat_dir_and_file): utility * dbus/dbus-test-main.c (main): take an argument which is the directory containing test data * dbus/dbus-message.c (_dbus_message_test): pass a test_data_dir argument to this and load all the messages in test/data/ checking that they can be loaded or not loaded as appropriate. --- dbus/dbus-sysdeps.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) (limited to 'dbus/dbus-sysdeps.c') diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index d8b202c7..bcb81f7d 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -32,11 +32,13 @@ #include #include #include +#include #include #include #include #include #include + #ifdef HAVE_WRITEV #include #endif @@ -1100,4 +1102,148 @@ _dbus_file_get_contents (DBusString *str, } } +/** + * Appends the given filename to the given directory. + * + * @param dir the directory name + * @param next_component the filename + * @returns #TRUE on success + */ +dbus_bool_t +_dbus_concat_dir_and_file (DBusString *dir, + const DBusString *next_component) +{ + dbus_bool_t dir_ends_in_slash; + dbus_bool_t file_starts_with_slash; + + if (_dbus_string_get_length (dir) == 0 || + _dbus_string_get_length (next_component) == 0) + return TRUE; + + dir_ends_in_slash = '/' == _dbus_string_get_byte (dir, + _dbus_string_get_length (dir) - 1); + + file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0); + + if (dir_ends_in_slash && file_starts_with_slash) + { + _dbus_string_shorten (dir, 1); + } + else if (!(dir_ends_in_slash || file_starts_with_slash)) + { + if (!_dbus_string_append_byte (dir, '/')) + return FALSE; + } + + return _dbus_string_copy (next_component, 0, dir, + _dbus_string_get_length (dir)); +} + +struct DBusDirIter +{ + DIR *d; + +}; + +/** + * Open a directory to iterate over. + * + * @param filename the directory name + * @param result return location for error code if #NULL returned + * @returns new iterator, or #NULL on error + */ +DBusDirIter* +_dbus_directory_open (const DBusString *filename, + DBusResultCode *result) +{ + DIR *d; + DBusDirIter *iter; + const char *filename_c; + + _dbus_string_get_const_data (filename, &filename_c); + + d = opendir (filename_c); + if (d == NULL) + { + dbus_set_result (result, _dbus_result_from_errno (errno)); + return NULL; + } + + iter = dbus_new0 (DBusDirIter, 1); + if (iter == NULL) + { + closedir (d); + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + 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. #DBUS_RESULT_SUCCESS is always returned + * in result if no error occurs. + * + * @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 result return location for error, or #DBUS_RESULT_SUCCESS + * @returns #TRUE if filename was filled in with a new filename + */ +dbus_bool_t +_dbus_directory_get_next_file (DBusDirIter *iter, + DBusString *filename, + DBusResultCode *result) +{ + /* we always have to put something in result, since return + * value means whether there's a filename and doesn't + * reliably indicate whether an error was set. + */ + struct dirent *ent; + + dbus_set_result (result, DBUS_RESULT_SUCCESS); + + again: + errno = 0; + ent = readdir (iter->d); + if (ent == NULL) + { + dbus_set_result (result, + _dbus_result_from_errno (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_result (result, DBUS_RESULT_NO_MEMORY); + return FALSE; + } + else + return TRUE; + } +} + +/** + * Closes a directory iteration. + */ +void +_dbus_directory_close (DBusDirIter *iter) +{ + closedir (iter->d); + dbus_free (iter); +} + + /** @} end of sysdeps */ -- cgit