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