diff mbox

[libgfortran] PR46800 Handle CTRL-D correctly with STDIN

Message ID 53262AC8.5080302@charter.net
State New
Headers show

Commit Message

Jerry DeLisle March 16, 2014, 10:50 p.m. UTC
Hi all.

The problem here was that when reading a value from STDIN and the user just
entered an empty entry (LF),
we would end up getting nested into a second read (via next_char) and the user
would have to press CTRL-D twice to get out of the read. (The correct behavior
is to only hit CTRL-D once which sends us the EOF.

This was caused by a call to eat_separator right after we did the initial read.
 The eat_separator function then tries to read again and we get a condition of
waiting for user input on that read.  The patch eliminates this call to
eat_separator. This requires explicitly checking for the comma and end-of-line
conditions which are also done in eat_separator.

Regression tested on x86-64-gnu.  No test case can be done since it require
terminal input to read.

OK for trunk?

Regards,

Jerry

2014-03-16  Jerry DeLisle  <jvdelisle@gcc.gnu>

	PR libfortran/58324
	* io/list_read.c (list_formatted_read_scalar): Do not use
	eat_separator. Explicitly set the comma and end-of-line flags.
	Check for END condition from finish_separator.

Comments

Janne Blomqvist March 17, 2014, 1:40 p.m. UTC | #1
On Mon, Mar 17, 2014 at 12:50 AM, Jerry DeLisle <jvdelisle@charter.net> wrote:
> Hi all.
>
> The problem here was that when reading a value from STDIN and the user just
> entered an empty entry (LF),
> we would end up getting nested into a second read (via next_char) and the user
> would have to press CTRL-D twice to get out of the read. (The correct behavior
> is to only hit CTRL-D once which sends us the EOF.
>
> This was caused by a call to eat_separator right after we did the initial read.
>  The eat_separator function then tries to read again and we get a condition of
> waiting for user input on that read.  The patch eliminates this call to
> eat_separator. This requires explicitly checking for the comma and end-of-line
> conditions which are also done in eat_separator.
>
> Regression tested on x86-64-gnu.  No test case can be done since it require
> terminal input to read.
>
> OK for trunk?

Ok, thanks for the patch.

I wonder, would it be possible to set up some dejagnu testcases with
multiple programs communicating via pipes or such, we occasionally
seem to have regressions dealing with non-seekable files/terminals and
such which go undetected for a long time, since we're not regularly
testing it?
diff mbox

Patch

Index: list_read.c
===================================================================
--- list_read.c	(revision 208591)
+++ list_read.c	(working copy)
@@ -1923,17 +1923,31 @@  list_formatted_read_scalar (st_parameter_dt *dtp,
 	}
       if (is_separator (c))
 	{
-	  /* Found a null value.  */
-	  eat_separator (dtp);
+	  /* Found a null value. Do not use eat_separator here otherwise
+	     we will do an extra read from stdin.  */
 	  dtp->u.p.repeat_count = 0;
 
-	  /* eat_separator sets this flag if the separator was a comma.  */
-	  if (dtp->u.p.comma_flag)
-	    goto cleanup;
+	  /* Set comma_flag.  */
+	  if ((c == ';' 
+	      && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
+	      ||
+	      (c == ','
+	      && dtp->u.p.current_unit->decimal_status == DECIMAL_POINT))
+	    {
+	      dtp->u.p.comma_flag = 1;
+	      goto cleanup;
+	    }
 
-	  /* eat_separator sets this flag if the separator was a \n or \r.  */
-	  if (dtp->u.p.at_eol)
-	    finish_separator (dtp);
+	  /* Set end-of-line flag.  */
+	  if (c == '\n' || c == '\r')
+	    {
+	      dtp->u.p.at_eol = 1;
+	      if (finish_separator (dtp) == LIBERROR_END)
+		{
+		  err = LIBERROR_END;
+		  goto cleanup;
+		}
+	    }
 	  else
 	    goto cleanup;
 	}