diff options
-rw-r--r-- | command.c | 57 | ||||
-rw-r--r-- | commander.cfg | 3 |
2 files changed, 46 insertions, 14 deletions
@@ -4,6 +4,7 @@ #include <unistd.h> #include <errno.h> #include <fcntl.h> +#include <signal.h> #include <sys/types.h> #include <sys/wait.h> @@ -26,6 +27,8 @@ typedef struct { static size_t ncommands = 0; static command_t* commands = NULL; +//TODO timeouting / SIGKILL + int command_handle(int fd){ size_t n = 0; ssize_t bytes; @@ -35,7 +38,7 @@ int command_handle(int fd){ for(n = 0; n < ncommands; n++){ if(commands[n].flags & COMMAND_ALIVE && fd == commands[n].iopipe[0]){ - bytes = read(fd, input_buffer, sizeof(input_buffer)); + bytes = read(fd, input_buffer, sizeof(input_buffer) - 1); if(bytes < 0){ perror("cmd/recv"); } @@ -47,6 +50,7 @@ int command_handle(int fd){ } else{ //TODO handle + input_buffer[bytes] = 0; printf("%d bytes from command %lu: %s\n", bytes, n, input_buffer); } return 0; @@ -77,8 +81,11 @@ void command_reap(){ if(commands[n].child == status){ commands[n].flags = 0; commands[n].child = -1; - close(commands[n].iopipe[0]); - commands[n].iopipe[0] = -1; + if(commands[n].iopipe[0] >= 0){ + core_manage_fd(commands[n].iopipe[0], 0, system_command); + close(commands[n].iopipe[0]); + commands[n].iopipe[0] = -1; + } printf("Command %lu terminated\n", n); } } @@ -112,12 +119,24 @@ static int command_spawn(command_t* cmd, char* command_name, char* command_stati _exit(1); } + //make child a session leader + setpgrp(); + //connect stdout while((dup2(cmd->iopipe[1], STDOUT_FILENO) == -1) && (errno == EINTR)) { } close(cmd->iopipe[1]); - execl(command_name, command_static, NULL); - perror("cmd/exec"); + + //TODO set environment + + //run actual command + if(handler){ + execl(handler, handler, command_name, command_static, NULL); + } + else{ + execl(command_name, command_name, command_static, NULL); + } + perror("child/exec"); _exit(1); default: //parent @@ -169,6 +188,12 @@ int command_start(nfc_tag_info_t* info){ break; } } + + if(!strlen((char*) command_name)){ + printf("Tag contains invalid command data\n"); + free(command_name); + return 1; + } //FIXME might want to parse out any non-graphs if(p == ncommands){ @@ -176,7 +201,8 @@ int command_start(nfc_tag_info_t* info){ if(!commands){ ncommands = 0; printf("Failed to allocate memory\n"); - goto bail; + free(command_name); + return 1; } memset(commands + p, 0, sizeof(command_t)); ncommands++; @@ -187,11 +213,18 @@ int command_start(nfc_tag_info_t* info){ //TODO clean up and free command instance } -bail: free(command_name); return 0; } +static void command_stop_internal(size_t n){ + //send SIGTERM to process group + if(kill(-commands[n].child, (commands[n].flags & COMMAND_STOPPED) ? SIGKILL : SIGTERM)){ + perror("cmd/stop"); + } + commands[n].flags |= COMMAND_STOPPED; +} + int command_stop(nfc_tag_info_t* info){ size_t n = 0; @@ -199,8 +232,7 @@ int command_stop(nfc_tag_info_t* info){ if(commands[n].tag == info){ commands[n].tag = NULL; if(commands[n].flags & COMMAND_ALIVE){ - //TODO stop running command - commands[n].flags |= COMMAND_STOPPED; + command_stop_internal(n); } } } @@ -213,11 +245,10 @@ void command_free(){ printf("Shutting down any remaining commands\n"); for(n = 0; n < ncommands; n++){ - if(commands[n].flags & COMMAND_ALIVE){ - //TODO stop command, terminate command + while(commands[n].flags & COMMAND_ALIVE){ + command_stop_internal(n); + command_reap(); } - - //TODO free allocated data } ncommands = 0; diff --git a/commander.cfg b/commander.cfg index 87b5940..b32a064 100644 --- a/commander.cfg +++ b/commander.cfg @@ -11,4 +11,5 @@ bind = 0.0.0.0 7812 [command] ;commanddir = commands chdir = commands/ -handler = handle_tag +;handler = handle_tag + |