00001
00002
00003
00004
00005
00006
00007
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
00023
00024
00025
00026
00027
00028 int
00029 __os_openhandle(dbenv, name, flags, mode, fhpp)
00030 DB_ENV *dbenv;
00031 const char *name;
00032 int flags, mode;
00033 DB_FH **fhpp;
00034 {
00035 DB_FH *fhp;
00036 u_int nrepeat, retries;
00037 int ret;
00038 #ifdef HAVE_VXWORKS
00039 int newflags;
00040 #endif
00041
00042 if ((ret = __os_calloc(dbenv, 1, sizeof(DB_FH), fhpp)) != 0)
00043 return (ret);
00044 fhp = *fhpp;
00045
00046
00047 if (DB_GLOBAL(j_open) != NULL) {
00048 if ((fhp->fd = DB_GLOBAL(j_open)(name, flags, mode)) == -1) {
00049 ret = __os_get_errno();
00050 goto err;
00051 }
00052 F_SET(fhp, DB_FH_OPENED);
00053 return (0);
00054 }
00055
00056 retries = 0;
00057 for (nrepeat = 1; nrepeat < 4; ++nrepeat) {
00058 ret = 0;
00059 #ifdef HAVE_VXWORKS
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 if (LF_ISSET(O_CREAT)) {
00071 DB_BEGIN_SINGLE_THREAD;
00072 newflags = flags & ~(O_CREAT | O_EXCL);
00073 if ((fhp->fd = open(name, newflags, mode)) != -1) {
00074
00075
00076
00077
00078
00079
00080 F_SET(fhp, DB_FH_OPENED);
00081 if (LF_ISSET(O_EXCL)) {
00082
00083
00084
00085
00086
00087 DB_END_SINGLE_THREAD;
00088 ret = EEXIST;
00089 goto err;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 } else
00101 fhp->fd = creat(name, newflags);
00102 DB_END_SINGLE_THREAD;
00103 } else
00104
00105 #endif
00106 #ifdef __VMS
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 fhp->fd = open(name, flags, mode, "shr=get,put,upd,del,upi");
00117 #else
00118 fhp->fd = open(name, flags, mode);
00119 #endif
00120 if (fhp->fd != -1) {
00121 F_SET(fhp, DB_FH_OPENED);
00122
00123 #if defined(HAVE_FCNTL_F_SETFD)
00124
00125 if (fcntl(fhp->fd, F_SETFD, 1) == -1) {
00126 ret = __os_get_errno();
00127 __db_err(dbenv,
00128 "fcntl(F_SETFD): %s", strerror(ret));
00129 goto err;
00130 }
00131 #endif
00132 break;
00133 }
00134
00135 switch (ret = __os_get_errno()) {
00136 case EMFILE:
00137 case ENFILE:
00138 case ENOSPC:
00139
00140
00141
00142
00143
00144
00145 __os_sleep(dbenv, nrepeat * 2, 0);
00146 break;
00147 case EAGAIN:
00148 case EBUSY:
00149 case EINTR:
00150
00151
00152
00153
00154 if (++retries < DB_RETRY)
00155 --nrepeat;
00156 break;
00157 default:
00158 break;
00159 }
00160 }
00161
00162 err: if (ret != 0) {
00163 (void)__os_closehandle(dbenv, fhp);
00164 *fhpp = NULL;
00165 }
00166
00167 return (ret);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 int
00177 __os_closehandle(dbenv, fhp)
00178 DB_ENV *dbenv;
00179 DB_FH *fhp;
00180 {
00181 int ret;
00182
00183 ret = 0;
00184
00185
00186
00187
00188
00189 if (F_ISSET(fhp, DB_FH_OPENED)) {
00190 if (DB_GLOBAL(j_close) != NULL)
00191 ret = DB_GLOBAL(j_close)(fhp->fd);
00192 else
00193 RETRY_CHK((close(fhp->fd)), ret);
00194
00195 if (ret != 0)
00196 __db_err(dbenv, "close: %s", strerror(ret));
00197
00198
00199 if (F_ISSET(fhp, DB_FH_UNLINK)) {
00200 (void)__os_unlink(dbenv, fhp->name);
00201 __os_free(dbenv, fhp->name);
00202 }
00203 }
00204
00205 __os_free(dbenv, fhp);
00206
00207 return (ret);
00208 }