Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Sep 1999 13:48:02 +0400 (MSD)
From:      isupov@moonhe.jinr.ru
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   i386/14048: ``doscmd -r'' doesn't work
Message-ID:  <199909300948.NAA07887@moonhe.jinr.ru>

next in thread | raw e-mail | index | archive | help

>Number:         14048
>Category:       i386
>Synopsis:       ``doscmd -r'' doesn't work
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Sep 30 02:50:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Isupov A.Yu.
>Release:        FreeBSD 3.2-RELEASE i386
>Organization:
LHE, JINR
>Environment:

	- FreeBSD 3.2-RELEASE i386
	- doscmd(1) recompiled with X support, as described in doscmd.1
	manual pages, DIAGNOSTICS
	- Processors: AMD K6-III-400 and Pentium P54C 90MHz

>Description:

	1. doscmd/tty.c/console_init(): mmap() of /dev/vga:
	Invalid argument

	2. doscmd/tty.c/console_init(): doscmd/AsyncIO.c/_RegisterIO():
	1060: Invalid FD

	3. doscmd/trap.c/sigbus():
	ax=0003 bx=0000 cx=ffff dx=0000
	si=0000 di=ffff sp=7fe5 bp=0000
	cs=6f00 ss=9800 ds=0000 es=0000
	ip=0 eflags=b0286
	00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
	addb   %al,(%bx+%si)
	doscmd: fatal error unsupported instruction

	(Note, that ``doscmd -x'' works.)

>How-To-Repeat:

	1. ``doscmd -r'' on console
	2. ``doscmd -r'' on console after fix 1.
	3. ``doscmd -r'' on console after fix 2.

>Fix:
	
	1. device vga0 in kernel reports (and this reasonable!):

	/kernel: vga0 at 0x3b0-0x3df maddr 0xa0000 msize 131072 on isa

	but in the doscmd/tty.c/console_init() we have:

	    addr = mmap((caddr_t)0xA0000, 5 * 64 * 1024,
			PROT_EXEC | PROT_READ | PROT_WRITE,
			MAP_FILE | MAP_FIXED | MAP_INHERIT | MAP_SHARED,
			fd, 0);

	so 5*64*1024 = 327680 (from 0xA0000 to 0xEFFFF !) slightly huge...
	I think, 2*64*1024 = 131072 (from 0xA0000 to 0xBFFFF) will be enough ?

	Following fix proposed (diff -c):
	-----------------fix 1----------------------------------------------
	*** tty.c.orig	Thu Sep 30 12:21:23 1999
	--- tty.c	Thu Sep 30 13:25:07 1999
	***************
	*** 286,292 ****
	  	perror("/dev/vga");
	  	quit(1);
	      }
	!     addr = mmap((caddr_t)0xA0000, 5 * 64 * 1024,
	  		PROT_EXEC | PROT_READ | PROT_WRITE,
	  		MAP_FILE | MAP_FIXED | MAP_INHERIT | MAP_SHARED,
	  		fd, 0);
	--- 286,292 ----
	  	perror("/dev/vga");
	  	quit(1);
	      }
	!     addr = mmap((caddr_t)0xA0000, 2 * 64 * 1024,
	  		PROT_EXEC | PROT_READ | PROT_WRITE,
	  		MAP_FILE | MAP_FIXED | MAP_INHERIT | MAP_SHARED,
	  		fd, 0);
	-----------------fix 1 end-------------------------------------------

	2. In the doscmd/tty.c/console_init() we have:

	    if ((fd = open("/dev/console", 2)) < 0) {
		perror("/dev/console");
		quit(1);
	    }
	    fd = squirrel_fd(fd);

	squirrel_fd() duplicates file descriptor at the top of the permitted
	fd range. It's high limit obtained by sysconf(_SC_OPEN_MAX).
	But this incompatible with doscmd/AsyncIO.c, where we have definition:

	static	Async	handlers[OPEN_MAX];

	and direct check in the doscmd/AsyncIO.c/_RegisterIO() :

		if (fd < 0 || fd > OPEN_MAX) {
	printf("%d: Invalid FD\n", fd);
			return;
		}
	
	Following fix proposed (diff -c):
	-----------------fix 2------------------------------------------
	*** tty.c.orig	Thu Sep 30 12:21:23 1999
	--- tty.c	Thu Sep 30 13:25:07 1999
	***************
	*** 311,317 ****
	  	quit(1);
	      }
	  
	!     fd = squirrel_fd(fd);
	      kbd_fd = fd;
	  
	  #ifdef __FreeBSD__
	--- 311,317 ----
	  	quit(1);
	      }
	  
	!     fd = squirrel1_fd(fd);
	      kbd_fd = fd;
	  
	  #ifdef __FreeBSD__
	*** doscmd.c.orig	Thu Sep 30 12:21:23 1999
	--- doscmd.c		Thu Sep 30 13:25:41 1999
	***************
	*** 761,766 ****
	--- 761,784 ----
	      return(fd);
	  }
	  
	+ int
	+ squirrel1_fd(int fd)
	+ {
	+     int sfd = OPEN_MAX;
	+     struct stat sb;
	+ 
	+     do {
	+ 	errno = 0;
	+ 	fstat(--sfd, &sb);
	+     } while (sfd > 0 && errno != EBADF);
	+ 
	+     if (errno == EBADF && dup2(fd, sfd) >= 0) {
	+ 	close(fd);
	+ 	return(sfd);
	+     }
	+     return(fd);
	+ }
	+ 
	  /*
	  ** Exit-time stuff
	  */
	-----------------fix 2 end----------------------------------

	3. doscmd(1) obtain SIGBUS for unknown reasons. Fix unknown.


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199909300948.NAA07887>