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