v1.3 : added auto file reloading

+ Files now auto reload when changes are detected
+ Added --no-reload option to disable auto reloading
* Internal cleanups
This commit is contained in:
zawz 2019-09-26 11:42:11 +02:00
parent 8486fa3984
commit 1c8c3ac9d2
5 changed files with 147 additions and 58 deletions

View file

@ -8,8 +8,6 @@
#include "command.hpp" #include "command.hpp"
#include <ztd/filedat.hpp> #include <ztd/filedat.hpp>
void sh(std::string const& string);
class Device class Device
{ {
public: public:
@ -34,7 +32,6 @@ public:
std::vector<ConnectCommand> connectCommands; std::vector<ConnectCommand> connectCommands;
std::vector<DisconnectCommand> disconnectCommands; std::vector<DisconnectCommand> disconnectCommands;
std::thread thread;
pid_t thread_pid; pid_t thread_pid;
private: private:
static void loop(Device* dev); static void loop(Device* dev);
@ -42,4 +39,6 @@ private:
extern std::vector<Device*> device_list; extern std::vector<Device*> device_list;
void clean_devices();
#endif //DEVICE_HPP #endif //DEVICE_HPP

View file

@ -5,10 +5,16 @@
#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"
#include <string>
extern int announce_thread_pid; extern int announce_thread_pid;
void kill_all();
void device_check(); void device_check();
void announce_loop(); void announce_loop();
void filetime_loop(std::string filepath);
#endif //SYSTEM_HPP #endif //SYSTEM_HPP

View file

@ -5,6 +5,7 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <iostream> #include <iostream>
#include <ztd/shell.hpp> #include <ztd/shell.hpp>
#include "log.hpp" #include "log.hpp"
@ -40,11 +41,6 @@ static bool _isNum(char a)
return (a>='0' && a<='9'); return (a>='0' && a<='9');
} }
void sh(std::string const& string)
{
system(string.c_str());
}
Device::Device() Device::Device()
{ {
busy=false; busy=false;
@ -63,8 +59,7 @@ bool Device::start_loop()
if(this->busy) if(this->busy)
return false; return false;
this->busy = true; this->busy = true;
this->thread = std::thread(Device::loop, this); std::thread(Device::loop, this).detach();
this->thread.detach();
return true; return true;
} }
@ -295,7 +290,7 @@ void Device::run_signal(char* buff)
{ {
std::string command="code=" + strval + ";"; std::string command="code=" + strval + ";";
command += dequote(it.shell); command += dequote(it.shell);
std::thread(sh, command).detach(); std::thread(ztd::sh, command, true).detach();
} }
} }
else else
@ -372,7 +367,7 @@ void Device::run_signal(char* buff)
+ ";channel=" + std::to_string(channel) + ";channel=" + std::to_string(channel)
+ ";velocity=" + std::to_string(value) + ";"; + ";velocity=" + std::to_string(value) + ";";
command += dequote(it.shell); command += dequote(it.shell);
std::thread(sh, command).detach(); std::thread(ztd::sh, command, true).detach();
} }
} }
} }
@ -399,7 +394,7 @@ void Device::run_signal(char* buff)
else else
command += std::to_string((long int) result); command += std::to_string((long int) result);
command += ";" + dequote(it.shell); command += ";" + dequote(it.shell);
std::thread(sh, command).detach(); std::thread(ztd::sh, command, true).detach();
} }
} }
} }
@ -425,7 +420,7 @@ void Device::run_signal(char* buff)
else else
command += std::to_string((long int) result); command += std::to_string((long int) result);
command += ";" + dequote(it.shell); command += ";" + dequote(it.shell);
std::thread(sh, command).detach(); std::thread(ztd::sh, command, true).detach();
} }
} }
} // if type } // if type
@ -447,7 +442,7 @@ void Device::loop(Device* dev)
for( auto it : dev->connectCommands ) for( auto it : dev->connectCommands )
{ {
std::thread(sh, dequote(it.shell)).detach(); std::thread(ztd::sh, dequote(it.shell), true).detach();
} }
while (getline(&buff, &buff_size, stream) > 0) while (getline(&buff, &buff_size, stream) > 0)
@ -457,7 +452,7 @@ void Device::loop(Device* dev)
for( auto it : dev->disconnectCommands ) for( auto it : dev->disconnectCommands )
{ {
std::thread(sh, dequote(it.shell)).detach(); std::thread(ztd::sh, dequote(it.shell), true).detach();
} }
log("Device '" + dev->name + "' disconnected\n"); log("Device '" + dev->name + "' disconnected\n");
@ -466,3 +461,12 @@ void Device::loop(Device* dev)
dev->thread_pid=-1; dev->thread_pid=-1;
free(buff); free(buff);
} }
void clean_devices()
{
for(auto it : device_list)
{
delete it;
}
device_list.clear();
}

View file

@ -14,7 +14,7 @@
#include <ztd/options.hpp> #include <ztd/options.hpp>
#include <ztd/shell.hpp> #include <ztd/shell.hpp>
#define VERSION_STRING "v1.2" #define VERSION_STRING "v1.3"
ztd::option_set options; ztd::option_set options;
@ -59,8 +59,7 @@ void cleanup()
void stop(int ret) void stop(int ret)
{ {
if(announce_thread_pid>0) kill_all();
kill(announce_thread_pid, SIGINT);
exit(ret); exit(ret);
} }
@ -69,12 +68,59 @@ void inthandler(int dummy)
stop(0); stop(0);
} }
void load_filedat(ztd::filedat& file, bool from_stdin, std::string const& path)
{
if(from_stdin)
{
log("Loading map from stdin\n");
file.import_stdin();
}
else
{
file.setFilePath(path);
log("Loading map file '" + path + "'\n");
if(options.find("zfd")->activated)
{
file.import_file();
}
else if(options.find("mim")->activated)
{
file.data() = mimtochk(file_strimport(path));
}
else
{
std::string filestr=file_strimport(path);
if(is_mim(filestr))
{
file.data() = mimtochk(filestr);
}
else
{
file.import_file();
}
}
}
}
void load_commands(ztd::chunkdat const& data)
{
clean_devices();
for(int i=0 ; i<data.listSize() ; i++)
{
Device *newDevice = new Device;
newDevice->import_chunk(data[i]);
device_list.push_back(newDevice);
log("Loaded "+std::to_string(newDevice->nb_command)+" commands for device '"+newDevice->name+"'\n");
}
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
signal(SIGINT, inthandler); signal(SIGINT, inthandler);
signal(SIGCHLD, SIG_IGN); //not expecting returns from child processes signal(SIGCHLD, SIG_IGN); //not expecting returns from child processes
bool piped=false; bool piped=false;
bool autoreload=true;
if (!isatty(fileno(stdin))) if (!isatty(fileno(stdin)))
piped = true; piped = true;
@ -98,6 +144,7 @@ int main(int argc, char* argv[])
options.add(ztd::option('z',"zfd", false, "Read file in zfd format")); options.add(ztd::option('z',"zfd", false, "Read file in zfd format"));
options.add(ztd::option('o',"output", true, "Output the resulting zfd map to file. - for stdout", "file")); options.add(ztd::option('o',"output", true, "Output the resulting zfd map to file. - for stdout", "file"));
options.add(ztd::option("aligner", true, "String to use for aligning output map format. Default \\t", "string")); options.add(ztd::option("aligner", true, "String to use for aligning output map format. Default \\t", "string"));
options.add(ztd::option("no-reload", false, "Disable auto reloading when file changes are detected"));
options.add(ztd::option("\rIf no file format is specified, the program will try to guess the format")); options.add(ztd::option("\rIf no file format is specified, the program will try to guess the format"));
// options.add(ztd::option('i',"interactive", false, "Start in interactive mode")); // options.add(ztd::option('i',"interactive", false, "Start in interactive mode"));
@ -146,12 +193,12 @@ int main(int argc, char* argv[])
} }
if( options.find('L')->activated ) if( options.find('L')->activated )
{ {
sh("aseqdump -l"); ztd::sh("aseqdump -l", true);
stop(0); stop(0);
} }
if( options.find('l')->activated ) if( options.find('l')->activated )
{ {
sh(LIST_COMMAND); ztd::sh(LIST_COMMAND, true);
stop(0); stop(0);
} }
@ -168,6 +215,10 @@ int main(int argc, char* argv[])
} }
//behavioral options //behavioral options
if( options.find("no-reload")->activated )
{
autoreload=false;
}
if( options.find("no-log")->activated ) if( options.find("no-log")->activated )
{ {
log_on=false; log_on=false;
@ -181,6 +232,7 @@ int main(int argc, char* argv[])
//no argument: display help //no argument: display help
ztd::filedat file; ztd::filedat file;
bool no_arg=false; bool no_arg=false;
std::string filepath;
if (arg.size() <= 0 || arg[0] == "") if (arg.size() <= 0 || arg[0] == "")
{ {
no_arg=true; no_arg=true;
@ -192,42 +244,16 @@ int main(int argc, char* argv[])
} }
else else
{ {
file.setFilePath(arg[0]); filepath=arg[0];
} }
//main processing //main processing
try try
{ {
if(no_arg) //load
{ load_filedat(file, no_arg, filepath);
log("Loading map from stdin\n"); //output
file.import_stdin();
}
else
{
log("Loading map file '" + arg[0] + "'\n");
if(options.find("zfd")->activated)
{
file.import_file();
}
else if(options.find("mim")->activated)
{
file.data() = mimtochk(file_strimport(arg[0]));
}
else
{
std::string filestr=file_strimport(arg[0]);
if(is_mim(filestr))
{
file.data() = mimtochk(filestr);
}
else
{
file.import_file();
}
}
}
if(options.find('o')->activated) if(options.find('o')->activated)
{ {
if(options.find('o')->argument == "-") { if(options.find('o')->argument == "-") {
@ -240,17 +266,39 @@ int main(int argc, char* argv[])
return 0; return 0;
} }
//create commands //create commands
for(int i=0 ; i<file.data().listSize() ; i++) load_commands(file.data());
{
Device *newDevice = new Device; autoreload = autoreload && !no_arg;
newDevice->import_chunk(file[i]);
device_list.push_back(newDevice);
log("Loaded "+std::to_string(newDevice->nb_command)+" commands for device '"+newDevice->name+"'\n");
}
//main loop //main loop
log("Starting scan for devices\n"); log("Starting scan for devices\n");
if(autoreload)
std::thread(filetime_loop, filepath).detach();
announce_loop(); announce_loop();
ztd::chunkdat bak_data = file.data();
while(autoreload)
{
log("Reloading file\n");
try
{
load_filedat(file, false, filepath);
load_commands(file.data());
bak_data = file.data();
}
catch (ztd::format_error& e)
{
ztd::printFormatException(e);
log("Reloading old config\n");
load_commands(bak_data);
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << std::endl;
log("Reloading old config\n");
load_commands(bak_data);
}
announce_loop();
}
} }
catch (ztd::format_error& e) catch (ztd::format_error& e)
{ {

View file

@ -3,6 +3,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -13,6 +17,17 @@
int announce_thread_pid = 0; int announce_thread_pid = 0;
void kill_all()
{
if(announce_thread_pid>0)
kill(announce_thread_pid, SIGINT);
for(auto it : device_list)
{
if(it->thread_pid>0)
kill(it->thread_pid, SIGINT);
}
}
void device_check() void device_check()
{ {
char* buff = NULL; char* buff = NULL;
@ -86,3 +101,20 @@ void announce_loop()
if(buff != NULL) if(buff != NULL)
free(buff); free(buff);
} }
void filetime_loop(std::string filepath)
{
struct stat attrib;
stat(filepath.c_str(), &attrib);
time_t last_time=attrib.st_ctime;
while(true)
{
stat(filepath.c_str(), &attrib);
if(attrib.st_ctime > last_time)
{
kill_all();
last_time = attrib.st_ctime;
}
sleep(1);
}
}