ARPDAS_QNX6 1.0
DG_cmd.cc
Go to the documentation of this file.
00001 #include <unistd.h>
00002 #include <errno.h>
00003 #include <sys/types.h>
00004 #include <sys/stat.h>
00005 #include <fcntl.h>
00006 #include <string.h>
00007 #include <ctype.h>
00008 #include "DG_Resmgr.h"
00009 #include "DG_cmd.h"
00010 #include "nortlib.h"
00011 #include "nl_assert.h"
00012 #include "tm.h"
00013 
00014 static DG_cmd *Cmd;
00015 resmgr_connect_funcs_t DG_cmd::connect_funcs;
00016 resmgr_io_funcs_t DG_cmd::io_funcs;
00017 iofunc_attr_t DG_cmd::cmd_attr;
00018 
00019 /**
00020  * buf is guaranteed to be nul-terminated
00021  * We will strip any trailing newlines before forwarding to dg->execute()
00022  */
00023 int DG_cmd::execute(char *buf) {
00024   assert(buf != 0);
00025   int len = strlen(buf);
00026   while ( len > 0 && isspace(buf[len-1]) )
00027     buf[--len] = '\0';
00028   return dg->execute(buf);
00029 }
00030 
00031 DG_cmd::DG_cmd(data_generator *data_gen) : DG_dispatch_client() {
00032   dg = data_gen;
00033 }
00034 
00035 void DG_cmd::attach() {
00036   dispatch_t *dpp = dg->dispatch->dpp;
00037   if (Cmd != NULL)
00038       nl_error(3,"Only one DG_cmd instance allowed");
00039  
00040   // This is our write-only command interface
00041   resmgr_attr_t resmgr_attr;
00042   memset(&resmgr_attr, 0, sizeof(resmgr_attr));
00043   resmgr_attr.nparts_max = 1;
00044   resmgr_attr.msg_max_size = DG_CMD_BUFSIZE+1;
00045 
00046   iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
00047       _RESMGR_IO_NFUNCS, &io_funcs );
00048   io_funcs.write = DG_cmd_io_write;
00049   
00050   iofunc_attr_init( &DG_cmd::cmd_attr, S_IFNAM | 0222, 0, 0 ); // write-only
00051   const char *wr_devname = tm_dev_name( "DG/cmd" );
00052   dev_id = resmgr_attach( dpp, &resmgr_attr, wr_devname, _FTYPE_ANY, 0,
00053                     &DG_cmd::connect_funcs, &DG_cmd::io_funcs, &DG_cmd::cmd_attr );
00054   if ( dev_id == -1 )
00055     nl_error( 3, "Unable to attach name %s: errno %d", wr_devname, errno );
00056  
00057   Cmd = this;
00058   DG_dispatch_client::attach(dg->dispatch); // Now get in on the quit loop
00059 }
00060 
00061 DG_cmd::~DG_cmd() { }
00062 
00063 int DG_cmd_io_write( resmgr_context_t *ctp,
00064          io_write_t *msg, RESMGR_OCB_T *ocb ) {
00065   int status, msgsize;
00066   char buf[DG_cmd::DG_CMD_BUFSIZE+1];
00067 
00068   status = iofunc_write_verify(ctp, msg, (iofunc_ocb_t *)ocb, NULL);
00069   if ( status != EOK )
00070     return status;
00071 
00072   if ((msg->i.xtype &_IO_XTYPE_MASK) != _IO_XTYPE_NONE )
00073     return ENOSYS;
00074 
00075   msgsize = msg->i.nbytes;
00076   if ( msgsize > DG_cmd::DG_CMD_BUFSIZE )
00077     return E2BIG;
00078 
00079 
00080   resmgr_msgread( ctp, buf, msgsize, sizeof(msg->i) );
00081   buf[msgsize] = '\0';
00082 
00083   // Handle the message
00084   // Reply to sender before handling the command to
00085   // reduce possibility of deadlock.
00086   MsgReply(ctp->rcvid, msg->i.nbytes, NULL, 0);
00087   Cmd->execute(buf);
00088   return _RESMGR_NOREPLY;
00089 
00090   //_IO_SET_WRITE_NBYTES( ctp, msg->i.nbytes );
00091   // return EOK;
00092 }
00093 
00094 /** DG_cmd::ready_to_quit() returns true if we are ready to terminate. For DG/cmd, that means all writers
00095   have closed their connections and we have detached the device.
00096 */
00097 int DG_cmd::ready_to_quit() {
00098   // unlink the name
00099   if ( dev_id != -1 ) {
00100     int rc = resmgr_detach( dispatch->dpp, dev_id, _RESMGR_DETACH_PATHNAME );
00101     if ( rc == -1 )
00102       nl_error( 2, "Error returned from resmgr_detach: %d", errno );
00103     dev_id = -1;
00104   }
00105   // ### Need to make sure my data_generator knows it's time to quit
00106   return cmd_attr.count == 0;
00107 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines