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.5 (Berkeley) 11/07/92"; 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 BTREE *t; 34 int rval; 35 36 if (__rec_sync(dbp) == RET_ERROR) 37 return (RET_ERROR); 38 39 /* Committed to closing. */ 40 t = dbp->internal; 41 rval = t->bt_rfp == NULL ? close(t->bt_rfd) : fclose(t->bt_rfp); 42 43 if (__bt_close(dbp) == RET_ERROR) 44 return (RET_ERROR); 45 46 return (rval ? RET_ERROR : RET_SUCCESS); 47 } 48 49 /* 50 * __REC_SYNC -- sync the recno tree to disk. 51 * 52 * Parameters: 53 * dbp: pointer to access method 54 * 55 * Returns: 56 * RET_SUCCESS, RET_ERROR. 57 */ 58 int 59 __rec_sync(dbp) 60 const DB *dbp; 61 { 62 struct iovec iov[2]; 63 BTREE *t; 64 DBT data, key; 65 off_t off; 66 recno_t scursor, trec; 67 int status; 68 69 t = dbp->internal; 70 71 if (ISSET(t, BTF_INMEM) || ISSET(t, BTF_RDONLY) || 72 NOTSET(t, BTF_MODIFIED)) 73 return (RET_SUCCESS); 74 75 /* Read any remaining records into the tree. */ 76 if (t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 77 return (RET_ERROR); 78 79 /* Rewind the file descriptor. */ 80 if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0) 81 return (RET_ERROR); 82 83 iov[1].iov_base = "\n"; 84 iov[1].iov_len = 1; 85 scursor = t->bt_rcursor; 86 87 key.size = sizeof(recno_t); 88 key.data = &trec; 89 90 status = (dbp->seq)(dbp, &key, &data, R_FIRST); 91 while (status == RET_SUCCESS) { 92 iov[0].iov_base = data.data; 93 iov[0].iov_len = data.size; 94 if (writev(t->bt_rfd, iov, 2) != data.size + 1) 95 return (RET_ERROR); 96 status = (dbp->seq)(dbp, &key, &data, R_NEXT); 97 } 98 t->bt_rcursor = scursor; 99 if (status == RET_ERROR) 100 return (RET_ERROR); 101 if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) != 0) 102 return (RET_ERROR); 103 if (ftruncate(t->bt_rfd, off)) 104 return (RET_ERROR); 105 UNSET(t, BTF_MODIFIED); 106 return (RET_SUCCESS); 107 } 108