diff --git a/client/Makefile b/client/Makefile index c21a7dbd..4ab75393 100644 --- a/client/Makefile +++ b/client/Makefile @@ -1,7 +1,7 @@ VERSION = 0.01 CC = /usr/bin/g++ CFLAGS = -std=gnu++0x -Wall -Wno-unused-function -O3 -D_REENTRANT -DVERSION=\"$(VERSION)\" -I.. -LDFLAGS = -lrt -lpthread -lportaudio -lboost_system +LDFLAGS = -lrt -lpthread -lportaudio -lboost_system -lboost_program_options OBJ = snapClient.o stream.o ../common/chunk.o BIN = snapclient diff --git a/client/snapClient.cpp b/client/snapClient.cpp index a314b1ee..bac801d7 100644 --- a/client/snapClient.cpp +++ b/client/snapClient.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "common/chunk.h" #include "common/utils.h" @@ -22,21 +24,21 @@ using boost::asio::ip::tcp; using namespace std; +namespace po = boost::program_options; -int bufferMs; int deviceIdx; Stream* stream; -void player() +void player(const std::string& ip, int port) { try { boost::asio::io_service io_service; tcp::resolver resolver(io_service); - tcp::resolver::query query(tcp::v4(), "192.168.0.2", "98765"); + tcp::resolver::query query(tcp::v4(), ip, boost::lexical_cast(port)); tcp::resolver::iterator iterator = resolver.resolve(query); while (true) @@ -178,12 +180,27 @@ error: int main (int argc, char *argv[]) { - deviceIdx = -1; - bufferMs = 300; - if (argc > 1) - bufferMs = atoi(argv[1]); - if (argc > 2) - deviceIdx = atoi(argv[2]); + string ip; + int bufferMs; + size_t port; + po::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "produce help message") + ("port,p", po::value(&port)->default_value(98765), "port where the server listens on") + ("ip,i", po::value(&ip)->default_value("192.168.0.2"), "server IP") + ("device,d", po::value(&deviceIdx)->default_value(-1), "index of the soundcard") + ("buffer,b", po::value(&bufferMs)->default_value(300), "buffer size [ms]") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) + { + cout << desc << "\n"; + return 1; + } stream = new Stream(); stream->setBufferLen(bufferMs); @@ -191,10 +208,10 @@ int main (int argc, char *argv[]) PaStream* paStream = initAudio(paError); stream->setLatency(1000*Pa_GetStreamInfo(paStream)->outputLatency); - std::thread playerThread(player); + std::thread playerThread(player, ip, port); std::string cmd; - while (true && (argc > 3)) +/* while (true && (argc > 3)) { std::cout << "> "; std::getline(std::cin, cmd); @@ -210,7 +227,7 @@ int main (int argc, char *argv[]) stream->setBufferLen(atoi(cmd.c_str())); } } - +*/ playerThread.join(); return 0; diff --git a/common/signalHandler.h b/common/signalHandler.h new file mode 100644 index 00000000..b253aab9 --- /dev/null +++ b/common/signalHandler.h @@ -0,0 +1,27 @@ +#ifndef SIGNAL_HANDLER_H +#define SIGNAL_HANDLER_H + +#include +#include + +extern bool g_terminated; + +void signal_handler(int sig) { + + switch(sig) { + case SIGHUP: + syslog(LOG_WARNING, "Received SIGHUP signal."); + break; + case SIGTERM: + syslog(LOG_WARNING, "Received SIGTERM signal."); + g_terminated = true; + break; + default: + syslog(LOG_WARNING, "Unhandled signal "); + break; + } +} + +#endif + + diff --git a/server/snapServer.cpp b/server/snapServer.cpp index 9dcddc63..7fff049f 100644 --- a/server/snapServer.cpp +++ b/server/snapServer.cpp @@ -23,6 +23,8 @@ #include "common/chunk.h" #include "common/timeUtils.h" #include "common/queue.h" +#include "common/signalHandler.h" +#include using boost::asio::ip::tcp; @@ -35,6 +37,9 @@ using namespace std; using namespace std::chrono; +bool g_terminated = false; + + std::string return_current_time_and_date() { auto now = system_clock::now(); @@ -149,7 +154,7 @@ public: void stop() { - acceptThread->join(); +// acceptThread->join(); } private: @@ -160,17 +165,62 @@ private: }; +void daemonize() +{ + /* Our process ID and Session ID */ + pid_t pid, sid; + + /* Fork off the parent process */ + pid = fork(); + if (pid < 0) + exit(EXIT_FAILURE); + + /* If we got a good PID, then + we can exit the parent process. */ + if (pid > 0) + exit(EXIT_SUCCESS); + + /* Change the file mode mask */ + umask(0); + + /* Open any logs here */ + + /* Create a new SID for the child process */ + sid = setsid(); + if (sid < 0) + { + /* Log the failure */ + exit(EXIT_FAILURE); + } + + /* Change the current working directory */ + if ((chdir("/")) < 0) + { + /* Log the failure */ + exit(EXIT_FAILURE); + } + + /* Close out the standard file descriptors */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); +} + + int main(int argc, char* argv[]) { try { size_t port; string fifoName; + bool runAsDaemon; + po::options_description desc("Allowed options"); desc.add_options() ("help,h", "produce help message") ("port,p", po::value(&port)->default_value(98765), "port to listen on") ("fifo,f", po::value(&fifoName)->default_value("/tmp/snapfifo"), "name of fifo file") + ("daemon,d", po::bool_switch(&runAsDaemon)->default_value(false), "daemonize") ; po::variables_map vm; @@ -198,6 +248,11 @@ int main(int argc, char* argv[]) } */ + if (runAsDaemon) + daemonize(); + + openlog ("firstdaemon", LOG_PID, LOG_DAEMON); + using namespace std; // For atoi. Server* server = new Server(port); server->start(); @@ -206,34 +261,11 @@ int main(int argc, char* argv[]) gettimeofday(&tvChunk, NULL); long nextTick = getTickCount(); -/* pid_t pid, sid; - - pid = fork(); - if (pid < 0) { - exit(EXIT_FAILURE); - } - if (pid > 0) { - exit(EXIT_SUCCESS); - } - - umask(0); - - sid = setsid(); - if (sid < 0) { - exit(EXIT_FAILURE); - } - - if ((chdir("/")) < 0) { - exit(EXIT_FAILURE); - } - - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - */ mkfifo(fifoName.c_str(), 0777); - while (true) + + while (!g_terminated) { +syslog (LOG_NOTICE, "First daemon started."); int fd = open(fifoName.c_str(), O_RDONLY); try { @@ -281,7 +313,6 @@ int main(int argc, char* argv[]) close(fd); } - return 0; server->stop(); } catch (std::exception& e) @@ -289,7 +320,8 @@ int main(int argc, char* argv[]) std::cerr << "Exception: " << e.what() << "\n"; } - return 0; + syslog (LOG_NOTICE, "First daemon terminated."); + closelog(); }