void QSerial::InitModbus() { if ((m_nFdModbus = Open(szModbusCom, O_RDWR | O_NONBLOCK)) < 0) { //assert(false); //perror(szModbusCom); return ; } struct termios _opt; bzero(&_opt, sizeof(_opt)); //清除结构体以放入新的序列埠设定值 Tcgetattr(m_nFdModbus, &_opt); _opt.c_cc[VMIN] = 1; _opt.c_iflag = 0; _opt.c_oflag = 0; _opt.c_lflag = 0; _opt.c_cflag = B9600 | CS8 | CLOCAL | CREAD; if (Tcsetattr(m_nFdModbus, TCSANOW, &_opt)) { // perror("tcsetattr error"); //assert(false); //exit(1); } //注册响应 QSocketNotifier* notify = new QSocketNotifier(m_nFdModbus, QSocketNotifier::Read, this); connect(notify, SIGNAL(activated(int)), this, SLOT(OnReceiveChar())); }
/* open for writing: if the filesystem entry already exists, the data is appended if it does not exist, a file is created and the data is appended */ static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3) { const char *filename = argv[1]; int rw = (xioflags & XIO_ACCMODE); bool exists; bool opt_unlink_close = false; int result; /* remove old file, or set user/permissions on old file; parse options */ if ((result = _xioopen_named_early(argc, argv, fd, groups, &exists, opts)) < 0) { return result; } retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close); if (opt_unlink_close) { if ((fd->stream.unlink_close = strdup(filename)) == NULL) { Error1("strdup(\"%s\"): out of memory", filename); } fd->stream.opt_unlink_close = true; } Notice3("opening %s \"%s\" for %s", filetypenames[(result&S_IFMT)>>12], filename, ddirection[rw]); if ((result = _xioopen_open(filename, rw, opts)) < 0) return result; fd->stream.fd = result; #if WITH_TERMIOS if (Isatty(fd->stream.fd)) { if (Tcgetattr(fd->stream.fd, &fd->stream.savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", fd->stream.fd, strerror(errno)); } else { fd->stream.ttyvalid = true; } } #endif /* WITH_TERMIOS */ applyopts_named(filename, opts, PH_FD); applyopts(fd->stream.fd, opts, PH_FD); applyopts_cloexec(fd->stream.fd, opts); applyopts_fchown(fd->stream.fd, opts); if ((result = _xio_openlate(&fd->stream, opts)) < 0) return result; return 0; }
int xiotermios_clrflag(int fd, int word, tcflag_t mask) { union { struct termios termarg; tcflag_t flags[4]; } tdata; if (Tcgetattr(fd, &tdata.termarg) < 0) { Error3("tcgetattr(%d, %p): %s", fd, &tdata.termarg, strerror(errno)); return -1; } tdata.flags[word] &= ~mask; if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) { Error3("tcsetattr(%d, TCSADRAIN, %p): %s", fd, &tdata.termarg, strerror(errno)); return -1; } return 0; }
/* retrieve and apply options to a standard file descriptor. Do not set FD_CLOEXEC flag. */ int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3) { xfd->fd = numfd; xfd->howtoend = END_NONE; #if WITH_TERMIOS if (Isatty(xfd->fd)) { if (Tcgetattr(xfd->fd, &xfd->savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", xfd->fd, strerror(errno)); } else { xfd->ttyvalid = true; } } #endif /* WITH_TERMIOS */ if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1; applyopts(-1, opts, PH_INIT); applyopts2(xfd->fd, opts, PH_INIT, PH_FD); return _xio_openlate(xfd, opts); }
/* process a bidirectional "stdio" or "-" argument with options. */ int xioopen_stdio_bi(xiofile_t *sock) { struct opt *opts1, *opts2, *optspr; unsigned int groups1 = xioaddr_stdio0.groups, groups2 = xioaddr_stdio0.groups; int result; sock->stream.rfd = 0 /*stdin*/; sock->stream.wfd = 1 /*stdout*/; #if WITH_TERMIOS if (Isatty(sock->stream.rfd)) { if (Tcgetattr(sock->stream.rfd, &sock->stream.savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", sock->stream.rfd, strerror(errno)); } else { sock->stream.ttyvalid = true; } } if (Isatty(sock->stream.wfd) && (sock->stream.wfd != sock->stream.rfd)) { if (Tcgetattr(sock->stream.wfd, &sock->stream.savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", sock->stream.wfd, strerror(errno)); } else { sock->stream.ttyvalid = true; } } #endif /* WITH_TERMIOS */ if (applyopts_single(&sock->stream, sock->stream.opts, PH_INIT) < 0) return -1; applyopts(-1, sock->stream.opts, PH_INIT); if (sock->stream.howtoshut == XIOSHUT_UNSPEC) sock->stream.howtoshut = XIOSHUT_NONE; /* options here are one-time and one-direction, no second use */ retropt_bool(sock->stream.opts, OPT_IGNOREEOF, &sock->stream.ignoreeof); /* extract opts that should be applied only once */ if ((optspr = copyopts(sock->stream.opts, GROUP_PROCESS)) == NULL) { return -1; } if ((result = applyopts(-1, optspr, PH_EARLY)) < 0) return result; if ((result = applyopts(-1, optspr, PH_PREOPEN)) < 0) return result; /* here we copy opts, because most have to be applied twice! */ if ((opts1 = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups1&~GROUP_PROCESS))) == NULL) { return -1; } /* apply options to first FD */ if ((result = applyopts(sock->stream.rfd, opts1, PH_ALL)) < 0) { return result; } if ((result = _xio_openlate(&sock->stream, opts1)) < 0) { return result; } if ((opts2 = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups2&~GROUP_PROCESS))) == NULL) { return -1; } /* apply options to second FD */ if ((result = applyopts(sock->stream.wfd, opts2, PH_ALL)) < 0) { return result; } if ((result = _xio_openlate(&sock->stream, opts2)) < 0) { return result; } if ((result = _xio_openlate(&sock->stream, optspr)) < 0) { return result; } Notice("reading from and writing to stdio"); return 0; }
/* process a bidirectional "stdio" or "-" argument with options. generate a dual address. */ int xioopen_stdio_bi(xiofile_t *sock) { struct opt *optspr; unsigned int groups1 = addr_stdio.groups; int result; if (xioopen_makedual(sock) < 0) { return -1; } sock->dual.stream[0]->tag = XIO_TAG_RDONLY; sock->dual.stream[0]->fd = 0 /*stdin*/; sock->dual.stream[1]->tag = XIO_TAG_WRONLY; sock->dual.stream[1]->fd = 1 /*stdout*/; sock->dual.stream[0]->howtoend = sock->dual.stream[1]->howtoend = END_NONE; #if WITH_TERMIOS if (Isatty(sock->dual.stream[0]->fd)) { if (Tcgetattr(sock->dual.stream[0]->fd, &sock->dual.stream[0]->savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", sock->dual.stream[0]->fd, strerror(errno)); } else { sock->dual.stream[0]->ttyvalid = true; } } if (Isatty(sock->dual.stream[1]->fd)) { if (Tcgetattr(sock->dual.stream[1]->fd, &sock->dual.stream[1]->savetty) < 0) { Warn2("cannot query current terminal settings on fd %d: %s", sock->dual.stream[1]->fd, strerror(errno)); } else { sock->dual.stream[1]->ttyvalid = true; } } #endif /* WITH_TERMIOS */ /* options here are one-time and one-direction, no second use */ retropt_bool(sock->stream.opts, OPT_IGNOREEOF, &sock->dual.stream[0]->ignoreeof); /* extract opts that should be applied only once */ if ((optspr = copyopts(sock->stream.opts, GROUP_PROCESS)) == NULL) { return -1; } /* here we copy opts, because most have to be applied twice! */ if ((sock->dual.stream[1]->opts = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups1&~GROUP_PROCESS))) == NULL) { return -1; } sock->dual.stream[0]->opts = sock->stream.opts; sock->stream.opts = NULL; if (applyopts_single(sock->dual.stream[0], sock->dual.stream[0]->opts, PH_INIT) < 0) return -1; if (applyopts_single(sock->dual.stream[1], sock->dual.stream[1]->opts, PH_INIT) < 0) return -1; applyopts(-1, sock->dual.stream[0]->opts, PH_INIT); applyopts(-1, sock->dual.stream[1]->opts, PH_INIT); if ((result = applyopts(-1, optspr, PH_EARLY)) < 0) return result; if ((result = applyopts(-1, optspr, PH_PREOPEN)) < 0) return result; /* apply options to first FD */ if ((result = applyopts(sock->dual.stream[0]->fd, sock->dual.stream[0]->opts, PH_ALL)) < 0) { return result; } if ((result = _xio_openlate(sock->dual.stream[0], sock->dual.stream[0]->opts)) < 0) { return result; } #if 0 /* ignore this opt */ retropt_bool(sock->dual.stream[0]->opts, OPT_COOL_WRITE); #endif /* apply options to second FD */ if ((result = applyopts(sock->dual.stream[1]->fd, sock->dual.stream[1]->opts, PH_ALL)) < 0) { return result; } if ((result = _xio_openlate(sock->dual.stream[1], sock->dual.stream[1]->opts)) < 0) { return result; } #if 0 if ((result = _xio_openlate(sock->dual.stream[1], optspr)) < 0) { return result; } #endif Notice("reading from and writing to stdio"); return 0; }