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; }
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; }
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; }
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; }
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; }