xref: /original-bsd/lib/libc/db/recno/rec_close.c (revision 044d1bee)
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