2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
4 \subsection[openFile.lc]{openFile Runtime Support}
11 #ifdef HAVE_SYS_TYPES_H
12 #include <sys/types.h>
15 #ifdef HAVE_SYS_STAT_H
40 * Since we aren't supposed to succeed when we're opening for writing and
41 * there's another writer, we can't just do an fopen() for "w" mode.
46 oflags = O_WRONLY | O_NOCTTY | O_APPEND;
50 oflags = O_WRONLY | O_NOCTTY;
54 #if defined(cygwin32_TARGET_OS)
55 /* With cygwin32-b19, fdopen() returns EBADF under some
56 hard-to-reproduce situations (causing hsc's renamer
57 to break on some ~10 modules when recompiling it.)
58 As a temporary workaround, we open files that was requested
59 opened as read-only instead as read-write, since fdopen()
60 only appears to fail on RO file descriptors.
62 This won't have any impact on the correctness of the Haskell IO
63 implementation since the Handle in Haskell land will record the
64 file as being read-only, so illegal writes will be caught.
66 ToDo: isolate and report.
68 oflags = how[1] == '+' ? O_RDWR | O_NOCTTY : O_RDWR | O_NOCTTY;
70 oflags = how[1] == '+' ? O_RDWR | O_NOCTTY : O_RDONLY | O_NOCTTY;
75 fprintf(stderr, "openFile: unknown mode `%s'\n", how);
79 /* First try to open without creating */
80 while ((fd = open(file, oflags, 0666)) < 0) {
81 if (errno == ENOENT) {
82 if (how[0] == 'r' && how[1] == '\0') {
83 /* For ReadMode, just bail out now */
84 ghc_errtype = ERR_NOSUCHTHING;
85 ghc_errstr = "file does not exist";
88 /* If it is a dangling symlink, break off now, too. */
90 if ( lstat(file,&st) == 0) {
91 ghc_errtype = ERR_NOSUCHTHING;
92 ghc_errstr = "dangling symlink";
96 /* Now try to create it */
97 while ((fd = open(file, oflags | O_CREAT | O_EXCL, 0666)) < 0) {
98 if (errno == EEXIST) {
99 /* Race detected; go back and open without creating it */
101 } else if (errno != EINTR) {
109 ghc_errtype = ERR_NOSUCHTHING;
110 ghc_errstr = "no path to file";
113 ghc_errtype = ERR_PERMISSIONDENIED;
114 ghc_errstr = "unsupported owner or group";
124 } else if (errno != EINTR) {
131 ghc_errtype = ERR_NOSUCHTHING;
132 ghc_errstr = "no path to file";
135 ghc_errtype = ERR_PERMISSIONDENIED;
136 ghc_errstr = "unsupported owner or group";
143 /* Make sure that we aren't looking at a directory */
145 while (fstat(fd, &sb) < 0) {
146 /* highly unlikely */
147 if (errno != EINTR) {
155 if (S_ISDIR(sb.st_mode)) {
156 ghc_errtype = ERR_INAPPROPRIATETYPE;
157 ghc_errstr = "file is a directory";
158 /* We can't have created it in this case. */
163 /* Use our own personal locking */
165 if (lockFile(fd, exclusive) < 0) {
173 ghc_errtype = ERR_RESOURCEBUSY;
174 ghc_errstr = "file is locked";
184 * Write mode is supposed to truncate the file. Unfortunately, our pal
185 * ftruncate() is non-POSIX, so we truncate with a second open, which may fail.
192 while ((fd2 = open(file, oflags, 0666)) < 0) {
193 if (errno != EINTR) {
203 ghc_errtype = ERR_RESOURCEBUSY;
204 ghc_errstr = "enforced lock prevents truncation";
207 ghc_errtype = ERR_NOSUCHTHING;
208 ghc_errstr = "no path to file";
211 ghc_errtype = ERR_PERMISSIONDENIED;
212 ghc_errstr = "unsupported owner or group";
220 errno = 0; /* Just in case fdopen() is lame */
221 while ((fp = fdopen(fd, how)) == NULL) {
222 if (errno != EINTR) {
223 #if defined(cygwin32_TARGET_OS) && defined(DEBUG)
224 fprintf(stderr, "openFile %s : %s : %d : %d\n", file, how, errno, fd);