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