Message-Id: <3.0.1.32.19971124145854.007b56c0@yacker.xiotech.com> Date: Mon, 24 Nov 1997 14:58:54 -0600 To: djgpp-workers AT delorie DOT com From: Randy Maas Subject: some proposed "new" fsext c files Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=====================_880426734==_" Precedence: bulk --=====================_880426734==_ Content-Type: text/plain; charset="us-ascii" Attached are the proposed "new" files for libc. --=====================_880426734==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="_copy.c" /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details Modified: 1997, Randall Maas. based on the _open example, and the majority of code here is from DJ Delorie's copy code from _link. */ #include #include #include #include #include #include #ifdef __DJGPP__ #include #else #include "fsext.h" #endif int _copy(const char* path1, const char* path2) { int rv; struct stat statbuf1, statbuf2; struct utimbuf times; char buf[16384]; int fd1, fd2, nbyte, status1, status2; /* Check to see if an extension will handle the copy*/ if (__FSEXT_call_open_handlers(__FSEXT_copy, &rv, &path1)) return rv; /* Fail if either path is null */ if (path1 == NULL || path2 == NULL) { errno = EFAULT; return -1; } if (*path1 == '\0' || *path2 == '\0') { errno = ENOENT; return -1; } /* Fail if path1 does not exist - stat() will set errno */ if (stat(path1, &statbuf1) < 0) return -1; # if defined(S_ISREG) /* Fail if path1 is not a regular file -- assume it is on platforms without S_ISREG concept*/ if (!S_ISREG(statbuf1.st_mode)) { errno = EPERM; return -1; } # endif /* Fail if unable to open path1 - open() will set errno */ fd1 = open(path1, O_RDONLY | O_BINARY); if (fd1 < 0) return -1; /* Fail if unable to create path2 - open() will set errno */ fd2 = open(path2, O_WRONLY | O_BINARY | O_CREAT | O_EXCL, 0600); if (fd2 < 0) { (void) close(fd1); return -1; } /* Fail if path1 and path2 are on different devices */ if (fstat(fd2, &statbuf2) < 0) return -1; if (statbuf1.st_dev != statbuf2.st_dev) { (void)close(fd1); (void)close(fd2); (void)unlink(path2); errno = EXDEV; return -1; } /* Copy path1 to path2 */ do { nbyte = read(fd1, buf, sizeof buf); if (nbyte <= 0) break; if (write(fd2, buf, nbyte) != nbyte) nbyte = -1; } while (nbyte > 0); /* Fail if the copy failed or we can't clean up */ status1 = close(fd1); status2 = close(fd2); if (nbyte < 0 || status1 < 0 || status2 < 0) { (void) unlink(path2); return -1; } /* Success! */ /* Set the mode to match the original, ignoring errors */ (void) chmod(path2, statbuf1.st_mode); /* Set the file time to match the original, ignoring errors */ times.actime = statbuf1.st_atime; times.modtime = statbuf1.st_mtime; (void) utime(path2, ×); return 0; } --=====================_880426734==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="_dup2.c" /* a _dup2 to call the file system extension Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details Modified 1997, Randall Maas: this is mostly from dup2.c v2.01 */ #include #include #include #include #include #include #include #include #include #if defined(__DJGPP__) #include #else #include "fsext.h" #endif int _dup2(int fd, int newfd) { __FSEXT_Function * func = NULL; void *state = NULL; __dpmi_regs r; if (fd == newfd) return newfd; if (__FSEXT_get_handler(fd, &func, &state) && func) { int rv; if (func(__FSEXT_dup2, &rv, &fd, state)) return rv; /* one bit of a problem: if newfd refers to an extension we close the descriptor. For safety's sake, we then force DOS to dup2' the descriptor to prevent to descriptor aliasing (ie, a future open returning the same value as newfd!) */ if (__FSEXT_get_function(fd)) close(newfd); __FSEXT_set_handler(newfd, func, state); } __file_handle_set(newfd, __file_handle_modes[fd] ^ (O_BINARY|O_TEXT)); r.h.ah = 0x46; r.x.bx = fd; r.x.cx = newfd; __dpmi_int(0x21, &r); if (r.x.flags & 1) { if (func) __FSEXT_set_handler(newfd, NULL, NULL); /* prevent weird bugs */ errno = __doserr_to_errno(r.x.ax); return -1; } setmode(newfd, __file_handle_modes[fd]); return newfd; } --=====================_880426734==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="_fse_nop.c" /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details Written 1997, Randall Maas. */ #include #include int _FSEXT_nop(int handle) { __FSEXT_Function* func = NULL; void* state; if (__FSEXT_get_handler(handle, &func, &state) && func) { int rv; if (func(__FSEXT_nop, &rv, &handle, state)) return rv; } return -1; } --=====================_880426734==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="_link.c" /* simulates link by calling the file system extensions or _copy Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details Written 1997, Randall Maas. */ #include #include #if defined(__DJGPP__) #include #else #include "fsext.h" #endif int _link(const char* src, const char* dest) { int rv; if (__FSEXT_call_open_handlers(__FSEXT_link, &rv, &src)) return rv; /* This emulates a link by calling copy. */ /* We call _copy instead of emulating it here in the hopes that a File System Extension will properly handle the copying. */ return _copy(path1, path2); } --=====================_880426734==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="_lseek.c" /* has dos or extension lseek in an open file Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details Modified 1997 Randall Maas from lseek.c and added fsext hook. */ #include #include #include #include #include #include off_t _lseek(int handle, off_t offset, int whence) { __dpmi_regs r; __FSEXT_Function *func; void* state; if (__FSEXT_get_handler(handle, &func, &state) && func) { int rv; if (func(__FSEXT_lseek, &rv, &handle, state)) return rv; } r.h.ah = 0x42; r.h.al = whence; r.x.bx = handle; r.x.cx = offset >> 16; r.x.dx = offset & 0xffff; __dpmi_int(0x21, &r); if (r.x.flags & 1) { errno = __doserr_to_errno(r.x.ax); return -1; } return (r.x.dx << 16) + r.x.ax; } --=====================_880426734==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="_unlink.c" /* has DOS or an extension remove a named file Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details Modified 1997, Randall Maas: the heart is from remove.c, but added the hooks to fsext. */ #include #include #include #include #include #include #include #include int _unlink(const char *fn) { __dpmi_regs r; unsigned attr; int directory_p; int use_lfn = _USE_LFN; /* Check to see if an extension will handle the unlink*/ if (__FSEXT_call_open_handlers(__FSEXT_unlink, &rv, &fn)) return rv; /* Get the file attribute byte. */ attr = _chmod(fn, 0); directory_p = attr & 0x10; /* Now, make the file writable. We must reset Vol, Dir, Sys and Hidden bits in addition to the Read-Only bit, or else 214301 will fail. */ _chmod(fn, 1, attr & 0xffe0); /* Now delete it. Note, _chmod leaves dir name in tranfer buffer. */ if (directory_p) r.h.ah = 0x3a; /* DOS Remove Directory function */ else r.h.ah = 0x41; /* DOS Remove File function */ if(use_lfn) { r.h.al = r.h.ah; r.h.ah = 0x71; r.x.si = 0; /* No Wildcards */ } r.x.dx = __tb_offset; r.x.ds = __tb_segment; __dpmi_int(0x21, &r); if(r.x.flags & 1) { /* We failed. Leave the things as we've found them. */ int e = __doserr_to_errno(r.x.ax); _chmod(fn, 1, attr & 0xffe7); errno = e; return -1; } return 0; } --=====================_880426734==_ Content-Type: text/plain; charset="us-ascii" --=====================_880426734==_--