diff options
author | Bill Kendall <wkendall@sgi.com> | 2011-11-10 12:55:42 -0600 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2011-11-20 19:41:03 +0000 |
commit | 66ad1ba48320c7b12b6f5d1728f2f1cca64863bf (patch) | |
tree | 69703ec7f5e64225cb4d8c74a35d133cfb45566e | |
parent | 7ffdf9d1fbd65eb38171b8772ed4c31315cbbef6 (diff) | |
download | xfsdump-dev-66ad1ba48320c7b12b6f5d1728f2f1cca64863bf.tar.gz |
xfsdump: handle Ctrl-D during prompts
xfsdump does not currently handle Ctrl-D well during a dialog
prompt. If some text is entered followed by Ctrl-D, an assert
will trip because xfsdump expects a new-line character at the
end of the user's input (or if asserts are disabled, the last
character the user entered will be dropped).
If Ctrl-D is entered without entering any response, some dialog
callers (e.g., tree_subtree_inter()) will abort because they
receive an unexpected response code.
This patch changes xfsdump to behave like other interactive
commands (xfs_db, bash, parted, ...) with respect to Ctrl-D.
If Ctrl-D precedes any input, an empty string is returned.
If Ctrl-D follows some input, it is ignored and xfsdump will
continue to wait for more input.
Signed-off-by: Bill Kendall <wkendall@sgi.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | common/dlog.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/common/dlog.c b/common/dlog.c index 51666cf0..ac0cafc7 100644 --- a/common/dlog.c +++ b/common/dlog.c @@ -382,6 +382,7 @@ promptinput( char *buf, time32_t now = time( NULL ); intgen_t nread = -1; sigset_t orig_set; + char *bufp = buf; /* display the pre-prompt */ @@ -447,8 +448,27 @@ promptinput( char *buf, rc = select( dlog_ttyfd + 1, &rfds, NULL, NULL, &tv ); if ( rc > 0 && FD_ISSET( dlog_ttyfd, &rfds ) ) { - nread = read( dlog_ttyfd, buf, bufsz - 1 ); - break; + nread = read( dlog_ttyfd, bufp, bufsz ); + if ( nread < 0 ) { + break; // error handled below + } else if ( nread == 0 && buf == bufp ) { + mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE, "\n" ); + *bufp = 0; + break; // no input, return an empty string + } else if ( nread > 0 && bufp[nread-1] == '\n' ) { + // received a full line, chomp the newline + bufp[nread-1] = 0; + break; + } else if ( nread == bufsz ) { + // no more room, truncate and return + bufp[nread-1] = 0; + break; + } + + // keep waiting for a full line of input + bufp += nread; + bufsz -= nread; + nread = -1; } now = time( NULL ); } @@ -489,17 +509,8 @@ promptinput( char *buf, *exceptionixp = sigquitix; } return BOOL_FALSE; - } else if ( nread == 0 ) { - *exceptionixp = timeoutix; - if ( bufsz > 0 ) { - buf[ 0 ] = 0; - } - return BOOL_FALSE; } else { ASSERT( dlog_signo_received == -1 ); - ASSERT( ( size_t )nread < bufsz ); - ASSERT( buf[ nread - 1 ] == '\n' ); - buf[ nread - 1 ] = 0; *exceptionixp = 0; return BOOL_TRUE; } |