kbhit() with nowait option misses characters.
Joe Rothweiler
octaveuser at sensicomm.com
Tue Jun 30 15:31:50 CDT 2009
Bug report for Octave 3.2.0 configured for i686-pc-linux-gnu
Description:
-----------
I'm trying to use the kbhit builtin function under Linux in
nowait mode: c1=kbhit(1); It is
supposed to return a character if a key has been hit,
else return an empty string. In fact, it often
returns an empty string even if a key has been hit.
Here's what I think is happening:
in src/sysdep.cc, if macro HAVE__KBHIT is not defined,
then subroutine octave_kbhit () calls
raw_mode(...) at line 515. In turn, raw_mode
calls tcsetattr (tty_fd, TCSAFLUSH, &s) at line 395.
Per the tcsetattr man page:
"TCSAFLUSH ... all input that has been received but
not read will be discarded"
So, input keystrokes will be lost unless they occur
after the call to tcsetattr but before the read at
line 531.
Repeat-By:
---------
------ Test file keytest.m:
while 1
c1=kbhit(1);
if (~isempty(c1))
fprintf(2,'got %s\n',c1);
break;
end
end
------
Execute using: octave -q -i keytest.m
then hit any keyboard key, say 'q'. Output should be:
qgot q
(where the first q is the input being echoed).
Actual output is
qqqqqgot q
(ie, the key must be struck several times before
it is detected).
Fix:
---
In src/sysdep.cc, subroutine raw_mode, line 395:
TCSAFLUSH should be TCSADRAIN.
(This makes kbhit() work correctly; I don't know
if raw_mode is called anywhere else.)
Configuration (please do not edit this section):
-----------------------------------------------
uname output: Linux caspian 2.6.22-2-k7 #1 SMP Fri Aug 31 01:02:37
UTC 2007 i686 GNU/Linux
configure opts:
Fortran compiler: gfortran
FFLAGS: -O -mieee-fp
FLIBS: -L/usr/lib/gcc/i486-linux-gnu/4.3.3
-L/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib -L/lib/../lib
-L/usr/lib/../lib -L/usr/lib/gcc/i486-linux-gnu/4.3.3/../../..
-L/usr/lib/i486-linux-gnu -lhdf5 -lz -lgfortranbegin -lgfortran -lm
CPPFLAGS:
INCFLAGS: -I. -I. -I./liboctave -I./src -I./libcruft/misc
C compiler: gcc, version 4.3.3 (Debian 4.3.3-10)
CFLAGS: -g -O2
CPICFLAG: -fPIC
C++ compiler: g++, version 4.3.3
CXXFLAGS: -g -O2
CXXPICFLAG: -fPIC
LD_CXX: g++
LDFLAGS:
LIBFLAGS: -L.
RLD_FLAG: -Wl,-rpath -Wl,/usr/local/lib/octave-3.2.0
BLAS_LIBS: -llapack -lblas
FFTW_LIBS: -lfftw3 -lfftw3f
LIBS: -lreadline -lncurses -ldl -lblas -lhdf5 -lz -lm
LEXLIB:
LIBGLOB:
SED: /bin/sed
DEFS:
-DPACKAGE_NAME="" -DPACKAGE_TARNAME="" -DPACKAGE_VERSION=""
-DPACKAGE_STRING="" -DPACKAGE_BUGREPORT="" -DOCTAVE_SOURCE=1
-D_GNU_SOURCE=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1
-DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1
-DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -D__EXTENSIONS__=1
-D_POSIX_PTHREAD_SEMANTICS=1 -D_TANDEM_SOURCE=1 -DSEPCHAR=':'
-DSEPCHAR_STR=":" -D__NO_MATH_INLINES=1 -DCXX_NEW_FRIEND_TEMPLATE_DECL=1
-DCXX_ISO_COMPLIANT_LIBRARY=1 -DHAVE_X_WINDOWS=1 -DHAVE_LIBM=1
-DHAVE_PCRE_COMPILE=1 -DHAVE_PCRE=1 -DHAVE_REGEXEC=1 -DHAVE_REGEX=1
-DHAVE_ZLIB_H=1 -DHAVE_ZLIB=1 -DHAVE_HDF5_H=1 -DHAVE_HDF5=1
-DHAVE_H5GGET_NUM_OBJS=1 -DHAVE_FFTW3=1 -DHAVE_GL_GL_H=1 -DHAVE_GL_GLU_H=1
-DHAVE_OPENGL=1 -DHAVE_FTGL_FTGL_H=1 -DHAVE_FTGL=1 -DHAVE_FLTK=1
-DHAVE_IEEE754_DATA_FORMAT=1 -DF77_FUNC(name,NAME)=name ## _
-DF77_FUNC_(name,NAME)=name ## _ -DHAVE_BLAS=1 -DHAVE_GETHOSTNAME=1
-DHAVE_GETPWNAM=1 -DHAVE_DEV_T=1 -DHAVE_INO_T=1 -DHAVE_NLINK_T=1
-DHAVE_NLINK_T=1 -DHAVE_LONG_LONG_INT=1 -DHAVE_UNSIGNED_LONG_LONG_INT=1
-DHAVE_SIGSET_T=1 -DHAVE_SIG_ATOMIC_T=1 -DSIZEOF_SHORT=2
-DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DHAVE_ALLOCA_H=1
-DHAVE_ALLOCA=1 -DHAVE_PLACEMENT_DELETE=1 -DHAVE_DYNAMIC_AUTO_ARRAYS=1
-DHAVE_FAST_INT_OPS=1 -DSIZEOF_LONG_DOUBLE=12 -DSTDC_HEADERS=1
-DHAVE_DIRENT_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SYS_WAIT_H=1
-DHAVE_ASSERT_H=1 -DHAVE_CURSES_H=1 -DHAVE_DLFCN_H=1 -DHAVE_FCNTL_H=1
-DHAVE_FLOAT_H=1 -DHAVE_GRP_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_LIMITS_H=1
-DHAVE_LOCALE_H=1 -DHAVE_MEMORY_H=1 -DHAVE_NCURSES_H=1 -DHAVE_POLL_H=1
-DHAVE_PTHREAD_H=1 -DHAVE_PWD_H=1 -DHAVE_STDINT_H=1 -DHAVE_STDLIB_H=1
-DHAVE_STRING_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_PARAM_H=1
-DHAVE_SYS_POLL_H=1 -DHAVE_SYS_RESOURCE_H=1 -DHAVE_SYS_SELECT_H=1
-DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1
-DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_UTSNAME_H=1 -DHAVE_TERMCAP_H=1
-DHAVE_UNISTD_H=1 -DHAVE_UTIME_H=1 -DHAVE_SSTREAM=1 -DHAVE_TERMIOS_H=1
-DHAVE_TERMIO_H=1 -DHAVE_SGTTY_H=1 -DHAVE_GLOB_H=1 -DHAVE_FNMATCH_H=1
-DHAVE_FNMATCH=1 -DHAVE_GLOB=1 -DHAVE_ATEXIT=1 -DHAVE_BASENAME=1
-DHAVE_BCOPY=1 -DHAVE_BZERO=1 -DHAVE_CANONICALIZE_FILE_NAME=1
-DHAVE_CHMOD=1 -DHAVE_DUP2=1 -DHAVE_ENDGRENT=1 -DHAVE_ENDPWENT=1
-DHAVE_EXECVP=1 -DHAVE_EXPM1=1 -DHAVE_EXPM1F=1 -DHAVE_FCNTL=1
-DHAVE_FORK=1 -DHAVE_FSTAT=1 -DHAVE_GETCWD=1 -DHAVE_GETEGID=1
-DHAVE_GETEUID=1 -DHAVE_GETGID=1 -DHAVE_GETGRENT=1 -DHAVE_GETGRGID=1
-DHAVE_GETGRNAM=1 -DHAVE_GETPGRP=1 -DHAVE_GETPID=1 -DHAVE_GETPPID=1
-DHAVE_GETPWENT=1 -DHAVE_GETPWUID=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_GETUID=1
-DHAVE_GETWD=1 -DHAVE_KILL=1 -DHAVE_LGAMMA=1 -DHAVE_LGAMMAF=1
-DHAVE_LGAMMA_R=1 -DHAVE_LGAMMAF_R=1 -DHAVE_LINK=1 -DHAVE_LOCALTIME_R=1
-DHAVE_LOG1P=1 -DHAVE_LOG1PF=1 -DHAVE_LSTAT=1 -DHAVE_MEMMOVE=1
-DHAVE_MKDIR=1 -DHAVE_MKFIFO=1 -DHAVE_MKSTEMP=1 -DHAVE_ON_EXIT=1
-DHAVE_PIPE=1 -DHAVE_POLL=1 -DHAVE_PUTENV=1 -DHAVE_RAISE=1
-DHAVE_READLINK=1 -DHAVE_REALPATH=1 -DHAVE_RENAME=1 -DHAVE_RINDEX=1
-DHAVE_RMDIR=1 -DHAVE_ROUNDL=1 -DHAVE_SELECT=1 -DHAVE_SETGRENT=1
-DHAVE_SETLOCALE=1 -DHAVE_SETPWENT=1 -DHAVE_SETVBUF=1 -DHAVE_SIGACTION=1
-DHAVE_SIGLONGJMP=1 -DHAVE_SIGPENDING=1 -DHAVE_SIGPROCMASK=1
-DHAVE_SIGSUSPEND=1 -DHAVE_SNPRINTF=1 -DHAVE_STAT=1 -DHAVE_STRCASECMP=1
-DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRNCASECMP=1 -DHAVE_STRPTIME=1
-DHAVE_STRSIGNAL=1 -DHAVE_SYMLINK=1 -DHAVE_TEMPNAM=1 -DHAVE_TGAMMAF=1
-DHAVE_TRUNC=1 -DHAVE_UMASK=1 -DHAVE_UNAME=1 -DHAVE_UNLINK=1
-DHAVE_USLEEP=1 -DHAVE_UTIME=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1
-DHAVE_VSNPRINTF=1 -DHAVE_WAITPID=1 -DHAVE_DECL_EXP2=1 -DHAVE_DECL_ROUND=1
-DHAVE_DECL_TGAMMA=1 -DHAVE_EXP2=1 -DHAVE_ROUND=1 -DHAVE_TGAMMA=1
-DHAVE_STRFTIME=1 -DHAVE_C99_VSNPRINTF=1 -DHAVE_LIBDL=1 -DHAVE_DLOPEN=1
-DHAVE_DLSYM=1 -DHAVE_DLERROR=1 -DHAVE_DLCLOSE=1 -DHAVE_DLOPEN_API=1
-DENABLE_DYNAMIC_LINKING=1 -DHAVE_TIMEVAL=1 -DHAVE_CMATH_ISNAN=1
-DHAVE_CMATH_ISNANF=1 -DHAVE_CMATH_ISINF=1 -DHAVE_CMATH_ISINFF=1
-DHAVE_CMATH_ISFINITE=1 -DHAVE_CMATH_ISFINITEF=1 -DHAVE_FINITE=1
-DHAVE_ISNAN=1 -DHAVE_ISINF=1 -DHAVE_COPYSIGN=1 -DHAVE_DECL_SIGNBIT=1
-DHAVE_ACOSH=1 -DHAVE_ACOSHF=1 -DHAVE_ASINH=1 -DHAVE_ASINHF=1
-DHAVE_ATANH=1 -DHAVE_ATANHF=1 -DHAVE_ERF=1 -DHAVE_ERFF=1 -DHAVE_ERFC=1
-DHAVE_ERFCF=1 -DHAVE_EXP2F=1 -DHAVE_LOG2=1 -DHAVE_LOG2F=1 -DHAVE_HYPOTF=1
-DHAVE_STRUCT_STAT_ST_BLKSIZE=1 -DHAVE_STRUCT_STAT_ST_BLOCKS=1
-DHAVE_STRUCT_STAT_ST_RDEV=1 -DHAVE_STRUCT_TM_TM_ZONE=1
-DHAVE_TM_ZONE=1 -DUSE_READLINE=1 -DEXCEPTION_IN_MATH=1 -DRETSIGTYPE=void
-DHAVE_DECL_SYS_SIGLIST=1 -DHAVE_POSIX_SIGNALS=1 -DRETSIGTYPE_IS_VOID=1
-DHAVE_GETRUSAGE=1 -DHAVE_TIMES=1 -DYYTEXT_POINTER=1
User-preferences (please do not edit this section):
--------------------------------------------------
EDITOR = emacs
EXEC_PATH =
/usr/local/libexec/octave/3.2.0/site/exec/i686-pc-linux-gnu:/usr/local/libexec/octave/api-v37/site/exec/i686-pc-linux-gnu:/usr/local/libexec/octave/site/exec/i686-pc-linux-gnu:/usr/local/libexec/octave/3.2.0/exec/i686-pc-linux-gnu:/usr/local/bin:.:/home/jrothwei/share/bin:/home/jrothwei/i386/bin:/home/jrothwei/olds:/usr/local/bin:/usr/bin:/bin:/usr/games
IMAGE_PATH = .:/usr/local/share/octave/3.2.0/imagelib
PAGER = less
PS1 = \s:\#>
PS2 = >
PS4 = +
beep_on_error = 0
completion_append_char =
crash_dumps_octave_core = 1
echo_executing_commands = 0
fixed_point_format = 0
gnuplot_binary = gnuplot
# gnuplot_command_end = <no value or error in displaying it>
# gnuplot_command_plot = <no value or error in displaying it>
# gnuplot_command_replot = <no value or error in displaying it>
# gnuplot_command_splot = <no value or error in displaying it>
# gnuplot_command_title = <no value or error in displaying it>
# gnuplot_command_using = <no value or error in displaying it>
# gnuplot_command_with = <no value or error in displaying it>
history_file = /home/jrothwei/.octave_hist
history_size = 1024
ignore_function_time_stamp = system
info_file = /usr/local/share/info/octave.info
info_program = info
makeinfo_program = makeinfo
max_recursion_depth = 256
output_max_field_width = 5
output_precision = 5
page_output_immediately = 0
page_screen_output = 1
# print_answer_id_name = <no value or error in displaying it>
print_empty_dimensions = 1
save_precision = 16
saving_history = 1
sighup_dumps_octave_core = 1
sigterm_dumps_octave_core = 1
silent_functions = 0
split_long_rows = 1
string_fill_char =
struct_levels_to_print = 2
suppress_verbose_help_message = 0
More information about the Bug-octave
mailing list