diff --git a/obexd/plugins/filesystem.c b/obexd/plugins/filesystem.c
index bf2898d..7458674 100644
--- a/obexd/plugins/filesystem.c
+++ b/obexd/plugins/filesystem.c
}
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:
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 {
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);
}
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;
if (size)
*size = object->buffer->len;
- return object;
+ goto done;
}
argv[0] = &name[1];
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;
DIR *dp;
GString *object;
gboolean root, pcsuite;
- gint err;
+ int ret;
os = obex_get_session(NULL);
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;
}
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);
if (size)
*size = object->len;
+ if (err)
+ *err = 0;
+
return object;
failed:
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 80f7374..e3e1f1b 100644
--- a/obexd/src/mimetype.c
+++ b/obexd/src/mimetype.c
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;
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 8ddb9e3..d9f067f 100644
--- a/obexd/src/mimetype.h
+++ b/obexd/src/mimetype.h
#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);
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 a596171..a8c716a 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
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;
}
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;
{
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;
}
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;
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;
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;
}