Linux bluetooth development
 help / color / mirror / Atom feed
From: Luiz Fernando Capitulino <lcapitulino@conectiva.com.br>
To: marcel@holtmann.org
Cc: bluez-users@lists.sourceforge.net
Subject: [PATCH] - Fixes rfcomm program error codes.
Date: Mon, 13 Jun 2005 14:22:44 -0300	[thread overview]
Message-ID: <20050613142244.59f281c4.lcapitulino@conectiva.com.br> (raw)


Hi there,

rfcomm program does not return proper error codes to the environment,
this makes hard to use it from a shell script or from another program.

Here goes a patch to fix it. I didn't have much time to test it, so
feedback are welcome.


- Changes functions to return -1 on error and 0 on success
- Adds missing error checks
- Adds missing error messages
- Fixed rfcomm exit() return codes

 rfcomm/main.c |  192 +++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 131 insertions(+), 61 deletions(-)


diff -X /home/lcapitulino/kernels/2.6/dontdiff -Nparu a/rfcomm/main.c a~/rfcomm/main.c
--- a/rfcomm/main.c	2004-11-25 10:05:16.000000000 -0200
+++ a~/rfcomm/main.c	2005-06-12 20:09:07.000000000 -0300
@@ -120,7 +120,7 @@ static void print_dev_info(struct rfcomm
 		di->flags ? rfcomm_flagstostr(di->flags) : "");
 }
 
-static void print_dev_list(int ctl, int flags)
+static int print_dev_list(int ctl, int flags)
 {
 	struct rfcomm_dev_list_req *dl;
 	struct rfcomm_dev_info *di;
@@ -129,7 +129,7 @@ static void print_dev_list(int ctl, int 
 	dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di));
 	if (!dl) {
 		perror("Can't allocate memory");
-		exit(1);
+		return -1;
 	}
 
 	dl->dev_num = RFCOMM_MAX_DEV;
@@ -137,11 +137,13 @@ static void print_dev_list(int ctl, int 
 
 	if (ioctl(ctl, RFCOMMGETDEVLIST, (void *) dl) < 0) {
 		perror("Can't get device list");
-		exit(1);
+		return -1;
 	}
 
 	for (i = 0; i < dl->dev_num; i++)
 		print_dev_info(di + i);
+
+	return 0;
 }
 
 static int create_dev(int ctl, int dev, uint32_t flags, bdaddr_t *bdaddr, int argc, char **argv)
@@ -165,7 +167,7 @@ static int create_dev(int ctl, int dev, 
 
 		if (bacmp(&req.dst, BDADDR_ANY) == 0) {
 			fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev);
-			return -EFAULT;
+			return -1;
 		}
 		
 	} else {
@@ -205,7 +207,8 @@ static int create_all(int ctl)
 		req.channel = rfcomm_opts[i].channel;
 
 		if (bacmp(&req.dst, BDADDR_ANY) != 0)
-			ioctl(ctl, RFCOMMCREATEDEV, &req);
+			if (ioctl(ctl, RFCOMMCREATEDEV, &req) < 0)
+				perror("Can't create RFCOMM device");
 	}
 
 	return 0;
@@ -234,7 +237,7 @@ static int release_all(int ctl)
 	dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di));
 	if (!dl) {
 		perror("Can't allocate memory");
-		exit(1);
+		return -1;
 	}
 
 	dl->dev_num = RFCOMM_MAX_DEV;
@@ -242,7 +245,7 @@ static int release_all(int ctl)
 
 	if (ioctl(ctl, RFCOMMGETDEVLIST, (void *) dl) < 0) {
 		perror("Can't get device list");
-		exit(1);
+		return -1;
 	}
 
 	for (i = 0; i < dl->dev_num; i++)
@@ -251,7 +254,7 @@ static int release_all(int ctl)
 	return 0;
 }
 
-static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
+static int cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
 {
 	struct sockaddr_rc laddr, raddr;
 	struct rfcomm_dev_req req;
@@ -268,7 +271,7 @@ static void cmd_connect(int ctl, int dev
 	if (argc < 2) {
 		if (rfcomm_read_config(rfcomm_config_file) < 0) {
 			perror("Can't open RFCOMM config file");
-			return;
+			return -1;
 		}
 
 		raddr.rc_family = AF_BLUETOOTH;
@@ -277,7 +280,7 @@ static void cmd_connect(int ctl, int dev
 
 		if (bacmp(&raddr.rc_bdaddr, BDADDR_ANY) == 0) {
 			fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev);
-			return;
+			return -1;
 		}
 	} else {
 		raddr.rc_family = AF_BLUETOOTH;
@@ -291,26 +294,26 @@ static void cmd_connect(int ctl, int dev
 
 	if ((sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
 		perror("Can't create RFCOMM socket");
-		return;
+		return -1;
 	}
 
 	if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
 		perror("Can't bind RFCOMM socket");
 		close(sk);
-		return;
+		return -1;
 	}
 
 	if (connect(sk, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) {
 		perror("Can't connect RFCOMM socket");
 		close(sk);
-		return;
+		return -1;
 	}
 
 	alen = sizeof(laddr);
 	if (getsockname(sk, (struct sockaddr *)&laddr, &alen) < 0) {
 		perror("Can't get RFCOMM socket name");
 		close(sk);
-		return;
+		return -1;
 	}
 
 	memset(&req, 0, sizeof(req));
@@ -324,7 +327,7 @@ static void cmd_connect(int ctl, int dev
 	if ((dev = ioctl(sk, RFCOMMCREATEDEV, &req)) < 0) {
 		perror("Can't create RFCOMM TTY");
 		close(sk);
-		return;
+		return -1;
 	}
 
 	snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev);
@@ -344,35 +347,60 @@ static void cmd_connect(int ctl, int dev
 			ioctl(ctl, RFCOMMRELEASEDEV, &req);
 
 			close(sk);
-			return;
+			return -1;
 		}
 	}
 
+	close(sk);
+
 	if (rfcomm_raw_tty) {
-		tcflush(fd, TCIOFLUSH);
+		if (tcflush(fd, TCIOFLUSH) < 0) {
+			perror("Can't flush device data");
+			return -1;
+		}
 
 		cfmakeraw(&ti);
-		tcsetattr(fd, TCSANOW, &ti);
-	}
 
-	close(sk);
+		if (tcsetattr(fd, TCSANOW, &ti) < 0) {
+			perror("Can't set terminal attributes");
+			return -1;
+		}
+	}
 
 	ba2str(&req.dst, dst);
 	printf("Connected %s to %s on channel %d\n", devname, dst, req.channel);
-	printf("Press CTRL-C for hangup\n");
 
 	memset(&sa, 0, sizeof(sa));
 	sa.sa_flags   = SA_NOCLDSTOP;
 	sa.sa_handler = SIG_IGN;
-	sigaction(SIGCHLD, &sa, NULL);
-	sigaction(SIGPIPE, &sa, NULL);
+	if (sigaction(SIGCHLD, &sa, NULL) < 0) {
+		perror("Can't change SIGCHLD behaivor");
+		return -1;
+	}
+
+	if (sigaction(SIGPIPE, &sa, NULL) < 0) {
+		perror("Can't change SIGPIPE behaivor");
+		return -1;
+	}
 
 	sa.sa_handler = sig_term;
-	sigaction(SIGTERM, &sa, NULL);
-	sigaction(SIGINT,  &sa, NULL);
+	if (sigaction(SIGTERM, &sa, NULL) < 0) {
+		perror("Can't change SIGTERM behaivor");
+		return -1;
+	}
+
+	if (sigaction(SIGINT,  &sa, NULL) < 0) {
+		perror("Can't change SIGINT behaivor");
+		return -1;
+	}
+
+	printf("Press CTRL-C for hangup\n");
 
 	sa.sa_handler = sig_hup;
-	sigaction(SIGHUP, &sa, NULL);
+	if (sigaction(SIGHUP, &sa, NULL) < 0) {
+		perror("Can't change SIGHUP baivor");
+		return -1;
+	}
 
 	p.fd = fd;
 	p.events = POLLERR | POLLHUP;
@@ -386,9 +414,10 @@ static void cmd_connect(int ctl, int dev
 	printf("Disconnected\n");
 
 	close(fd);
+	return 0;
 }
 
-static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
+static int cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
 {
 	struct sockaddr_rc laddr, raddr;
 	struct rfcomm_dev_req req;
@@ -404,27 +433,36 @@ static void cmd_listen(int ctl, int dev,
 
 	if ((sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
 		perror("Can't create RFCOMM socket");
-		return;
+		return -1;
 	}
 
 	if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
 		perror("Can't bind RFCOMM socket");
 		close(sk);
-		return;
+		return -1;
 	}
 
 	printf("Waiting for connection on channel %d\n", laddr.rc_channel);
 
-	listen(sk, 10);
+	if (listen(sk, 10) < 0) {
+		perror("Can't listen RFCOMM socket");
+		close(sk);
+		return -1;
+	}
 
 	alen = sizeof(raddr);
-	nsk = accept(sk, (struct sockaddr *) &raddr, &alen);
+	if ((nsk = accept(sk, (struct sockaddr *) &raddr, &alen)) < 0) {
+		perror("Can't accept connection in RFCOMM socket");
+		close(sk);
+		return -1;
+	}
 
 	alen = sizeof(laddr);
 	if (getsockname(nsk, (struct sockaddr *)&laddr, &alen) < 0) {
 		perror("Can't get RFCOMM socket name");
+		close(sk);
 		close(nsk);
-		return;
+		return -1;
 	}
 
 	memset(&req, 0, sizeof(req));
@@ -438,7 +476,8 @@ static void cmd_listen(int ctl, int dev,
 	if ((dev = ioctl(nsk, RFCOMMCREATEDEV, &req)) < 0) {
 		perror("Can't create RFCOMM TTY");
 		close(sk);
-		return;
+		close(nsk);
+		return -1;
 	}
 
 	snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev);
@@ -458,36 +497,61 @@ static void cmd_listen(int ctl, int dev,
 			ioctl(ctl, RFCOMMRELEASEDEV, &req);
 
 			close(sk);
-			return;
+			return -1;
 		}
 	}
 
+	close(sk);
+	close(nsk);
+
 	if (rfcomm_raw_tty) {
-		tcflush(fd, TCIOFLUSH);
+		if (tcflush(fd, TCIOFLUSH) < 0) {
+			perror("Can't flush device data");
+			return -1;
+		}
 
 		cfmakeraw(&ti);
-		tcsetattr(fd, TCSANOW, &ti);
-	}
 
-	close(sk);
-	close(nsk);
+		if (tcsetattr(fd, TCSANOW, &ti) < 0) {
+			perror("Can't set terminal attributes");
+			return -1;
+		}
+	}
 
 	ba2str(&req.dst, dst);
 	printf("Connection from %s to %s\n", dst, devname);
-	printf("Press CTRL-C for hangup\n");
 
 	memset(&sa, 0, sizeof(sa));
 	sa.sa_flags   = SA_NOCLDSTOP;
 	sa.sa_handler = SIG_IGN;
-	sigaction(SIGCHLD, &sa, NULL);
-	sigaction(SIGPIPE, &sa, NULL);
+	if (sigaction(SIGCHLD, &sa, NULL) < 0) {
+		perror("Can't change SIGCHLD behaivor");
+		return -1;
+	}
+
+	if (sigaction(SIGPIPE, &sa, NULL) < 0) {
+		perror("Can't change SIGPIPE behaivor");
+		return -1;
+	}
 
 	sa.sa_handler = sig_term;
-	sigaction(SIGTERM, &sa, NULL);
-	sigaction(SIGINT,  &sa, NULL);
+	if (sigaction(SIGTERM, &sa, NULL) < 0) {
+		perror("Can't change SIGTERM behaivor");
+		return -1;
+	}
+
+	if (sigaction(SIGINT,  &sa, NULL) < 0) {
+		perror("Can't change SIGINT behaivor");
+		return -1;
+	}
+
+	printf("Press CTRL-C for hangup\n");
 
 	sa.sa_handler = sig_hup;
-	sigaction(SIGHUP, &sa, NULL);
+	if (sigaction(SIGHUP, &sa, NULL) < 0) {
+		perror("Can't change SIGHUP baivor");
+		return -1;
+	}
 
 	p.fd = fd;
 	p.events = POLLERR | POLLHUP;
@@ -501,43 +565,49 @@ static void cmd_listen(int ctl, int dev,
 	printf("Disconnected\n");
 
 	close(fd);
+	return 0;
 }
 
-static void cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
+static int cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
 {
 	if (strcmp(argv[0], "all") == 0)
-		create_all(ctl);
+		return create_all(ctl);
 	else
-		create_dev(ctl, dev, 0, bdaddr, argc, argv);
+		return create_dev(ctl, dev, 0, bdaddr, argc, argv);
 }
 
-static void cmd_release(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
+static int cmd_release(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
 {
 	if (strcmp(argv[0], "all") == 0)
-		release_all(ctl);
+		return release_all(ctl);
 	else
-		release_dev(ctl, dev, 0);
+		return release_dev(ctl, dev, 0);
 }
 
-static void cmd_show(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
+static int cmd_show(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
 {
+	int ret;
+
 	if (strcmp(argv[0], "all") == 0)
-		print_dev_list(ctl, 0);
+		ret = print_dev_list(ctl, 0);
 	else {
 		struct rfcomm_dev_info di = { id: atoi(argv[0]) };
 		if (ioctl(ctl, RFCOMMGETDEVINFO, &di) < 0) {
 			perror("Get info failed");
-			exit(1);
+			return -1;
 		}
 
 		print_dev_info(&di);
+		ret = 0;
 	}
+
+	return ret;
 }
 
 struct {
 	char *cmd;
 	char *alt;
-	void (*func)(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv);
+	int (*func)(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv);
 	char *opt;
 	char *doc;
 } command[] = {
@@ -587,7 +657,7 @@ int main(int argc, char *argv[]) 
 {
 
 	bdaddr_t bdaddr;
-	int i, opt, ctl, dev_id, show_all = 0;
+	int i, err, opt, ctl, dev_id, show_all = 0;
 
 	bacpy(&bdaddr, BDADDR_ANY);
 
@@ -616,7 +686,7 @@ int main(int argc, char *argv[]) 
 			exit(0);
 
 		default:
-			exit(0);
+			exit(1);
 		}
 	}
 
@@ -633,9 +703,9 @@ int main(int argc, char *argv[]) 
 	}
 
 	if (show_all) {
-		print_dev_list(ctl, 0);
+		err = print_dev_list(ctl, 0);
 		close(ctl);
-		exit(0);
+		err ? exit(1) : exit(0);
 	}
 
 	if (strncmp(argv[1], "/dev/rfcomm", 11) == 0)
@@ -650,9 +720,9 @@ int main(int argc, char *argv[]) 
 			continue;
 		argc--;
 		argv++;
-		command[i].func(ctl, dev_id, &bdaddr, argc, argv);
+		err = command[i].func(ctl, dev_id, &bdaddr, argc, argv);
 		close(ctl);
-		exit(0);
+		err ? exit(1) : exit(0);
 	}
 
 	usage();

                 reply	other threads:[~2005-06-13 17:22 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050613142244.59f281c4.lcapitulino@conectiva.com.br \
    --to=lcapitulino@conectiva.com.br \
    --cc=bluez-users@lists.sourceforge.net \
    --cc=marcel@holtmann.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox