Mail Archives: cygwin/2005/05/01/19:56:24
--0-264193783-1114991773=:69871
Content-Type: text/plain; charset=us-ascii
Content-Id:
Content-Disposition: inline
Hi all,
I tried to forward this message to the main cygwin
list yesterday, but had a little trouble getting it
there, probably because I mentioned "xterm" in the
subject. I'm trying again in case this is NOT an "X"
problem but a base cygwin problem.
I have attached the test program xtermbug.c instead
of pasting it inline. I hope that is OK for this
list.
If there is anything I can do to help debug the reason
I am seeing this problem, please just tell me what to
do.
BTW, thanks to all the developers for an awesome
product.
Regards,
Peter Farley
--- Peter Farley <pjfarley3 AT yahoo DOT com> wrote:
> Hi all,
>
> The following program demonstrates what looks to me
> like a bug in the "read" function in an xterm (as
> opposed to a Cygwin console window). To run the
> test, compile with:
>
> gcc -g -o xtermbug.exe xtermbug.c
>
> When you run it in a console window, you can enter
> normal keyboard characters, then a return to see
> "cmdline=<what you typed>". Press the Esc key to
> exit the program.
>
> When run in an xterm window, the first keypress
> causes this behavior:
>
> 1. Select returns with rc = 0 and readset set to
> indicate that a key was received
> 2. "read" returns with kblen = 1 and kbbuf[0] = '\0'
> 3. (1) and (2) repeat forever.
>
> I put in a "maxdbg" parameter and terminate the
> program after 5 occurrences of this loop.
>
> This problem was first detected trying to run a copy
> of the hercules IBM mainframe emulator in a Cygwin
> xterm window. The code below is extracted and
> minimalized as much as possible from the hercules
> keyboard input routine.
>
> Peter Farley
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
--0-264193783-1114991773=:69871
Content-Type: text/plain; name="xtermbug.c"
Content-Description: 414424534-xtermbug.c
Content-Disposition: inline; filename="xtermbug.c"
/*-------------------------------------------------------------------*/
/* This is a test program to show a cygwin xterm bug, possibly */
/* in the read function. */
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* Definitions for keyboard input sequences */
/*-------------------------------------------------------------------*/
#define KBD_DELETE "\x1B[3~"
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
#define MSG_SIZE 80 /* Size of one message */
#define CMD_SIZE 32767 /* Length of command line */
#define BYTE unsigned char
int ttyreset = 0;
struct termios kbattr; /* Terminal I/O structure */
/*-------------------------------------------------------------------*/
/* xterm display subroutine */
/*-------------------------------------------------------------------*/
void xterm_display (void)
{
int rc; /* Return code */
int i; /* Array subscripts */
char cmdline[CMD_SIZE+1]; /* Command line buffer */
int cmdoff = 0; /* Cursor position in cmdline*/
int cmdlen = 0; /* Number of bytes in cmdline*/
//BYTE c; /* Character work area */
FILE *confp; /* Console file pointer */
size_t kbbufsize = CMD_SIZE; /* Size of keyboard buffer */
char *kbbuf = NULL; /* Keyboard input buffer */
int kblen; /* Number of chars in kbbuf */
int keybfd; /* Keyboard file descriptor */
int maxfd; /* Highest file descriptor */
fd_set readset; /* Select file descriptors */
struct timeval tv; /* Select timeout structure */
int maxdbg = 0;
/* Set up the input file descriptors */
confp = stdout;
keybfd = STDIN_FILENO;
fprintf(confp, "start kbbuf=%8.8X,&kbbuf=%8.8X\n",
kbbuf, &kbbuf);
/* Obtain storage for the keyboard buffer */
if (!(kbbuf = (char *)malloc (kbbufsize)))
{
fprintf(stderr, "HHCPN002S Cannot obtain keyboard buffer: %s\n",
strerror(errno));
return;
}
fprintf(confp, "start kbbuf=%8.8X,&kbbuf=%8.8X,*kbbuf=%8.8X\n",
kbbuf, &kbbuf, *kbbuf);
/* Set screen output stream to fully buffered */
setvbuf (confp, NULL, _IOFBF, 0);
/* Put the terminal into cbreak mode */
tcgetattr (keybfd, &kbattr);
kbattr.c_lflag &= ~(ECHO | ICANON);
kbattr.c_cc[VMIN] = 0;
kbattr.c_cc[VTIME] = 0;
tcsetattr (keybfd, TCSANOW, &kbattr);
ttyreset = 1;
fprintf(confp, "Starting while(1) loop.\n");
fflush(confp);
/* Process messages and commands */
while (1)
{
/* Set the file descriptors for select */
FD_ZERO (&readset);
FD_SET (keybfd, &readset);
maxfd = keybfd;
/* Wait for a key to be pressed,
or the inactivity interval to expire */
tv.tv_sec = 1;
tv.tv_usec = 1 % 1000000;
rc = select (maxfd + 1, &readset, NULL, NULL, &tv);
if (rc < 0 )
{
if (errno == EINTR) continue;
fprintf (stderr,
"HHCPN004E select: %s\n",
strerror(errno));
break;
}
fprintf(confp, "rc=%d,readset={%8.8X,%8.8X}\n", rc,
readset.fds_bits[0], readset.fds_bits[1]);
fflush(confp);
/* If keyboard input has arrived then process it */
if (FD_ISSET(keybfd, &readset))
{
/* Read character(s) from the keyboard */
kblen = read (keybfd, kbbuf, kbbufsize-1);
fprintf(confp, "kblen=%d\n", kblen);
if (kblen < 0)
{
fprintf (stderr,
"HHCPN005E keyboard read: %s\n",
strerror(errno));
break;
}
kbbuf[kblen] = '\0';
fprintf(confp, "kbbuf[0-%d]=", kblen);
for (i = 0; i <= kblen; i++)
{
fprintf(confp, "%2.2X", kbbuf[i]);
if (i < kblen) fprintf(confp, ",");
}
fprintf(confp, "\n");
/* Process characters in the keyboard buffer */
for (i = 0; i < kblen; )
{
/* Process backspace character */
if (kbbuf[i] == '\b' || kbbuf[i] == '\x7F')
{
if (cmdoff > 0) {
int j;
for (j = cmdoff-1; j<cmdlen; j++)
cmdline[j] = cmdline[j+1];
cmdoff--;
cmdlen--;
}
i++;
break;
}
/* Process DEL character */
if (strcmp(kbbuf+i, KBD_DELETE) == 0) {
if (cmdoff < cmdlen) {
int j;
for (j = cmdoff; j<cmdlen; j++)
cmdline[j] = cmdline[j+1];
cmdlen--;
}
i++;
break;
}
/* Process escape key */
if (kbbuf[i] == '\x1B')
{
cmdline[0] = '\0';
cmdoff = 0;
cmdlen = 0;
/* Restore the terminal mode */
tcgetattr (STDIN_FILENO, &kbattr);
kbattr.c_lflag |= (ECHO | ICANON);
tcsetattr (STDIN_FILENO, TCSANOW, &kbattr);
ttyreset = 0;
fprintf(confp, "\n\nTerminating xtermbug test!\n");
fflush(confp);
return;
}
/* Process the command if newline was read */
if (kbbuf[i] == '\n')
{
fprintf (confp, "\ncmdline=%s\n", cmdline);
break;
}
/* Ignore non-printable characters */
if (!isprint(kbbuf[i]))
{
fprintf(stderr, "Unprintable:%8.8X\n",
*(kbbuf+i));
i++;
if (++maxdbg > 5) { return; }
break;
}
/* Append the character to the command buffer */
if (cmdoff < CMD_SIZE-1) {
if (cmdoff < cmdlen) {
int j;
for (j=cmdlen-1; j>=cmdoff; j--)
cmdline[j+1] = cmdline[j];
cmdline[cmdoff++] = kbbuf[i];
}
else
cmdline[cmdoff++] = kbbuf[i];
cmdlen++;
}
i++;
} /* end for(i) */
}
} /* end while */
return;
} /* end function xterm_display */
int main(int argc, char *argv[]) {
xterm_display();
if (ttyreset)
{
/* Restore the terminal mode */
tcgetattr (STDIN_FILENO, &kbattr);
kbattr.c_lflag |= (ECHO | ICANON);
tcsetattr (STDIN_FILENO, TCSANOW, &kbattr);
}
return(0);
}
--0-264193783-1114991773=:69871
Content-Type: text/plain; charset=us-ascii
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
--0-264193783-1114991773=:69871--
- Raw text -