2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997
5 * Sleepycat Software. All rights reserved.
11 static const char sccsid
[] = "@(#)db_err.c 10.18 (Sleepycat) 8/27/97";
14 #ifndef NO_SYSTEM_INCLUDES
15 #include <sys/types.h>
27 #include "common_ext.h"
29 static int __db_rdonly
__P((const DB_ENV
*, const char *));
33 * Standard DB error routine.
35 * PUBLIC: #ifdef __STDC__
36 * PUBLIC: void __db_err __P((const DB_ENV *dbenv, const char *fmt, ...));
38 * PUBLIC: void __db_err();
43 __db_err(const DB_ENV
*dbenv
, const char *fmt
, ...)
45 __db_err(dbenv
, fmt
, va_alist
)
52 char errbuf
[2048]; /* XXX: END OF THE STACK DON'T TRUST SPRINTF. */
62 if (dbenv
->db_errcall
!= NULL
) {
63 (void)vsnprintf(errbuf
, sizeof(errbuf
), fmt
, ap
);
64 dbenv
->db_errcall(dbenv
->db_errpfx
, errbuf
);
66 if (dbenv
->db_errfile
!= NULL
) {
67 if (dbenv
->db_errpfx
!= NULL
)
68 (void)fprintf(dbenv
->db_errfile
, "%s: ",
70 (void)vfprintf(dbenv
->db_errfile
, fmt
, ap
);
71 (void)fprintf(dbenv
->db_errfile
, "\n");
72 (void)fflush(dbenv
->db_errfile
);
79 * Provide ANSI C prototypes for the panic functions. Some compilers, (e.g.,
80 * MS VC 4.2) get upset if they aren't here, even though the K&R declaration
81 * appears before the assignment in the __db__panic() call.
83 static int __db_ecursor
__P((DB
*, DB_TXN
*, DBC
**));
84 static int __db_edel
__P((DB
*, DB_TXN
*, DBT
*, int));
85 static int __db_efd
__P((DB
*, int *));
86 static int __db_egp
__P((DB
*, DB_TXN
*, DBT
*, DBT
*, int));
87 static int __db_estat
__P((DB
*, void *, void *(*)(size_t), int));
88 static int __db_esync
__P((DB
*, int));
92 * After-panic cursor routine.
100 a
= a
; b
= b
; c
= c
; /* XXX: Shut the compiler up. */
107 * After-panic delete routine.
110 __db_edel(a
, b
, c
, d
)
116 a
= a
; b
= b
; c
= c
; d
= d
; /* XXX: Shut the compiler up. */
123 * After-panic fd routine.
130 a
= a
; b
= b
; /* XXX: Shut the compiler up. */
137 * After-panic get/put routine.
140 __db_egp(a
, b
, c
, d
, e
)
146 a
= a
; b
= b
; c
= c
; d
= d
; e
= e
; /* XXX: Shut the compiler up. */
153 * After-panic stat routine.
156 __db_estat(a
, b
, c
, d
)
159 void *(*c
) __P((size_t));
162 a
= a
; b
= b
; c
= c
; d
= d
; /* XXX: Shut the compiler up. */
169 * After-panic sync routine.
176 a
= a
; b
= b
; /* XXX: Shut the compiler up. */
183 * Lock out the tree due to unrecoverable error.
185 * PUBLIC: int __db_panic __P((DB *));
193 * We should shut down all of the process's cursors, too.
195 * We should call mpool and have it shut down the file, so we get
196 * other processes sharing this file as well.
198 dbp
->cursor
= __db_ecursor
;
199 dbp
->del
= __db_edel
;
203 dbp
->stat
= __db_estat
;
204 dbp
->sync
= __db_esync
;
209 /* Check for invalid flags. */
210 #undef DB_CHECK_FLAGS
211 #define DB_CHECK_FLAGS(dbenv, name, flags, ok_flags) \
212 if ((flags) & ~(ok_flags)) \
213 return (__db_ferr(dbenv, name, 0));
214 /* Check for invalid flag combinations. */
215 #undef DB_CHECK_FCOMBO
216 #define DB_CHECK_FCOMBO(dbenv, name, flags, flag1, flag2) \
217 if ((flags) & (flag1) && (flags) & (flag2)) \
218 return (__db_ferr(dbenv, name, 1));
222 * General flags checking routine.
224 * PUBLIC: int __db_fchk __P((DB_ENV *, const char *, int, int));
227 __db_fchk(dbenv
, name
, flags
, ok_flags
)
232 DB_CHECK_FLAGS(dbenv
, name
, flags
, ok_flags
);
238 * General combination flags checking routine.
240 * PUBLIC: int __db_fcchk __P((DB_ENV *, const char *, int, int, int));
243 __db_fcchk(dbenv
, name
, flags
, flag1
, flag2
)
246 int flags
, flag1
, flag2
;
248 DB_CHECK_FCOMBO(dbenv
, name
, flags
, flag1
, flag2
);
254 * Common cursor delete argument checking routine.
256 * PUBLIC: int __db_cdelchk __P((const DB *, int, int, int));
259 __db_cdelchk(dbp
, flags
, isrdonly
, isvalid
)
261 int flags
, isrdonly
, isvalid
;
263 /* Check for changes to a read-only tree. */
265 return (__db_rdonly(dbp
->dbenv
, "c_del"));
267 /* Check for invalid dbc->c_del() function flags. */
268 DB_CHECK_FLAGS(dbp
->dbenv
, "c_del", flags
, 0);
271 * The cursor must be initialized, return -1 for an invalid cursor,
274 return (isvalid
? 0 : EINVAL
);
279 * Common cursor get argument checking routine.
281 * PUBLIC: int __db_cgetchk __P((const DB *, DBT *, DBT *, int, int));
284 __db_cgetchk(dbp
, key
, data
, flags
, isvalid
)
293 /* Check for invalid dbc->c_get() function flags. */
307 if (!F_ISSET(dbp
, DB_BT_RECNUM
))
312 err
: return (__db_ferr(dbp
->dbenv
, "c_get", 0));
315 /* Check for invalid key/data flags. */
316 DB_CHECK_FLAGS(dbp
->dbenv
, "key", key
->flags
,
317 DB_DBT_MALLOC
| DB_DBT_USERMEM
| DB_DBT_PARTIAL
);
318 DB_CHECK_FLAGS(dbp
->dbenv
, "data", data
->flags
,
319 DB_DBT_MALLOC
| DB_DBT_USERMEM
| DB_DBT_PARTIAL
);
321 /* Check dbt's for valid flags when multi-threaded. */
322 if (F_ISSET(dbp
, DB_AM_THREAD
)) {
323 if (!F_ISSET(data
, DB_DBT_USERMEM
| DB_DBT_MALLOC
))
324 return (__db_ferr(dbp
->dbenv
, "threaded data", 1));
326 !F_ISSET(key
, DB_DBT_USERMEM
| DB_DBT_MALLOC
))
327 return (__db_ferr(dbp
->dbenv
, "threaded key", 1));
331 * The cursor must be initialized for DB_CURRENT, return -1 for an
332 * invalid cursor, otherwise 0.
334 return (isvalid
|| flags
!= DB_CURRENT
? 0 : EINVAL
);
339 * Common cursor put argument checking routine.
341 * PUBLIC: int __db_cputchk __P((const DB *,
342 * PUBLIC: const DBT *, DBT *, int, int, int));
345 __db_cputchk(dbp
, key
, data
, flags
, isrdonly
, isvalid
)
349 int flags
, isrdonly
, isvalid
;
353 /* Check for changes to a read-only tree. */
355 return (__db_rdonly(dbp
->dbenv
, "c_put"));
357 /* Check for invalid dbc->c_put() function flags. */
362 if (dbp
->type
== DB_RECNO
&& !F_ISSET(dbp
, DB_RE_RENUMBER
))
364 if (dbp
->type
!= DB_RECNO
&& !F_ISSET(dbp
, DB_AM_DUP
))
371 if (dbp
->type
== DB_RECNO
)
376 err
: return (__db_ferr(dbp
->dbenv
, "c_put", 0));
379 /* Check for invalid key/data flags. */
381 DB_CHECK_FLAGS(dbp
->dbenv
, "key", key
->flags
,
382 DB_DBT_MALLOC
| DB_DBT_USERMEM
| DB_DBT_PARTIAL
);
383 DB_CHECK_FLAGS(dbp
->dbenv
, "data", data
->flags
,
384 DB_DBT_MALLOC
| DB_DBT_USERMEM
| DB_DBT_PARTIAL
);
387 * The cursor must be initialized for anything other than DB_KEYFIRST
388 * and DB_KEYLAST, return -1 for an invalid cursor, otherwise 0.
391 (flags
!= DB_KEYFIRST
&& flags
!= DB_KEYLAST
) ? 0 : EINVAL
);
396 * Common delete argument checking routine.
398 * PUBLIC: int __db_delchk __P((const DB *, int, int));
401 __db_delchk(dbp
, flags
, isrdonly
)
405 /* Check for changes to a read-only tree. */
407 return (__db_rdonly(dbp
->dbenv
, "delete"));
409 /* Check for invalid db->del() function flags. */
410 DB_CHECK_FLAGS(dbp
->dbenv
, "delete", flags
, 0);
417 * Common get argument checking routine.
419 * PUBLIC: int __db_getchk __P((const DB *, const DBT *, DBT *, int));
422 __db_getchk(dbp
, key
, data
, flags
)
428 /* Check for invalid db->get() function flags. */
429 DB_CHECK_FLAGS(dbp
->dbenv
,
430 "get", flags
, F_ISSET(dbp
, DB_BT_RECNUM
) ? DB_SET_RECNO
: 0);
432 /* Check for invalid key/data flags. */
433 DB_CHECK_FLAGS(dbp
->dbenv
, "key", key
->flags
, 0);
434 DB_CHECK_FLAGS(dbp
->dbenv
, "data", data
->flags
,
435 DB_DBT_MALLOC
| DB_DBT_USERMEM
| DB_DBT_PARTIAL
);
436 DB_CHECK_FCOMBO(dbp
->dbenv
,
437 "data", data
->flags
, DB_DBT_MALLOC
, DB_DBT_USERMEM
);
438 if (F_ISSET(dbp
, DB_AM_THREAD
) &&
439 !F_ISSET(data
, DB_DBT_MALLOC
| DB_DBT_USERMEM
))
440 return (__db_ferr(dbp
->dbenv
, "threaded data", 1));
447 * Common put argument checking routine.
449 * PUBLIC: int __db_putchk __P((const DB *, DBT *, const DBT *, int, int, int));
452 __db_putchk(dbp
, key
, data
, flags
, isrdonly
, isdup
)
456 int flags
, isrdonly
, isdup
;
458 /* Check for changes to a read-only tree. */
460 return (__db_rdonly(dbp
->dbenv
, "put"));
462 /* Check for invalid db->put() function flags. */
463 DB_CHECK_FLAGS(dbp
->dbenv
, "put", flags
,
464 DB_NOOVERWRITE
| (dbp
->type
== DB_RECNO
? DB_APPEND
: 0));
466 /* Check for invalid key/data flags. */
467 DB_CHECK_FLAGS(dbp
->dbenv
, "key", key
->flags
, 0);
468 DB_CHECK_FLAGS(dbp
->dbenv
, "data", data
->flags
,
469 DB_DBT_MALLOC
| DB_DBT_USERMEM
| DB_DBT_PARTIAL
);
470 DB_CHECK_FCOMBO(dbp
->dbenv
,
471 "data", data
->flags
, DB_DBT_MALLOC
, DB_DBT_USERMEM
);
473 /* Check for partial puts in the presence of duplicates. */
474 if (isdup
&& F_ISSET(data
, DB_DBT_PARTIAL
)) {
476 "a partial put in the presence of duplicates requires a cursor operation");
484 * Common stat argument checking routine.
486 * PUBLIC: int __db_statchk __P((const DB *, int));
489 __db_statchk(dbp
, flags
)
493 /* Check for invalid db->stat() function flags. */
494 DB_CHECK_FLAGS(dbp
->dbenv
, "stat", flags
, DB_RECORDCOUNT
);
496 if (LF_ISSET(DB_RECORDCOUNT
) &&
497 dbp
->type
== DB_BTREE
&& !F_ISSET(dbp
, DB_BT_RECNUM
))
498 return (__db_ferr(dbp
->dbenv
, "stat", 0));
505 * Common sync argument checking routine.
507 * PUBLIC: int __db_syncchk __P((const DB *, int));
510 __db_syncchk(dbp
, flags
)
514 /* Check for invalid db->sync() function flags. */
515 DB_CHECK_FLAGS(dbp
->dbenv
, "sync", flags
, 0);
522 * Common flag errors.
524 * PUBLIC: int __db_ferr __P((const DB_ENV *, const char *, int));
527 __db_ferr(dbenv
, name
, combo
)
532 __db_err(dbenv
, "illegal flag %sspecified to %s",
533 combo
? "combination " : "", name
);
539 * Common readonly message.
542 __db_rdonly(dbenv
, name
)
546 __db_err(dbenv
, "%s: attempt to modify a read-only tree", name
);