+ if (! O_CLOEXEC && 0 <= fd)
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
+ return fd;
+}
+
+/* Open FILE as a stream for Emacs use, with mode MODE.
+ Act like emacs_open with respect to threads, signals, and quits. */
+
+FILE *
+emacs_fopen (char const *file, char const *mode)
+{
+ int fd, omode, oflags;
+ int bflag = 0;
+ char const *m = mode;
+
+ switch (*m++)
+ {
+ case 'r': omode = O_RDONLY; oflags = 0; break;
+ case 'w': omode = O_WRONLY; oflags = O_CREAT | O_TRUNC; break;
+ case 'a': omode = O_WRONLY; oflags = O_CREAT | O_APPEND; break;
+ default: emacs_abort ();
+ }
+
+ while (*m)
+ switch (*m++)
+ {
+ case '+': omode = O_RDWR; break;
+ case 'b': bflag = O_BINARY; break;
+ case 't': bflag = O_TEXT; break;
+ default: /* Ignore. */ break;
+ }
+
+ fd = emacs_open (file, omode | oflags | bflag, 0666);
+ return fd < 0 ? 0 : fdopen (fd, mode);