Some niggles but this is a big improvement to the code.
Can you really get a speed below 1 baud ?
If there is a hangup requested (c_cflag & CBAUD) == B0 then you don't
want to overwrite the baud rate but that you handled in set_termios
already.
close should never be called with tty == NULL unless there is some kind
of internal abuse of it - is the tty check really needed ?
Open on the other hand is currently called with tty = NULL in the case it
is used as a console device (ugly and something I want to fix but it
happens for now)
set_termios should never be called with tty == NULL nowdays so that test
should be removable.
This could race another set_handshake ? I'm not sure it matters and I'd
suggest that stuff gets fixed after this is submitted separately
--