Fix binary stdin/stdout io in Windows
Make --font-file accept "-" to mean stdin, and have it work
in Windows too!
diff --git a/configure.ac b/configure.ac
index 8245181..e1b6bf8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,7 +53,7 @@
# Functions and headers
AC_CHECK_FUNCS(mprotect sysconf getpagesize mmap)
-AC_CHECK_HEADERS(unistd.h sys/mman.h)
+AC_CHECK_HEADERS(unistd.h sys/mman.h io.h)
# Compiler flags
AC_CANONICAL_HOST
diff --git a/util/common.hh b/util/common.hh
index 015dbf4..1ce61af 100644
--- a/util/common.hh
+++ b/util/common.hh
@@ -40,6 +40,11 @@
#include <math.h>
#include <locale.h>
#include <errno.h>
+#include <fcntl.h>
+#if HAVE_IO_H
+#include <io.h> /* for _setmode() under Windows */
+#endif
+
#include <hb.h>
#include <glib.h>
diff --git a/util/options.cc b/util/options.cc
index 561b6aa..b1fb4ce 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -424,23 +424,66 @@
/* Create the blob */
{
- const char *font_data;
- unsigned int len;
+ char *font_data;
+ unsigned int len = 0;
hb_destroy_func_t destroy;
void *user_data;
hb_memory_mode_t mm;
+ /* This is a hell of a lot of code for just reading a file! */
if (!font_file)
fail (TRUE, "No font file set");
- GMappedFile *mf = g_mapped_file_new (font_file, FALSE, NULL);
- if (!mf)
- fail (FALSE, "Failed opening font file `%s'", g_filename_display_name (font_file));
- font_data = g_mapped_file_get_contents (mf);
- len = g_mapped_file_get_length (mf);
- destroy = (hb_destroy_func_t) g_mapped_file_unref;
- user_data = (void *) mf;
- mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
+ if (0 == strcmp (font_file, "-")) {
+ /* read it */
+ GString *gs = g_string_new (NULL);
+ char buf[BUFSIZ];
+#if HAVE_IO_H
+ _setmode (fileno (stdin), O_BINARY);
+#endif
+ while (!feof (stdin)) {
+ size_t ret = fread (buf, 1, sizeof (buf), stdin);
+ if (ferror (stdin))
+ fail (FALSE, "Failed reading font from standard input: %s",
+ strerror (errno));
+ g_string_append_len (gs, buf, ret);
+ }
+ len = gs->len;
+ font_data = g_string_free (gs, FALSE);
+ user_data = font_data;
+ destroy = (hb_destroy_func_t) g_free;
+ mm = HB_MEMORY_MODE_WRITABLE;
+ } else {
+ GMappedFile *mf = g_mapped_file_new (font_file, FALSE, NULL);
+ if (mf) {
+ font_data = g_mapped_file_get_contents (mf);
+ len = g_mapped_file_get_length (mf);
+ if (len) {
+ destroy = (hb_destroy_func_t) g_mapped_file_unref;
+ user_data = (void *) mf;
+ mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
+ } else
+ g_mapped_file_unref (mf);
+ }
+ if (!len) {
+ /* GMappedFile is buggy, it doesn't fail if file isn't regular.
+ * Try reading.
+ * https://bugzilla.gnome.org/show_bug.cgi?id=659212 */
+ GError *error = NULL;
+ gsize l;
+ if (g_file_get_contents (font_file, &font_data, &l, &error)) {
+ len = l;
+ destroy = (hb_destroy_func_t) g_free;
+ user_data = (void *) font_data;
+ mm = HB_MEMORY_MODE_WRITABLE;
+ } else {
+ fail (FALSE, "Failed reading font file `%s': %s",
+ g_filename_display_name (font_file),
+ error->message);
+ //g_error_free (error);
+ }
+ }
+ }
blob = hb_blob_create (font_data, len, mm, user_data, destroy);
}
@@ -476,7 +519,6 @@
fail (FALSE, "Failed opening text file `%s'", g_filename_display_name (text_file));
text = g_mapped_file_get_contents (mf);
text_len = g_mapped_file_get_length (mf);
- printf ("%d\n", text_len);
}
if (text_len == (unsigned int) -1)
diff --git a/util/options.hh b/util/options.hh
index b213872..623e25a 100644
--- a/util/options.hh
+++ b/util/options.hh
@@ -208,7 +208,6 @@
mutable unsigned int text_len;
};
-
struct output_options_t : option_group_t
{
output_options_t (option_parser_t *parser) {
@@ -243,7 +242,14 @@
if (fp)
return fp;
- fp = output_file ? fopen (output_file, "wb") : stdout;
+ if (output_file)
+ fp = fopen (output_file, "wb");
+ else {
+#if HAVE_IO_H
+ _setmode (fileno (stdout), O_BINARY);
+#endif
+ fp = stdout;
+ }
if (!fp)
fail (FALSE, "Cannot open output file `%s': %s",
g_filename_display_name (output_file), strerror (errno));