[project @ 2001-01-11 14:09:50 by simonpj]
[ghc-hetmet.git] / ghc / lib / std / cbits / renameFile.c
1 /* 
2  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
3  *
4  * $Id: renameFile.c,v 1.8 2000/04/06 10:33:06 rrt Exp $
5  *
6  * renameFile Runtime Support
7  */
8
9 #include "Rts.h"
10 #include "stgio.h"
11
12 #ifdef HAVE_SYS_TYPES_H
13 #include <sys/types.h>
14 #endif
15
16 #ifdef HAVE_SYS_STAT_H
17 #include <sys/stat.h>
18 #endif
19
20 #ifdef HAVE_FCNTL_H
21 #include <fcntl.h>
22 #endif
23
24
25 StgInt
26 renameFile(StgByteArray opath, StgByteArray npath)
27 {
28     struct stat sb;
29
30     /* Check for a non-directory source */
31     while (stat(opath, &sb) != 0) {
32         if (errno != EINTR) {
33             cvtErrno();
34             stdErrno();
35             return -1;
36         }
37     }
38     if (S_ISDIR(sb.st_mode)) {
39         ghc_errtype = ERR_INAPPROPRIATETYPE;
40         ghc_errstr = "file is a directory";
41         return -1;
42     }
43
44     /* Check for a non-directory destination */
45     while (stat(npath, &sb) != 0 && errno != ENOENT) {
46         if (errno != EINTR) {
47             cvtErrno();
48             stdErrno();
49             return -1;
50         }
51     }
52
53     if (errno != ENOENT) {
54         if (S_ISDIR(sb.st_mode)) {
55             ghc_errtype = ERR_INAPPROPRIATETYPE;
56             ghc_errstr = "file is a directory";
57             return -1;
58         }
59         while (chmod(npath, S_IWUSR) != 0) {
60             if (errno != EINTR) {
61                 cvtErrno();
62                 stdErrno();
63                 return -1;
64             }
65         }
66         while (unlink(npath) != 0) {
67             if (errno != EINTR) {
68                 cvtErrno();
69                 stdErrno();
70                 return -1;
71             }
72         }
73     }
74
75     while(rename(opath, npath) != 0) {
76         if (errno != EINTR) {
77             cvtErrno();
78             stdErrno();
79             return -1;
80         }
81     }
82
83     return 0;
84 }