blob: 71e2fabc84ab1e54fb38f7d4b17cce83aee8345a [file] [log] [blame]
H. Peter Anvinbdae10b2016-03-08 01:22:13 -08001/* ----------------------------------------------------------------------- *
2 *
3 * Copyright 1996-2016 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * ----------------------------------------------------------------------- */
33
34#include "compiler.h"
35#include "nasmlib.h"
36
37#include <errno.h>
38
39#ifdef HAVE_IO_H
40# include <io.h>
41#endif
42#ifdef HAVE_UNISTD_H
43# include <unistd.h>
44#endif
45
H. Peter Anvin7ab55952016-03-08 02:23:23 -080046/* Can we adjust the file size without actually writing all the bytes? */
47#ifdef HAVE_FILENO /* Useless without fileno() */
48# ifdef HAVE__CHSIZE_S
H. Peter Anvinc0aaf972016-05-10 15:18:00 -070049# define nasm_ftruncate(fd,size) _chsize_s(fd,size)
H. Peter Anvin7ab55952016-03-08 02:23:23 -080050# elif defined(HAVE__CHSIZE)
51# define nasm_ftruncate(fd,size) _chsize(fd,size)
52# elif defined(HAVE_FTRUNCATE)
53# define nasm_ftruncate(fd,size) ftruncate(fd,size)
54# endif
55#endif
56
H. Peter Anvinbdae10b2016-03-08 01:22:13 -080057void nasm_write(const void *ptr, size_t size, FILE *f)
58{
59 size_t n = fwrite(ptr, 1, size, f);
60 if (n != size || ferror(f) || feof(f))
61 nasm_fatal(0, "unable to write output: %s", strerror(errno));
62}
63
64#ifdef WORDS_LITTLEENDIAN
65
66void fwriteint16_t(uint16_t data, FILE * fp)
67{
68 nasm_write(&data, 2, fp);
69}
70
71void fwriteint32_t(uint32_t data, FILE * fp)
72{
73 nasm_write(&data, 4, fp);
74}
75
76void fwriteint64_t(uint64_t data, FILE * fp)
77{
78 nasm_write(&data, 8, fp);
79}
80
81void fwriteaddr(uint64_t data, int size, FILE * fp)
82{
83 nasm_write(&data, size, fp);
84}
85
86#else /* not WORDS_LITTLEENDIAN */
87
88void fwriteint16_t(uint16_t data, FILE * fp)
89{
90 char buffer[2], *p = buffer;
91 WRITESHORT(p, data);
92 nasm_write(buffer, 2, fp);
93}
94
95void fwriteint32_t(uint32_t data, FILE * fp)
96{
97 char buffer[4], *p = buffer;
98 WRITELONG(p, data);
99 nasm_write(buffer, 4, fp);
100}
101
102void fwriteint64_t(uint64_t data, FILE * fp)
103{
104 char buffer[8], *p = buffer;
105 WRITEDLONG(p, data);
106 nasm_write(buffer, 8, fp);
107}
108
109void fwriteaddr(uint64_t data, int size, FILE * fp)
110{
111 char buffer[8], *p = buffer;
112 WRITEADDR(p, data, size);
113 nasm_write(buffer, size, fp);
114}
115
116#endif
117
118
H. Peter Anvinbdae10b2016-03-08 01:22:13 -0800119void fwritezero(size_t bytes, FILE *fp)
120{
121 size_t blksize;
122
123#ifdef nasm_ftruncate
124 if (bytes >= BUFSIZ && !ferror(fp) && !feof(fp)) {
125 off_t pos = ftello(fp);
126 if (pos >= 0) {
127 if (!fflush(fp) &&
128 !nasm_ftruncate(fileno(fp), pos + bytes) &&
129 !fseeko(fp, pos+bytes, SEEK_SET))
130 return;
131 }
132 }
133#endif
134
135 while (bytes) {
136 blksize = (bytes < ZERO_BUF_SIZE) ? bytes : ZERO_BUF_SIZE;
137
138 nasm_write(zero_buffer, blksize, fp);
139 bytes -= blksize;
140 }
141}
H. Peter Anvin3e83cec2016-05-25 04:28:46 -0700142
143#ifdef __GLIBC__
144/* If we are using glibc, attempt to mmap the files for speed */
145# define READ_TEXT_FILE "rtm"
146# define READ_BIN_FILE "rbm"
147#else
148# define READ_TEXT_FILE "rt"
149# define READ_BIN_FILE "rb"
150#endif
151#define WRITE_TEXT_FILE "wt"
152#define WRITE_BIN_FILE "wb"
153
154FILE *nasm_open_read(const char *filename, enum file_flags flags)
155{
156 FILE *f;
157
158 f = fopen(filename, (flags & NF_TEXT) ? READ_TEXT_FILE : READ_BIN_FILE);
159 if (!f && (flags & NF_FATAL))
160 nasm_fatal(ERR_NOFILE, "unable to open input file: `%s': %s",
161 filename, strerror(errno));
162
163 return f;
164}
165
166FILE *nasm_open_write(const char *filename, enum file_flags flags)
167{
168 FILE *f;
169
170 f = fopen(filename, (flags & NF_TEXT) ? WRITE_TEXT_FILE : WRITE_BIN_FILE);
171 if (!f && (flags & NF_FATAL))
172 nasm_fatal(ERR_NOFILE, "unable to open output file: `%s': %s",
173 filename, strerror(errno));
174
175 return f;
176}
H. Peter Anvinc1700892016-09-20 18:26:42 -0700177
178off_t