xref: /original-bsd/lib/libc/db/recno/rec_close.c (revision b4971bb3)
1 /*-
2  * Copyright (c) 1990, 1993
3  *	The Regents of the University of California.  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	8.1 (Berkeley) 06/04/93";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <sys/types.h>
13 #include <sys/uio.h>
14 #include <sys/mman.h>
15 
16 #include <errno.h>
17 #include <limits.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 
21 #include <db.h>
22 #include "recno.h"
23 
24 /*
25  * __REC_CLOSE -- Close a recno tree.
26  *
27  * Parameters:
28  *	dbp:	pointer to access method
29  *
30  * Returns:
31  *	RET_ERROR, RET_SUCCESS
32  */
33 int
34 __rec_close(dbp)
35 	DB *dbp;
36 {
37 	BTREE *t;
38 	int rval;
39 
40 	if (__rec_sync(dbp, 0) == RET_ERROR)
41 		return (RET_ERROR);
42 
43 	/* Committed to closing. */
44 	t = dbp->internal;
45 
46 	rval = RET_SUCCESS;
47 	if (ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
48 		rval = RET_ERROR;
49 
50 	if (!ISSET(t, R_INMEM))
51 		if (ISSET(t, R_CLOSEFP)) {
52 			if (fclose(t->bt_rfp))
53 				rval = RET_ERROR;
54 		} else
55 			if (close(t->bt_rfd))
56 				rval = RET_ERROR;
57 
58 	if (__bt_close(dbp) == RET_ERROR)
59 		rval = RET_ERROR;
60 
61 	return (rval);
62 }
63 
64 /*
65  * __REC_SYNC -- sync the recno tree to disk.
66  *
67  * Parameters:
68  *	dbp:	pointer to access method
69  *
70  * Returns:
71  *	RET_SUCCESS, RET_ERROR.
72  */
73 int
74 __rec_sync(dbp, flags)
75 	const DB *dbp;
76 	u_int flags;
77 {
78 	struct iovec iov[2];
79 	BTREE *t;
80 	DBT data, key;
81 	off_t off;
82 	recno_t scursor, trec;
83 	int status;
84 
85 	t = dbp->internal;
86 
87 	if (flags == R_RECNOSYNC)
88 		return (__bt_sync(dbp, 0));
89 
90 	if (ISSET(t, R_RDONLY | R_INMEM) || !ISSET(t, R_MODIFIED))
91 		return (RET_SUCCESS);
92 
93 	/* Read any remaining records into the tree. */
94 	if (!ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
95 		return (RET_ERROR);
96 
97 	/* Rewind the file descriptor. */
98 	if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
99 		return (RET_ERROR);
100 
101 	iov[1].iov_base = "\n";
102 	iov[1].iov_len = 1;
103 	scursor = t->bt_rcursor;
104 
105 	key.size = sizeof(recno_t);
106 	key.data = &trec;
107 
108 	status = (dbp->seq)(dbp, &key, &data, R_FIRST);
109         while (status == RET_SUCCESS) {
110 		iov[0].iov_base = data.data;
111 		iov[0].iov_len = data.size;
112 		if (writev(t->bt_rfd, iov, 2) != data.size + 1)
113 			return (RET_ERROR);
114                 status = (dbp->seq)(dbp, &key, &data, R_NEXT);
115         }
116 	t->bt_rcursor = scursor;
117 	if (status == RET_ERROR)
118 		return (RET_ERROR);
119 	if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
120 		return (RET_ERROR);
121 	if (ftruncate(t->bt_rfd, off))
122 		return (RET_ERROR);
123 	CLR(t, R_MODIFIED);
124 	return (RET_SUCCESS);
125 }
126