/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: renameFile.c,v 1.1 1998/04/10 10:54:48 simonm Exp $
+ * $Id: renameFile.c,v 1.8 2000/04/06 10:33:06 rrt Exp $
*
* renameFile Runtime Support
*/
#include <fcntl.h>
#endif
+
StgInt
renameFile(StgByteArray opath, StgByteArray npath)
{
struct stat sb;
- int fd;
- int created = 0;
/* Check for a non-directory source */
while (stat(opath, &sb) != 0) {
return -1;
}
- /* Ensure a non-directory destination */
-
- /* First try to open without creating */
- while ((fd = open(npath, O_RDONLY | O_NOCTTY, 0)) < 0) {
- if (errno == ENOENT) {
- /* Now try to create it */
- while ((fd = open(npath, O_RDONLY | O_NOCTTY | O_CREAT | O_EXCL, 0)) < 0) {
- if (errno == EEXIST) {
- /* Race detected; go back and open without creating it */
- break;
- } else if (errno != EINTR) {
- cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_ENOENT:
- case GHC_ENOTDIR:
- ghc_errtype = ERR_NOSUCHTHING;
- ghc_errstr = "no path to file";
- break;
- case GHC_EINVAL:
- ghc_errtype = ERR_PERMISSIONDENIED;
- ghc_errstr = "unsupported owner or group";
- break;
- }
- return -1;
- }
- }
- if (fd >= 0) {
- created = 1;
- break;
- }
- } else if (errno != EINTR) {
+ /* Check for a non-directory destination */
+ while (stat(npath, &sb) != 0 && errno != ENOENT) {
+ if (errno != EINTR) {
cvtErrno();
- switch (ghc_errno) {
- default:
- stdErrno();
- break;
- case GHC_ENOTDIR:
- ghc_errtype = ERR_NOSUCHTHING;
- ghc_errstr = "no path to file";
- break;
- case GHC_EINVAL:
- ghc_errtype = ERR_PERMISSIONDENIED;
- ghc_errstr = "unsupported owner or group";
- break;
- }
+ stdErrno();
return -1;
}
}
- /* Make sure that we aren't looking at a directory */
-
- while (fstat(fd, &sb) < 0) {
- /* highly unlikely */
- if (errno != EINTR) {
- cvtErrno();
- if (created)
- (void) unlink(npath);
- (void) close(fd);
+ if (errno != ENOENT) {
+ if (S_ISDIR(sb.st_mode)) {
+ ghc_errtype = ERR_INAPPROPRIATETYPE;
+ ghc_errstr = "file is a directory";
return -1;
+ }
+ while (chmod(npath, S_IWUSR) != 0) {
+ if (errno != EINTR) {
+ cvtErrno();
+ stdErrno();
+ return -1;
+ }
+ }
+ while (unlink(npath) != 0) {
+ if (errno != EINTR) {
+ cvtErrno();
+ stdErrno();
+ return -1;
+ }
}
- }
- if (S_ISDIR(sb.st_mode)) {
- ghc_errtype = ERR_INAPPROPRIATETYPE;
- ghc_errstr = "destination is a directory";
- /* We can't have created it in this case. */
- (void) close(fd);
- return -1;
}
while(rename(opath, npath) != 0) {
if (errno != EINTR) {
cvtErrno();
stdErrno();
- if (created)
- (void) unlink(npath);
- (void) close(fd);
return -1;
}
}
- close(fd);
return 0;
}