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 30 static FILE *ofp; 31 32 33 int 34 dba_open(const char *fname) 35 { 36 ofp = fopen(fname, "w"); 37 return ofp == NULL ? -1 : 0; 38 } 39 40 int 41 dba_close(void) 42 { 43 return fclose(ofp) == EOF ? -1 : 0; 44 } 45 46 int32_t 47 dba_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 60 void 61 dba_seek(int32_t pos) 62 { 63 if (fseek(ofp, pos, SEEK_SET) == -1) 64 err(1, "fseek(%d)", pos); 65 } 66 67 int32_t 68 dba_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 80 int32_t 81 dba_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 96 void 97 dba_char_write(int c) 98 { 99 if (putc(c, ofp) == EOF) 100 err(1, "fputc"); 101 } 102 103 void 104 dba_str_write(const char *str) 105 { 106 if (fputs(str, ofp) == EOF) 107 err(1, "fputs"); 108 dba_char_write('\0'); 109 } 110 111 void 112 dba_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