xref: /netbsd-src/external/bsd/mdocml/dist/dba_write.c (revision 9508192e445c6bc8463a56d16765781892ab889e)
1*9508192eSchristos /*	Id: dba_write.c,v 1.3 2016/08/05 23:15:08 schwarze Exp  */
2*9508192eSchristos /*
3*9508192eSchristos  * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
4*9508192eSchristos  *
5*9508192eSchristos  * Permission to use, copy, modify, and distribute this software for any
6*9508192eSchristos  * purpose with or without fee is hereby granted, provided that the above
7*9508192eSchristos  * copyright notice and this permission notice appear in all copies.
8*9508192eSchristos  *
9*9508192eSchristos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*9508192eSchristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*9508192eSchristos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*9508192eSchristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*9508192eSchristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*9508192eSchristos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*9508192eSchristos  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*9508192eSchristos  *
17*9508192eSchristos  * Low-level functions for serializing allocation-based data to disk.
18*9508192eSchristos  * The interface is defined in "dba_write.h".
19*9508192eSchristos  */
20*9508192eSchristos #include "config.h"
21*9508192eSchristos 
22*9508192eSchristos #include <assert.h>
23*9508192eSchristos #if HAVE_ENDIAN
24*9508192eSchristos #include <endian.h>
25*9508192eSchristos #elif HAVE_SYS_ENDIAN
26*9508192eSchristos #include <sys/endian.h>
27*9508192eSchristos #elif HAVE_NTOHL
28*9508192eSchristos #include <arpa/inet.h>
29*9508192eSchristos #endif
30*9508192eSchristos #if HAVE_ERR
31*9508192eSchristos #include <err.h>
32*9508192eSchristos #endif
33*9508192eSchristos #include <errno.h>
34*9508192eSchristos #include <fcntl.h>
35*9508192eSchristos #include <stdint.h>
36*9508192eSchristos #include <stdio.h>
37*9508192eSchristos 
38*9508192eSchristos #include "dba_write.h"
39*9508192eSchristos 
40*9508192eSchristos static FILE	*ofp;
41*9508192eSchristos 
42*9508192eSchristos 
43*9508192eSchristos int
dba_open(const char * fname)44*9508192eSchristos dba_open(const char *fname)
45*9508192eSchristos {
46*9508192eSchristos 	ofp = fopen(fname, "w");
47*9508192eSchristos 	return ofp == NULL ? -1 : 0;
48*9508192eSchristos }
49*9508192eSchristos 
50*9508192eSchristos int
dba_close(void)51*9508192eSchristos dba_close(void)
52*9508192eSchristos {
53*9508192eSchristos 	return fclose(ofp) == EOF ? -1 : 0;
54*9508192eSchristos }
55*9508192eSchristos 
56*9508192eSchristos int32_t
dba_tell(void)57*9508192eSchristos dba_tell(void)
58*9508192eSchristos {
59*9508192eSchristos 	long		 pos;
60*9508192eSchristos 
61*9508192eSchristos 	if ((pos = ftell(ofp)) == -1)
62*9508192eSchristos 		err(1, "ftell");
63*9508192eSchristos 	if (pos >= INT32_MAX) {
64*9508192eSchristos 		errno = EOVERFLOW;
65*9508192eSchristos 		err(1, "ftell = %ld", pos);
66*9508192eSchristos 	}
67*9508192eSchristos 	return pos;
68*9508192eSchristos }
69*9508192eSchristos 
70*9508192eSchristos void
dba_seek(int32_t pos)71*9508192eSchristos dba_seek(int32_t pos)
72*9508192eSchristos {
73*9508192eSchristos 	if (fseek(ofp, pos, SEEK_SET) == -1)
74*9508192eSchristos 		err(1, "fseek(%d)", pos);
75*9508192eSchristos }
76*9508192eSchristos 
77*9508192eSchristos int32_t
dba_align(void)78*9508192eSchristos dba_align(void)
79*9508192eSchristos {
80*9508192eSchristos 	int32_t		 pos;
81*9508192eSchristos 
82*9508192eSchristos 	pos = dba_tell();
83*9508192eSchristos 	while (pos & 3) {
84*9508192eSchristos 		dba_char_write('\0');
85*9508192eSchristos 		pos++;
86*9508192eSchristos 	}
87*9508192eSchristos 	return pos;
88*9508192eSchristos }
89*9508192eSchristos 
90*9508192eSchristos int32_t
dba_skip(int32_t nmemb,int32_t sz)91*9508192eSchristos dba_skip(int32_t nmemb, int32_t sz)
92*9508192eSchristos {
93*9508192eSchristos 	const int32_t	 out[5] = {0, 0, 0, 0, 0};
94*9508192eSchristos 	int32_t		 i, pos;
95*9508192eSchristos 
96*9508192eSchristos 	assert(sz >= 0);
97*9508192eSchristos 	assert(nmemb > 0);
98*9508192eSchristos 	assert(nmemb <= 5);
99*9508192eSchristos 	pos = dba_tell();
100*9508192eSchristos 	for (i = 0; i < sz; i++)
101*9508192eSchristos 		if (nmemb - fwrite(&out, sizeof(out[0]), nmemb, ofp))
102*9508192eSchristos 			err(1, "fwrite");
103*9508192eSchristos 	return pos;
104*9508192eSchristos }
105*9508192eSchristos 
106*9508192eSchristos void
dba_char_write(int c)107*9508192eSchristos dba_char_write(int c)
108*9508192eSchristos {
109*9508192eSchristos 	if (putc(c, ofp) == EOF)
110*9508192eSchristos 		err(1, "fputc");
111*9508192eSchristos }
112*9508192eSchristos 
113*9508192eSchristos void
dba_str_write(const char * str)114*9508192eSchristos dba_str_write(const char *str)
115*9508192eSchristos {
116*9508192eSchristos 	if (fputs(str, ofp) == EOF)
117*9508192eSchristos 		err(1, "fputs");
118*9508192eSchristos 	dba_char_write('\0');
119*9508192eSchristos }
120*9508192eSchristos 
121*9508192eSchristos void
dba_int_write(int32_t i)122*9508192eSchristos dba_int_write(int32_t i)
123*9508192eSchristos {
124*9508192eSchristos 	i = htobe32(i);
125*9508192eSchristos 	if (fwrite(&i, sizeof(i), 1, ofp) != 1)
126*9508192eSchristos 		err(1, "fwrite");
127*9508192eSchristos }
128