diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2006-11-10 23:09:02 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2006-11-10 23:09:02 +0000 |
commit | f64cc95873c872ad5a34abe6418a2e26570d5d02 (patch) | |
tree | 0b9fbe3bd2e3ac54c11b03e54c6681f552921fcd | |
parent | e1046e6b02c2eef72ad63f2a61949e1ca606f63f (diff) |
Allow running a command after successful connection creation
-rw-r--r-- | rfcomm/main.c | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/rfcomm/main.c b/rfcomm/main.c index 9baf8533..efffcc9a 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -40,6 +40,7 @@ #include <sys/param.h> #include <sys/ioctl.h> #include <sys/socket.h> +#include <sys/wait.h> #include <bluetooth/bluetooth.h> #include <bluetooth/hci.h> @@ -257,6 +258,56 @@ static int release_all(int ctl) return 0; } +static void run_cmdline(struct pollfd *p, sigset_t* sigs, char *devname, + int argc, char **argv) +{ + int i = 0; + pid_t pid, child; + struct timespec ts; + int status = 0; + char **cmdargv; + + cmdargv = malloc((argc + 1) * sizeof(char*)); + if (!cmdargv) + return; + + for (i = 0; i < argc; i++) + cmdargv[i] = (strcmp(argv[i], "{}") == 0) ? devname : argv[i]; + cmdargv[i] = NULL; + + pid = fork(); + + switch (pid) { + case 0: + i = execvp(cmdargv[0], cmdargv); + fprintf(stderr, "Couldn't execute command %s (errno=%d:%s)\n", + cmdargv[0], errno, strerror(errno)); + break; + case -1: + fprintf(stderr, "Couldn't fork to execute command %s\n", + cmdargv[0]); + break; + default: + while (1) { + child = waitpid(-1, &status, WNOHANG); + if (child == pid || (child < 0 && errno != EAGAIN)) + break; + + p->revents = 0; + ts.tv_sec = 0; + ts.tv_nsec = 200; + if (ppoll(p, 1, &ts, sigs) || __io_canceled) { + kill(pid, SIGTERM); + waitpid(pid, &status, 0); + break; + } + } + break; + } + + free(cmdargv); +} + static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) { struct sockaddr_rc laddr, raddr; @@ -520,17 +571,32 @@ static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv p.fd = fd; p.events = POLLERR | POLLHUP; - while (!__io_canceled) { - p.revents = 0; - if (ppoll(&p, 1, NULL, &sigs) > 0) - break; - } + if (argc <= 2) { + while (!__io_canceled) { + p.revents = 0; + if (ppoll(&p, 1, NULL, &sigs) > 0) + break; + } + } else + run_cmdline(&p, &sigs, devname, argc - 2, argv + 2); + + sa.sa_handler = NULL; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); printf("Disconnected\n"); close(fd); } +static void cmd_watch(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ + while (!__io_canceled) { + cmd_listen(ctl, dev, bdaddr, argc, argv); + usleep(10000); + } +} + static void cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) { if (strcmp(argv[0], "all") == 0) @@ -573,7 +639,8 @@ struct { { "release", "unbind", cmd_release, "<dev>", "Release device" }, { "show", "info", cmd_show, "<dev>", "Show device" }, { "connect", "conn", cmd_connect, "<dev> <bdaddr> [channel]", "Connect device" }, - { "listen", "server", cmd_listen, "<dev> [channel]", "Listen" }, + { "listen", "server", cmd_listen, "<dev> [channel [cmd]]", "Listen" }, + { "watch", "watch", cmd_watch, "<dev> [channel [cmd]]", "Watch" }, { NULL, NULL, NULL, 0, 0 } }; |