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);
238 fdopen() plus implement locking.
250 * Since we aren't supposed to succeed when we're opening for writing and
251 * there's another writer, we can't just do an fopen() for "w" mode.
256 oflags = O_WRONLY | O_NOCTTY | O_APPEND;
260 oflags = O_WRONLY | O_NOCTTY;
264 #if defined(cygwin32_TARGET_OS)
265 /* With cygwin32-b19, fdopen() returns EBADF under some
266 hard-to-reproduce situations (causing hsc's renamer
267 to break on some ~10 modules when recompiling it.)
268 As a temporary workaround, we open files that was requested
269 opened as read-only instead as read-write, since fdopen()
270 only appears to fail on RO file descriptors.
272 This won't have any impact on the correctness of the Haskell IO
273 implementation since the Handle in Haskell land will record the
274 file as being read-only, so illegal writes will be caught.
276 ToDo: isolate and report.
278 oflags = how[1] == '+' ? O_RDWR | O_NOCTTY : O_RDWR | O_NOCTTY;
280 oflags = how[1] == '+' ? O_RDWR | O_NOCTTY : O_RDONLY | O_NOCTTY;
285 fprintf(stderr, "openFd: unknown mode `%s'\n", how);
290 if (lockFile(fd, exclusive) < 0) {
298 ghc_errtype = ERR_RESOURCEBUSY;
299 ghc_errstr = "file is locked";
306 errno = 0; /* Just in case fdopen() is lame */
307 while ((fp = fdopen(fd, how)) == NULL) {
308 if (errno != EINTR) {
309 #if defined(cygwin32_TARGET_OS) && defined(DEBUG)
310 fprintf(stderr, "openFd %s : %s : %d : %d\n", file, how, errno, fd);