Пример #1
0
bool RtclSignalAction::ClearAction(int signum, RerrMsg& emsg)
{
  if (!ValidSignal(signum, emsg)) return false;
  if (!fActionSet[signum]) {
    emsg.Init("RtclSignalAction::ClearAction", "no action for signal");
    return false;
  }

  if (::sigaction(signum, &fOldAction[signum], NULL) != 0) {
    emsg.InitErrno("RtclSignalAction::ClearAction",
                   "sigaction() failed: ", errno);
    return false;
  }  
  fpScript[signum] = 0;
  fActionSet[signum] = false;
  return true;
}
Пример #2
0
//------------------------------------------+-----------------------------------
//! FIXME_docs
bool RtclSignalAction::Init(Tcl_Interp* interp, RerrMsg& emsg)
{
  if (fpObj) {
    emsg.Init("RtclSignalAction::Init", "already initialized");
    return false;
  }
  
  try {
    fpObj = new RtclSignalAction(interp);
  } catch (exception& e) {
    emsg.Init("RtclSignalAction::Init", string("exception: ")+e.what());
    return false;
  }

  Tcl_CreateExitHandler((Tcl_ExitProc*) ThunkTclExitProc, (ClientData) fpObj);

  return true;
}
Пример #3
0
bool Rw11VirtTermPty::Snd(const uint8_t* data, size_t count, RerrMsg& emsg)
{
  fStats.Inc(kStatNVTSnd);
  ssize_t irc = write(fFd, data, count);
  if (irc != ssize_t(count)) {
    emsg.InitErrno("Rw11VirtTermPty::Snd", "write() failed: ", errno);
    return false;
  }
  fStats.Inc(kStatNVTSndByt, double(count));
  return true;
}
Пример #4
0
bool RtclSignalAction::GetAction(int signum, Tcl_Obj*& pobj, RerrMsg& emsg)
{
  if (!ValidSignal(signum, emsg)) return false;
  if (!fActionSet[signum]) {
    emsg.Init("RtclSignalAction::GetAction", "no action for signal");
    return false;
  }

  pobj = fpScript[signum];
  return true;
}
Пример #5
0
bool Rw11VirtTermPty::Open(const std::string& url, RerrMsg& emsg)
{
  int fd = posix_openpt(O_RDWR);
  if (fd < 0) {
    emsg.InitErrno("Rw11VirtTermPty::Open", "posix_openpt() failed: ", errno);
    return false;
  }

  int irc = grantpt(fd);
  if (irc < 0) {
    emsg.InitErrno("Rw11VirtTermPty::Open", "grantpt() failed: ", errno);
    close(fd);
    return false;
  }
  
  irc = unlockpt(fd);
  if (irc < 0) {
    emsg.InitErrno("Rw11VirtTermPty::Open", "unlockpt() failed: ", errno);
    close(fd);
    return false;
  }
  
  char* pname = ptsname(fd);
  if (pname == 0) {
    emsg.InitErrno("Rw11VirtTermPty::Open", "ptsname() failed: ", errno);
    close(fd);
    return false;
  }
  
  fFd = fd;
  fChannelId = pname;

  Server().AddPollHandler(boost::bind(&Rw11VirtTermPty::RcvPollHandler,
                                      this, _1), 
                          fFd, POLLIN);

  return true;
}
Пример #6
0
bool RtclSignalAction::ValidSignal(int signum, RerrMsg& emsg)
{
  if (signum > 0 && signum < 32) {
    switch (signum) {
    case SIGHUP:
    case SIGINT:
    case SIGTERM:
    case SIGUSR1:
    case SIGUSR2:
      return true;
    default:
      break;
    }
  }
  emsg.Init("RtclSignalAction::ValidSignal", "unsupported signal");
  return false;
}
Пример #7
0
bool RtclSignalAction::SetAction(int signum, Tcl_Obj* pobj, RerrMsg& emsg)
{
  if (!ValidSignal(signum, emsg)) return false;
  if (fActionSet[signum] && !ClearAction(signum, emsg)) return false;

  struct sigaction sigact;
  ::memset(&sigact, 0, sizeof(sigact));
  sigact.sa_handler = SignalHandler;

  if (::sigaction(signum, &sigact, &fOldAction[signum]) != 0) {
    emsg.InitErrno("RtclSignalAction::SetAction",
                   "sigaction() failed: ", errno);
    return false;
  }

  fpScript[signum] = pobj;
  fActionSet[signum] = true;
  return true;
}
Пример #8
0
bool Rw11Unit::Attach(const std::string& url, RerrMsg& emsg)
{
  emsg.Init("Rw11Unit::Attach","attach not available for this device type");
  return false;
}
Пример #9
0
bool RlinkPortTerm::Open(const std::string& url, RerrMsg& emsg)
{
  if (IsOpen()) Close();

  if (!ParseUrl(url, "|baud=|break|cts|xon", emsg)) return false;

  // if path doesn't start with a '/' prepend a '/dev/tty'
  if (fPath.substr(0,1) != "/") {
    string dev = fPath;
    fPath  = "/dev/tty";
    fPath += dev;
  }

  speed_t speed = B115200;
  string baud;
  if (UrlFindOpt("baud", baud)) {
    speed = B0;
    if (baud=="2400")                     speed = B2400;
    if (baud=="4800")                     speed = B4800;
    if (baud=="9600")                     speed = B9600;
    if (baud=="19200"   || baud=="19k")   speed = B19200;
    if (baud=="38400"   || baud=="38k")   speed = B38400;
    if (baud=="57600"   || baud=="57k")   speed = B57600;
    if (baud=="115200"  || baud=="115k")  speed = B115200;
    if (baud=="230400"  || baud=="230k")  speed = B230400;
    if (baud=="460800"  || baud=="460k")  speed = B460800;
    if (baud=="500000"  || baud=="500k")  speed = B500000;
    if (baud=="921600"  || baud=="921k")  speed = B921600;
    if (baud=="1000000" || baud=="1000k" || baud=="1M") speed = B1000000;
    if (baud=="1152000" || baud=="1152k")               speed = B1152000;
    if (baud=="1500000" || baud=="1500k")               speed = B1500000;
    if (baud=="2000000" || baud=="2000k" || baud=="2M") speed = B2000000;
    if (baud=="2500000" || baud=="2500k")               speed = B2500000;
    if (baud=="3000000" || baud=="3000k" || baud=="3M") speed = B3000000;
    if (baud=="3500000" || baud=="3500k")               speed = B3500000;
    if (baud=="4000000" || baud=="4000k" || baud=="4M") speed = B4000000;
    if (speed == B0) {
      emsg.Init("RlinkPortTerm::Open()", 
                string("invalid baud rate \"") + baud + string("\" specified"));
      return false;
    }
  }

  int fd;

  fd = open(fPath.c_str(), O_RDWR|O_NOCTTY);
  if (fd < 0) {
    emsg.InitErrno("RlinkPortTerm::Open()", 
                   string("open() for \"") + fPath + string("\" failed: "),
                   errno);
    return false;
  }

  if (!isatty(fd)) {
    emsg.Init("RlinkPortTerm::Open()", 
              string("isatty() check for \"") + fPath + 
              string("\" failed: not a TTY"));
    close(fd);
    return false;
  }

  if (tcgetattr(fd, &fTiosOld) != 0) {
    emsg.InitErrno("RlinkPortTerm::Open()", 
                   string("tcgetattr() for \"") + fPath + string("\" failed: "),
                   errno);
    close(fd);
    return false;
  }

  bool use_cts = UrlFindOpt("cts");
  bool use_xon = UrlFindOpt("xon");
  fUseXon = use_xon;
  fPendXesc = false;

  fTiosNew = fTiosOld;

  fTiosNew.c_iflag = IGNBRK |               // ignore breaks on input
                     IGNPAR;                // ignore parity errors
  if (use_xon) {
    fTiosNew.c_iflag |= IXON|               // XON/XOFF flow control output
                        IXOFF;              // XON/XOFF flow control input
  }

  fTiosNew.c_oflag = 0;

  fTiosNew.c_cflag = CS8 |                  // 8 bit chars
                     CSTOPB |               // 2 stop bits
                     CREAD |                // enable receiver
                     CLOCAL;                // ignore modem control
  if (use_cts) {
    fTiosNew.c_cflag |= CRTSCTS;            // enable hardware flow control
  }

  fTiosNew.c_lflag = 0;

  if (cfsetspeed(&fTiosNew, speed) != 0) {
    emsg.InitErrno("RlinkPortTerm::Open()", 
                   string("cfsetspeed() for \"") + baud + string("\" failed: "),
                   errno);
    close(fd);
    return false;
  }

  fTiosNew.c_cc[VEOF]   = 0;                // undef
  fTiosNew.c_cc[VEOL]   = 0;                // undef
  fTiosNew.c_cc[VERASE] = 0;                // undef
  fTiosNew.c_cc[VINTR]  = 0;                // undef
  fTiosNew.c_cc[VKILL]  = 0;                // undef
  fTiosNew.c_cc[VQUIT]  = 0;                // undef
  fTiosNew.c_cc[VSUSP]  = 0;                // undef
  fTiosNew.c_cc[VSTART] = 0;                // undef
  fTiosNew.c_cc[VSTOP]  = 0;                // undef
  fTiosNew.c_cc[VMIN]   = 1;                // wait for 1 char
  fTiosNew.c_cc[VTIME]  = 0;                // 
  if (use_xon) {
    fTiosNew.c_cc[VSTART] = kc_xon;         // setup XON  -> ^Q
    fTiosNew.c_cc[VSTOP]  = kc_xoff;        // setup XOFF -> ^S   
  }

  if (tcsetattr(fd, TCSANOW, &fTiosNew) != 0) {
    emsg.InitErrno("RlinkPortTerm::Open()", 
                   string("tcsetattr() for \"") + fPath + string("\" failed: "),
                   errno);
    close(fd);
    return false;
  }

  // tcsetattr() returns success if any of the requested changes could be
  // successfully carried out. Therefore the termios structure is read back
  // and verified.

  struct termios tios;
  if (tcgetattr(fd, &tios) != 0) {
    emsg.InitErrno("RlinkPortTerm::Open()", 
                   string("2nd tcgetattr() for \"") + fPath + 
                     string("\" failed: "), 
                   errno);
    close(fd);
    return false;
  }

  const char* pmsg = 0;
  if (tios.c_iflag != fTiosNew.c_iflag) pmsg = "c_iflag";
  if (tios.c_oflag != fTiosNew.c_oflag) pmsg = "c_oflag";
  if (tios.c_cflag != fTiosNew.c_cflag) pmsg = "c_cflag";
  if (tios.c_lflag != fTiosNew.c_lflag) pmsg = "c_lflag";
  if (cfgetispeed(&tios) != speed)      pmsg = "ispeed";
  if (cfgetospeed(&tios) != speed)      pmsg = "ospeed";
  for (int i=0; i<NCCS; i++) {
    if (tios.c_cc[i] != fTiosNew.c_cc[i]) pmsg = "c_cc char";
  }

  if (pmsg) {
    emsg.Init("RlinkPortTerm::Open()",
              string("tcsetattr() failed to set") +
                string(pmsg));
    close(fd);
    return false;
  }

  fFdWrite = fd;
  fFdRead  = fd;
  fIsOpen  = true;

  if (UrlFindOpt("break")) {
    if (tcsendbreak(fd, 0) != 0) {
      emsg.InitErrno("RlinkPortTerm::Open()", 
                     string("tcsendbreak() for \"") + fPath + 
                     string("\" failed: "), errno);
      Close();
      return false;
    }
    uint8_t buf[1];
    buf[0] = 0x80;
    if (Write(buf, 1, emsg) != 1) {
      Close();
      return false;      
    }
  }

  return true;
}