blob: ce22ea312ff84cf7bd170f513fef764e9cf0e8f1 [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/* Missing fseeko/ftello */
47#ifndef HAVE_FSEEKO
48# undef off_t /* Just in case it is a macro */
49# ifdef HAVE__FSEEKI64
50# define fseeko _fseeki64
51# define ftello _ftelli64
52# define off_t int64_t
53# else
54# define fseeko fseek
55# define ftello ftell
56# define off_t long
57# endif
58#endif
59
60/* Can we adjust the file size without actually writing all the bytes? */
61#ifdef HAVE_FILENO /* Useless without fileno() */
62# ifdef HAVE__CHSIZE_S
H. Peter Anvin55e51d92016-05-10 15:14:30 -070063static int nasm_ftruncate(int fd, int64_t size)
64{
65 int err = _chsize_s(fd, size);
66
67 if (!err)
68 return 0;
69
70 errno = err;
71 return -1;
72}
73# define nasm_ftruncate(fd,size) nasm_ftruncate(fd,size)
H. Peter Anvin7ab55952016-03-08 02:23:23 -080074# elif defined(HAVE__CHSIZE)
75# define nasm_ftruncate(fd,size) _chsize(fd,size)
76# elif defined(HAVE_FTRUNCATE)
77# define nasm_ftruncate(fd,size) ftruncate(fd,size)
78# endif
79#endif
80
H. Peter Anvinbdae10b2016-03-08 01:22:13 -080081void nasm_write(const void *ptr, size_t size, FILE *f)
82{
83 size_t n = fwrite(ptr, 1, size, f);
84 if (n != size || ferror(f) || feof(f))
85 nasm_fatal(0, "unable to write output: %s", strerror(errno));
86}
87
88#ifdef WORDS_LITTLEENDIAN
89
90void fwriteint16_t(uint16_t data, FILE * fp)
91{
92 nasm_write(&data, 2, fp);
93}
94
95void fwriteint32_t(uint32_t data, FILE * fp)
96{
97 nasm_write(&data, 4, fp);
98}
99
100void fwriteint64_t(uint64_t data, FILE * fp)
101{
102 nasm_write(&data, 8, fp);
103}
104
105void fwriteaddr(uint64_t data, int size, FILE * fp)
106{
107 nasm_write(&data, size, fp);
108}
109
110#else /* not WORDS_LITTLEENDIAN */
111
112void fwriteint16_t(uint16_t data, FILE * fp)
113{
114 char buffer[2], *p = buffer;
115 WRITESHORT(p, data);
116 nasm_write(buffer, 2, fp);
117}
118
119void fwriteint32_t(uint32_t data, FILE * fp)
120{
121 char buffer[4], *p = buffer;
122 WRITELONG(p, data);
123 nasm_write(buffer, 4, fp);
124}
125
126void fwriteint64_t(uint64_t data, FILE * fp)
127{
128 char buffer[8], *p = buffer;
129 WRITEDLONG(p, data);
130 nasm_write(buffer, 8, fp);
131}
132
133void fwriteaddr(uint64_t data, int size, FILE * fp)
134{
135 char buffer[8], *p = buffer;
136 WRITEADDR(p, data, size);
137 nasm_write(buffer, size, fp);
138}
139
140#endif
141
142
H. Peter Anvinbdae10b2016-03-08 01:22:13 -0800143void fwritezero(size_t bytes, FILE *fp)
144{
145 size_t blksize;
146
147#ifdef nasm_ftruncate
148 if (bytes >= BUFSIZ && !ferror(fp) && !feof(fp)) {
149 off_t pos = ftello(fp);
150 if (pos >= 0) {
151 if (!fflush(fp) &&
152 !nasm_ftruncate(fileno(fp), pos + bytes) &&
153 !fseeko(fp, pos+bytes, SEEK_SET))
154 return;
155 }
156 }
157#endif
158
159 while (bytes) {
160 blksize = (bytes < ZERO_BUF_SIZE) ? bytes : ZERO_BUF_SIZE;
161
162 nasm_write(zero_buffer, blksize, fp);
163 bytes -= blksize;
164 }
165}