150995Sbostic /*- 250995Sbostic * Copyright (c) 1990 The Regents of the University of California. 350995Sbostic * All rights reserved. 450995Sbostic * 550995Sbostic * %sccs.include.redist.c% 650995Sbostic */ 750995Sbostic 850995Sbostic #if defined(LIBC_SCCS) && !defined(lint) 9*51087Sbostic static char sccsid[] = "@(#)rec_close.c 5.2 (Berkeley) 09/11/91"; 1050995Sbostic #endif /* LIBC_SCCS and not lint */ 1150995Sbostic 1250995Sbostic #include <sys/param.h> 1350995Sbostic #include <sys/uio.h> 1450995Sbostic #include <errno.h> 1550995Sbostic #include <db.h> 1650995Sbostic #include <unistd.h> 1750995Sbostic #include <stdio.h> 18*51087Sbostic #include "recno.h" 1950995Sbostic 2050995Sbostic /* 2150995Sbostic * __REC_CLOSE -- Close a recno tree. 2250995Sbostic * 2350995Sbostic * Parameters: 2450995Sbostic * dbp: pointer to access method 2550995Sbostic * 2650995Sbostic * Returns: 2750995Sbostic * RET_ERROR, RET_SUCCESS 2850995Sbostic */ 2950995Sbostic int 3050995Sbostic __rec_close(dbp) 3150995Sbostic DB *dbp; 3250995Sbostic { 3350995Sbostic if (__rec_sync(dbp) == RET_ERROR) 3450995Sbostic return (RET_ERROR); 3550995Sbostic return (__bt_close(dbp)); 3650995Sbostic } 3750995Sbostic 3850995Sbostic /* 3950995Sbostic * __REC_SYNC -- sync the recno tree to disk. 4050995Sbostic * 4150995Sbostic * Parameters: 4250995Sbostic * dbp: pointer to access method 4350995Sbostic * 4450995Sbostic * Returns: 4550995Sbostic * RET_SUCCESS, RET_ERROR. 4650995Sbostic * 4750995Sbostic * XXX 4850995Sbostic * Currently don't handle a key marked for deletion when the tree is synced. 4950995Sbostic * Should copy the page and write it out instead of the real page. 5050995Sbostic */ 5150995Sbostic int 5250995Sbostic __rec_sync(dbp) 5350995Sbostic const DB *dbp; 5450995Sbostic { 5550995Sbostic struct iovec iov[2]; 5650995Sbostic BTREE *t; 5750995Sbostic DBT data, key; 58*51087Sbostic off_t off; 5950995Sbostic recno_t scursor; 6050995Sbostic int status; 6150995Sbostic 6250995Sbostic t = dbp->internal; 6350995Sbostic 6450995Sbostic if (ISSET(t, BTF_INMEM) || NOTSET(t, BTF_MODIFIED)) 6550995Sbostic return (RET_SUCCESS); 6650995Sbostic 6750995Sbostic if (ISSET(t, BTF_RDONLY)) { 6850995Sbostic errno = EPERM; 6950995Sbostic return (RET_ERROR); 7050995Sbostic } 7150995Sbostic 7250995Sbostic /* Suck any remaining records into the tree. */ 7350995Sbostic if (t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 7450995Sbostic return (RET_ERROR); 7550995Sbostic 7650995Sbostic /* Rewind the file descriptor. */ 7750995Sbostic if (lseek(t->bt_rfd, 0L, SEEK_SET) != 0L) 7850995Sbostic return (RET_ERROR); 7950995Sbostic 8050995Sbostic iov[1].iov_base = "\n"; 8150995Sbostic iov[1].iov_len = 1; 8250995Sbostic scursor = t->bt_rcursor; 8350995Sbostic 8450995Sbostic status = (dbp->seq)(dbp, &key, &data, R_FIRST); 8550995Sbostic while (status == RET_SUCCESS) { 8650995Sbostic iov[0].iov_base = data.data; 8750995Sbostic iov[0].iov_len = data.size; 8850995Sbostic if (writev(t->bt_rfd, iov, 2) != data.size + 1) 8950995Sbostic return (RET_ERROR); 9050995Sbostic status = (dbp->seq)(dbp, &key, &data, R_NEXT); 9150995Sbostic } 9250995Sbostic t->bt_rcursor = scursor; 93*51087Sbostic if (status == RET_ERROR) 94*51087Sbostic return (RET_ERROR); 95*51087Sbostic if ((off = lseek(t->bt_rfd, 0L, SEEK_CUR)) == -1) 96*51087Sbostic return (RET_ERROR); 97*51087Sbostic if (ftruncate(t->bt_rfd, off)) 98*51087Sbostic return (RET_ERROR); 99*51087Sbostic UNSET(t, BTF_MODIFIED); 100*51087Sbostic return (RET_SUCCESS); 10150995Sbostic } 102