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.2 (Berkeley) 09/11/91"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/param.h> 13 #include <sys/uio.h> 14 #include <errno.h> 15 #include <db.h> 16 #include <unistd.h> 17 #include <stdio.h> 18 #include "recno.h" 19 20 /* 21 * __REC_CLOSE -- Close a recno tree. 22 * 23 * Parameters: 24 * dbp: pointer to access method 25 * 26 * Returns: 27 * RET_ERROR, RET_SUCCESS 28 */ 29 int 30 __rec_close(dbp) 31 DB *dbp; 32 { 33 if (__rec_sync(dbp) == RET_ERROR) 34 return (RET_ERROR); 35 return (__bt_close(dbp)); 36 } 37 38 /* 39 * __REC_SYNC -- sync the recno tree to disk. 40 * 41 * Parameters: 42 * dbp: pointer to access method 43 * 44 * Returns: 45 * RET_SUCCESS, RET_ERROR. 46 * 47 * XXX 48 * Currently don't handle a key marked for deletion when the tree is synced. 49 * Should copy the page and write it out instead of the real page. 50 */ 51 int 52 __rec_sync(dbp) 53 const DB *dbp; 54 { 55 struct iovec iov[2]; 56 BTREE *t; 57 DBT data, key; 58 off_t off; 59 recno_t scursor; 60 int status; 61 62 t = dbp->internal; 63 64 if (ISSET(t, BTF_INMEM) || NOTSET(t, BTF_MODIFIED)) 65 return (RET_SUCCESS); 66 67 if (ISSET(t, BTF_RDONLY)) { 68 errno = EPERM; 69 return (RET_ERROR); 70 } 71 72 /* Suck any remaining records into the tree. */ 73 if (t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 74 return (RET_ERROR); 75 76 /* Rewind the file descriptor. */ 77 if (lseek(t->bt_rfd, 0L, SEEK_SET) != 0L) 78 return (RET_ERROR); 79 80 iov[1].iov_base = "\n"; 81 iov[1].iov_len = 1; 82 scursor = t->bt_rcursor; 83 84 status = (dbp->seq)(dbp, &key, &data, R_FIRST); 85 while (status == RET_SUCCESS) { 86 iov[0].iov_base = data.data; 87 iov[0].iov_len = data.size; 88 if (writev(t->bt_rfd, iov, 2) != data.size + 1) 89 return (RET_ERROR); 90 status = (dbp->seq)(dbp, &key, &data, R_NEXT); 91 } 92 t->bt_rcursor = scursor; 93 if (status == RET_ERROR) 94 return (RET_ERROR); 95 if ((off = lseek(t->bt_rfd, 0L, SEEK_CUR)) == -1) 96 return (RET_ERROR); 97 if (ftruncate(t->bt_rfd, off)) 98 return (RET_ERROR); 99 UNSET(t, BTF_MODIFIED); 100 return (RET_SUCCESS); 101 } 102