Date: Sun, 22 Mar 1998 16:25:03 +0300 (IDT) From: Eli Zaretskii To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: Re: __FSEXT_alloc_fd freed from FILES= limits In-Reply-To: <199803151812.NAA18113@delorie.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk On Sun, 15 Mar 1998, DJ Delorie wrote: > Um, if the initial fsext closes, don't you lose the handle to > null_dev_fd? You don't have anything in there to detect that you've > closed that one. Oops! Shame on me. Here's take 2: *** src/libc/fsext/fsext.c~0 Fri Jan 2 05:29:06 1998 --- src/libc/fsext/fsext.c Fri Mar 20 19:12:40 1998 *************** *** 1,3 **** --- 1,4 ---- + /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include *************** *** 8,13 **** --- 9,15 ---- #include #include #include + #include typedef struct __FSEXT_entry { __FSEXT_Function *function; *************** static __FSEXT_entry *fsext_list; *** 20,52 **** extern void (*__FSEXT_exit_hook)(void); static void __FSEXT_close_all(void); ! static void init(void) { static int init_count = -1; if (init_count == __bss_count) ! return; init_count = __bss_count; num_fds = 0; fsext_list = 0; /* Attach our hook to close all of the remaining open extensions. */ __FSEXT_exit_hook = __FSEXT_close_all; } int __FSEXT_alloc_fd(__FSEXT_Function *_function) { int fd; __dpmi_regs r; ! init(); ! _put_path("nul"); ! r.x.ax = 0x3d82; /* open, no inherit, read/write */ ! r.x.dx = __tb_offset; ! r.x.ds = __tb_segment; ! __dpmi_int(0x21, &r); if (r.x.flags & 1) { --- 22,68 ---- extern void (*__FSEXT_exit_hook)(void); static void __FSEXT_close_all(void); ! static int init(void) { static int init_count = -1; if (init_count == __bss_count) ! return 0; init_count = __bss_count; num_fds = 0; fsext_list = 0; /* Attach our hook to close all of the remaining open extensions. */ __FSEXT_exit_hook = __FSEXT_close_all; + return 1; } int __FSEXT_alloc_fd(__FSEXT_Function *_function) { + static int null_dev_fd = -1; int fd; __dpmi_regs r; ! if (init() || null_dev_fd == -1) ! { ! /* This is our first time. Open the NUL device, just this once. */ ! _put_path("nul"); ! r.x.ax = 0x3d82; /* open, no inherit, read/write */ ! r.x.dx = __tb_offset; ! r.x.ds = __tb_segment; ! __dpmi_int(0x21, &r); ! null_dev_fd = (r.x.flags & 1) == 0 ? r.x.ax : -1; ! } ! if (null_dev_fd != -1) ! { ! /* To get a new handle, just dup the handle we got the first time. This ! has the advantage of being independent of what their FILES= says. */ ! r.h.ah = 0x45; ! r.x.bx = null_dev_fd; ! __dpmi_int(0x21, &r); ! } if (r.x.flags & 1) { *************** __FSEXT_alloc_fd(__FSEXT_Function *_func *** 55,60 **** --- 71,77 ---- } fd = r.x.ax; + __file_handle_set(fd, O_BINARY); /* so the JFT is expanded as needed */ __FSEXT_set_function(fd, _function); return fd; } *** src/libc/fsext/fsext.t~0 Fri Jan 2 05:28:02 1998 --- src/libc/fsext/fsext.txh Sat Mar 14 20:31:24 1998 *************** *** 161,169 **** This function is part of the @ref{File System Extensions}. It is used by extensions that fully emulate the I/O functions, and thus don't ! have a corresponding DOS file handle. This function opens DOS's ! @samp{NUL} device, so as to allocate a handle that DOS won't then reuse. ! It also assigns the handler function for that descriptor. The module is responsible for calling @code{_close} on the descriptor after setting the handler function to zero in the extended close --- 161,174 ---- This function is part of the @ref{File System Extensions}. It is used by extensions that fully emulate the I/O functions, and thus don't ! have a corresponding DOS file handle. Upon the first call, this ! function opens DOS's @samp{NUL} device, so as to allocate a handle that ! DOS won't then reuse. Upon subsequent calls, that handle is duplicated ! by calling the DOS @code{dup} function; this makes all of the handles ! use a single entry in the System File Table, and thus be independent of ! what the @samp{FILES=} parameter of @file{CONFIG.SYS} says. ! @code{__FSEXT_alloc_fd} also assigns the handler function for the handle ! it returns. The module is responsible for calling @code{_close} on the descriptor after setting the handler function to zero in the extended close *** src/docs/kb/wc202.t~6 Fri Mar 6 20:07:06 1998 --- src/docs/kb/wc202.txi Sat Mar 14 19:29:10 1998 *************** *** 351,353 **** --- 351,360 ---- other processes can create files in the same directory, and opens the file in DENY_ALL mode. @findex mkstemp + + @code{__FSEXT_alloc_fd} now duplicates the initial file handle instead + of reopening the NUL device on each call. Thus, it is no longer limited + by the value of the @samp{FILES=} parameter on your @file{CONFIG.SYS}, + but can allocate up to 254 handles (which is the maximum number allowed + by DOS). + @findex __FSEXT_alloc_fd