// -*- c++ -*- // Generated by assa-genesis //------------------------------------------------------------------------------ // $Id: smoker.cpp,v 1.9 2005/12/07 03:12:55 vlg Exp $ //------------------------------------------------------------------------------ // Smoker.cpp //------------------------------------------------------------------------------ // // Author : Vladislav Grinchenko // Date : Sat Jul 20 18:47:32 2002 //------------------------------------------------------------------------------ static const char help_msg[]= " \n" " NAME: \n" " Smoker - helper program for PipeTest \n" " \n" " DESCRIPTION: \n" " \n" " Smoker is the external command that pipe_test runs to test \n" " its read/write/kill capabilities. Smoker's standard input(read) or \n" " output (write) are connected via UNIX pipe to pipe_test. \n" " \n" " USAGE: \n" " \n" " shell> smoker [OPTIONS] \n" " \n" " OPTIONS: \n" " \n" " --write=NUM - Write NUM messages to standard output. \n" " If NUM = -1, keep writing messages forever. \n" " --delay NUM - Delay between consecutive messages. \n" " (Default: 1 sec). \n" " --pidfile NAME - PID file name. \n" " -D, --log-file NAME - Write debug to NAME file \n" " -d, --log-stdout - Write debug to standard output \n" " -z, --log-size NUM - Maximum size debug file can reach (dfl: is 10Mb) \n" " -m, --mask MASK - Mask (default: ALL = 0x7fffffff) \n" " -h, --help - Print this messag \n" " -v, --version - Print version number \n"; /******************************************************************************/ #include using std::string; #include #include using namespace std; #include "assa/GenServer.h" #include "assa/Singleton.h" #include "assa/TimeVal.h" #include "assa/IPv4Socket.h" #include "assa/Pipe.h" using namespace ASSA; class Smoker : public GenServer, public Singleton { public: Smoker (); virtual void init_service (); virtual void process_events (); virtual int handle_read (int); virtual int handle_timeout (TimerId); virtual int handle_close (int); private: int m_write; int m_read; int m_line_count; double m_delay; string m_msg; string m_input_line; // Buffer that keeps partially-received // characters }; // Useful defines #define SMOKER Smoker::get_instance() #define REACTOR Smoker::get_instance()->get_reactor() // Static declarations mandated by Singleton class ASSA_DECL_SINGLETON(Smoker); Smoker:: Smoker () : m_write (0), m_read (0), m_line_count (0), m_msg ("It's rarely helpful to blame anyone for anything") { set_id ("Smoker"); add_opt (0, "write", &m_write); add_opt (0, "read", &m_read); add_opt (0, "delay", &m_delay); // ---General--- // rm_opt ('h', "help" ); // rm_opt ('v', "version" ); // ---Debugging--- // rm_opt ('m', "mask" ); // rm_opt ('d', "log-stdout" ); // rm_opt ('D', "log-file" ); // rm_opt ('z', "log-size" ); // ---Configuration--- rm_opt ('f', "config-file" ); rm_opt ('n', "instance" ); rm_opt ('p', "port" ); // ---Process bookkeeping--- rm_opt ('b', "daemon" ); // rm_opt ('l', "pidfile" ); rm_opt ('L', "ommit-pidfile"); /*--- * Disable all debugging *---*/ // m_debug_mask = 0x0; } void Smoker:: init_service () { trace("Smoker::init_service"); Log::disable_timestamp (); if (m_read == 0 && m_write == 0) { DL((APP,"Either {--read} or {--write} is required\n")); DL((APP,"See 'Smoker --help' for details\n")); set_exit_value (1); SMOKER->stop_service (); return; } if (m_write != 0) { REACTOR->registerTimerHandler (this, m_delay); } else { REACTOR->registerIOHandler (this, STDIN_FILENO, READ_EVENT); } DL((APP,"Service has been initialized\n")); } void Smoker:: process_events () { trace("Smoker::process_events"); REACTOR->waitForEvents (); REACTOR->stopReactor (); DL((APP,"Service stopped!\n")); } int Smoker:: handle_read (int fd_) { trace("Smoker::handle_read"); char buf [128]; while (cin.getline (buf, 128)) { DL((APP,"Line %d: \"%s\"\n", m_line_count++, buf)); if (m_line_count == m_read) { DL((APP,"Wrote last message out ... exiting\n")); SMOKER->stop_service (); return -1; } } return BYTES_LEFT_IN_SIN; } int Smoker:: handle_close (int fd_) { trace("Smoker::handle_close"); DL((APP,"PipeTest must have exited!\n")); return 0; } int Smoker:: handle_timeout (TimerId) { trace("Smoker::handle_timeout"); if (m_write == 0) { DL((APP,"Shouldn't happen!\n")); Assure_exit (false); } cout << m_msg << endl; DL((APP,"Message # %d is out\n", m_write)); if (--m_write == 0) { DL((APP,"Wrote last message - stopping server\n")); SMOKER->stop_service (); } else { REACTOR->registerTimerHandler (this, m_delay); } return 0; } int main (int argc, char* argv[]) { static const char release[] = "0.1"; int patch_level = 0; Smoker& server = *Smoker::get_instance (); server.set_version (release, patch_level); server.set_author ("Vladislav Grinchenko"); server.set_flags (GenServer::RMLOG); server.init (&argc, argv, help_msg); server.init_service (); server.process_events (); return server.get_exit_value (); }