+Added no-log option

*Safer kill method
This commit is contained in:
zawz 2019-08-06 17:49:58 +02:00
parent 43502018c5
commit e7c1384079
10 changed files with 171 additions and 28 deletions

View file

@ -16,10 +16,13 @@ endif
$(shell mkdir -p $(ODIR)) $(shell mkdir -p $(ODIR))
$(shell mkdir -p $(BINDIR)) $(shell mkdir -p $(BINDIR))
# automatically finds .hpp # automatically finds .h and .hpp
DEPS = $(shell if [ -n "$(ld $(IDIR))" ] ; then ls $(IDIR)/*.hpp ; fi) DEPS = $(shell if [ -n "$(ld $(IDIR))" ] ; then ls $(IDIR)/*.hpp $(IDIR)/*.h 2>/dev/null ; fi)
# automatically finds .cpp and makes the corresponding .o rule # automatically finds .c and .cpp and makes the corresponding .o rule
OBJ = $(shell ls $(SRCDIR)/*.cpp | sed 's/.cpp/.o/g;s|$(SRCDIR)/|$(ODIR)/|g') 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) $(ODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
$(CC) $(CXXFLAGS) -c -o $@ $< $(CC) $(CXXFLAGS) -c -o $@ $<
@ -36,5 +39,5 @@ clean:
clear: clear:
rm $(BINDIR)/$(NAME) rm $(BINDIR)/$(NAME)
install: $(BINDIR)/$(NAME) obj:
mv $(BINDIR)/$(NAME) /usr/local/bin echo $(OBJ)

View file

@ -8,9 +8,6 @@
#include "command.hpp" #include "command.hpp"
#include "Filedat.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); void sh(std::string const& string);
class Device class Device
@ -38,6 +35,7 @@ public:
std::vector<DisconnectCommand> disconnectCommands; std::vector<DisconnectCommand> disconnectCommands;
std::thread thread; std::thread thread;
pid_t thread_pid;
private: private:
static void loop(Device* dev); static void loop(Device* dev);
}; };

12
include/log.hpp Normal file
View 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
View 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

View file

@ -1,10 +1,15 @@
#ifndef SYSTEM_HPP #ifndef SYSTEM_HPP
#define SYSTEM_HPP #define SYSTEM_HPP
#include "popen.h"
#define ANNOUNCE_COMMAND "aseqdump -p System:1" #define ANNOUNCE_COMMAND "aseqdump -p System:1"
#define LIST_COMMAND "aseqdump -l | tail -n +2 | cut -c10-42 | tr -s ' '" #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" #define LIST_EXTENDED_COMMAND "aseqdump -l | tail -n +2 | cut -c-42"
extern pid_t announce_thread_pid;
void device_check(); void device_check();
void announce_loop(); void announce_loop();

View file

@ -6,6 +6,9 @@
#include <iostream> #include <iostream>
#include "log.hpp"
#include "popen.h"
std::vector<Device*> device_list; std::vector<Device*> device_list;
static bool _isNum(char a) static bool _isNum(char a)
@ -23,6 +26,7 @@ Device::Device()
busy=false; busy=false;
nb_command=0; nb_command=0;
client_id=-1; client_id=-1;
thread_pid=-1;
} }
Device::~Device() Device::~Device()
@ -245,8 +249,7 @@ void Device::run_signal(char* buff)
{ {
if ( (strstr(buff, "Port unsubscribed") != NULL) ) // distonnected if ( (strstr(buff, "Port unsubscribed") != NULL) ) // distonnected
{ {
std::string kill_command=KILL_COMMAND_FH + std::to_string(this->client_id) + KILL_COMMAND_SH; kill(this->thread_pid, SIGINT);
system(kill_command.c_str()); // kill the process
this->busy=false; this->busy=false;
this->client_id=-1; this->client_id=-1;
} }
@ -411,10 +414,12 @@ void Device::run_signal(char* buff)
void Device::loop(Device* dev) 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; char* buff = NULL;
size_t buff_size = 0; 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 ) for( auto it : dev->connectCommands )
{ {
@ -431,8 +436,9 @@ void Device::loop(Device* dev)
std::thread(sh, it.shell).detach(); 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); free(buff);
} }

11
src/log.cpp Normal file
View 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());
}

View file

@ -1,16 +1,17 @@
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <cstring> #include <string.h>
#include "device.hpp" #include "device.hpp"
#include "system.hpp" #include "system.hpp"
#include "log.hpp"
#include "help.h"
#include "Filedat.hpp" #include "Filedat.hpp"
#include "options.hpp" #include "options.hpp"
#include "popen.h"
#include "help.h"
OptionSet options; OptionSet options;
void help() void help()
@ -23,19 +24,20 @@ void help()
void option_p(const std::string& port) void option_p(const std::string& port)
{ {
std::string command="aseqdump -p '" + 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; char* buff = NULL;
size_t buff_size = 0; size_t buff_size = 0;
while (getline(&buff, &buff_size, stream) > 0) while (getline(&buff, &buff_size, stream) > 0)
{ {
if ( (strstr(buff, "Port unsubscribed") != NULL) ) // distonnected if ( (strstr(buff, "Port unsubscribed") != NULL) ) // distonnected
{ {
std::string kill_command=KILL_COMMAND_FH + port + KILL_COMMAND_SH; kill(pid, SIGINT); // kill the process
system(kill_command.c_str()); // kill the process
} }
else else
printf("%s", buff); printf("%s", buff);
} }
pclose2(stream, pid);
} }
void cleanup() void cleanup()
@ -46,6 +48,7 @@ void cleanup()
void stop(int ret) void stop(int ret)
{ {
kill(announce_thread_pid, SIGINT);
exit(ret); 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',"list", false, "List detected devices"));
options.addOption(Option('L',"full-list", false, "Print whole device list details")); 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('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")); // options.addOption(Option('i',"interactive", false, "Start in interactive mode"));
auto argvec = argVector(argc, argv); auto argvec = argVector(argc, argv);
@ -75,6 +79,7 @@ int main(int argc, char* argv[])
if( !t.second ) //invalid option if( !t.second ) //invalid option
return 1; return 1;
//exit options
Option* op=nullptr; Option* op=nullptr;
op = options.findOption('h'); op = options.findOption('h');
if( op->activated ) if( op->activated )
@ -125,6 +130,14 @@ int main(int argc, char* argv[])
return 0; 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] == "") if (arg.size() <= 0 || arg[0] == "")
{ {
help(); help();
@ -138,9 +151,10 @@ int main(int argc, char* argv[])
return 10; return 10;
} }
printf("Loading map file '%s'\n", arg[0].c_str()); //main processing
try try
{ {
log("Loading map file '" + arg[0] + "'\n");
file.import_file(); file.import_file();
//create commands //create commands
@ -149,11 +163,11 @@ int main(int argc, char* argv[])
Device *newDevice = new Device; Device *newDevice = new Device;
newDevice->import_chunk(file[i]); newDevice->import_chunk(file[i]);
device_list.push_back(newDevice); 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 //main loop
printf("Starting scan for devices\n"); log("Starting scan for devices\n");
announce_loop(); announce_loop();
} }
catch (format_error& e) catch (format_error& e)

80
src/popen.c Normal file
View 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;
}

View file

@ -9,12 +9,13 @@
#include <string> #include <string>
#include <vector> #include <vector>
pid_t announce_thread_pid = -1;
void device_check() void device_check()
{ {
char* buff = NULL; char* buff = NULL;
size_t buff_size = 0; size_t buff_size = 0;
FILE *stream = popen(LIST_EXTENDED_COMMAND, "r"); FILE *stream = popen(LIST_EXTENDED_COMMAND, "r");
std::string str;
std::vector<std::pair<int,std::string>> ls_device; std::vector<std::pair<int,std::string>> ls_device;
getline(&buff, &buff_size, stream); //discard the first line getline(&buff, &buff_size, stream); //discard the first line
@ -37,9 +38,10 @@ void device_check()
i++; i++;
while(buff[i-1] == ' ') while(buff[i-1] == ' ')
i--; i--;
//insert element
ls_device.push_back(std::make_pair(t, std::string(buff+j, i-j))); ls_device.push_back(std::make_pair(t, std::string(buff+j, i-j)));
} }
pclose(stream);
for ( auto dev : device_list ) // iterate devices 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 if( !dev->busy && dev->name == ls->second && ls->first > 0) //device detected
{ {
dev->client_id = ls->first; dev->client_id = ls->first;
printf("Device '%s' found\n", dev->name.c_str());
dev->start_loop(); dev->start_loop();
} }
if( dev->busy && dev->client_id == ls->first ) if( dev->busy && dev->client_id == ls->first )
@ -64,7 +65,7 @@ void announce_loop()
{ {
char* buff = NULL; char* buff = NULL;
size_t buff_size = 0; size_t buff_size = 0;
FILE *stream = popen(ANNOUNCE_COMMAND,"r"); FILE* stream = popen2(ANNOUNCE_COMMAND, "r", &announce_thread_pid);
if (stream == NULL) if (stream == NULL)
{ {
@ -78,6 +79,8 @@ void announce_loop()
device_check(); device_check();
} }
pclose2(stream, announce_thread_pid);
if(buff != NULL) if(buff != NULL)
free(buff); free(buff);
} }