+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 $(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)

View file

@ -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
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
#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();

View file

@ -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
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 <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
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 <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);
}