Diff between fd6e896dd1fb2964075b1c7d5ebe77ecb3dd94ba and bdf845d31a2841b0e3abee0a28bbe9b118e63dda

Changed Files

File Additions Deletions Status
obexd/plugins/filesystem.c +65 -30 modified
obexd/src/mimetype.c +2 -2 modified
obexd/src/mimetype.h +4 -3 modified
obexd/src/obex.c +18 -22 modified

Full Patch

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
@@ -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 80f7374..e3e1f1b 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 8ddb9e3..d9f067f 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 a596171..a8c716a 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;
 	}