summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--command.c57
-rw-r--r--commander.cfg3
2 files changed, 46 insertions, 14 deletions
diff --git a/command.c b/command.c
index 305664b..12e24c6 100644
--- a/command.c
+++ b/command.c
@@ -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
+