linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* man termios
@ 2014-03-20 18:42 Peter Hurley
  2014-03-21 10:45 ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Hurley @ 2014-03-20 18:42 UTC (permalink / raw)
  To: Michael Kerrisk; +Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

Hi Michael,

Some issues have arisen [1] regarding a discrepancy between the Linux behavior of
read() on a tty and 'man termios' and 'Linux Programming Interface', Chapter 62.

Firstly, if MIN==0 and TIME==0 and no input is available, read() returns 0,
even if O_NONBLOCK is set. This is also true of the other non-canonical read()'s with
timeout (TIME > 0).

'man termios' is silent here, but 62.6.2 in LPI implies that O_NONBLOCK will return
-1 with errno==EAGAIN; it does not.

This is unspecified by POSIX (11.1.7).

Secondly, in all 4 of the non-canonical read() modes, the MIN value does not limit
the number of bytes which may be returned by the read(). Only the 'count' parameter
to read() has this effect.

LPI has this to say (man-pages reads similar):

"MIN > 0, TIME == 0 (blocking read)

The read() blocks (possibly indefinitely) until the lesser of the number of bytes
requested or MIN bytes are available, and returns the lesser of the two values."

However, read() may unblock when MIN bytes are available but return up to the
'count' parameter if more input arrives in between waking and copying into the
user buffer.

So, for example, if MIN == 5,

   n = read(tty, &buffer, 30 /*sizeof(buffer)*/)

n may be up to 30 on return.

Finally, if the 'count' parameter is less than MIN, read() may return before MIN
bytes have been received, if 'count' bytes have been received.

Regards,
Peter Hurley

[1] https://bugzilla.kernel.org/show_bug.cgi?id=71671

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-20 18:42 man termios Peter Hurley
@ 2014-03-21 10:45 ` Michael Kerrisk (man-pages)
  2014-03-21 11:21   ` Peter Hurley
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Kerrisk (man-pages) @ 2014-03-21 10:45 UTC (permalink / raw)
  To: Peter Hurley; +Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

Hello Peter,

On Thu, Mar 20, 2014 at 7:42 PM, Peter Hurley <peter@hurleysoftware.com> wrote:
> Hi Michael,
>
> Some issues have arisen [1] regarding a discrepancy between the Linux
> behavior of
> read() on a tty and 'man termios' and 'Linux Programming Interface', Chapter
> 62.
>
> Firstly, if MIN==0 and TIME==0 and no input is available, read() returns 0,
> even if O_NONBLOCK is set.

Yes.

> This is also true of the other non-canonical
> read()'s with
> timeout (TIME > 0).

Here, if I understand you correctly, you mean this case:
* TIME > 0
* MIN == 0
* O_NONBLOCK set on the FD
* No input available

You are saying that read() returns 0 in this case? This doesn't appear
to me to be correct (on Linux). How did you verify this?

> 'man termios' is silent here, but 62.6.2 in LPI implies that O_NONBLOCK will
> return
> -1 with errno==EAGAIN; it does not.

I guess you are referring to this text in TLPI:

[[
This mode is somewhat similar to setting the O_NONBLOCK flag for the
terminal (Section 5.9). However, with O_NONBLOCK, if no bytes are
available for reading, then read() returns –1 with the error
EAGAIN.
]]

Oops. The text was not meant to imply that. Rather the comparison was
intended to be with O_NONBLOCK *in canonical mode*. However, I agree
that I could have made that more explicit. (I'll add an erratum to
mention canonical mode.)

> This is unspecified by POSIX (11.1.7).

Yep, I see. XBD 11.1.7 says:

[[
Therefore, if O_NONBLOCK is set, read( ) may return immediately,
regardless of the setting of MIN or TIME. Also, if no data is
available, read( ) may either return 0, or return -1 with errno set to
[EAGAIN].
]]

So, it seems to be saying that either behavior is allowed, right? And
as far as I can see, for the TIME>0 case on Linux, read() returns -1 +
EGAIN.

In any case, I've added this text to termios(3):

       POSIX  does  not  specify whether the setting of the O_NONBLOCK
       file status flag takes precedence over the MIN  and  TIME  set‐
       tings.  If O_NONBLOCK is set, a read() in noncanonical mode may
       return immediately, regardless of the setting of MIN  or  TIME.
       Furthermore, if no data is available, POSIX permits a read() in
       noncanonical mode to return either 0, or -1 with errno  set  to
       EAGAIN.

> Secondly, in all 4 of the non-canonical read() modes, the MIN value does not
> limit
> the number of bytes which may be returned by the read(). Only the 'count'
> parameter
> to read() has this effect.
>
> LPI has this to say (man-pages reads similar):
>
> "MIN > 0, TIME == 0 (blocking read)
>
> The read() blocks (possibly indefinitely) until the lesser of the number of
> bytes
> requested or MIN bytes are available, and returns the lesser of the two
> values."
>
> However, read() may unblock when MIN bytes are available but return up to
> the
> 'count' parameter if more input arrives in between waking and copying into
> the
> user buffer.

Yup, you are obviously correct. It would make no sense for read() to
return the lesser of [MIN, count]. I got myself into a small thinko as
I wrote that text.

I've applied this patch to the termios.3 page:

[[
diff --git a/man3/termios.3 b/man3/termios.3
index b069ec0..63aba07 100644
--- a/man3/termios.3
+++ b/man3/termios.3
@@ -728,8 +728,7 @@ completes; there are four distinct cases:
 MIN == 0; TIME == 0:
 If data is available,
 .BR read (2)
-returns immediately, with the lesser of the number of bytes
-available, or the number of bytes requested.
+returns immediately, returning up to the number of bytes requested.
 If no data is available,
 .BR read (2)
 returns 0.
]]

I'll write a similar erratum for TLPI.

[...]

> Finally, if the 'count' parameter is less than MIN, read() may return before
> MIN
> bytes have been received, if 'count' bytes have been received.

Yes. But it's not clear to me here: do you mean that something in the
man page (or in TLPI) needs fixing?

Thanks for the report, Peter.

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-21 10:45 ` Michael Kerrisk (man-pages)
@ 2014-03-21 11:21   ` Peter Hurley
  2014-03-21 13:15     ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Hurley @ 2014-03-21 11:21 UTC (permalink / raw)
  To: mtk.manpages; +Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

On 03/21/2014 06:45 AM, Michael Kerrisk (man-pages) wrote:
>> This is also true of the other non-canonical
>> read()'s with timeout (TIME > 0).
>
> Here, if I understand you correctly, you mean this case:
> * TIME > 0
> * MIN == 0
> * O_NONBLOCK set on the FD
> * No input available
>
> You are saying that read() returns 0 in this case? This doesn't appear
> to me to be correct (on Linux). How did you verify this?

Apologies, my mistake here.

(aside: O_NONBLOCK can be changed while the reader is blocked, but that's
not what I meant originally, and I wouldn't document it there)

>> 'man termios' is silent here, but 62.6.2 in LPI implies that O_NONBLOCK will
>> return -1 with errno==EAGAIN; it does not.
>
> I guess you are referring to this text in TLPI:

Yes.

> [[
> This mode is somewhat similar to setting the O_NONBLOCK flag for the
> terminal (Section 5.9). However, with O_NONBLOCK, if no bytes are
> available for reading, then read() returns –1 with the error
> EAGAIN.
> ]]
>
> Oops. The text was not meant to imply that. Rather the comparison was
> intended to be with O_NONBLOCK *in canonical mode*. However, I agree
> that I could have made that more explicit. (I'll add an erratum to
> mention canonical mode.)
>
>> This is unspecified by POSIX (11.1.7).
>
> Yep, I see. XBD 11.1.7 says:
>
> [[
> Therefore, if O_NONBLOCK is set, read( ) may return immediately,
> regardless of the setting of MIN or TIME. Also, if no data is
> available, read( ) may either return 0, or return -1 with errno set to
> [EAGAIN].
> ]]
>
> So, it seems to be saying that either behavior is allowed, right?

Exactly.

> And as far as I can see, for the TIME>0 case on Linux, read() returns
> -1 + EGAIN.

You're right about the TIME>0 case.

> In any case, I've added this text to termios(3):
>
>         POSIX  does  not  specify whether the setting of the O_NONBLOCK
>         file status flag takes precedence over the MIN  and  TIME  set‐
>         tings.  If O_NONBLOCK is set, a read() in noncanonical mode may
>         return immediately, regardless of the setting of MIN  or  TIME.
>         Furthermore, if no data is available, POSIX permits a read() in
>         noncanonical mode to return either 0, or -1 with errno  set  to
>         EAGAIN.


Great; I think that will really help clarify the usage wrt O_NONBLOCK.


>> Secondly, in all 4 of the non-canonical read() modes, the MIN value does not
>> limit the number of bytes which may be returned by the read(). Only the
>> 'count' parameter to read() has this effect.
>>
>> LPI has this to say (man-pages reads similar):
>>
>> "MIN > 0, TIME == 0 (blocking read)
>>
>> The read() blocks (possibly indefinitely) until the lesser of the number of
>> bytes requested or MIN bytes are available, and returns the lesser of the
>> two values."
>>
>> However, read() may unblock when MIN bytes are available but return up to
>> the 'count' parameter if more input arrives in between waking and copying
>> into the user buffer.
>
> Yup, you are obviously correct. It would make no sense for read() to
> return the lesser of [MIN, count]. I got myself into a small thinko as
> I wrote that text.
>
> I've applied this patch to the termios.3 page:
>
> [[
> diff --git a/man3/termios.3 b/man3/termios.3
> index b069ec0..63aba07 100644
> --- a/man3/termios.3
> +++ b/man3/termios.3
> @@ -728,8 +728,7 @@ completes; there are four distinct cases:
>   MIN == 0; TIME == 0:
>   If data is available,
>   .BR read (2)
> -returns immediately, with the lesser of the number of bytes
> -available, or the number of bytes requested.
> +returns immediately, returning up to the number of bytes requested.
>   If no data is available,
>   .BR read (2)
>   returns 0.
> ]]
>
> I'll write a similar erratum for TLPI.

Thanks.

> [...]
>
>> Finally, if the 'count' parameter is less than MIN, read() may return before
>> MIN bytes have been received, if 'count' bytes have been received.
>
> Yes. But it's not clear to me here: do you mean that something in the
> man page (or in TLPI) needs fixing?

Well, what I mean here is that read() may also _not_ return until MIN bytes have
been received, even if 'count' bytes have been received.

Regards,
Peter Hurley



--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-21 11:21   ` Peter Hurley
@ 2014-03-21 13:15     ` Michael Kerrisk (man-pages)
  2014-03-21 14:03       ` Peter Hurley
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Kerrisk (man-pages) @ 2014-03-21 13:15 UTC (permalink / raw)
  To: Peter Hurley
  Cc: mtk.manpages, linux kernel, linux-serial, One Thousand Gnomes,
	Ivan

[-- Attachment #1: Type: text/plain, Size: 6221 bytes --]

On 03/21/2014 12:21 PM, Peter Hurley wrote:
> On 03/21/2014 06:45 AM, Michael Kerrisk (man-pages) wrote:
>>> This is also true of the other non-canonical
>>> read()'s with timeout (TIME > 0).
>>
>> Here, if I understand you correctly, you mean this case:
>> * TIME > 0
>> * MIN == 0
>> * O_NONBLOCK set on the FD
>> * No input available
>>
>> You are saying that read() returns 0 in this case? This doesn't appear
>> to me to be correct (on Linux). How did you verify this?
> 
> Apologies, my mistake here.

Okay -- thanks for confirming.

> (aside: O_NONBLOCK can be changed while the reader is blocked, but that's
> not what I meant originally, and I wouldn't document it there)
> 
>>> 'man termios' is silent here, but 62.6.2 in LPI implies that O_NONBLOCK will
>>> return -1 with errno==EAGAIN; it does not.
>>
>> I guess you are referring to this text in TLPI:
> 
> Yes.
> 
>> [[
>> This mode is somewhat similar to setting the O_NONBLOCK flag for the
>> terminal (Section 5.9). However, with O_NONBLOCK, if no bytes are
>> available for reading, then read() returns –1 with the error
>> EAGAIN.
>> ]]
>>
>> Oops. The text was not meant to imply that. Rather the comparison was
>> intended to be with O_NONBLOCK *in canonical mode*. However, I agree
>> that I could have made that more explicit. (I'll add an erratum to
>> mention canonical mode.)
>>
>>> This is unspecified by POSIX (11.1.7).
>>
>> Yep, I see. XBD 11.1.7 says:
>>
>> [[
>> Therefore, if O_NONBLOCK is set, read( ) may return immediately,
>> regardless of the setting of MIN or TIME. Also, if no data is
>> available, read( ) may either return 0, or return -1 with errno set to
>> [EAGAIN].
>> ]]
>>
>> So, it seems to be saying that either behavior is allowed, right?
> 
> Exactly.
> 
>> And as far as I can see, for the TIME>0 case on Linux, read() returns
>> -1 + EGAIN.
> 
> You're right about the TIME>0 case.
> 
>> In any case, I've added this text to termios(3):
>>
>>         POSIX  does  not  specify whether the setting of the O_NONBLOCK
>>         file status flag takes precedence over the MIN  and  TIME  set‐
>>         tings.  If O_NONBLOCK is set, a read() in noncanonical mode may
>>         return immediately, regardless of the setting of MIN  or  TIME.
>>         Furthermore, if no data is available, POSIX permits a read() in
>>         noncanonical mode to return either 0, or -1 with errno  set  to
>>         EAGAIN.
> 
> 
> Great; I think that will really help clarify the usage wrt O_NONBLOCK.

[...]

>>> Finally, if the 'count' parameter is less than MIN, read() may return before
>>> MIN bytes have been received, if 'count' bytes have been received.
>>
>> Yes. But it's not clear to me here: do you mean that something in the
>> man page (or in TLPI) needs fixing?
> 
> Well, what I mean here is that read() may also _not_ return until MIN bytes have
> been received, even if 'count' bytes have been received.

Ahh -- I see what you mean. And, it looks like there is a point here where Linux
differs from POSIX and (at least) Solaris. See the current man-page text below,
in particular the MIN>0, TIME>0 case. I've also attached a simple test program 
that I used, below.

       In noncanonical mode input is available immediately (without  the
       user  having  to  type a line-delimiter character), no input pro‐
       cessing is performed, and line editing is disabled.  The settings
       of  MIN (c_cc[VMIN]) and TIME (c_cc[VTIME]) determine the circum‐
       stances in which a read(2) completes;  there  are  four  distinct
       cases:

       MIN == 0; TIME == 0:
              If  data  is  available, read(2) returns immediately, with
              the lesser of the number of bytes available, or the number
              of  bytes  requested.   If  no  data is available, read(2)
              returns 0.

       MIN > 0; TIME == 0:
              read(2) blocks until MIN bytes are available, and  returns
              up to the number of bytes requested.

       MIN == 0; TIME > 0:
              TIME  specifies  the limit for a timer in tenths of a sec‐
              ond.   The  timer  is  started  when  read(2)  is  called.
              read(2)  returns  either when at least one byte of data is
              available, or  when  the  timer  expires.   If  the  timer
              expires  without  any  input  becoming  available, read(2)
              returns 0.  If data is already available at  the  time  of
              the call to read() the call behaves as though the data was
              received immediately after the call.

       MIN > 0; TIME > 0:
              TIME specifies the limit for a timer in tenths of  a  sec‐
              ond.  Once an initial byte of input becomes available, the
              timer is restarted after each further  byte  is  received.
              read(2)  returns  when  any of the following conditions is
              met:

              *  MIN bytes have been received.

              *  The interbyte timer expires.

              *  The number of  bytes  requested  by  read(2)  has  been
                 received.   (POSIX  does  not  specify this termination
                 condition, and on  some  other  implementations  read()
                 does not return in this case.)

              Because  the  timer is started only after the initial byte
              becomes available, at least one byte  will  be  read.   If
              data  is  already  available  at  the  time of the call to
              read() the call behaves as though the  data  was  received
              immediately after the call.

       POSIX does not specify whether the setting of the O_NONBLOCK file
       status flag takes precedence over the MIN and TIME settings.   If
       O_NONBLOCK is set, a read() in noncanonical mode may return imme‐
       diately, regardless of the setting of MIN or TIME.   Furthermore,
       if  no  data is available, POSIX permits a read() in noncanonical
       mode to return either 0, or -1 with errno set to EAGAIN.

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

[-- Attachment #2: noncanonical.c --]
[-- Type: text/x-csrc, Size: 1443 bytes --]

/*#* noncanonical.c

   Usage: see below.
*/
#include <termios.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define errExit(msg) 	do { perror(msg); exit(EXIT_FAILURE); \
			} while (0)


int
main(int argc, char *argv[])
{
    char buf[100000];
    struct termios tp;
    ssize_t numRead;
    int sleepTime;

    if (argc < 4) {
	fprintf(stderr, "Usage: %s TIME MIN num-bytes-to-read "
		"[sleep-secs [O_NONBLOCK flag]]\n", argv[0]);
	exit(EXIT_FAILURE);
    }

    if (tcgetattr(STDIN_FILENO, &tp) == -1)
	errExit("tcgetattr");

    tp.c_lflag &= ~ICANON;
    tp.c_cc[VTIME] = atoi(argv[1]);
    tp.c_cc[VMIN] = atoi(argv[2]);

    if (tcsetattr(STDIN_FILENO, TCSANOW, &tp) == -1)
        errExit("tcsetattr");

    if (argc > 5) {
	int flags;

	flags = fcntl(STDIN_FILENO, F_GETFL);
	if (flags == -1)
	    errExit("fcntl");
	flags |= O_NONBLOCK;
	if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1)
	    errExit("fcntl");
    }

    sleepTime = (argc > 4) ? atoi(argv[4]) : 5;
    printf("About to sleep for %d seconds\n", sleepTime);
    sleep(sleepTime);
    printf("Done sleeping\n");

    printf("About to read %d bytes\n", atoi(argv[3]));
    numRead = read(STDIN_FILENO, buf, atoi(argv[3]));
    if (numRead == -1)
	errExit("read");
    printf("read returned %ld\n", (long) numRead);

    exit(EXIT_SUCCESS);
} /* main */

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-21 13:15     ` Michael Kerrisk (man-pages)
@ 2014-03-21 14:03       ` Peter Hurley
  2014-03-21 14:17         ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Hurley @ 2014-03-21 14:03 UTC (permalink / raw)
  To: Michael Kerrisk (man-pages)
  Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

On 03/21/2014 09:15 AM, Michael Kerrisk (man-pages) wrote:
> On 03/21/2014 12:21 PM, Peter Hurley wrote:
>> On 03/21/2014 06:45 AM, Michael Kerrisk (man-pages) wrote:

>>>> Finally, if the 'count' parameter is less than MIN, read() may return before
>>>> MIN bytes have been received, if 'count' bytes have been received.
>>>
>>> Yes. But it's not clear to me here: do you mean that something in the
>>> man page (or in TLPI) needs fixing?
>>
>> Well, what I mean here is that read() may also _not_ return until MIN bytes have
>> been received, even if 'count' bytes have been received.
>
> Ahh -- I see what you mean. And, it looks like there is a point here where Linux
> differs from POSIX and (at least) Solaris. See the current man-page text below,
> in particular the MIN>0, TIME>0 case. I've also attached a simple test program
> that I used, below.
>
>         In noncanonical mode input is available immediately (without  the
>         user  having  to  type a line-delimiter character), no input pro‐
>         cessing is performed, and line editing is disabled.  The settings
>         of  MIN (c_cc[VMIN]) and TIME (c_cc[VTIME]) determine the circum‐
>         stances in which a read(2) completes;  there  are  four  distinct
>         cases:
>
>         MIN == 0; TIME == 0:
>                If  data  is  available, read(2) returns immediately, with
>                the lesser of the number of bytes available, or the number
>                of  bytes  requested.   If  no  data is available, read(2)
>                returns 0.
>
>         MIN > 0; TIME == 0:
>                read(2) blocks until MIN bytes are available, and  returns
>                up to the number of bytes requested.
>
>         MIN == 0; TIME > 0:
>                TIME  specifies  the limit for a timer in tenths of a sec‐
>                ond.   The  timer  is  started  when  read(2)  is  called.
>                read(2)  returns  either when at least one byte of data is
>                available, or  when  the  timer  expires.   If  the  timer
>                expires  without  any  input  becoming  available, read(2)
>                returns 0.  If data is already available at  the  time  of
>                the call to read() the call behaves as though the data was
>                received immediately after the call.
>
>         MIN > 0; TIME > 0:
>                TIME specifies the limit for a timer in tenths of  a  sec‐
>                ond.  Once an initial byte of input becomes available, the
>                timer is restarted after each further  byte  is  received.
>                read(2)  returns  when  any of the following conditions is
>                met:
>
>                *  MIN bytes have been received.
>
>                *  The interbyte timer expires.
>
>                *  The number of  bytes  requested  by  read(2)  has  been
>                   received.   (POSIX  does  not  specify this termination
>                   condition, and on  some  other  implementations  read()
>                   does not return in this case.)
>
>                Because  the  timer is started only after the initial byte
>                becomes available, at least one byte  will  be  read.   If
>                data  is  already  available  at  the  time of the call to
>                read() the call behaves as though the  data  was  received
>                immediately after the call.
>
>         POSIX does not specify whether the setting of the O_NONBLOCK file
>         status flag takes precedence over the MIN and TIME settings.   If
>         O_NONBLOCK is set, a read() in noncanonical mode may return imme‐
>         diately, regardless of the setting of MIN or TIME.   Furthermore,
>         if  no  data is available, POSIX permits a read() in noncanonical
>         mode to return either 0, or -1 with errno set to EAGAIN.

All looks good.

Thanks again,
Peter Hurley

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-21 14:03       ` Peter Hurley
@ 2014-03-21 14:17         ` Michael Kerrisk (man-pages)
  2014-03-21 14:51           ` Peter Hurley
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Kerrisk (man-pages) @ 2014-03-21 14:17 UTC (permalink / raw)
  To: Peter Hurley; +Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

On Fri, Mar 21, 2014 at 3:03 PM, Peter Hurley <peter@hurleysoftware.com> wrote:
> On 03/21/2014 09:15 AM, Michael Kerrisk (man-pages) wrote:
>>
>> On 03/21/2014 12:21 PM, Peter Hurley wrote:
>>>
>>> On 03/21/2014 06:45 AM, Michael Kerrisk (man-pages) wrote:
>
>
>>>>> Finally, if the 'count' parameter is less than MIN, read() may return
>>>>> before
>>>>> MIN bytes have been received, if 'count' bytes have been received.
>>>>
>>>>
>>>> Yes. But it's not clear to me here: do you mean that something in the
>>>> man page (or in TLPI) needs fixing?
>>>
>>>
>>> Well, what I mean here is that read() may also _not_ return until MIN
>>> bytes have
>>> been received, even if 'count' bytes have been received.
>>
>>
>> Ahh -- I see what you mean. And, it looks like there is a point here where
>> Linux
>> differs from POSIX and (at least) Solaris. See the current man-page text
>> below,
>> in particular the MIN>0, TIME>0 case. I've also attached a simple test
>> program
>> that I used, below.
>>
>>         In noncanonical mode input is available immediately (without  the
>>         user  having  to  type a line-delimiter character), no input pro‐
>>         cessing is performed, and line editing is disabled.  The settings
>>         of  MIN (c_cc[VMIN]) and TIME (c_cc[VTIME]) determine the circum‐
>>         stances in which a read(2) completes;  there  are  four  distinct
>>         cases:
>>
>>         MIN == 0; TIME == 0:
>>                If  data  is  available, read(2) returns immediately, with
>>                the lesser of the number of bytes available, or the number
>>                of  bytes  requested.   If  no  data is available, read(2)
>>                returns 0.
>>
>>         MIN > 0; TIME == 0:
>>                read(2) blocks until MIN bytes are available, and  returns
>>                up to the number of bytes requested.
>>
>>         MIN == 0; TIME > 0:
>>                TIME  specifies  the limit for a timer in tenths of a sec‐
>>                ond.   The  timer  is  started  when  read(2)  is  called.
>>                read(2)  returns  either when at least one byte of data is
>>                available, or  when  the  timer  expires.   If  the  timer
>>                expires  without  any  input  becoming  available, read(2)
>>                returns 0.  If data is already available at  the  time  of
>>                the call to read() the call behaves as though the data was
>>                received immediately after the call.
>>
>>         MIN > 0; TIME > 0:
>>                TIME specifies the limit for a timer in tenths of  a  sec‐
>>                ond.  Once an initial byte of input becomes available, the
>>                timer is restarted after each further  byte  is  received.
>>                read(2)  returns  when  any of the following conditions is
>>                met:
>>
>>                *  MIN bytes have been received.
>>
>>                *  The interbyte timer expires.
>>
>>                *  The number of  bytes  requested  by  read(2)  has  been
>>                   received.   (POSIX  does  not  specify this termination
>>                   condition, and on  some  other  implementations  read()
>>                   does not return in this case.)
>>
>>                Because  the  timer is started only after the initial byte
>>                becomes available, at least one byte  will  be  read.   If
>>                data  is  already  available  at  the  time of the call to
>>                read() the call behaves as though the  data  was  received
>>                immediately after the call.
>>
>>         POSIX does not specify whether the setting of the O_NONBLOCK file
>>         status flag takes precedence over the MIN and TIME settings.   If
>>         O_NONBLOCK is set, a read() in noncanonical mode may return imme‐
>>         diately, regardless of the setting of MIN or TIME.   Furthermore,
>>         if  no  data is available, POSIX permits a read() in noncanonical
>>         mode to return either 0, or -1 with errno set to EAGAIN.
>
>
> All looks good.

Peter, do you agree that Linux appears to differ from POSIX here? (Not
sure if you tried my test program to verify...)

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-21 14:17         ` Michael Kerrisk (man-pages)
@ 2014-03-21 14:51           ` Peter Hurley
  2014-03-21 15:41             ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Hurley @ 2014-03-21 14:51 UTC (permalink / raw)
  To: mtk.manpages; +Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

On 03/21/2014 10:17 AM, Michael Kerrisk (man-pages) wrote:
> On Fri, Mar 21, 2014 at 3:03 PM, Peter Hurley <peter@hurleysoftware.com> wrote:
>> On 03/21/2014 09:15 AM, Michael Kerrisk (man-pages) wrote:
>>>
>>> On 03/21/2014 12:21 PM, Peter Hurley wrote:
>>>>
>>>> On 03/21/2014 06:45 AM, Michael Kerrisk (man-pages) wrote:
>>
>>
>>>>>> Finally, if the 'count' parameter is less than MIN, read() may return
>>>>>> before
>>>>>> MIN bytes have been received, if 'count' bytes have been received.
>>>>>
>>>>>
>>>>> Yes. But it's not clear to me here: do you mean that something in the
>>>>> man page (or in TLPI) needs fixing?
>>>>
>>>>
>>>> Well, what I mean here is that read() may also _not_ return until MIN
>>>> bytes have
>>>> been received, even if 'count' bytes have been received.
>>>
>>>
>>> Ahh -- I see what you mean. And, it looks like there is a point here where
>>> Linux
>>> differs from POSIX and (at least) Solaris. See the current man-page text
>>> below,
>>> in particular the MIN>0, TIME>0 case. I've also attached a simple test
>>> program
>>> that I used, below.
>>>
>>>          In noncanonical mode input is available immediately (without  the
>>>          user  having  to  type a line-delimiter character), no input pro‐
>>>          cessing is performed, and line editing is disabled.  The settings
>>>          of  MIN (c_cc[VMIN]) and TIME (c_cc[VTIME]) determine the circum‐
>>>          stances in which a read(2) completes;  there  are  four  distinct
>>>          cases:
>>>
>>>          MIN == 0; TIME == 0:
>>>                 If  data  is  available, read(2) returns immediately, with
>>>                 the lesser of the number of bytes available, or the number
>>>                 of  bytes  requested.   If  no  data is available, read(2)
>>>                 returns 0.
>>>
>>>          MIN > 0; TIME == 0:
>>>                 read(2) blocks until MIN bytes are available, and  returns
>>>                 up to the number of bytes requested.
>>>
>>>          MIN == 0; TIME > 0:
>>>                 TIME  specifies  the limit for a timer in tenths of a sec‐
>>>                 ond.   The  timer  is  started  when  read(2)  is  called.
>>>                 read(2)  returns  either when at least one byte of data is
>>>                 available, or  when  the  timer  expires.   If  the  timer
>>>                 expires  without  any  input  becoming  available, read(2)
>>>                 returns 0.  If data is already available at  the  time  of
>>>                 the call to read() the call behaves as though the data was
>>>                 received immediately after the call.
>>>
>>>          MIN > 0; TIME > 0:
>>>                 TIME specifies the limit for a timer in tenths of  a  sec‐
>>>                 ond.  Once an initial byte of input becomes available, the
>>>                 timer is restarted after each further  byte  is  received.
>>>                 read(2)  returns  when  any of the following conditions is
>>>                 met:
>>>
>>>                 *  MIN bytes have been received.
>>>
>>>                 *  The interbyte timer expires.
>>>
>>>                 *  The number of  bytes  requested  by  read(2)  has  been
>>>                    received.   (POSIX  does  not  specify this termination
>>>                    condition, and on  some  other  implementations  read()
>>>                    does not return in this case.)
>>>
>>>                 Because  the  timer is started only after the initial byte
>>>                 becomes available, at least one byte  will  be  read.   If
>>>                 data  is  already  available  at  the  time of the call to
>>>                 read() the call behaves as though the  data  was  received
>>>                 immediately after the call.
>>>
>>>          POSIX does not specify whether the setting of the O_NONBLOCK file
>>>          status flag takes precedence over the MIN and TIME settings.   If
>>>          O_NONBLOCK is set, a read() in noncanonical mode may return imme‐
>>>          diately, regardless of the setting of MIN or TIME.   Furthermore,
>>>          if  no  data is available, POSIX permits a read() in noncanonical
>>>          mode to return either 0, or -1 with errno set to EAGAIN.
>>
>>
>> All looks good.
>
> Peter, do you agree that Linux appears to differ from POSIX here? (Not
> sure if you tried my test program to verify...)

I did run the test program to validate that it's observed behavior is that
implemented by Linux, with which I'm very familiar.
I don't have a test setup for other *nixes.

I would be interested to know the results of

   ./noncanonical 0 5 3 0
   hello

and

   ./noncanonical 0 5 3 2
    hel

on other platforms.

With respect to POSIX compliance, it's hard to say. I'm not sure the
spec contemplates the degenerate case where max bytes < MIN. And specifically
with regard to terminal i/o behavior, POSIX is essentially ex post facto,
and is really documenting existing behavior.

Other than the degenerate case of max bytes < MIN, is there any other
variation between Solaris and Linux in non-canonical mode?

Regards,
Peter Hurley

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-21 14:51           ` Peter Hurley
@ 2014-03-21 15:41             ` Michael Kerrisk (man-pages)
  2014-03-21 16:11               ` Peter Hurley
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Kerrisk (man-pages) @ 2014-03-21 15:41 UTC (permalink / raw)
  To: Peter Hurley; +Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

>> Peter, do you agree that Linux appears to differ from POSIX here? (Not
>> sure if you tried my test program to verify...)
>
>
> I did run the test program to validate that it's observed behavior is that
> implemented by Linux, with which I'm very familiar.
> I don't have a test setup for other *nixes.
>
> I would be interested to know the results of
>
>   ./noncanonical 0 5 3 0
>   hello

Solaris 10:
read() completes when 5 bytes received.
OpenBSD 5.4
read() completes when 5 bytes received.

> and
>
>   ./noncanonical 0 5 3 2
>    hel

Solaris
read blocks()
OpenBSD
read blocks


Plus my test case where Linux differs:

./noncanonical 100 5 3 0

Linux: read() returns after 3 bytes input

Solaris: read() returns only after 5 bytes input
OpenBSD: read() returns only after 5 bytes input


> on other platforms.
>
> With respect to POSIX compliance, it's hard to say. I'm not sure the
> spec contemplates the degenerate case where max bytes < MIN. And

Well, given the way the other implementations behave, I think it does
contemplate it, because it carefull avoids talking about the number of
bytes requested by read() in that case.

> specifically
> with regard to terminal i/o behavior, POSIX is essentially ex post facto,
> and is really documenting existing behavior.
>
> Other than the degenerate case of max bytes < MIN, is there any other
> variation between Solaris and Linux in non-canonical mode?

The only one I've seen is the one I noted. I haven't tested too
exhaustively though.

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-21 15:41             ` Michael Kerrisk (man-pages)
@ 2014-03-21 16:11               ` Peter Hurley
  2014-03-21 18:45                 ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Hurley @ 2014-03-21 16:11 UTC (permalink / raw)
  To: mtk.manpages; +Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

On 03/21/2014 11:41 AM, Michael Kerrisk (man-pages) wrote:
>>> Peter, do you agree that Linux appears to differ from POSIX here? (Not
>>> sure if you tried my test program to verify...)
>>
>>
>> I did run the test program to validate that it's observed behavior is that
>> implemented by Linux, with which I'm very familiar.
>> I don't have a test setup for other *nixes.
>>
>> I would be interested to know the results of
>>
>>    ./noncanonical 0 5 3 0
>>    hello
>
> Solaris 10:
> read() completes when 5 bytes received.
> OpenBSD 5.4
> read() completes when 5 bytes received.

Ok, Linux does the same.

>> and
>>
>>    ./noncanonical 0 5 3 2
>>     hel
>
> Solaris
> read blocks()
> OpenBSD
> read blocks

If you type fast, Linux will complete this read() with 3 bytes.

> Plus my test case where Linux differs:
>
> ./noncanonical 100 5 3 0
>
> Linux: read() returns after 3 bytes input
>
> Solaris: read() returns only after 5 bytes input
> OpenBSD: read() returns only after 5 bytes input

Ok, thanks for testing.

>> on other platforms.
>>
>> With respect to POSIX compliance, it's hard to say. I'm not sure the
>> spec contemplates the degenerate case where max bytes < MIN. And
>
> Well, given the way the other implementations behave, I think it does
> contemplate it, because it carefull avoids talking about the number of
> bytes requested by read() in that case.

I agree that's certainly a valid interpretation.
I'll go back and see if this is a regression but I doubt it.

>> specifically
>> with regard to terminal i/o behavior, POSIX is essentially ex post facto,
>> and is really documenting existing behavior.
>>
>> Other than the degenerate case of max bytes < MIN, is there any other
>> variation between Solaris and Linux in non-canonical mode?
>
> The only one I've seen is the one I noted. I haven't tested too
> exhaustively though.

Thanks again. Please feel free to direct mail my way if you find other
variation.

Regards,
Peter Hurley


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: man termios
  2014-03-21 16:11               ` Peter Hurley
@ 2014-03-21 18:45                 ` Michael Kerrisk (man-pages)
  0 siblings, 0 replies; 10+ messages in thread
From: Michael Kerrisk (man-pages) @ 2014-03-21 18:45 UTC (permalink / raw)
  To: Peter Hurley; +Cc: linux kernel, linux-serial, One Thousand Gnomes, Ivan

Just double checked things....

On Fri, Mar 21, 2014 at 5:11 PM, Peter Hurley <peter@hurleysoftware.com> wrote:

[...]

>>> and
>>>
>>>    ./noncanonical 0 5 3 2
>>>     hel
>>
>>
>> Solaris
>> read blocks()
>> OpenBSD
>> read blocks
>
>
> If you type fast, Linux will complete this read() with 3 bytes.

Sorry -- I got this one wrong. I was not typing fast enough, Solaris
and OpenBSD are the same as Linux.

[...]

>>> on other platforms.
>>>
>>> With respect to POSIX compliance, it's hard to say. I'm not sure the
>>> spec contemplates the degenerate case where max bytes < MIN. And
>>
>>
>> Well, given the way the other implementations behave, I think it does
>> contemplate it, because it carefull avoids talking about the number of
>> bytes requested by read() in that case.
>
>
> I agree that's certainly a valid interpretation.
> I'll go back and see if this is a regression but I doubt it.

I doubt it too. I suspect it's been like that forever, but it's a
corner case that no-one cares about.

>>> specifically
>>> with regard to terminal i/o behavior, POSIX is essentially ex post facto,
>>> and is really documenting existing behavior.
>>>
>>> Other than the degenerate case of max bytes < MIN, is there any other
>>> variation between Solaris and Linux in non-canonical mode?
>>
>>
>> The only one I've seen is the one I noted. I haven't tested too
>> exhaustively though.
>
>
> Thanks again. Please feel free to direct mail my way if you find other
> variation.

Okay.

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-03-21 18:45 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-20 18:42 man termios Peter Hurley
2014-03-21 10:45 ` Michael Kerrisk (man-pages)
2014-03-21 11:21   ` Peter Hurley
2014-03-21 13:15     ` Michael Kerrisk (man-pages)
2014-03-21 14:03       ` Peter Hurley
2014-03-21 14:17         ` Michael Kerrisk (man-pages)
2014-03-21 14:51           ` Peter Hurley
2014-03-21 15:41             ` Michael Kerrisk (man-pages)
2014-03-21 16:11               ` Peter Hurley
2014-03-21 18:45                 ` Michael Kerrisk (man-pages)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).