1/* update.c - The routines for updating the file to a consistent state. */
2
3/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
4    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
5
6    GDBM is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GDBM is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GDBM; see the file COPYING.  If not, write to
18    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
20    You may contact the author by:
21       e-mail:  phil@cs.wwu.edu
22      us-mail:  Philip A. Nelson
23                Computer Science Department
24                Western Washington University
25                Bellingham, WA 98226
26
27*************************************************************************/
28
29
30/* include system configuration before all else. */
31#include "autoconf.h"
32
33#include "gdbmdefs.h"
34
35static void write_header __P((gdbm_file_info *));
36
37/* This procedure writes the header back to the file described by DBF. */
38
39static void
40write_header (dbf)
41     gdbm_file_info *dbf;
42{
43  int  num_bytes;	/* Return value for write. */
44  off_t file_pos;	/* Return value for lseek. */
45
46  file_pos = lseek (dbf->desc, 0L, L_SET);
47  if (file_pos != 0) _gdbm_fatal (dbf, "lseek error");
48  num_bytes = write (dbf->desc, dbf->header, dbf->header->block_size);
49  if (num_bytes != dbf->header->block_size)
50    _gdbm_fatal (dbf, "write error");
51
52  /* Wait for all output to be done. */
53  if (!dbf->fast_write)
54    fsync (dbf->desc);
55}
56
57
58/* After all changes have been made in memory, we now write them
59   all to disk. */
60void
61_gdbm_end_update (dbf)
62     gdbm_file_info *dbf;
63{
64  int  num_bytes;	/* Return value for write. */
65  off_t file_pos;	/* Return value for lseek. */
66
67
68  /* Write the current bucket. */
69  if (dbf->bucket_changed && (dbf->cache_entry != NULL))
70    {
71      _gdbm_write_bucket (dbf, dbf->cache_entry);
72      dbf->bucket_changed = FALSE;
73    }
74
75  /* Write the other changed buckets if there are any. */
76  if (dbf->second_changed)
77    {
78      if(dbf->bucket_cache != NULL)
79        {
80          register int index;
81
82          for (index = 0; index < dbf->cache_size; index++)
83	    {
84	      if (dbf->bucket_cache[index].ca_changed)
85	        _gdbm_write_bucket (dbf, &dbf->bucket_cache[index]);
86            }
87        }
88      dbf->second_changed = FALSE;
89    }
90
91  /* Write the directory. */
92  if (dbf->directory_changed)
93    {
94      file_pos = lseek (dbf->desc, dbf->header->dir, L_SET);
95      if (file_pos != dbf->header->dir) _gdbm_fatal (dbf, "lseek error");
96      num_bytes = write (dbf->desc, dbf->dir, dbf->header->dir_size);
97      if (num_bytes != dbf->header->dir_size)
98	_gdbm_fatal (dbf, "write error");
99      dbf->directory_changed = FALSE;
100      if (!dbf->header_changed && !dbf->fast_write)
101	fsync (dbf->desc);
102    }
103
104  /* Final write of the header. */
105  if (dbf->header_changed)
106    {
107      write_header (dbf);
108      dbf->header_changed = FALSE;
109    }
110}
111
112
113/* If a fatal error is detected, come here and exit. VAL tells which fatal
114   error occured. */
115
116void
117_gdbm_fatal (dbf, val)
118     gdbm_file_info *dbf;
119     char *val;
120{
121  if ((dbf != NULL) && (dbf->fatal_err != NULL))
122    (*dbf->fatal_err) (val);
123  else
124    {
125      write (STDERR_FILENO, "gdbm fatal: ", 12);
126      if (val != NULL)
127	write (STDERR_FILENO, val, strlen(val));
128      write (STDERR_FILENO, "\n", 1);
129    }
130  exit (1);
131  /* NOTREACHED */
132}
133