From bdf845d31a2841b0e3abee0a28bbe9b118e63dda Mon Sep 17 00:00:00 2001 From: Luiz Augusto Von Dentz Date: Fri, 26 Feb 2010 16:31:06 +0200 Subject: [PATCH] obexd: Fix writing to errno The primary intention of this is to avoid writing to errno since it belongs to libc, but we also follow posix recomendation to have the errno as return: "All POSIX.1c functions avoid using errno and, instead, return the error number directly as the function return value, with a return value of zero indicating that no error was detected. This strategy is, in fact, being followed on a POSIX-wide basis for all new functions." --- obexd/plugins/filesystem.c | 95 ++++++++++++++++++++++++++------------ obexd/src/mimetype.c | 4 +- obexd/src/mimetype.h | 7 +-- obexd/src/obex.c | 40 ++++++++-------- 4 files changed, 89 insertions(+), 57 deletions(-) diff --git a/obexd/plugins/filesystem.c b/obexd/plugins/filesystem.c index bf2898d6e..745867407 100644 --- a/obexd/plugins/filesystem.c +++ b/obexd/plugins/filesystem.c @@ -123,37 +123,49 @@ static gchar *file_stat_line(gchar *filename, struct stat *fstat, } static gpointer filesystem_open(const char *name, int oflag, mode_t mode, - size_t *size) + size_t *size, int *err) { struct stat stats; struct statvfs buf; int fd = open(name, oflag, mode); - if (fd < 0) + if (fd < 0) { + if (err) + *err = -errno; return NULL; + } if (fstat(fd, &stats) < 0) { - error("fstat(fd=%d): %s (%d)", fd, strerror(errno), errno); + if (err) + *err = -errno; goto failed; } if (oflag == O_RDONLY) { if (size) *size = stats.st_size; - return GINT_TO_POINTER(fd); + goto done; } - if (fstatvfs(fd, &buf) < 0) + if (fstatvfs(fd, &buf) < 0) { + if (err) + *err = -errno; goto failed; + } if (size == NULL) - return GINT_TO_POINTER(fd); + goto done; if (buf.f_bsize * buf.f_bavail < *size) { - errno = ENOSPC; + if (err) + *err = -ENOSPC; goto failed; } +done: + if (err) + *err = 0; + return GINT_TO_POINTER(fd); failed: @@ -163,17 +175,32 @@ failed: static int filesystem_close(gpointer object) { - return close(GPOINTER_TO_INT(object)); + if (close(GPOINTER_TO_INT(object)) < 0) + return -errno; + + return 0; } static ssize_t filesystem_read(gpointer object, void *buf, size_t count) { - return read(GPOINTER_TO_INT(object), buf, count); + ssize_t ret; + + ret = read(GPOINTER_TO_INT(object), buf, count); + if (ret < 0) + return -errno; + + return ret; } static ssize_t filesystem_write(gpointer object, const void *buf, size_t count) { - return write(GPOINTER_TO_INT(object), buf, count); + ssize_t ret; + + ret = write(GPOINTER_TO_INT(object), buf, count); + if (ret < 0) + return -errno; + + return ret; } struct capability_object { @@ -195,9 +222,9 @@ static void script_exited(GPid pid, gint status, gpointer data) memset(buf, 0, sizeof(buf)); if (read(object->err, buf, sizeof(buf)) > 0) error("%s", buf); - obex_object_set_io_flags(data, G_IO_ERR); + obex_object_set_io_flags(data, G_IO_ERR, -EPERM); } else - obex_object_set_io_flags(data, G_IO_IN); + obex_object_set_io_flags(data, G_IO_IN, 0); g_spawn_close_pid(pid); } @@ -212,14 +239,14 @@ static int capability_exec(const char **argv, int *output, int *err) NULL, &pid, NULL, output, err, &gerr)) { error("%s", gerr->message); g_error_free(gerr); - return -EINVAL; + return -EPERM; } return pid; } static gpointer capability_open(const char *name, int oflag, mode_t mode, - size_t *size) + size_t *size, int *err) { struct capability_object *object = NULL; gchar *buf; @@ -249,7 +276,7 @@ static gpointer capability_open(const char *name, int oflag, mode_t mode, if (size) *size = object->buffer->len; - return object; + goto done; } argv[0] = &name[1]; @@ -264,16 +291,22 @@ static gpointer capability_open(const char *name, int oflag, mode_t mode, if (size) *size = 1; +done: + if (err) + *err = 0; + return object; fail: + if (err) + *err = -EPERM; + g_free(object); - errno = EPERM; return NULL; } static gpointer folder_open(const char *name, int oflag, mode_t mode, - size_t *size) + size_t *size, int *err) { struct obex_session *os; struct stat fstat, dstat; @@ -281,7 +314,7 @@ static gpointer folder_open(const char *name, int oflag, mode_t mode, DIR *dp; GString *object; gboolean root, pcsuite; - gint err; + int ret; os = obex_get_session(NULL); @@ -296,20 +329,21 @@ static gpointer folder_open(const char *name, int oflag, mode_t mode, dp = opendir(name); if (dp == NULL) { - errno = ENOENT; + if (err) + *err = -ENOENT; goto failed; } if (root && os->server->symlinks) - err = stat(name, &dstat); + ret = stat(name, &dstat); else { object = g_string_append(object, FL_PARENT_FOLDER_ELEMENT); - err = lstat(name, &dstat); + ret = lstat(name, &dstat); } - if (err < 0) { - error("%s: %s(%d)", root ? "stat" : "lstat", - strerror(errno), errno); + if (ret < 0) { + if (err) + *err = -errno; goto failed; } @@ -330,11 +364,11 @@ static gpointer folder_open(const char *name, int oflag, mode_t mode, fullname = g_build_filename(os->current_folder, ep->d_name, NULL); if (root && os->server->symlinks) - err = stat(fullname, &fstat); + ret = stat(fullname, &fstat); else - err = lstat(fullname, &fstat); + ret = lstat(fullname, &fstat); - if (err < 0) { + if (ret < 0) { debug("%s: %s(%d)", root ? "stat" : "lstat", strerror(errno), errno); g_free(name); @@ -362,6 +396,9 @@ static gpointer folder_open(const char *name, int oflag, mode_t mode, if (size) *size = object->len; + if (err) + *err = 0; + return object; failed: @@ -403,10 +440,8 @@ static ssize_t capability_read(gpointer object, void *buf, size_t count) if (obj->buffer) return string_read(obj->buffer, buf, count); - if (obj->pid >= 0) { - errno = EAGAIN; + if (obj->pid >= 0) return -EAGAIN; - } return read(obj->output, buf, count); } diff --git a/obexd/src/mimetype.c b/obexd/src/mimetype.c index 80f73742b..e3e1f1bb4 100644 --- a/obexd/src/mimetype.c +++ b/obexd/src/mimetype.c @@ -46,7 +46,7 @@ struct io_watch { gpointer user_data; }; -void obex_object_set_io_flags(gpointer object, int flags) +void obex_object_set_io_flags(gpointer object, int flags, int err) { GSList *l; @@ -56,7 +56,7 @@ void obex_object_set_io_flags(gpointer object, int flags) if (watch->object != object) continue; - if (watch->func(object, flags, watch->user_data) == TRUE) + if (watch->func(object, flags, err, watch->user_data) == TRUE) continue; if (g_slist_find(watches, watch) == NULL) diff --git a/obexd/src/mimetype.h b/obexd/src/mimetype.h index 8ddb9e3bc..d9f067fd7 100644 --- a/obexd/src/mimetype.h +++ b/obexd/src/mimetype.h @@ -23,13 +23,14 @@ #define TARGET_SIZE 16 -typedef gboolean (*obex_object_io_func) (gpointer object, int flags, +typedef gboolean (*obex_object_io_func) (gpointer object, int flags, int err, gpointer user_data); struct obex_mime_type_driver { const guint8 *target; const char *mimetype; - gpointer (*open) (const char *name, int oflag, mode_t mode, size_t *size); + gpointer (*open) (const char *name, int oflag, mode_t mode, + size_t *size, int *err); int (*close) (gpointer object); ssize_t (*read) (gpointer object, void *buf, size_t count); ssize_t (*write) (gpointer object, const void *buf, size_t count); @@ -43,4 +44,4 @@ void obex_mime_type_driver_unregister(struct obex_mime_type_driver *driver); struct obex_mime_type_driver *obex_mime_type_driver_find(const guint8 *target, const char *mimetype); -void obex_object_set_io_flags(gpointer object, int flags); +void obex_object_set_io_flags(gpointer object, int flags, int err); diff --git a/obexd/src/obex.c b/obexd/src/obex.c index a596171ff..a8c716afd 100644 --- a/obexd/src/obex.c +++ b/obexd/src/obex.c @@ -388,10 +388,9 @@ int os_prepare_get(struct obex_session *os, gchar *filename, size_t *size) gint err; gpointer object; - object = os->driver->open(filename, O_RDONLY, 0, size); + object = os->driver->open(filename, O_RDONLY, 0, size, &err); if (object == NULL) { - err = -errno; - error("open(%s): %s (%d)", filename, strerror(errno), errno); + error("open(%s): %s (%d)", filename, strerror(-err), -err); goto fail; } @@ -434,15 +433,13 @@ static gint obex_write_stream(struct obex_session *os, len = os->driver->read(os->object, os->buf, os->tx_mtu); if (len < 0) { - gint err = errno; - - error("read(): %s (%d)", strerror(err), err); - if (err == EAGAIN) - return -err; + error("read(): %s (%d)", strerror(-len), -len); + if (len == -EAGAIN) + return len; g_free(os->buf); os->buf = NULL; - return -err; + return len; } ptr = os->buf; @@ -471,13 +468,14 @@ gint os_prepare_put(struct obex_session *os) { gchar *path; gint len; + int err; path = g_build_filename(os->current_folder, os->name, NULL); os->object = os->driver->open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600, os->size != OBJECT_SIZE_UNKNOWN ? - (size_t *) &os->size : NULL); + (size_t *) &os->size : NULL, &err); if (os->object == NULL) { - error("open(%s): %s (%d)", path, strerror(errno), errno); + error("open(%s): %s (%d)", path, strerror(-err), -err); g_free(path); return -EPERM; } @@ -495,13 +493,11 @@ gint os_prepare_put(struct obex_session *os) w = os->driver->write(os->object, os->buf + len, os->offset - len); if (w < 0) { - gint err = errno; - error("write(%s): %s (%d)", path, strerror(errno), - errno); - if (err == EINTR) + error("write(%s): %s (%d)", path, strerror(-w), -w); + if (w == -EINTR) continue; else - return -err; + return w; } len += w; @@ -550,11 +546,10 @@ static gint obex_read_stream(struct obex_session *os, obex_t *obex, w = os->driver->write(os->object, buffer + len, size - len); if (w < 0) { - gint err = errno; - if (err == EINTR) + if (w == -EINTR) continue; else - return -err; + return w; } len += w; @@ -565,13 +560,14 @@ static gint obex_read_stream(struct obex_session *os, obex_t *obex, return 0; } -static gboolean handle_async_io(gpointer object, int flags, gpointer user_data) +static gboolean handle_async_io(gpointer object, int flags, int err, + gpointer user_data) { struct obex_session *os = user_data; int ret = 0; - if (flags & (G_IO_ERR | G_IO_HUP)) { - ret = -errno; + if (err < 0) { + ret = err; goto proceed; } -- 2.47.3