Return-Path: Date: Mon, 13 Jun 2005 14:22:44 -0300 From: Luiz Fernando Capitulino To: marcel@holtmann.org Cc: bluez-users@lists.sourceforge.net Subject: [PATCH] - Fixes rfcomm program error codes. Message-Id: <20050613142244.59f281c4.lcapitulino@conectiva.com.br> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII List-ID: 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();