Commit 22819cd9 authored by Richard M. Stallman's avatar Richard M. Stallman

[__DJGPP_MINOR__ == 0] (_rename): New function, a

substitute for library low-level file-renaming function which
works around Windows 95 bug.
parent 2fa58881
......@@ -2327,6 +2327,122 @@ __write (int handle, const void *buffer, size_t count)
}
}
/* A low-level file-renaming function which works around Windows 95 bug.
This is pulled directly out of DJGPP v2.01 library sources, and only
used when you compile with DJGPP v2.0. */
#include <io.h>
int _rename(const char *old, const char *new)
{
__dpmi_regs r;
int olen = strlen(old) + 1;
int i;
int use_lfn = _USE_LFN;
char tempfile[FILENAME_MAX];
const char *orig = old;
int lfn_fd = -1;
r.x.dx = __tb_offset;
r.x.di = __tb_offset + olen;
r.x.ds = r.x.es = __tb_segment;
if (use_lfn)
{
/* Windows 95 bug: for some filenames, when you rename
file -> file~ (as in Emacs, to leave a backup), the
short 8+3 alias doesn't change, which effectively
makes OLD and NEW the same file. We must rename
through a temporary file to work around this. */
char *pbase = 0, *p;
static char try_char[] = "abcdefghijklmnopqrstuvwxyz012345789";
int idx = sizeof(try_char) - 1;
/* Generate a temporary name. Can't use `tmpnam', since $TMPDIR
might point to another drive, which will fail the DOS call. */
strcpy(tempfile, old);
for (p = tempfile; *p; p++) /* ensure temporary is on the same drive */
if (*p == '/' || *p == '\\' || *p == ':')
pbase = p;
if (pbase)
pbase++;
else
pbase = tempfile;
strcpy(pbase, "X$$djren$$.$$temp$$");
do
{
if (idx <= 0)
return -1;
*pbase = try_char[--idx];
} while (_chmod(tempfile, 0) != -1);
r.x.ax = 0x7156;
_put_path2(tempfile, olen);
_put_path(old);
__dpmi_int(0x21, &r);
if (r.x.flags & 1)
{
errno = __doserr_to_errno(r.x.ax);
return -1;
}
/* Now create a file with the original name. This will
ensure that NEW will always have a 8+3 alias
different from that of OLD. (Seems to be required
when NameNumericTail in the Registry is set to 0.) */
lfn_fd = _creat(old, 0);
olen = strlen(tempfile) + 1;
old = tempfile;
r.x.di = __tb_offset + olen;
}
for (i=0; i<2; i++)
{
if(use_lfn)
r.x.ax = 0x7156;
else
r.h.ah = 0x56;
_put_path2(new, olen);
_put_path(old);
__dpmi_int(0x21, &r);
if(r.x.flags & 1)
{
if (r.x.ax == 5 && i == 0) /* access denied */
remove(new); /* and try again */
else
{
errno = __doserr_to_errno(r.x.ax);
/* Restore to original name if we renamed it to temporary. */
if (use_lfn)
{
if (lfn_fd != -1)
{
_close (lfn_fd);
remove (orig);
}
_put_path2(orig, olen);
_put_path(tempfile);
r.x.ax = 0x7156;
__dpmi_int(0x21, &r);
}
return -1;
}
}
else
break;
}
/* Success. Delete the file possibly created to work
around the Windows 95 bug. */
if (lfn_fd != -1)
return (_close (lfn_fd) == 0) ? remove (orig) : -1;
return 0;
}
#endif /* __DJGPP__ == 2 && __DJGPP_MINOR__ == 0 */
DEFUN ("msdos-long-file-names", Fmsdos_long_file_names, Smsdos_long_file_names,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment