delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/03/31/21:48:43

Date: Tue, 31 Mar 1998 21:45:43 -0500 (EST)
Message-Id: <199804010245.VAA24878@delorie.com>
From: DJ Delorie <dj AT delorie DOT com>
To: djgpp-workers AT delorie DOT com
Subject: [gerlach AT netcom DOT com: Even more RCS with network drives.]

I haven't been following the thread much, but this one has diffs for
libc.  Thoughts?

------- Start of forwarded message -------
Newsgroups: comp.os.msdos.djgpp
From: gerlach AT netcom DOT com (Matthew H. Gerlach)
Subject: Even more RCS with network drives.
Organization: Netcom On-Line Services
Date: Wed, 1 Apr 1998 02:13:45 GMT
Lines: 115
Sender: gerlach AT netcom16 DOT netcom DOT com
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com
Precedence: bulk



Hi fellow RCSers,

I seem to be a little closer to understanding my problems with
dgjpp v 2.01, rcs, and network drives.  I recently got the 
latest rcs sources, version 5.7 patch 13, and was able to get them
to work with NFS network drives.  To get things working I copied
the code in libc's remove.c into rcsedit.c and hacked as needed.
My hacks are included at the bottom of this posting.

My first change, should probably be part of the official libc.a, whereby
if the file doesn't exist, just exit and set errno to ENOENT.  This change
fixes initializing rcs files on network drives.

The second problem I ran into was if a unix user was the last to touch the
rcsfile, she would own it, and the djgpp rcs tools had problems modifying 
these files.  This problem was fixed in three possible ways.  In the code 
below, either code chunk in "ifdef MAKES_IT_WORK" would fix my problem.
In both cases, the code in "ifdef MAKES_IT_WORK" would cause remove() to
exit setting errno to ENOENT.  Doing so made the rcs code code "do the right
thing".  God only knows why a printf after the _chmod making the file 
writeable makes a difference, but it does.  In particular having the \n 
in the printf string is critical.  Without the \n in the printf the
function would return erroneously and set errno to EACCES, which the rcs
code did not like.

The two kludges in "ifdef MAKES_IT_WORK" did not sit well with me.  By
setting "#define bad_b_rename 0" in rcs's conf.h, I fixed my problem with
files owned by other people.  By changing this configuration variable,
rcs nolonger tried removing a file owned by "other" unix user.  Instead
it would just rename its tempfile over the old archive file previously owned
by another UNIX user.

Any insight into the behavior I've seen would be greatly appreciated.
In addition what is the process by which I can make the changes official?

Matthew


/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#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
remove(const char *fn)
{
  __dpmi_regs r;
  unsigned attr;
  int rval;
  int directory_p;
  int use_lfn = _USE_LFN;
 
  /* Get the file attribute byte.  */
  attr = _chmod(fn, 0);

  /* This should be part of the official libc.a.
     The above _chmod will return -1 if the file
     does not exist.  If it doesn't don't bother
     doing anything else, return an error, and
     set errno properly. */
  if (attr == -1)
  {
      errno = ENOENT;
      return(-1);
  }

  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.  */
  rval = _chmod(fn, 1, attr & 0xffe0);

  if (rval == -1)
  {
#ifdef MAKES_IT_WORK
    printf("\n");
#endif
  }

  /* 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;
#ifdef MAKES_IT_WORK
    printf("remove(%s) failed errno = %d\n", fn, errno);
    if (errno == EACCES)
        errno = ENOENT;
#endif
    return -1;
  }
  return 0;
}
------- End of forwarded message -------

- Raw text -


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