Well, first off I have no doubt I'm doing something wrong, I'm new to both sockets programming and serial device programming under Linux.
My application creates 3 sockets and controls a serial device through a serial port. However I found that under Linux (maybe all Unixes?) I have to "reset" the stdin/stdout terminal settings just to get things to function properly. I don't know why this must be done, maybe I'm doing it incorrectly, but this is what I'm doing when I open my serial device:
Code:
/* set my serial port settings above (raw mode).....*/
tcgetattr(1,&port->ser_old_stdout_tio); // we gotta do this - there is a Linux bug
tcsetattr(1,TCSANOW,&port->ser_newtio); // make stdout settings like modem settings
tcgetattr(0,&port->ser_oldstdtio); // get stdin settings for restoration ...
tcgetattr(0,&port->ser_newstdtio); // ... and use them as a basis for changes
tcsetattr(0,TCSANOW,&port->ser_newstdtio); // set the new attributes immediately
Now, in the foreground everything works fine, at least so far as I can tell, my app's been running for 96 hours nonstop without a hitch, doing everything it's supposed to.
When I try the suggested code in the FAQ, the terminal settings get reset to the serial port settings and remain that way. Thus, if I execute,
# program
my terminal settings are all messed-up (correct for the serial device I'm controlling, but ugly for the user). Typing 'reset' fixes it, but that's not very nice.
I thought by running my child in its own session it would be terminalless(?), so I removed the above bit of code when opening my serial port. However then (just as if it were running in the fg), my serial device doesn't work any longer.
The mystery to me is the very first thing I ever do
in my code is fork off my child. It's behaving as if the child is controlling the same terminal as its parent was, which (I think) would explain everything I'm seeing. I could understand this if setsid failed, but it doesn't (never executes the code under "if setsid returned -1...").
On page 245 of "Advanced Programming in the UNIX Environment" it states:
3. The process [that called setsid] has no controlling terminal....If the process had a controlling terminal before calling setsid, that association is broken.
So I'm a little confused as to why my child seems to be controlling its parent's terminal. I could understand if the serial settings were executed by the parent before it died, so it died before resetting the port settings, but they're not, my parent returns(1) before it ever gets a chance to mess with the serial port settings.
Since the only way I can get serial ports to work under Linux is to reset stdin/stdout, does this mean I can never run my application in the background without putting-up with those raw shell terminal settings?
Thanks as always for any help.