xref: /csrg-svn/lib/libc/db/recno/rec_close.c (revision 56702)
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