From fc8b941b4c76b0c1cb64939665787ba887b045bf Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Tue, 7 May 2013 00:14:15 -0600 Subject: [PATCH] Bug 857830: Part 2 - Adds readahead to read-only fopen calls in Hunspell. r=ehsan --- .../hunspell/src/hunspell_fopen_hooks.h | 79 +++++++++++++++++++ mozilla-config.h.in | 5 +- 2 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 extensions/spellcheck/hunspell/src/hunspell_fopen_hooks.h diff --git a/extensions/spellcheck/hunspell/src/hunspell_fopen_hooks.h b/extensions/spellcheck/hunspell/src/hunspell_fopen_hooks.h new file mode 100644 index 000000000000..bcca437e0f88 --- /dev/null +++ b/extensions/spellcheck/hunspell/src/hunspell_fopen_hooks.h @@ -0,0 +1,79 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef fopen_hooks_h__ +#define fopen_hooks_h__ + +/** + * This file is force-included in hunspell code. Its purpose is to add + * readahead to fopen() calls in hunspell without modifying its code, in order + * to ease future upgrades. + * + * This file is force-included through mozilla-config.h which is generated + * during the configure step. + */ + +#include "mozilla/FileUtils.h" +#include +#include + +#if defined(XP_WIN) +#include "nsString.h" + +#include +#include +// Hunspell defines a function named near. Windef.h #defines near. +#undef near +// mozHunspell defines a function named RemoveDirectory. +#undef RemoveDirectory +#endif /* defined(XP_WIN) */ + +inline FILE* +hunspell_fopen_readahead(const char* filename, const char* mode) +{ + if (!filename || !mode) { + return nullptr; + } + // Fall back to libc's fopen for modes not supported by ReadAheadFile + if (!strchr(mode, 'r') || strchr(mode, '+')) { + return fopen(filename, mode); + } + int fd = -1; +#if defined(XP_WIN) + HANDLE handle = INVALID_HANDLE_VALUE; + mozilla::ReadAheadFile(NS_ConvertUTF8toUTF16(filename).get(), 0, SIZE_MAX, + &handle); + if (handle == INVALID_HANDLE_VALUE) { + return nullptr; + } + int flags = _O_RDONLY; + // MSVC CRT's _open_osfhandle only supports adding _O_TEXT, not _O_BINARY + if (strchr(mode, 't')) { + // Force translated mode + flags |= _O_TEXT; + } + // Import the Win32 fd into the CRT + fd = _open_osfhandle((intptr_t)handle, flags); + if (fd < 0) { + CloseHandle(handle); + return nullptr; + } +#else + mozilla::ReadAheadFile(filename, 0, SIZE_MAX, &fd); + if (fd < 0) { + return nullptr; + } +#endif /* defined(XP_WIN) */ + + FILE* file = fdopen(fd, mode); + if (!file) { + close(fd); + } + return file; +} + +#define fopen(filename, mode) hunspell_fopen_readahead(filename, mode) + +#endif /* fopen_hooks_h__ */ + diff --git a/mozilla-config.h.in b/mozilla-config.h.in index b821728cc708..4957a260c804 100644 --- a/mozilla-config.h.in +++ b/mozilla-config.h.in @@ -13,14 +13,15 @@ * is defined before is included. */ #define __STDC_LIMIT_MACROS -/* Force-include hunspell_alloc_hooks.h for hunspell, so that we don't need to - * modify it directly. +/* Force-include hunspell_alloc_hooks.h and hunspell_fopen_hooks.h for hunspell, + * so that we don't need to modify it directly. * * HUNSPELL_STATIC is defined in extensions/spellcheck/hunspell/src/Makefile.in, * unless --enable-system-hunspell is defined. */ #if defined(HUNSPELL_STATIC) #include "hunspell_alloc_hooks.h" +#include "hunspell_fopen_hooks.h" #endif #endif /* _MOZILLA_CONFIG_H_ */