Diff between add7fa2da69abc7c0c72dcfb475f7f142a923cad and 67fd343844f55ac9da95f308b54d1d6a84a15470

Changed Files

File Additions Deletions Status
obexd/src/main.c +27 -10 modified
obexd/src/obex.c +34 -17 modified
obexd/src/obex.h +2 -1 modified

Full Patch

diff --git a/obexd/src/main.c b/obexd/src/main.c
index a9a1f8f..ca6aa59 100644
--- a/obexd/src/main.c
+++ b/obexd/src/main.c
@@ -62,6 +62,7 @@ static GMainLoop *main_loop = NULL;
 
 static int services = 0;
 static gboolean tty_needs_reinit = FALSE;
+static gboolean tty_open_allowed = TRUE;
 static int signal_pipe[2];
 
 #define TTY_RX_MTU 65535
@@ -77,6 +78,9 @@ int tty_init(int services, const gchar *root_path,
 
 	tty_needs_reinit = TRUE;
 
+	if (!tty_open_allowed)
+		return -EACCES;
+
 	fd = open(devnode, O_RDWR | O_NOCTTY);
 	if (fd < 0)
 		return fd;
@@ -178,7 +182,7 @@ static GOptionEntry options[] = {
 	{ NULL },
 };
 
-static void sig_usr1(int sig)
+static void sig_tty(int sig)
 {
 	if (write(signal_pipe[1], &sig, sizeof(sig)) != sizeof(sig))
 		error("unable to write to signal pipe");
@@ -190,13 +194,27 @@ static gboolean handle_signal(GIOChannel *io, GIOCondition cond,
 	int sig, fd = g_io_channel_unix_get_fd(io);
 
 	if (read(fd, &sig, sizeof(sig)) != sizeof(sig)) {
-		error("handle_sigusr1: unable to read signal from pipe");
+		error("handle_signal: unable to read signal from pipe");
 		return TRUE;
 	}
 
-	if (sig == SIGUSR1 && tty_needs_reinit)
-		tty_init(services, option_root, option_capability,
-				option_devnode);
+	switch (sig) {
+	case SIGUSR1:
+		debug("SIGUSR1");
+		tty_open_allowed = TRUE;
+		if (tty_needs_reinit)
+			tty_init(services, option_root, option_capability,
+							option_devnode);
+		break;
+	case SIGHUP:
+		debug("SIGHUP");
+		tty_open_allowed = FALSE;
+		obex_tty_session_stop();
+		break;
+	default:
+		error("handle_signal: got unexpected signal %d", sig);
+		break;
+	}
 
 	return TRUE;
 }
@@ -214,13 +232,12 @@ static int devnode_setup(void)
 	g_io_channel_unref(pipe_io);
 
 	memset(&sa, 0, sizeof(sa));
-	sa.sa_handler = sig_usr1;
+	sa.sa_handler = sig_tty;
 	sigaction(SIGUSR1, &sa, NULL);
+	sigaction(SIGHUP, &sa, NULL);
 
-	if (option_pcsuite) {
-		tty_needs_reinit = TRUE;
-		return 0;
-	}
+	if (option_pcsuite)
+		tty_open_allowed = FALSE;
 
 	return tty_init(services, option_root, option_capability,
 			option_devnode);
diff --git a/obexd/src/obex.c b/obexd/src/obex.c
index e8137be..6380702 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
@@ -65,6 +65,8 @@ static const guint8 PBAP_TARGET[TARGET_SIZE] = {
 /* Connection ID */
 static guint32 cid = 0x0000;
 
+static GSList *sessions = NULL;
+
 typedef struct {
 	guint8  version;
 	guint8  flags;
@@ -131,11 +133,16 @@ static void os_session_mark_aborted(struct obex_session *os)
 
 static void obex_session_free(struct obex_session *os)
 {
+	sessions = g_slist_remove(sessions, os);
+
 	os_reset_session(os);
 
 	if (os->current_folder)
 		g_free(os->current_folder);
 
+	if (os->io)
+		g_io_channel_unref(os->io);
+
 	if (os->target && !memcmp(os->target, PBAP_TARGET, TARGET_SIZE))
 		pbap_phonebook_context_destroy(os);
 
@@ -932,28 +939,27 @@ static gboolean obex_handle_input(GIOChannel *io,
 				GIOCondition cond, gpointer user_data)
 {
 	obex_t *obex = user_data;
-
-	if (cond & G_IO_NVAL)
-		return FALSE;
-
-	if (cond & (G_IO_HUP | G_IO_ERR)) {
-		struct obex_session *os;
-
-		error("HUP");
-
-		os = OBEX_GetUserData(obex);
-		if (os->server->devnode)
-			tty_closed();
-
-		return FALSE;
+	struct obex_session *os = OBEX_GetUserData(obex);
+
+	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+		error("obex_handle_input: poll event %s%s%s",
+				(cond & G_IO_HUP) ? "HUP " : "",
+				(cond & G_IO_ERR) ? "ERR " : "",
+				(cond & G_IO_NVAL) ? "NVAL " : "");
+		goto failed;
 	}
 
 	if (OBEX_HandleInput(obex, 1) < 0) {
 		error("Handle input error");
-		return FALSE;
+		goto failed;
 	}
 
 	return TRUE;
+
+failed:
+	if (os->server->devnode)
+		tty_closed();
+	return FALSE;
 }
 
 gint obex_session_start(gint fd, struct server *server)
@@ -1000,12 +1006,23 @@ gint obex_session_start(gint fd, struct server *server)
 			G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 			obex_handle_input, obex, obex_handle_destroy);
 	g_io_channel_set_close_on_unref(io, TRUE);
-	g_io_channel_unref(io);
+	os->io = io;
+
+	sessions = g_slist_prepend(sessions, os);
 
 	return 0;
 }
 
-gint obex_session_stop()
+gint obex_tty_session_stop(void)
 {
+	GSList *l;
+
+	for (l = sessions; l != NULL; l = l->next) {
+		struct obex_session *os = l->data;
+
+		if (os->server->devnode && os->io)
+			g_io_channel_shutdown(os->io, TRUE, NULL);
+	}
+
 	return 0;
 }
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index 021ac45..49f8b25 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
@@ -65,6 +65,7 @@ struct server {
 };
 
 struct obex_session {
+	GIOChannel	*io;
 	guint32		cid;
 	guint16		tx_mtu;
 	guint16		rx_mtu;
@@ -88,7 +89,7 @@ struct obex_session {
 };
 
 gint obex_session_start(gint fd, struct server *server);
-gint obex_session_stop();
+gint obex_tty_session_stop(void);
 
 void opp_get(obex_t *obex, obex_object_t *obj);
 void opp_put(obex_t *obex, obex_object_t *obj);