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