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 oflags = how[1] == '+' ? O_RDWR | O_NOCTTY : O_RDONLY | O_NOCTTY;
58 fprintf(stderr, "openFile: unknown mode `%s'\n", how);
62 /* First try to open without creating */
63 while ((fd = open(file, oflags, 0666)) < 0) {
64 if (errno == ENOENT) {
65 if (how[0] == 'r' && how[1] == '\0') {
66 /* For ReadMode, just bail out now */
67 ghc_errtype = ERR_NOSUCHTHING;
68 ghc_errstr = "file does not exist";
71 /* If it is a dangling symlink, break off now, too. */
73 if ( lstat(file,&st) == 0) {
74 ghc_errtype = ERR_NOSUCHTHING;
75 ghc_errstr = "dangling symlink";
79 /* Now try to create it */
80 while ((fd = open(file, oflags | O_CREAT | O_EXCL, 0666)) < 0) {
81 if (errno == EEXIST) {
82 /* Race detected; go back and open without creating it */
84 } else if (errno != EINTR) {
92 ghc_errtype = ERR_NOSUCHTHING;
93 ghc_errstr = "no path to file";
96 ghc_errtype = ERR_PERMISSIONDENIED;
97 ghc_errstr = "unsupported owner or group";
107 } else if (errno != EINTR) {
114 ghc_errtype = ERR_NOSUCHTHING;
115 ghc_errstr = "no path to file";
118 ghc_errtype = ERR_PERMISSIONDENIED;
119 ghc_errstr = "unsupported owner or group";
126 /* Make sure that we aren't looking at a directory */
128 while (fstat(fd, &sb) < 0) {
129 /* highly unlikely */
130 if (errno != EINTR) {
138 if (S_ISDIR(sb.st_mode)) {
139 ghc_errtype = ERR_INAPPROPRIATETYPE;
140 ghc_errstr = "file is a directory";
141 /* We can't have created it in this case. */
146 /* Use our own personal locking */
148 if (lockFile(fd, exclusive) < 0) {
156 ghc_errtype = ERR_RESOURCEBUSY;
157 ghc_errstr = "file is locked";
167 * Write mode is supposed to truncate the file. Unfortunately, our pal
168 * ftruncate() is non-POSIX, so we truncate with a second open, which may fail.
175 while ((fd2 = open(file, oflags, 0666)) < 0) {
176 if (errno != EINTR) {
186 ghc_errtype = ERR_RESOURCEBUSY;
187 ghc_errstr = "enforced lock prevents truncation";
190 ghc_errtype = ERR_NOSUCHTHING;
191 ghc_errstr = "no path to file";
194 ghc_errtype = ERR_PERMISSIONDENIED;
195 ghc_errstr = "unsupported owner or group";
203 errno = 0; /* Just in case fdopen() is lame */
204 while ((fp = fdopen(fd, how)) == NULL) {
205 if (errno != EINTR) {