+Added no-log option
*Safer kill method
This commit is contained in:
parent
43502018c5
commit
e7c1384079
10 changed files with 171 additions and 28 deletions
15
Makefile
15
Makefile
|
|
@ -16,10 +16,13 @@ endif
|
|||
$(shell mkdir -p $(ODIR))
|
||||
$(shell mkdir -p $(BINDIR))
|
||||
|
||||
# automatically finds .hpp
|
||||
DEPS = $(shell if [ -n "$(ld $(IDIR))" ] ; then ls $(IDIR)/*.hpp ; fi)
|
||||
# automatically finds .cpp and makes the corresponding .o rule
|
||||
OBJ = $(shell ls $(SRCDIR)/*.cpp | sed 's/.cpp/.o/g;s|$(SRCDIR)/|$(ODIR)/|g')
|
||||
# automatically finds .h and .hpp
|
||||
DEPS = $(shell if [ -n "$(ld $(IDIR))" ] ; then ls $(IDIR)/*.hpp $(IDIR)/*.h 2>/dev/null ; fi)
|
||||
# automatically finds .c and .cpp and makes the corresponding .o rule
|
||||
OBJ = $(shell ls $(SRCDIR)/*.cpp $(SRCDIR)/*.c 2>/dev/null | sed 's|\.cpp|.o|g;s|\.c|.o|g;s|$(SRCDIR)/|$(ODIR)/|g')
|
||||
|
||||
$(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS)
|
||||
$(CC) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
$(ODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
|
||||
$(CC) $(CXXFLAGS) -c -o $@ $<
|
||||
|
|
@ -36,5 +39,5 @@ clean:
|
|||
clear:
|
||||
rm $(BINDIR)/$(NAME)
|
||||
|
||||
install: $(BINDIR)/$(NAME)
|
||||
mv $(BINDIR)/$(NAME) /usr/local/bin
|
||||
obj:
|
||||
echo $(OBJ)
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@
|
|||
#include "command.hpp"
|
||||
#include "Filedat.hpp"
|
||||
|
||||
#define KILL_COMMAND_FH "kill -s INT $(pgrep -f \"aseqdump -p "
|
||||
#define KILL_COMMAND_SH "\")"
|
||||
|
||||
void sh(std::string const& string);
|
||||
|
||||
class Device
|
||||
|
|
@ -38,6 +35,7 @@ public:
|
|||
std::vector<DisconnectCommand> disconnectCommands;
|
||||
|
||||
std::thread thread;
|
||||
pid_t thread_pid;
|
||||
private:
|
||||
static void loop(Device* dev);
|
||||
};
|
||||
|
|
|
|||
12
include/log.hpp
Normal file
12
include/log.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef LOG_HPP
|
||||
#define LOG_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#define DEFAULT_LOG_STATE true
|
||||
|
||||
extern bool log_on;
|
||||
|
||||
void log(const std::string& str);
|
||||
|
||||
#endif //LOG_HPP
|
||||
11
include/popen.h
Normal file
11
include/popen.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef POPEN_HPP
|
||||
#define POPEN_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
FILE* popen2(const char* command, const char* type, pid_t* pid);
|
||||
|
||||
int pclose2(FILE* fp, pid_t pid);
|
||||
|
||||
#endif //POPEN_HPP
|
||||
|
|
@ -1,10 +1,15 @@
|
|||
#ifndef SYSTEM_HPP
|
||||
#define SYSTEM_HPP
|
||||
|
||||
#include "popen.h"
|
||||
|
||||
#define ANNOUNCE_COMMAND "aseqdump -p System:1"
|
||||
#define LIST_COMMAND "aseqdump -l | tail -n +2 | cut -c10-42 | tr -s ' '"
|
||||
#define LIST_EXTENDED_COMMAND "aseqdump -l | tail -n +2 | cut -c-42"
|
||||
|
||||
|
||||
extern pid_t announce_thread_pid;
|
||||
|
||||
void device_check();
|
||||
|
||||
void announce_loop();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "log.hpp"
|
||||
#include "popen.h"
|
||||
|
||||
std::vector<Device*> device_list;
|
||||
|
||||
static bool _isNum(char a)
|
||||
|
|
@ -23,6 +26,7 @@ Device::Device()
|
|||
busy=false;
|
||||
nb_command=0;
|
||||
client_id=-1;
|
||||
thread_pid=-1;
|
||||
}
|
||||
|
||||
Device::~Device()
|
||||
|
|
@ -245,8 +249,7 @@ void Device::run_signal(char* buff)
|
|||
{
|
||||
if ( (strstr(buff, "Port unsubscribed") != NULL) ) // distonnected
|
||||
{
|
||||
std::string kill_command=KILL_COMMAND_FH + std::to_string(this->client_id) + KILL_COMMAND_SH;
|
||||
system(kill_command.c_str()); // kill the process
|
||||
kill(this->thread_pid, SIGINT);
|
||||
this->busy=false;
|
||||
this->client_id=-1;
|
||||
}
|
||||
|
|
@ -411,10 +414,12 @@ void Device::run_signal(char* buff)
|
|||
|
||||
void Device::loop(Device* dev)
|
||||
{
|
||||
std::string command = "aseqdump -p '" + std::to_string(dev->client_id) + '\'';
|
||||
FILE *stream = popen(command.c_str(), "r");
|
||||
char* buff = NULL;
|
||||
size_t buff_size = 0;
|
||||
std::string command = "aseqdump -p '" + std::to_string(dev->client_id) + '\'';
|
||||
FILE *stream = popen2(command.c_str(), "r", &dev->thread_pid);
|
||||
|
||||
log("Device '" + dev->name + "' connected\n");
|
||||
|
||||
for( auto it : dev->connectCommands )
|
||||
{
|
||||
|
|
@ -431,8 +436,9 @@ void Device::loop(Device* dev)
|
|||
std::thread(sh, it.shell).detach();
|
||||
}
|
||||
|
||||
printf("Device '%s' disconnected\n", dev->name.c_str());
|
||||
log("Device '" + dev->name + "' disconnected\n");
|
||||
|
||||
pclose(stream);
|
||||
pclose2(stream, dev->thread_pid);
|
||||
dev->thread_pid=-1;
|
||||
free(buff);
|
||||
}
|
||||
|
|
|
|||
11
src/log.cpp
Normal file
11
src/log.cpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "log.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
bool log_on=DEFAULT_LOG_STATE;
|
||||
|
||||
void log(const std::string& str)
|
||||
{
|
||||
if(log_on)
|
||||
printf("%s", str.c_str());
|
||||
}
|
||||
32
src/main.cpp
32
src/main.cpp
|
|
@ -1,16 +1,17 @@
|
|||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include <string.h>
|
||||
|
||||
#include "device.hpp"
|
||||
#include "system.hpp"
|
||||
#include "log.hpp"
|
||||
#include "help.h"
|
||||
|
||||
#include "Filedat.hpp"
|
||||
#include "options.hpp"
|
||||
#include "popen.h"
|
||||
|
||||
|
||||
#include "help.h"
|
||||
|
||||
OptionSet options;
|
||||
|
||||
void help()
|
||||
|
|
@ -23,19 +24,20 @@ void help()
|
|||
void option_p(const std::string& port)
|
||||
{
|
||||
std::string command="aseqdump -p '" + port + '\'';
|
||||
FILE *stream = popen(command.c_str(), "r");
|
||||
pid_t pid;
|
||||
FILE *stream = popen2(command.c_str(), "r", &pid);
|
||||
char* buff = NULL;
|
||||
size_t buff_size = 0;
|
||||
while (getline(&buff, &buff_size, stream) > 0)
|
||||
{
|
||||
if ( (strstr(buff, "Port unsubscribed") != NULL) ) // distonnected
|
||||
{
|
||||
std::string kill_command=KILL_COMMAND_FH + port + KILL_COMMAND_SH;
|
||||
system(kill_command.c_str()); // kill the process
|
||||
kill(pid, SIGINT); // kill the process
|
||||
}
|
||||
else
|
||||
printf("%s", buff);
|
||||
}
|
||||
pclose2(stream, pid);
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
|
|
@ -46,6 +48,7 @@ void cleanup()
|
|||
|
||||
void stop(int ret)
|
||||
{
|
||||
kill(announce_thread_pid, SIGINT);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
|
|
@ -66,6 +69,7 @@ int main(int argc, char* argv[])
|
|||
options.addOption(Option('l',"list", false, "List detected devices"));
|
||||
options.addOption(Option('L',"full-list", false, "Print whole device list details"));
|
||||
options.addOption(Option('p',"port", true, "Connect to device and output to console", "device"));
|
||||
options.addOption(Option("no-log", false, "Disable console logging"));
|
||||
// options.addOption(Option('i',"interactive", false, "Start in interactive mode"));
|
||||
|
||||
auto argvec = argVector(argc, argv);
|
||||
|
|
@ -75,6 +79,7 @@ int main(int argc, char* argv[])
|
|||
if( !t.second ) //invalid option
|
||||
return 1;
|
||||
|
||||
//exit options
|
||||
Option* op=nullptr;
|
||||
op = options.findOption('h');
|
||||
if( op->activated )
|
||||
|
|
@ -125,6 +130,14 @@ int main(int argc, char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
//behavioral options
|
||||
op = options.findOption("no-log");
|
||||
if( op->activated )
|
||||
{
|
||||
log_on=false;
|
||||
}
|
||||
|
||||
//no argument: display help
|
||||
if (arg.size() <= 0 || arg[0] == "")
|
||||
{
|
||||
help();
|
||||
|
|
@ -138,9 +151,10 @@ int main(int argc, char* argv[])
|
|||
return 10;
|
||||
}
|
||||
|
||||
printf("Loading map file '%s'\n", arg[0].c_str());
|
||||
//main processing
|
||||
try
|
||||
{
|
||||
log("Loading map file '" + arg[0] + "'\n");
|
||||
file.import_file();
|
||||
|
||||
//create commands
|
||||
|
|
@ -149,11 +163,11 @@ int main(int argc, char* argv[])
|
|||
Device *newDevice = new Device;
|
||||
newDevice->import_chunk(file[i]);
|
||||
device_list.push_back(newDevice);
|
||||
printf("Loaded %d commands for device '%s'\n", newDevice->nb_command, newDevice->name.c_str());
|
||||
log("Loaded "+std::to_string(newDevice->nb_command)+" commands for device '"+newDevice->name+"'\n");
|
||||
}
|
||||
|
||||
//main loop
|
||||
printf("Starting scan for devices\n");
|
||||
log("Starting scan for devices\n");
|
||||
announce_loop();
|
||||
}
|
||||
catch (format_error& e)
|
||||
|
|
|
|||
80
src/popen.c
Normal file
80
src/popen.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include "popen.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define READ 0
|
||||
#define WRITE 1
|
||||
|
||||
FILE* popen2(const char* command, const char* type, int* pid)
|
||||
{
|
||||
pid_t child_pid;
|
||||
int fd[2];
|
||||
pipe(fd);
|
||||
|
||||
if((child_pid = fork()) == -1)
|
||||
{
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* child process */
|
||||
if (child_pid == 0)
|
||||
{
|
||||
if ( index(type, 'r') != NULL )
|
||||
{
|
||||
close(fd[READ]); //Close the READ end of the pipe since the child's fd is write-only
|
||||
dup2(fd[WRITE], 1); //Redirect stdout to pipe
|
||||
}
|
||||
else
|
||||
{
|
||||
close(fd[WRITE]); //Close the WRITE end of the pipe since the child's fd is read-only
|
||||
dup2(fd[READ], 0); //Redirect stdin to pipe
|
||||
}
|
||||
|
||||
setpgid(child_pid, child_pid); //Needed so negative PIDs can kill children of /bin/sh
|
||||
execl("/bin/sh", "/bin/sh", "-c", command, NULL);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( index(type, 'r') != NULL )
|
||||
{
|
||||
close(fd[WRITE]); //Close the WRITE end of the pipe since parent's fd is read-only
|
||||
}
|
||||
else
|
||||
{
|
||||
close(fd[READ]); //Close the READ end of the pipe since parent's fd is write-only
|
||||
}
|
||||
}
|
||||
if(pid != NULL)
|
||||
*pid = child_pid;
|
||||
|
||||
if ( index(type, 'r') != NULL )
|
||||
{
|
||||
return fdopen(fd[READ], "r");
|
||||
}
|
||||
|
||||
return fdopen(fd[WRITE], "w");
|
||||
}
|
||||
|
||||
int pclose2(FILE* fp, pid_t pid)
|
||||
{
|
||||
int stat;
|
||||
|
||||
fclose(fp);
|
||||
while (waitpid(pid, &stat, 0) == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
stat = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
|
@ -9,12 +9,13 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
pid_t announce_thread_pid = -1;
|
||||
|
||||
void device_check()
|
||||
{
|
||||
char* buff = NULL;
|
||||
size_t buff_size = 0;
|
||||
FILE *stream = popen(LIST_EXTENDED_COMMAND, "r");
|
||||
std::string str;
|
||||
std::vector<std::pair<int,std::string>> ls_device;
|
||||
|
||||
getline(&buff, &buff_size, stream); //discard the first line
|
||||
|
|
@ -37,9 +38,10 @@ void device_check()
|
|||
i++;
|
||||
while(buff[i-1] == ' ')
|
||||
i--;
|
||||
|
||||
//insert element
|
||||
ls_device.push_back(std::make_pair(t, std::string(buff+j, i-j)));
|
||||
}
|
||||
pclose(stream);
|
||||
|
||||
for ( auto dev : device_list ) // iterate devices
|
||||
{
|
||||
|
|
@ -48,7 +50,6 @@ void device_check()
|
|||
if( !dev->busy && dev->name == ls->second && ls->first > 0) //device detected
|
||||
{
|
||||
dev->client_id = ls->first;
|
||||
printf("Device '%s' found\n", dev->name.c_str());
|
||||
dev->start_loop();
|
||||
}
|
||||
if( dev->busy && dev->client_id == ls->first )
|
||||
|
|
@ -64,7 +65,7 @@ void announce_loop()
|
|||
{
|
||||
char* buff = NULL;
|
||||
size_t buff_size = 0;
|
||||
FILE *stream = popen(ANNOUNCE_COMMAND,"r");
|
||||
FILE* stream = popen2(ANNOUNCE_COMMAND, "r", &announce_thread_pid);
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
|
|
@ -78,6 +79,8 @@ void announce_loop()
|
|||
device_check();
|
||||
}
|
||||
|
||||
pclose2(stream, announce_thread_pid);
|
||||
|
||||
if(buff != NULL)
|
||||
free(buff);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue