From 941f2b85489b344698bf036922c589483034a7f2 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 18 Jun 2018 20:35:40 +0430 Subject: [PATCH] Support pipe and friends on hb_blob_create_from_file (#1061) With this hb-view/hb-shape support pipes and possibly socket and named pipe also, anything fails just on mmap. We can later do the same for Windows also. This however reveals two issues, the fact most of our bots don't have HAVE_MMAP and using this instead the other fread/fopen reader can make failure on CI. I should look at them separately this change however is very low risk I believe. --- src/hb-blob.cc | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/hb-blob.cc b/src/hb-blob.cc index c138648ca..77dbc7150 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -499,6 +499,36 @@ hb_blob_t::try_make_writable (void) # define MAP_NORESERVE 0 #endif +static hb_blob_t * +_fread_to_end (FILE *file) +{ + int allocated = BUFSIZ * 16; + char *blob = (char *) malloc (allocated); + if (blob == nullptr) return hb_blob_get_empty (); + + int len = 0; + while (!feof (file)) + { + if (allocated - len < BUFSIZ) + { + allocated *= 2; + char *new_blob = (char *) realloc (blob, allocated); + if (unlikely (!new_blob)) goto fail; + blob = new_blob; + } + + len += fread (blob + len, 1, allocated - len, file); + if (ferror (file)) goto fail; + } + + return hb_blob_create (blob, len, HB_MEMORY_MODE_WRITABLE, blob, + (hb_destroy_func_t) free); + +fail: + free (blob); + return hb_blob_get_empty (); +} + struct hb_mapped_file_t { char *contents; @@ -557,7 +587,19 @@ hb_blob_create_from_file (const char *file_name) writable ? PROT_READ|PROT_WRITE : PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0); - if (unlikely (file->contents == MAP_FAILED)) goto fail; + if (unlikely (file->contents == MAP_FAILED)) + { + free (file); + FILE *f = fdopen (fd, "rb"); + if (unlikely (f == nullptr)) + { + CLOSE (fd); + return hb_blob_get_empty (); + } + hb_blob_t *blob = _fread_to_end (f); + fclose (f); + return blob; + } #elif defined(_WIN32) || defined(__CYGWIN__) HANDLE fd = CreateFile (file_name,