From 3e83cec90e19de8cb019db29bd1db1f867785dd3 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 25 May 2016 04:28:46 -0700 Subject: [PATCH] Add wrappers around fopen(), use mmap on glibc Add wrappers to fopen(). The intent is to replace references to FILE * with an internal structure which can also cache things like the filename and, when needed, the full pathname and checksums. Also, add the "m" flag if we are compiling for glibc, for speed. Signed-off-by: H. Peter Anvin --- assemble.c | 4 ++-- listing.c | 2 +- nasm.c | 12 ++++++------ nasmlib.h | 13 +++++++++++++ nasmlib/file.c | 35 +++++++++++++++++++++++++++++++++++ ndisasm.c | 2 +- output/codeview.c | 2 +- output/outbin.c | 2 +- preproc-nop.c | 2 +- preproc.c | 12 ++++++------ preproc.h | 3 ++- 11 files changed, 69 insertions(+), 20 deletions(-) diff --git a/assemble.c b/assemble.c index 8cd72d9e5..20e35c272 100644 --- a/assemble.c +++ b/assemble.c @@ -511,7 +511,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, iflag_t cp, const char *fname = instruction->eops->stringval; FILE *fp; - fp = fopen(fname, "rb"); + fp = nasm_open_read(fname, NF_BINARY); if (!fp) { nasm_error(ERR_NONFATAL, "`incbin': unable to open file `%s'", fname); @@ -806,7 +806,7 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, iflag_t cp, int64_t val = 0; size_t len; - fp = fopen(fname, "rb"); + fp = nasm_open_read(fname, NF_BINARY); if (!fp) nasm_error(ERR_NONFATAL, "`incbin': unable to open file `%s'", fname); diff --git a/listing.c b/listing.c index 27d16ed1a..084386dcf 100644 --- a/listing.c +++ b/listing.c @@ -132,7 +132,7 @@ static void list_init(const char *fname) return; } - listfp = fopen(fname, "w"); + listfp = nasm_open_write(fname, NF_TEXT); if (!listfp) { nasm_error(ERR_NONFATAL, "unable to open listing file `%s'", fname); diff --git a/nasm.c b/nasm.c index e39e1e94a..3ed3bfdbf 100644 --- a/nasm.c +++ b/nasm.c @@ -290,7 +290,7 @@ static void emit_dependencies(StrList *list) StrList *l, *nl; if (depend_file && strcmp(depend_file, "-")) { - deps = fopen(depend_file, "w"); + deps = nasm_open_write(depend_file, NF_TEXT); if (!deps) { nasm_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE, "unable to write dependency file `%s'", depend_file); @@ -406,7 +406,7 @@ int main(int argc, char **argv) int lineinc = 0; if (*outname) { - ofile = fopen(outname, "w"); + ofile = nasm_open_write(outname, NF_TEXT); if (!ofile) nasm_fatal(ERR_NOFILE, "unable to open output file `%s'", @@ -459,7 +459,7 @@ int main(int argc, char **argv) */ ofmt->filename(inname, outname); - ofile = fopen(outname, (ofmt->flags & OFMT_TEXT) ? "w" : "wb"); + ofile = nasm_open_write(outname, (ofmt->flags & OFMT_TEXT) ? NF_TEXT : NF_BINARY); if (!ofile) nasm_fatal(ERR_NOFILE, "unable to open output file `%s'", outname); @@ -1106,7 +1106,7 @@ static void process_args(char *args) static void process_response_file(const char *file) { char str[2048]; - FILE *f = fopen(file, "r"); + FILE *f = nasm_open_read(file, NF_TEXT); if (!f) { perror(file); exit(-1); @@ -1159,7 +1159,7 @@ static void parse_cmdline(int argc, char **argv) if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') { p = get_param(argv[0], argc > 1 ? argv[1] : NULL, &advance); if (p) { - rfile = fopen(p, "r"); + rfile = nasm_open_read(p, NF_TEXT); if (rfile) { process_respfile(rfile); fclose(rfile); @@ -1188,7 +1188,7 @@ static void parse_cmdline(int argc, char **argv) inname); if (*errname) { - error_file = fopen(errname, "w"); + error_file = nasm_open_write(errname, NF_TEXT); if (!error_file) { error_file = stderr; /* Revert to default! */ nasm_fatal(ERR_NOFILE | ERR_USAGE, diff --git a/nasmlib.h b/nasmlib.h index 9d0904b47..cf4a919ad 100644 --- a/nasmlib.h +++ b/nasmlib.h @@ -434,6 +434,19 @@ char *nasm_realpath(const char *rel_path); const char *prefix_name(int); +/* + * Wrappers around fopen()... for future change to a dedicated structure + */ +enum file_flags { + NF_BINARY = 0x00000000, /* Binary file (default) */ + NF_TEXT = 0x00000001, /* Text file */ + NF_NONFATAL = 0x00000000, /* Don't die on open failure (default) */ + NF_FATAL = 0x00000002 /* Die on open failure */ +}; + +FILE *nasm_open_read(const char *filename, enum file_flags flags); +FILE *nasm_open_write(const char *filename, enum file_flags flags); + #define ZERO_BUF_SIZE 4096 /* Default value */ #if defined(BUFSIZ) && (BUFSIZ > ZERO_BUF_SIZE) # undef ZERO_BUF_SIZE diff --git a/nasmlib/file.c b/nasmlib/file.c index 6ba384446..8c35f0e16 100644 --- a/nasmlib/file.c +++ b/nasmlib/file.c @@ -153,3 +153,38 @@ void fwritezero(size_t bytes, FILE *fp) bytes -= blksize; } } + +#ifdef __GLIBC__ +/* If we are using glibc, attempt to mmap the files for speed */ +# define READ_TEXT_FILE "rtm" +# define READ_BIN_FILE "rbm" +#else +# define READ_TEXT_FILE "rt" +# define READ_BIN_FILE "rb" +#endif +#define WRITE_TEXT_FILE "wt" +#define WRITE_BIN_FILE "wb" + +FILE *nasm_open_read(const char *filename, enum file_flags flags) +{ + FILE *f; + + f = fopen(filename, (flags & NF_TEXT) ? READ_TEXT_FILE : READ_BIN_FILE); + if (!f && (flags & NF_FATAL)) + nasm_fatal(ERR_NOFILE, "unable to open input file: `%s': %s", + filename, strerror(errno)); + + return f; +} + +FILE *nasm_open_write(const char *filename, enum file_flags flags) +{ + FILE *f; + + f = fopen(filename, (flags & NF_TEXT) ? WRITE_TEXT_FILE : WRITE_BIN_FILE); + if (!f && (flags & NF_FATAL)) + nasm_fatal(ERR_NOFILE, "unable to open output file: `%s': %s", + filename, strerror(errno)); + + return f; +} diff --git a/ndisasm.c b/ndisasm.c index d90b5c3b5..9356270b6 100644 --- a/ndisasm.c +++ b/ndisasm.c @@ -271,7 +271,7 @@ int main(int argc, char **argv) } if (strcmp(filename, "-")) { - fp = fopen(filename, "rb"); + fp = nasm_open_read(filename, NF_BINARY); if (!fp) { fprintf(stderr, "%s: unable to open `%s': %s\n", pname, filename, strerror(errno)); diff --git a/output/codeview.c b/output/codeview.c index 945e22255..d3c72ae37 100644 --- a/output/codeview.c +++ b/output/codeview.c @@ -341,7 +341,7 @@ static void calc_md5(const char *const filename, FILE *f; MD5_CTX ctx; - f = pp_input_fopen(filename, "rb"); + f = pp_input_fopen(filename, NF_BINARY); if (!f) goto done; diff --git a/output/outbin.c b/output/outbin.c index 3e1ec2866..fa76f605b 100644 --- a/output/outbin.c +++ b/output/outbin.c @@ -1347,7 +1347,7 @@ static int bin_directive(enum directives directive, char *args, int pass) else if (!nasm_stricmp(p, "stderr")) rf = stderr; else { /* Must be a filename. */ - rf = fopen(p, "wt"); + rf = nasm_open_write(p, NF_TEXT); if (!rf) { nasm_error(ERR_WARNING, "unable to open map file `%s'", p); diff --git a/preproc-nop.c b/preproc-nop.c index b3f9b0d23..1cb144574 100644 --- a/preproc-nop.c +++ b/preproc-nop.c @@ -61,7 +61,7 @@ static void nop_reset(char *file, int pass, StrList **deplist) { src_set(0, file); nop_lineinc = 1; - nop_fp = fopen(file, "r"); + nop_fp = nasm_open_read(file, NF_TEXT); if (!nop_fp) nasm_fatal(ERR_NOFILE, "unable to open input file `%s'", file); diff --git a/preproc.c b/preproc.c index 845f8fc13..e36ae9c9b 100644 --- a/preproc.c +++ b/preproc.c @@ -1507,7 +1507,7 @@ static bool in_list(const StrList *list, const char *str) * the end of the path. */ static FILE *inc_fopen(const char *file, StrList **dhead, StrList ***dtail, - bool missing_ok, const char *mode) + bool missing_ok, enum file_flags mode) { FILE *fp; char *prefix = ""; @@ -1520,7 +1520,7 @@ static FILE *inc_fopen(const char *file, StrList **dhead, StrList ***dtail, sl = nasm_malloc(prefix_len+len+1+sizeof sl->next); memcpy(sl->str, prefix, prefix_len); memcpy(sl->str+prefix_len, file, len+1); - fp = fopen(sl->str, mode); + fp = nasm_open_read(sl->str, mode); if (fp && dhead && !in_list(*dhead, sl->str)) { sl->next = NULL; **dtail = sl; @@ -1562,7 +1562,7 @@ static FILE *inc_fopen(const char *file, StrList **dhead, StrList ***dtail, * that get a file:lineno pair and need to look at the file again * (e.g. the CodeView debug backend). Returns NULL on failure. */ -FILE *pp_input_fopen(const char *filename, const char *mode) +FILE *pp_input_fopen(const char *filename, enum file_flags mode) { FILE *fp; StrList *xsl = NULL; @@ -2515,7 +2515,7 @@ static int do_directive(Token * tline) inc = nasm_malloc(sizeof(Include)); inc->next = istk; inc->conds = NULL; - inc->fp = inc_fopen(p, dephead, &deptail, pass == 0, "r"); + inc->fp = inc_fopen(p, dephead, &deptail, pass == 0, NF_TEXT); if (!inc->fp) { /* -MG given but file not found */ nasm_free(inc); @@ -3258,7 +3258,7 @@ issue_error: if (t->type != TOK_INTERNAL_STRING) nasm_unquote(p, NULL); - fp = inc_fopen(p, &xsl, &xst, true, "r"); + fp = inc_fopen(p, &xsl, &xst, true, NF_TEXT); if (fp) { p = xsl->str; fclose(fp); /* Don't actually care about the file */ @@ -4851,7 +4851,7 @@ pp_reset(char *file, int apass, StrList **deplist) istk->conds = NULL; istk->expansion = NULL; istk->mstk = NULL; - istk->fp = fopen(file, "r"); + istk->fp = nasm_open_read(file, NF_TEXT); istk->fname = NULL; src_set(0, file); istk->lineinc = 1; diff --git a/preproc.h b/preproc.h index 3d1aa9c7c..fcf8695b2 100644 --- a/preproc.h +++ b/preproc.h @@ -38,6 +38,7 @@ #ifndef NASM_PREPROC_H #define NASM_PREPROC_H +#include "nasmlib.h" #include "pptok.h" extern const char * const pp_directives[]; @@ -49,6 +50,6 @@ typedef const unsigned char macros_t; enum preproc_token pp_token_hash(const char *token); /* Opens an include file or input file. This uses the include path. */ -FILE *pp_input_fopen(const char *filename, const char *mode); +FILE *pp_input_fopen(const char *filename, enum file_flags mode); #endif