Mail Archives: djgpp-workers/1996/06/30/09:17:18
===============================================================================
Markus F.X.J. Oberhumer <markus DOT oberhumer AT jk DOT uni-linz DOT ac DOT at>
Subject: rename() problem in Win95 ?
To: djgpp-workers AT delorie DOT com
===============================================================================
Some days ago I compiled Vim 4.2 (a vi clone) with djgpp v2.
Everything works fine, and I've found this interresting
code fragment in msdos.c. As I don't have Windows 95 I can't
verify the claims herein, but maybe it proves useful as
a patch for rename().
from vim-4.2/src/msdos.c:
#ifdef DJGPP
/*
* djgpp_rename() works around a bug in rename (aka MoveFile) in
* Windows 95: rename("foo.bar", "foo.bar~") will generate a
* file whose shortfilename is "FOO.BAR" (its longfilename will
* be correct: "foo.bar~"). Because a file can be accessed by
* either its SFN or its LFN, "foo.bar" has effectively been
* renamed to "foo.bar", which is not at all what was wanted. This
* seems to happen only when renaming files with three-character
* extensions by appending a suffix that does not include ".".
* Windows NT gets it right, however, with an SFN of "FOO~1.BAR".
* This works like win95rename in win32.c, but is a bit simpler.
*
* Like rename(), returns 0 upon success, non-zero upon failure.
* Should probably set errno appropriately when errors occur.
*/
#undef rename
int
djgpp_rename(const char *OldFile, const char *NewFile)
{
char_u *TempFile;
int retval;
int fd;
/* rename() works correctly without long file names, so use that */
if (!_use_lfn())
return rename(OldFile, NewFile);
if ((TempFile = alloc((unsigned)(STRLEN(OldFile) + TMPNAMELEN))) == NULL)
return -1;
STRCPY(TempFile, OldFile);
STRCPY(gettail(TempFile), TMPNAME1);
if (rename(OldFile, TempFile))
retval = -1;
else
{
/* now create an empty file called OldFile; this prevents
* the operating system using OldFile as an alias (SFN)
* if we're renaming within the same directory. For example,
* we're editing a file called filename.asc.txt by its SFN,
* filena~1.txt. If we rename filena~1.txt to filena~1.txt~
* (i.e., we're making a backup while writing it), the SFN
* for filena~1.txt~ will be filena~1.txt, by default, which
* will cause all sorts of problems later in buf_write. So, we
* create an empty file called filena~1.txt and the system will have
* to find some other SFN for filena~1.txt~, such as filena~2.txt
*/
if ((fd = open(OldFile, O_RDWR|O_CREAT|O_EXCL, 0444)) < 0)
return -1;
retval = rename(TempFile, NewFile);
close(fd);
vim_remove((char_u *)OldFile);
}
vim_free(TempFile);
return retval; /* success */
}
#endif
- Raw text -