LINUX.ORG.RU

mrxvt & materm


0

0

Захотелось чего-нибудь лёгкого и мультитабного...
Поставил mrxvt - всё нравится, но имеет место глюк с просмотром
содержимого .bz2 и .gz под mc - подобное действие вешает
этого mrxvt наглухо... Кто-то здесь, вроде, писал, что это дело
исправили, но нигде я конкретной информации по этому поводу не
нашёл. Может кто-нибудь знает, как убрать сей баг?
Следующим решил попробовать materm - тоже обнаружилась досадная мелочь
- в том-же mc не работает прокрутка мышачьим колёсиком. Собирал с
'--enable-mousewheel' и непосредственно в терминале скролл работает...
Мелочь - а не удобно. Можно ли это дело как-то исправить?

--- src/command.c	2005-02-09 22:27:49.000000000 +0100
+++ src/command.c	2005-03-01 13:42:32.000000000 +0100
@@ -1873,8 +1873,13 @@ rxvt_cmd_getc(rxvt_t *r, int* p_page)
 			if (AVTS(r)->cmdbuf_ptr < AVTS(r)->cmdbuf_endp)	{
 				*p_page = ATAB(r);
 				return *(AVTS(r)->cmdbuf_ptr)++;
 			}
+
+			/* output any pending chars of page's v_buffer */
+			if (AVTS(r)->v_bufstr < AVTS(r)->v_bufptr)
+				rxvt_tt_write(r, ATAB(r), NULL, 0);
+
 			/*
 			** if there is no data in active tab, we go to process
 			** the X events before trying to find a tab that has
 			** some input/output. this should improve the response
@@ -1947,8 +1952,9 @@ rxvt_cmd_getc(rxvt_t *r, int* p_page)
 			/* In case button actions pushed chars to cmdbuf. */
 			if (-1 != page)	{
 				assert (PVTS(r, page)->cmdbuf_base <=
 					PVTS(r, page)->cmdbuf_endp);
+
 				if (PVTS(r, page)->cmdbuf_ptr <
 					PVTS(r, page)->cmdbuf_endp)
 					return *(PVTS(r, page)->cmdbuf_ptr)++;
 			}
@@ -2172,9 +2178,9 @@ rxvt_cmd_getc(rxvt_t *r, int* p_page)
 			** read in */
 			if (!FD_ISSET(PVTS(r, i)->cmd_fd, &readfds))
 				continue;
 
-			DBG_MSG(2, (stderr, "reading from shell %d\n", i));
+			DBG_MSG(1, (stderr, "reading from shell %d\n", i));
 
 			/* check our command buffer before reading data */
 			rxvt_check_cmdbuf (r, i);
 
@@ -2182,29 +2188,60 @@ rxvt_cmd_getc(rxvt_t *r, int* p_page)
 			/* The buffer size is the buffer length - used length */
 			count = bufsiz = (BUFSIZ - 1) -
 				(PVTS(r, i)->cmdbuf_endp - PVTS(r, i)->cmdbuf_base);
 
-			for (; count;
-				count -= n, PVTS(r, i)->cmdbuf_endp += n)	{
-				assert (n >= 0);
-				assert (PVTS(r, i)->cmdbuf_base <=
-					PVTS(r, i)->cmdbuf_endp);
+			while (count)	{
+				DBG_MSG(1, (stderr, "read maximal %d bytes\n", count));
+				n = read (PVTS(r, i)->cmd_fd, PVTS(r, i)->cmdbuf_endp,
+						count);
+				DBG_MSG(1, (stderr, "read %d bytes\n", n));
+
+				if (n > 0)	{
+					/* Update count and buffer pointer */
+					count -= n;
+					PVTS(r, i)->cmdbuf_endp += n;
 
-				n = read (PVTS(r, i)->cmd_fd,
-							PVTS(r, i)->cmdbuf_endp, count);
-
-				if (0 == n ||
-					(n < 0 && (errno == EAGAIN || errno == EIO)))
+					/*
+					** check the file descriptor to see if there are
+					** further input, this is to avoid blocking on
+					** read(), which seems to be an issue when running
+					** mc in bash. this will waste several CPU cycles,
+					** but it's safer than blocking.
+					*/
+					FD_ZERO(&readfds);
+					FD_SET(PVTS(r, i)->cmd_fd, &readfds);
+					value.tv_sec = 0;
+					value.tv_usec = 5;	/* time out, 5us */
+					select_res = select(r->num_fds, &readfds, NULL,
+						NULL, &value);
+					if (0 == select_res)	{
+						/* time-out, no further data to read */
+						DBG_MSG(1, (stderr, "no further data\n"));
+						break;
+					}
+					if (-1 == select_res)	{
+						/* error, stop reading */
+						DBG_MSG(1, (stderr, "select error\n"));
+						break;
+					}
+					/* continue the next loop iteration */
+					DBG_MSG(1, (stderr, "more data to read\n"));
+				}
+				else if (0 == n)	{
+					DBG_MSG(1, (stderr, "Should not happen?\n"));
 					break;
-				/*
-				** We must handle the following case!!! Otherwise the
-				** cmdbuf_endp will be move backward if something
-				** unexpected happens, e.g., the child process quits
-				** too fast. And this cause crash!!!
-				*/
-				if (n < 0)
-					n = 0;
-			}	/* for */
+				}
+				else if (n < 0)	{
+					if (errno == EAGAIN || errno == EIO)
+						break;
+					/*
+					** We do not update count and buffer pointer and
+					** continue trying read more data in the next
+					** loop iteration.
+					*/
+					DBG_MSG(1, (stderr, "%s\n", strerror(errno)));
+				}
+			}	/* while (count) */
 
 			assert (PVTS(r, i)->cmdbuf_base <= PVTS(r, i)->cmdbuf_endp);
 			/* check if a child died */
 			if (PVTS(r, i)->dead /* && errno == EIO*/)

yozhhh ★★★
()
Ответ на: комментарий от yozhhh

Это для rxvt.
patch -p0<patch.diff
в каталоге mrxvt-0.4.0

Проблема в том, что сам автор использует только csh, а баг проявляется в bash :)

yozhhh ★★★
()
Ответ на: комментарий от yozhhh

Спасибо тебе, добрый человек!
Помогло лекарство... ;-)

HomeUser
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.