+/* 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_fopen that closes file F with name FN; returns 0