73 lines
1.7 KiB
C
73 lines
1.7 KiB
C
/* _ r e n a m e */
|
|
|
|
/* The file named in the from part is given the name in the to
|
|
* part. Return EOF if something goes wrong, otherwise return 0.
|
|
*
|
|
* This code is attributed to Freeman Pascal.
|
|
*
|
|
* rename() will not rename across file systems or file types.
|
|
* If an attempt is made to copy across file systems both files
|
|
* will be left intact and an error will be returned. This
|
|
* is Posix conformant.
|
|
*
|
|
* Problems:
|
|
*
|
|
* o During the unlink(to), link(from, to) phase, to momentarily
|
|
* points nowhere in direct contravention of the Posix standard.
|
|
*
|
|
* o Directories aren't handled properly:
|
|
*
|
|
* . link() and unlink() won't work on directories unless
|
|
* you're superuser
|
|
* . some systems don't have mkdir() and rmdir() and
|
|
* . even if they did, there would still be the small
|
|
* window of time in which the to link points nowhere.
|
|
*
|
|
* Patchlevel 2.2
|
|
*
|
|
* Edit History:
|
|
* 08-Oct-1989 Do nothing if files are the same.
|
|
*/
|
|
|
|
#include "stdiolib.h"
|
|
|
|
/*LINTLIBRARY*/
|
|
|
|
#ifndef RENAME
|
|
|
|
int rename F2(CONST char *, from, CONST char *, to)
|
|
|
|
{
|
|
struct stat s_to, s_from;
|
|
signal_t s_int, s_hup, s_quit;
|
|
register int ret;
|
|
|
|
if (stat(from, &s_from) != 0)
|
|
return -1;
|
|
else {
|
|
if (stat(to, &s_to) == 0) {
|
|
if (s_to.st_dev == s_from.st_dev) {
|
|
errno = EXDEV;
|
|
return -1;
|
|
}
|
|
else if (s_to.st_ino == s_from.st_ino)
|
|
return 0;
|
|
}
|
|
|
|
s_int = signal(SIGINT, SIG_IGN);
|
|
s_hup = signal(SIGHUP, SIG_IGN);
|
|
s_quit = signal(SIGQUIT, SIG_IGN);
|
|
|
|
ret = unlink(to);
|
|
if ((ret = link(from, to)) == 0)
|
|
ret = unlink(from);
|
|
|
|
(void) signal(SIGINT, s_int);
|
|
(void) signal(SIGHUP, s_hup);
|
|
(void) signal(SIGQUIT, s_quit);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
#endif
|