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