fbuf: New data structure for buffered file I/O.
[pspp] / src / data / file-name.c
index 1c47b4751bd2cff865709fb000e02b20bc47838c..edbabd5ed8f871a67374490109a48176f608409d 100644 (file)
@@ -101,7 +101,7 @@ fn_search_path (const char *base_name, char **path)
       struct stat temp;
       if (( (stat (file, &temp) == 0 ) && ( ! S_ISDIR (temp.st_mode) )))
        return file;
-      
+
       free (file);
     }
 
@@ -142,7 +142,7 @@ safety_violation (const char *fn)
    NULL on failure.  If NULL is returned then errno is set to a
    sensible value.  */
 FILE *
-fn_open (const struct file_handle *fh, const char *mode)
+fn_fopen (const struct file_handle *fh, const char *mode)
 {
   const char *fn = fh_get_file_name (fh);
 
@@ -199,12 +199,51 @@ fn_open (const struct file_handle *fh, const char *mode)
       free (ss);
       return fp;
     }
-#else    
+#else
     return fopen (fn, mode);
-#endif    
+#endif
+}
+
+/* File open routine that understands `-' as stdin/stdout.  Returns file
+   descriptor on success, otherwise a negative errno value.  */
+int
+fn_open (const struct file_handle *fh, int flags, mode_t mode)
+{
+  const char *fn = fh_get_file_name (fh);
+
+  int orig_fd = -1;
+  if ((flags & O_ACCMODE) == O_RDONLY)
+    {
+      if (!strcmp (fn, "stdin") || !strcmp (fn, "-"))
+        orig_fd = STDIN_FILENO;
+    }
+  else
+    {
+      if (!strcmp (fn, "stdout") || !strcmp (fn, "-"))
+        orig_fd = STDOUT_FILENO;
+      else if (!strcmp (fn, "stderr"))
+        orig_fd = STDERR_FILENO;
+    }
+  if (orig_fd >= 0)
+    {
+      int fd = dup (orig_fd);
+      return fd >= 0 ? fd : -errno;
+    }
+
+#if WIN32
+  wchar_t *ss = convert_to_filename_encoding (fn, strlen (fn), fh_get_file_name_encoding (fh));
+  wchar_t *m =  (wchar_t *) recode_string ("UTF-16LE", "ASCII", mode, strlen (mode));
+  int fd = _wopen (fn, flags, mode);
+  free (m);
+  free (ss);
+#else
+  int fd = open (fn, flags, mode);
+#endif
+
+  return fd >= 0 ? fd : -errno;
 }
 
-/* Counterpart to fn_open that closes file F with name FN; returns 0
+/* Counterpart to fn_fopen that closes file F with name FN; returns 0
    on success, EOF on failure.  If EOF is returned, errno is set to a
    sensible value. */
 int