1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)rec_close.c 5.9 (Berkeley) 03/19/93"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/types.h> 13 #include <sys/uio.h> 14 #include <sys/mman.h> 15 16 #include <errno.h> 17 #include <limits.h> 18 #include <stdio.h> 19 #include <unistd.h> 20 21 #include <db.h> 22 #include "recno.h" 23 24 /* 25 * __REC_CLOSE -- Close a recno tree. 26 * 27 * Parameters: 28 * dbp: pointer to access method 29 * 30 * Returns: 31 * RET_ERROR, RET_SUCCESS 32 */ 33 int 34 __rec_close(dbp) 35 DB *dbp; 36 { 37 BTREE *t; 38 int rval; 39 40 if (__rec_sync(dbp) == RET_ERROR) 41 return (RET_ERROR); 42 43 /* Committed to closing. */ 44 t = dbp->internal; 45 46 rval = RET_SUCCESS; 47 if (ISSET(t, BTF_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize)) 48 rval = RET_ERROR; 49 50 if (!ISSET(t, BTF_RINMEM) && 51 ISSET(t, BTF_CLOSEFP) ? fclose(t->bt_rfp) : close(t->bt_rfd)) 52 rval = RET_ERROR; 53 54 if (__bt_close(dbp) == RET_ERROR) 55 rval = RET_ERROR; 56 57 return (rval); 58 } 59 60 /* 61 * __REC_SYNC -- sync the recno tree to disk. 62 * 63 * Parameters: 64 * dbp: pointer to access method 65 * 66 * Returns: 67 * RET_SUCCESS, RET_ERROR. 68 */ 69 int 70 __rec_sync(dbp) 71 const DB *dbp; 72 { 73 struct iovec iov[2]; 74 BTREE *t; 75 DBT data, key; 76 off_t off; 77 recno_t scursor, trec; 78 int status; 79 80 t = dbp->internal; 81 82 if (ISSET(t, BTF_RDONLY | BTF_RINMEM) || !ISSET(t, BTF_MODIFIED)) 83 return (RET_SUCCESS); 84 85 /* Read any remaining records into the tree. */ 86 if (!ISSET(t, BTF_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 87 return (RET_ERROR); 88 89 /* Rewind the file descriptor. */ 90 if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0) 91 return (RET_ERROR); 92 93 iov[1].iov_base = "\n"; 94 iov[1].iov_len = 1; 95 scursor = t->bt_rcursor; 96 97 key.size = sizeof(recno_t); 98 key.data = &trec; 99 100 status = (dbp->seq)(dbp, &key, &data, R_FIRST); 101 while (status == RET_SUCCESS) { 102 iov[0].iov_base = data.data; 103 iov[0].iov_len = data.size; 104 if (writev(t->bt_rfd, iov, 2) != data.size + 1) 105 return (RET_ERROR); 106 status = (dbp->seq)(dbp, &key, &data, R_NEXT); 107 } 108 t->bt_rcursor = scursor; 109 if (status == RET_ERROR) 110 return (RET_ERROR); 111 if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1) 112 return (RET_ERROR); 113 if (ftruncate(t->bt_rfd, off)) 114 return (RET_ERROR); 115 CLR(t, BTF_MODIFIED); 116 return (RET_SUCCESS); 117 } 118