Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
ExecutableCommPort.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_ExecutableCommPort_h_ 00003 #define INCLUDED_ExecutableCommPort_h_ 00004 00005 #include "local/CommPort.h" 00006 #include "Wireless/netstream.h" 00007 00008 //! Run a specified executable, with the comm port connected to its stdin and stdout 00009 /*! This can be handy for testing with a device simulator, or if you want to 00010 * interface with a device as an external process. It's more efficient to run your 00011 * driver as an DeviceDriver subclass than to spawn an external process however. 00012 * 00013 * If you need to keep your external program running across instances of the 00014 * simulator (or just want to launch it externally), you'll need to use file system 00015 * fifos (see mkfifo command), probably separate ones for reading and writing 00016 * with a RedirectionCommPort to combine them (unless your platform supports 00017 * bidirectional pipes... most don't) */ 00018 class ExecutableCommPort : public CommPort, public virtual plist::PrimitiveListener { 00019 public: 00020 explicit ExecutableCommPort(const std::string& name) 00021 : CommPort(autoRegisterExecutableCommPort,name), 00022 command(), shell("sh"), child(0), rbuf(), wbuf(), opened(0) 00023 { 00024 addEntry("Command",command,"Specifies the shell command to run, stdio from this process will be piped through the comm port"); 00025 addEntry("Shell",shell,"The shell executable to use for executing the command, can be found via PATH, or explicit path\n" 00026 "The shell will be passed '-c' and then your command"); 00027 } 00028 00029 //! destructor, checks that child process is no longer running, kills it if it is (after some delay) 00030 virtual ~ExecutableCommPort(); 00031 00032 virtual std::string getClassName() const { return autoRegisterExecutableCommPort; } 00033 00034 virtual streambuf& getReadStreambuf() { return rbuf; } 00035 virtual streambuf& getWriteStreambuf() { return wbuf; } 00036 virtual bool isWriteable() { wbuf.update_status(); return wbuf.is_open(); } 00037 virtual bool isReadable() { rbuf.update_status(); return rbuf.is_open(); } 00038 00039 //! launches the executable, connecting its stdin and stdout to this comm port 00040 virtual bool open(); 00041 00042 //! sends kill signal to the child process 00043 virtual bool close(); 00044 00045 //! if #command is modified, close current connection (if running) and launch new one 00046 virtual void plistValueChanged(const plist::PrimitiveBase& pl); 00047 00048 plist::Primitive<std::string> command; //!< shell command 00049 plist::Primitive<std::string> shell; //!< shell name 00050 00051 protected: 00052 pid_t child; //!< process ID of the child (0 if not launched, -1 if error) 00053 00054 basic_netbuf<std::ios::char_type> rbuf; //!< reads from child process 00055 basic_netbuf<std::ios::char_type> wbuf; //!< writes to child process 00056 00057 unsigned int opened; //!< reference count of the number of times we've been opened (i.e. pending close()s) 00058 00059 enum { 00060 READPIPE=0, //!< pipe() system call returns read end on the first entry, lets make it symbolic so it's more clear 00061 WRITEPIPE=1 //!< pipe() system call returns write end on the second entry, lets make it symbolic so it's more clear 00062 }; 00063 00064 //! waits for child process to exit for t milliseconds, polling status every p millseconds, returns true if no longer running 00065 bool waitChild(unsigned int t, unsigned int p); 00066 00067 //! returns true if child is still running 00068 bool isChildRunning() const; 00069 00070 //! holds the class name, set via registration with the CommPort registry 00071 static const std::string autoRegisterExecutableCommPort; 00072 }; 00073 00074 /*! @file 00075 * @brief 00076 * @author Ethan Tira-Thompson (ejt) (Creator) 00077 * 00078 * $Author: ejt $ 00079 * $Name: tekkotsu-4_0 $ 00080 * $Revision: 1.1 $ 00081 * $State: Exp $ 00082 * $Date: 2007/06/03 17:03:36 $ 00083 */ 00084 00085 #endif |
Tekkotsu Hardware Abstraction Layer 4.0 |
Generated Thu Nov 22 01:00:53 2007 by Doxygen 1.5.4 |