1/* $OpenBSD: dba_write.c,v 1.1 2016/08/01 10:32:39 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 <assert.h> 21#include <endian.h> 22#include <err.h> 23#include <errno.h> 24#include <fcntl.h> 25#include <stdint.h> 26#include <stdio.h> 27 28#include "dba_write.h" 29 30static FILE *ofp; 31 32 33int 34dba_open(const char *fname) 35{ 36 ofp = fopen(fname, "w"); 37 return ofp == NULL ? -1 : 0; 38} 39 40int 41dba_close(void) 42{ 43 return fclose(ofp) == EOF ? -1 : 0; 44} 45 46int32_t 47dba_tell(void) 48{ 49 long pos; 50 51 if ((pos = ftell(ofp)) == -1) 52 err(1, "ftell"); 53 if (pos >= INT32_MAX) { 54 errno = EOVERFLOW; 55 err(1, "ftell = %ld", pos); 56 } 57 return pos; 58} 59 60void 61dba_seek(int32_t pos) 62{ 63 if (fseek(ofp, pos, SEEK_SET) == -1) 64 err(1, "fseek(%d)", pos); 65} 66 67int32_t 68dba_align(void) 69{ 70 int32_t pos; 71 72 pos = dba_tell(); 73 while (pos & 3) { 74 dba_char_write('\0'); 75 pos++; 76 } 77 return pos; 78} 79 80int32_t 81dba_skip(int32_t nmemb, int32_t sz) 82{ 83 const int32_t out[5] = {0, 0, 0, 0, 0}; 84 int32_t i, pos; 85 86 assert(sz >= 0); 87 assert(nmemb > 0); 88 assert(nmemb <= 5); 89 pos = dba_tell(); 90 for (i = 0; i < sz; i++) 91 if (nmemb - fwrite(&out, sizeof(out[0]), nmemb, ofp)) 92 err(1, "fwrite"); 93 return pos; 94} 95 96void 97dba_char_write(int c) 98{ 99 if (putc(c, ofp) == EOF) 100 err(1, "fputc"); 101} 102 103void 104dba_str_write(const char *str) 105{ 106 if (fputs(str, ofp) == EOF) 107 err(1, "fputs"); 108 dba_char_write('\0'); 109} 110 111void 112dba_int_write(int32_t i) 113{ 114 i = htobe32(i); 115 if (fwrite(&i, sizeof(i), 1, ofp) != 1) 116 err(1, "fwrite"); 117} 118