50bb47269c63ce613f3a19107599ab0841fbc54e
[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.7 2000/04/06 10:26:09 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(opath, npath)
27 StgByteArray opath;
28 StgByteArray npath;
29 {
30     struct stat sb;
31
32     /* Check for a non-directory source */
33     while (stat(opath, &sb) != 0) {
34         if (errno != EINTR) {
35             cvtErrno();
36             stdErrno();
37             return -1;
38         }
39     }
40     if (S_ISDIR(sb.st_mode)) {
41         ghc_errtype = ERR_INAPPROPRIATETYPE;
42         ghc_errstr = "file is a directory";
43         return -1;
44     }
45
46     /* Check for a non-directory destination */
47     while (stat(npath, &sb) != 0 && errno != ENOENT) {
48         if (errno != EINTR) {
49             cvtErrno();
50             stdErrno();
51             return -1;
52         }
53     }
54
55     if (errno != ENOENT) {
56         if (S_ISDIR(sb.st_mode)) {
57             ghc_errtype = ERR_INAPPROPRIATETYPE;
58             ghc_errstr = "file is a directory";
59             return -1;
60         }
61         while (chmod(npath, S_IWUSR) != 0) {
62             if (errno != EINTR) {
63                 cvtErrno();
64                 stdErrno();
65                 return -1;
66             }
67         }
68         while (unlink(npath) != 0) {
69             if (errno != EINTR) {
70                 cvtErrno();
71                 stdErrno();
72                 return -1;
73             }
74         }
75     }
76
77     while(rename(opath, npath) != 0) {
78         if (errno != EINTR) {
79             cvtErrno();
80             stdErrno();
81             return -1;
82         }
83     }
84
85     return 0;
86 }