Unix Programming - stty and tcgetattr/tcsetattr do not match

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > September 2005 > stty and tcgetattr/tcsetattr do not match





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author stty and tcgetattr/tcsetattr do not match
Jim Alexander

2005-09-21, 5:54 pm

I'm trying to write a program that reads from the serial port, and one
of the things I would like it to do is flip CLOCAL on and off from within
the program. My problem is that the attributes I get back from tcgetattr
do not match what I see in stty, and any changes I make with tcsetattr
can be read back with tcgetattr, but again the changes do not appear
when I query the port with stty, and the port behaves according to
what stty says the settings are, not what tcgetattr says they are.
It's like tcgetattr and tcsetattr maintain a parallel set of terminal
properties, which don't actually do anything.

Here's a code fragment that tries to clear CLOCAL, if it is set:

fd = open_port_noblock();
if (tcgetattr(fd, termSettings) == -1){
perror("monitor: Couldn't check tty settings - ");
exit(1);
}
printf("%08o\n", termSettings->c_cflag);
if(termSettings->c_cflag&CLOCAL){
termSettings->c_cflag &= ~CLOCAL;
if (tcsetattr(fd, TCSANOW, termSettings) == -1){
perror("monitor: Couldn't change tty settings - ");
}
}
tcgetattr(fd, termSettings);
printf("%08o\n", termSettings->c_cflag);
close(fd);

The first printf prints 00004260, and the second prints 00000260, as
you might expect. Problem is, according to stty, the control modes
on the serial port are:

-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts

which should be 00006260. Plus, stty does not show -clocal once
the program has run - it stays in exactly the same mode.

Anyone know what I might be missing here?

--

________ Jim Alexander __________________ jalex@cis.upenn.edu ________________
I have yet to see a problem, however complicated, which, when you looked at it
in the right way, did not become still more complicated. -- Poul Anderson
Barry Margolin

2005-09-21, 8:49 pm

In article <dgsk9o$9fmm$1@netnews.upenn.edu>,
jalex@cis.upenn.edu (Jim Alexander) wrote:

> I'm trying to write a program that reads from the serial port, and one
> of the things I would like it to do is flip CLOCAL on and off from within
> the program. My problem is that the attributes I get back from tcgetattr
> do not match what I see in stty, and any changes I make with tcsetattr
> can be read back with tcgetattr, but again the changes do not appear
> when I query the port with stty, and the port behaves according to
> what stty says the settings are, not what tcgetattr says they are.
> It's like tcgetattr and tcsetattr maintain a parallel set of terminal
> properties, which don't actually do anything.
>
> Here's a code fragment that tries to clear CLOCAL, if it is set:
>
> fd = open_port_noblock();
> if (tcgetattr(fd, termSettings) == -1){
> perror("monitor: Couldn't check tty settings - ");
> exit(1);
> }
> printf("%08o\n", termSettings->c_cflag);
> if(termSettings->c_cflag&CLOCAL){
> termSettings->c_cflag &= ~CLOCAL;
> if (tcsetattr(fd, TCSANOW, termSettings) == -1){
> perror("monitor: Couldn't change tty settings - ");
> }
> }
> tcgetattr(fd, termSettings);
> printf("%08o\n", termSettings->c_cflag);
> close(fd);


The problem is with close(fd). When tty devices are closed, they revert
back to their default settings. If there are multiple descriptors
attached to the device (either in the same or different processes), this
happens when the last one is closed.

You need to open the device, set the attributes, do all the things that
depend on these attributes, and only then can you close the descriptor.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Jim Alexander

2005-09-22, 9:01 pm

In article <barmar-B3C7BB.21061521092005@comcast.dca.giganews.com>,
Barry Margolin <barmar@alum.mit.edu> wrote:
]In article <dgsk9o$9fmm$1@netnews.upenn.edu>,
] jalex@cis.upenn.edu (Jim Alexander) wrote:
]
]> I'm trying to write a program that reads from the serial port, and one
]> of the things I would like it to do is flip CLOCAL on and off from within
]> the program. My problem is that the attributes I get back from tcgetattr
]> do not match what I see in stty, and any changes I make with tcsetattr
]> can be read back with tcgetattr, but again the changes do not appear
]> when I query the port with stty, and the port behaves according to
]> what stty says the settings are, not what tcgetattr says they are.
]> It's like tcgetattr and tcsetattr maintain a parallel set of terminal
]> properties, which don't actually do anything.
]>
]> Here's a code fragment that tries to clear CLOCAL, if it is set:
]>
]> fd = open_port_noblock();
]> if (tcgetattr(fd, termSettings) == -1){
]> perror("monitor: Couldn't check tty settings - ");
]> exit(1);
]> }
]> printf("%08o\n", termSettings->c_cflag);
]> if(termSettings->c_cflag&CLOCAL){
]> termSettings->c_cflag &= ~CLOCAL;
]> if (tcsetattr(fd, TCSANOW, termSettings) == -1){
]> perror("monitor: Couldn't change tty settings - ");
]> }
]> }
]> tcgetattr(fd, termSettings);
]> printf("%08o\n", termSettings->c_cflag);
]> close(fd);
]
]The problem is with close(fd). When tty devices are closed, they revert
]back to their default settings. If there are multiple descriptors
]attached to the device (either in the same or different processes), this
]happens when the last one is closed.
]
]You need to open the device, set the attributes, do all the things that
]depend on these attributes, and only then can you close the descriptor.

That isn't the case on the Linux systems I'm working with. I suppose it
could be true of serial ports under to control of something like ttymon.
As Murphy's Law dictates, I found my problem shortly after posting,
and cancelled the article, but of course a lot of news servers ignore
cancel control messages.

For posterity, the problem was actually in the open_port_noblock(), whose
code I didn't post, arising from an incorrect cut-and-paste. It was always
returning 0 for the file descriptor, which means I was actually manipulating
the pty I was running the program in. So I really was manipulating a
different set of terminal properties!

--

________ Jim Alexander __________________ jalex@cis.upenn.edu ________________
I have yet to see a problem, however complicated, which, when you looked at it
in the right way, did not become still more complicated. -- Poul Anderson
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com