summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2006-11-10 23:09:02 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2006-11-10 23:09:02 +0000
commitf64cc95873c872ad5a34abe6418a2e26570d5d02 (patch)
tree0b9fbe3bd2e3ac54c11b03e54c6681f552921fcd
parente1046e6b02c2eef72ad63f2a61949e1ca606f63f (diff)
Allow running a command after successful connection creation
-rw-r--r--rfcomm/main.c79
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 }
};