1/* Id: dba_write.c,v 1.3 2016/08/05 23:15:08 schwarze Exp */ 2/* 3 * Copyright (c) 2016 Ingo Schwarze <schwarze@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 40static FILE *ofp; 41 42 43int 44dba_open(const char *fname) 45{ 46 ofp = fopen(fname, "w"); 47 return ofp == NULL ? -1 : 0; 48} 49 50int 51dba_close(void) 52{ 53 return fclose(ofp) == EOF ? -1 : 0; 54} 55 56int32_t 57dba_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 70void 71dba_seek(int32_t pos) 72{ 73 if (fseek(ofp, pos, SEEK_SET) == -1) 74 err(1, "fseek(%d)", pos); 75} 76 77int32_t 78dba_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 90int32_t 91dba_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 106void 107dba_char_write(int c) 108{ 109 if (putc(c, ofp) == EOF) 110 err(1, "fputc"); 111} 112 113void 114dba_str_write(const char *str) 115{ 116 if (fputs(str, ofp) == EOF) 117 err(1, "fputs"); 118 dba_char_write('\0'); 119} 120 121void 122dba_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