Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

os_handle.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1998-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: os_handle.c,v 12.3 2005/11/02 03:12:18 mjc Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <fcntl.h>
00016 #include <string.h>
00017 #endif
00018 
00019 #include "db_int.h"
00020 
00021 /*
00022  * __os_openhandle --
00023  *      Open a file, using POSIX 1003.1 open flags.
00024  */
00025 int
00026 __os_openhandle(dbenv, name, flags, mode, fhpp)
00027         DB_ENV *dbenv;
00028         const char *name;
00029         int flags, mode;
00030         DB_FH **fhpp;
00031 {
00032         DB_FH *fhp;
00033         int ret, nrepeat, retries;
00034 
00035         if ((ret = __os_calloc(dbenv, 1, sizeof(DB_FH), fhpp)) != 0)
00036                 return (ret);
00037         fhp = *fhpp;
00038 
00039         /* If the application specified an interface, use it. */
00040         if (DB_GLOBAL(j_open) != NULL) {
00041                 if ((fhp->fd = DB_GLOBAL(j_open)(name, flags, mode)) == -1) {
00042                         ret = __os_get_errno();
00043                         goto err;
00044                 }
00045                 F_SET(fhp, DB_FH_OPENED);
00046                 return (0);
00047         }
00048 
00049         retries = 0;
00050         for (nrepeat = 1; nrepeat < 4; ++nrepeat) {
00051                 ret = 0;
00052                 fhp->fd = _open(name, flags, mode);
00053 
00054                 if (fhp->fd != -1) {
00055                         F_SET(fhp, DB_FH_OPENED);
00056                         break;
00057                 }
00058 
00059                 switch (ret = __os_get_errno()) {
00060                 case EMFILE:
00061                 case ENFILE:
00062                 case ENOSPC:
00063                         /*
00064                          * If it's a "temporary" error, we retry up to 3 times,
00065                          * waiting up to 12 seconds.  While it's not a problem
00066                          * if we can't open a database, an inability to open a
00067                          * log file is cause for serious dismay.
00068                          */
00069                         __os_sleep(dbenv, nrepeat * 2, 0);
00070                         break;
00071                 case EAGAIN:
00072                 case EBUSY:
00073                 case EINTR:
00074                         /*
00075                          * If an EAGAIN, EBUSY or EINTR, retry immediately for
00076                          * DB_RETRY times.
00077                          */
00078                         if (++retries < DB_RETRY)
00079                                 --nrepeat;
00080                         break;
00081                 }
00082         }
00083 
00084 err:    if (ret != 0) {
00085                 (void)__os_closehandle(dbenv, fhp);
00086                 *fhpp = NULL;
00087         }
00088 
00089         return (ret);
00090 }
00091 
00092 /*
00093  * __os_closehandle --
00094  *      Close a file.
00095  */
00096 int
00097 __os_closehandle(dbenv, fhp)
00098         DB_ENV *dbenv;
00099         DB_FH *fhp;
00100 {
00101         int ret;
00102 
00103         ret = 0;
00104 
00105         /*
00106          * If we have a valid handle, close it and unlink any temporary
00107          * file.
00108          */
00109         if (F_ISSET(fhp, DB_FH_OPENED)) {
00110                 if (DB_GLOBAL(j_close) != NULL)
00111                         ret = DB_GLOBAL(j_close)(fhp->fd);
00112                 else if (fhp->handle != INVALID_HANDLE_VALUE)
00113                         RETRY_CHK((!CloseHandle(fhp->handle)), ret);
00114                 else
00115                         RETRY_CHK((_close(fhp->fd)), ret);
00116 
00117                 if (ret != 0)
00118                         __db_err(dbenv, "CloseHandle: %s", strerror(ret));
00119 
00120                 /* Unlink the file if we haven't already done so. */
00121                 if (F_ISSET(fhp, DB_FH_UNLINK)) {
00122                         (void)__os_unlink(dbenv, fhp->name);
00123                         __os_free(dbenv, fhp->name);
00124                 }
00125         }
00126 
00127         __os_free(dbenv, fhp);
00128 
00129         return (ret);
00130 }

Generated on Sun Dec 25 12:14:42 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2