In all cases the pattern was tcflush(fd, TCIOFLUSH) followed by
tcsetattr(fd, TCSAFLUSH, ...). The problem was that, for some drivers,
tcflush() was apparently doing nothing, so tcsetattr() might hang
forever waiting for the output buffers to drain (possible if flow
control is enabled). Replaced tcflush(fd, TCSAFLUSH), with tcsetattr(fd,
TCSANOW) which, after a tcflush() should anyway be equivalent.
If the requested baudrate is not a custom one (i.e. does not match one
of the Bxxx macros), then the cfsetospeed_custom() and
cfsetispeed_custom() are called to configure the "nexttermios" structure
with the requested non-standard baudrate. Same thing for reading the
baudrate: If cfgetospeed() and / or cfgetispeed() return a value that is
not among the Bxxx macros, cfgetospeed_custom() and cfgetispeed_custom()
are called, to read (and decode) the non-standard baudrate from the
"nexttermios" structure.
Currently the cf[set|get][i|o]speed_custom functions are only
implemented for Linux, and work only with non-ancient kernels (>2.6). So
in effect, custom baud-rate support is currently only supported for
Linux.
Function fd_readline() now displays non-printable and non-ascii
characters as hex codes (e.g \x12). These characters can be deleted
correctly using the [Backspace] or [DEL] key. This is applicable only
when picocom is compiled without linenoise support.
Picocom no longer uses /bin/sh to run external commands for
file-transfer operations. Parsing the command line and spliting it into
arguments is now performed internally by picocom, using quoting rules
very similar to those of the Unix shell. Hopefully, this makes it
impossible to inject shell-commands when supplying filenames or
extra arguments to the send- and receive-file commands.
Recent GCC / GLIBC combinations warn you when you call write(2) without
checking its return value. Casting the function to void, doesn't help
either. See: warn_unused_result.
If you define a large TTY_Q_SZ (which is quite useful for reliable
copy/paste) then write(2) would send large chucks to the tty in a single
gulp. On slow (very slow) baud rates this would make the tty fd buffers
take forever to drain on exit or when tcsetattrs() is
called. Unfortunatelly calling tcflush() doesn't really help (not on
linux, not with my serial driver).
So we limit the amount of data write(2) can send to the tty on a single
call, based on the port's baud rate (current setting baud-rate / 10
bytes, i.e. approx. one second worth of data). On my system (Linux) this
seems to be adequate: the fd does not become write-ready until most of
the data are sent through, so no huge buffers (with respect to the
baud-rate) are not accumulated and they don't take forever to drain.
- Don't call exit(3) from signal handler. Set a flag and let loop()
check it.
- Don't use system(3). Still uses /bin/sh to run the external
command. This should be fixed.
- Better signal disposition preparation for child process.
In term_exitfunc() (which is called via atexit(3)) and
term_lib_init() (which resets ALL managed terminals to their original
attributes), if tcsetattr(3) fails with EINTR, try again.