diff --git a/assemble.c b/assemble.c index 8cd72d9e..20e35c27 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 27d16ed1..084386dc 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 e39e1e94..3ed3bfdb 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 9d0904b4..cf4a919a 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 6ba38444..8c35f0e1 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 d90b5c3b..9356270b 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 945e2225..d3c72ae3 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 3e1ec286..fa76f605 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 b3f9b0d2..1cb14457 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 845f8fc1..e36ae9c9 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 3d1aa9c7..fcf8695b 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