delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1997/11/24/15:56:01

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 <randym AT acm DOT org>
Subject: some proposed "new" fsext c files
Mime-Version: 1.0

--=====================_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 <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <utime.h>
#ifdef __DJGPP__
#include <sys/fsext.h>
#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, &times);
  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 <libc/stubs.h>
#include <unistd.h>
#include <fcntl.h>
#include <dpmi.h>
#include <errno.h>
#include <io.h>
#include <libc/dosio.h>
#include <stdio.h>
#include <errno.h>
#if defined(__DJGPP__)
#include <sys/fsext.h>
#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 <fsext.h>
#include <io.h>

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 <stdio.h>
#include <errno.h>
#if defined(__DJGPP__)
#include <sys/fsext.h>
#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 <libc/stubs.h>
#include <unistd.h>
#include <errno.h>
#include <go32.h>
#include <dpmi.h>

#include <libc/dosio.h>

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 <libc/stubs.h>
#include <io.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <dpmi.h>
#include <go32.h>
#include <libc/dosio.h>
 
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==_--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019