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*58748Sbostic static char sccsid[] = "@(#)rec_close.c 5.9 (Berkeley) 03/19/93"; 1050995Sbostic #endif /* LIBC_SCCS and not lint */ 1150995Sbostic 1257462Sbostic #include <sys/types.h> 1350995Sbostic #include <sys/uio.h> 14*58748Sbostic #include <sys/mman.h> 1556754Sbostic 1650995Sbostic #include <errno.h> 1757462Sbostic #include <limits.h> 1856754Sbostic #include <stdio.h> 1950995Sbostic #include <unistd.h> 2056754Sbostic 2157933Sbostic #include <db.h> 2251087Sbostic #include "recno.h" 2350995Sbostic 2450995Sbostic /* 2550995Sbostic * __REC_CLOSE -- Close a recno tree. 2650995Sbostic * 2750995Sbostic * Parameters: 2850995Sbostic * dbp: pointer to access method 2950995Sbostic * 3050995Sbostic * Returns: 3150995Sbostic * RET_ERROR, RET_SUCCESS 3250995Sbostic */ 3350995Sbostic int 3450995Sbostic __rec_close(dbp) 3550995Sbostic DB *dbp; 3650995Sbostic { 3754280Sbostic BTREE *t; 3854280Sbostic int rval; 3954280Sbostic 4050995Sbostic if (__rec_sync(dbp) == RET_ERROR) 4150995Sbostic return (RET_ERROR); 4254280Sbostic 4354280Sbostic /* Committed to closing. */ 4454280Sbostic t = dbp->internal; 4554280Sbostic 46*58748Sbostic rval = RET_SUCCESS; 47*58748Sbostic if (ISSET(t, BTF_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize)) 48*58748Sbostic rval = RET_ERROR; 49*58748Sbostic 50*58748Sbostic if (!ISSET(t, BTF_RINMEM) && 51*58748Sbostic ISSET(t, BTF_CLOSEFP) ? fclose(t->bt_rfp) : close(t->bt_rfd)) 52*58748Sbostic rval = RET_ERROR; 53*58748Sbostic 5454280Sbostic if (__bt_close(dbp) == RET_ERROR) 55*58748Sbostic rval = RET_ERROR; 5654280Sbostic 57*58748Sbostic return (rval); 5850995Sbostic } 5950995Sbostic 6050995Sbostic /* 6150995Sbostic * __REC_SYNC -- sync the recno tree to disk. 6250995Sbostic * 6350995Sbostic * Parameters: 6450995Sbostic * dbp: pointer to access method 6550995Sbostic * 6650995Sbostic * Returns: 6750995Sbostic * RET_SUCCESS, RET_ERROR. 6850995Sbostic */ 6950995Sbostic int 7050995Sbostic __rec_sync(dbp) 7150995Sbostic const DB *dbp; 7250995Sbostic { 7350995Sbostic struct iovec iov[2]; 7450995Sbostic BTREE *t; 7550995Sbostic DBT data, key; 7651087Sbostic off_t off; 7755312Sbostic recno_t scursor, trec; 7850995Sbostic int status; 7950995Sbostic 8050995Sbostic t = dbp->internal; 8150995Sbostic 8256754Sbostic if (ISSET(t, BTF_RDONLY | BTF_RINMEM) || !ISSET(t, BTF_MODIFIED)) 8350995Sbostic return (RET_SUCCESS); 8450995Sbostic 8556702Sbostic /* Read any remaining records into the tree. */ 86*58748Sbostic if (!ISSET(t, BTF_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 8750995Sbostic return (RET_ERROR); 8850995Sbostic 8950995Sbostic /* Rewind the file descriptor. */ 9056702Sbostic if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0) 9150995Sbostic return (RET_ERROR); 9250995Sbostic 9350995Sbostic iov[1].iov_base = "\n"; 9450995Sbostic iov[1].iov_len = 1; 9550995Sbostic scursor = t->bt_rcursor; 9650995Sbostic 9755312Sbostic key.size = sizeof(recno_t); 9855312Sbostic key.data = &trec; 9955312Sbostic 10050995Sbostic status = (dbp->seq)(dbp, &key, &data, R_FIRST); 10150995Sbostic while (status == RET_SUCCESS) { 10250995Sbostic iov[0].iov_base = data.data; 10350995Sbostic iov[0].iov_len = data.size; 10450995Sbostic if (writev(t->bt_rfd, iov, 2) != data.size + 1) 10550995Sbostic return (RET_ERROR); 10650995Sbostic status = (dbp->seq)(dbp, &key, &data, R_NEXT); 10750995Sbostic } 10850995Sbostic t->bt_rcursor = scursor; 10951087Sbostic if (status == RET_ERROR) 11051087Sbostic return (RET_ERROR); 111*58748Sbostic if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1) 11251087Sbostic return (RET_ERROR); 11351087Sbostic if (ftruncate(t->bt_rfd, off)) 11451087Sbostic return (RET_ERROR); 11556754Sbostic CLR(t, BTF_MODIFIED); 11651087Sbostic return (RET_SUCCESS); 11750995Sbostic } 118