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 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