summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-sysdeps.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-03-13 00:56:43 +0000
committerHavoc Pennington <hp@redhat.com>2003-03-13 00:56:43 +0000
commit29560adcc79a259a0be3511c056ee7453aa26c04 (patch)
tree57e72dd26b5876da48379e5ff910c63e66cb7001 /dbus/dbus-sysdeps.c
parent799a3ff443f5357ae7857ebe989a7f92f7bd84df (diff)
2003-03-12 Havoc Pennington <hp@redhat.com>
Mega-patch that gets the message bus daemon initially handling out-of-memory. Work still needed. Also lots of random moving stuff to DBusError instead of ResultCode. * dbus/dbus-list.c (_dbus_list_length_is_one): new function * dbus/dbus-connection.c (dbus_connection_send_with_reply_and_block): use DBusError * dbus/dbus-bus.c: adapt to API changes, make it use DBusError not DBusResultCode * dbus/dbus-connection.c (dbus_connection_send): drop the result code here, as the only failure possible is OOM. * bus/connection.c (bus_connection_disconnect): rename bus_connection_disconnected as it's a notification only * bus/driver.c (bus_driver_handle_acquire_service): don't free "name" on get_args failure, should be done by get_args; don't disconnect client for bad args, just return an error. (bus_driver_handle_service_exists): ditto * bus/services.c (bus_services_list): NULL-terminate returned array * bus/driver.c (bus_driver_send_service_lost) (bus_driver_send_service_acquired): send messages from driver to a specific client to the client's unique name, not to the broadcast service. * dbus/dbus-message.c (decode_header_data): reject messages that contain no name field (_dbus_message_get_client_serial): rename to dbus_message_get_serial and make public (_dbus_message_set_serial): rename from set_client_serial (_dbus_message_set_reply_serial): make public (_dbus_message_get_reply_serial): make public * bus/connection.c (bus_connection_foreach): allow stopping iteration by returning FALSE from foreach function. * dbus/dbus-connection.c (dbus_connection_send_preallocated) (dbus_connection_free_preallocated_send) (dbus_connection_preallocate_send): new API for sending a message without possibility of malloc failure. (dbus_connection_send_message): rename to just dbus_connection_send (and same for whole function family) * dbus/dbus-errors.c (dbus_error_free): make this reinit the error * dbus/dbus-sysdeps.c (_dbus_exit): new function * bus/activation.c: handle/return errors * dbus/dbus-errors.h: add more DBUS_ERROR #define * dbus/dbus-sysdeps.c (_dbus_directory_open) (_dbus_file_get_contents) (_dbus_directory_get_next_file): use DBusError instead of DBusResultCode (_dbus_result_from_errno): move to this file
Diffstat (limited to 'dbus/dbus-sysdeps.c')
-rw-r--r--dbus/dbus-sysdeps.c321
1 files changed, 287 insertions, 34 deletions
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index d096ce3e..5d0be321 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)
*
- * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
*
* Licensed under the Academic Free License version 1.2
*
@@ -1604,11 +1604,13 @@ _dbus_get_current_time (long *tv_sec,
*
* @param str the string to append to
* @param filename filename to load
- * @returns result
+ * @param error place to set an error
+ * @returns #FALSE if error was set
*/
-DBusResultCode
+dbus_bool_t
_dbus_file_get_contents (DBusString *str,
- const DBusString *filename)
+ const DBusString *filename,
+ DBusError *error)
{
int fd;
struct stat sb;
@@ -1621,28 +1623,32 @@ _dbus_file_get_contents (DBusString *str,
/* O_BINARY useful on Cygwin */
fd = open (filename_c, O_RDONLY | O_BINARY);
if (fd < 0)
- return _dbus_result_from_errno (errno);
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "%s", _dbus_strerror (errno));
+ return FALSE;
+ }
if (fstat (fd, &sb) < 0)
{
- DBusResultCode result;
-
- result = _dbus_result_from_errno (errno); /* prior to close() */
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "%s", _dbus_strerror (errno));
_dbus_verbose ("fstat() failed: %s",
_dbus_strerror (errno));
close (fd);
- return result;
+ return FALSE;
}
if (sb.st_size > _DBUS_ONE_MEGABYTE)
{
- _dbus_verbose ("File size %lu is too large.\n",
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "File size %lu is too large.\n",
(unsigned long) sb.st_size);
close (fd);
- return DBUS_RESULT_FAILED;
+ return FALSE;
}
total = 0;
@@ -1657,34 +1663,35 @@ _dbus_file_get_contents (DBusString *str,
sb.st_size - total);
if (bytes_read <= 0)
{
- DBusResultCode result;
-
- result = _dbus_result_from_errno (errno); /* prior to close() */
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "%s", _dbus_strerror (errno));
_dbus_verbose ("read() failed: %s",
_dbus_strerror (errno));
close (fd);
_dbus_string_set_length (str, orig_len);
- return result;
+ return FALSE;
}
else
total += bytes_read;
}
close (fd);
- return DBUS_RESULT_SUCCESS;
+ return TRUE;
}
else if (sb.st_size != 0)
{
_dbus_verbose ("Can only open regular files at the moment.\n");
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Not a regular file");
close (fd);
- return DBUS_RESULT_FAILED;
+ return FALSE;
}
else
{
close (fd);
- return DBUS_RESULT_SUCCESS;
+ return TRUE;
}
}
@@ -1972,12 +1979,12 @@ struct DBusDirIter
* Open a directory to iterate over.
*
* @param filename the directory name
- * @param result return location for error code if #NULL returned
+ * @param error exception return object or #NULL
* @returns new iterator, or #NULL on error
*/
DBusDirIter*
_dbus_directory_open (const DBusString *filename,
- DBusResultCode *result)
+ DBusError *error)
{
DIR *d;
DBusDirIter *iter;
@@ -1988,15 +1995,16 @@ _dbus_directory_open (const DBusString *filename,
d = opendir (filename_c);
if (d == NULL)
{
- dbus_set_result (result, _dbus_result_from_errno (errno));
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "%s", _dbus_strerror (errno));
return NULL;
}
-
iter = dbus_new0 (DBusDirIter, 1);
if (iter == NULL)
{
closedir (d);
- dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
+ "Could not allocate memory for directory iterator");
return NULL;
}
@@ -2006,39 +2014,38 @@ _dbus_directory_open (const DBusString *filename,
}
/**
- * 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.
+ * 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 result return location for error, or #DBUS_RESULT_SUCCESS
+ * @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,
- DBusResultCode *result)
+ DBusError *error)
{
/* 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));
+ if (errno != 0)
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "%s", _dbus_strerror (errno));
return FALSE;
}
else if (ent->d_name[0] == '.' &&
@@ -2050,7 +2057,8 @@ _dbus_directory_get_next_file (DBusDirIter *iter,
_dbus_string_set_length (filename, 0);
if (!_dbus_string_append (filename, ent->d_name))
{
- dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
+ "No memory to read directory entry");
return FALSE;
}
else
@@ -2501,4 +2509,249 @@ _dbus_fd_set_close_on_exec (int fd)
fcntl (fd, F_SETFD, val);
}
+
+/**
+ * Converts a UNIX errno into a DBusResultCode.
+ *
+ * @todo should cover more errnos, specifically those
+ * from open().
+ *
+ * @param error_number the errno.
+ * @returns the result code.
+ */
+DBusResultCode
+_dbus_result_from_errno (int error_number)
+{
+ switch (error_number)
+ {
+ case 0:
+ return DBUS_RESULT_SUCCESS;
+
+#ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT:
+ return DBUS_RESULT_NOT_SUPPORTED;
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+ return DBUS_RESULT_NOT_SUPPORTED;
+#endif
+#ifdef ENFILE
+ case ENFILE:
+ return DBUS_RESULT_LIMITS_EXCEEDED; /* kernel out of memory */
+#endif
+#ifdef EMFILE
+ case EMFILE:
+ return DBUS_RESULT_LIMITS_EXCEEDED;
+#endif
+#ifdef EACCES
+ case EACCES:
+ return DBUS_RESULT_ACCESS_DENIED;
+#endif
+#ifdef EPERM
+ case EPERM:
+ return DBUS_RESULT_ACCESS_DENIED;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS:
+ return DBUS_RESULT_NO_MEMORY;
+#endif
+#ifdef ENOMEM
+ case ENOMEM:
+ return DBUS_RESULT_NO_MEMORY;
+#endif
+#ifdef EINVAL
+ case EINVAL:
+ return DBUS_RESULT_FAILED;
+#endif
+#ifdef EBADF
+ case EBADF:
+ return DBUS_RESULT_FAILED;
+#endif
+#ifdef EFAULT
+ case EFAULT:
+ return DBUS_RESULT_FAILED;
+#endif
+#ifdef ENOTSOCK
+ case ENOTSOCK:
+ return DBUS_RESULT_FAILED;
+#endif
+#ifdef EISCONN
+ case EISCONN:
+ return DBUS_RESULT_FAILED;
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED:
+ return DBUS_RESULT_NO_SERVER;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+ return DBUS_RESULT_TIMEOUT;
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH:
+ return DBUS_RESULT_NO_NETWORK;
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE:
+ return DBUS_RESULT_ADDRESS_IN_USE;
+#endif
+#ifdef EEXIST
+ case EEXIST:
+ return DBUS_RESULT_FILE_NOT_FOUND;
+#endif
+#ifdef ENOENT
+ case ENOENT:
+ return DBUS_RESULT_FILE_NOT_FOUND;
+#endif
+ }
+
+ return DBUS_RESULT_FAILED;
+}
+
+/**
+ * Converts a UNIX errno into a #DBusError name.
+ *
+ * @todo should cover more errnos, specifically those
+ * from open().
+ *
+ * @param error_number the errno.
+ * @returns an error name
+ */
+const char*
+_dbus_error_from_errno (int error_number)
+{
+ switch (error_number)
+ {
+ case 0:
+ return DBUS_ERROR_FAILED;
+
+#ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT:
+ return DBUS_ERROR_NOT_SUPPORTED;
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+ return DBUS_ERROR_NOT_SUPPORTED;
+#endif
+#ifdef ENFILE
+ case ENFILE:
+ return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
+#endif
+#ifdef EMFILE
+ case EMFILE:
+ return DBUS_ERROR_LIMITS_EXCEEDED;
+#endif
+#ifdef EACCES
+ case EACCES:
+ return DBUS_ERROR_ACCESS_DENIED;
+#endif
+#ifdef EPERM
+ case EPERM:
+ return DBUS_ERROR_ACCESS_DENIED;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS:
+ return DBUS_ERROR_NO_MEMORY;
+#endif
+#ifdef ENOMEM
+ case ENOMEM:
+ return DBUS_ERROR_NO_MEMORY;
+#endif
+#ifdef EINVAL
+ case EINVAL:
+ return DBUS_ERROR_FAILED;
+#endif
+#ifdef EBADF
+ case EBADF:
+ return DBUS_ERROR_FAILED;
+#endif
+#ifdef EFAULT
+ case EFAULT:
+ return DBUS_ERROR_FAILED;
+#endif
+#ifdef ENOTSOCK
+ case ENOTSOCK:
+ return DBUS_ERROR_FAILED;
+#endif
+#ifdef EISCONN
+ case EISCONN:
+ return DBUS_ERROR_FAILED;
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED:
+ return DBUS_ERROR_NO_SERVER;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+ return DBUS_ERROR_TIMEOUT;
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH:
+ return DBUS_ERROR_NO_NETWORK;
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE:
+ return DBUS_ERROR_ADDRESS_IN_USE;
+#endif
+#ifdef EEXIST
+ case EEXIST:
+ return DBUS_ERROR_FILE_NOT_FOUND;
+#endif
+#ifdef ENOENT
+ case ENOENT:
+ return DBUS_ERROR_FILE_NOT_FOUND;
+#endif
+ }
+
+ return DBUS_ERROR_FAILED;
+}
+
+/**
+ * Exit the process, returning the given value.
+ *
+ * @param code the exit code
+ */
+void
+_dbus_exit (int code)
+{
+ _exit (code);
+}
+
+/**
+ * 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_string_get_const_data (filename, &filename_c);
+
+ 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;
+}
+
/** @} end of sysdeps */