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 <signal.h>
00017 #include <string.h>
00018 #endif
00019
00020 #include "db_int.h"
00021
00022
00023
00024
00025
00026
00027
00028 int
00029 __os_have_direct()
00030 {
00031 return (1);
00032 }
00033
00034
00035
00036
00037
00038 __os_open(dbenv, name, flags, mode, fhpp)
00039 DB_ENV *dbenv;
00040 const char *name;
00041 u_int32_t flags;
00042 int mode;
00043 DB_FH **fhpp;
00044 {
00045 return (__os_open_extend(dbenv, name, 0, flags, mode, fhpp));
00046 }
00047
00048
00049
00050
00051
00052 int
00053 __os_open_extend(dbenv, name, page_size, flags, mode, fhpp)
00054 DB_ENV *dbenv;
00055 const char *name;
00056 u_int32_t page_size, flags;
00057 int mode;
00058 DB_FH **fhpp;
00059 {
00060 DB_FH *fhp;
00061 DWORD cluster_size, sector_size, free_clusters, total_clusters;
00062 int access, attr, createflag, nrepeat, oflags, ret, share;
00063 _TCHAR *drive, *tname;
00064 _TCHAR dbuf[4];
00065
00066 fhp = NULL;
00067 tname = NULL;
00068
00069 #define OKFLAGS \
00070 (DB_OSO_ABSMODE | DB_OSO_CREATE | DB_OSO_DIRECT | DB_OSO_DSYNC |\
00071 DB_OSO_EXCL | DB_OSO_RDONLY | DB_OSO_REGION | DB_OSO_SEQ | \
00072 DB_OSO_TEMP | DB_OSO_TRUNC)
00073 if ((ret = __db_fchk(dbenv, "__os_open", flags, OKFLAGS)) != 0)
00074 return (ret);
00075
00076
00077
00078
00079
00080
00081 if (DB_GLOBAL(j_open) != NULL) {
00082 oflags = O_BINARY | O_NOINHERIT;
00083
00084 if (LF_ISSET(DB_OSO_CREATE))
00085 oflags |= O_CREAT;
00086 #ifdef O_DSYNC
00087 if (LF_ISSET(DB_OSO_DSYNC))
00088 oflags |= O_DSYNC;
00089 #endif
00090
00091 if (LF_ISSET(DB_OSO_EXCL))
00092 oflags |= O_EXCL;
00093
00094 if (LF_ISSET(DB_OSO_RDONLY))
00095 oflags |= O_RDONLY;
00096 else
00097 oflags |= O_RDWR;
00098
00099 if (LF_ISSET(DB_OSO_SEQ))
00100 oflags |= _O_SEQUENTIAL;
00101 else
00102 oflags |= _O_RANDOM;
00103
00104 if (LF_ISSET(DB_OSO_TEMP))
00105 oflags |= _O_TEMPORARY;
00106
00107 if (LF_ISSET(DB_OSO_TRUNC))
00108 oflags |= O_TRUNC;
00109
00110 return (__os_openhandle(dbenv, name, oflags, mode, fhpp));
00111 }
00112
00113 TO_TSTRING(dbenv, name, tname, ret);
00114 if (ret != 0)
00115 goto err;
00116
00117 if ((ret = __os_calloc(dbenv, 1, sizeof(DB_FH), &fhp)) != 0)
00118 goto err;
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 access = GENERIC_READ;
00137 if (!LF_ISSET(DB_OSO_RDONLY))
00138 access |= GENERIC_WRITE;
00139
00140 share = FILE_SHARE_READ | FILE_SHARE_WRITE;
00141 if (__os_is_winnt())
00142 share |= FILE_SHARE_DELETE;
00143 attr = FILE_ATTRIBUTE_NORMAL;
00144
00145
00146
00147
00148
00149 if (LF_ISSET(DB_OSO_CREATE) && LF_ISSET(DB_OSO_EXCL))
00150 createflag = CREATE_NEW;
00151 else if (!LF_ISSET(DB_OSO_CREATE) && LF_ISSET(DB_OSO_TRUNC))
00152 createflag = TRUNCATE_EXISTING;
00153 else if (LF_ISSET(DB_OSO_TRUNC))
00154 createflag = CREATE_ALWAYS;
00155 else if (LF_ISSET(DB_OSO_CREATE))
00156 createflag = OPEN_ALWAYS;
00157 else
00158 createflag = OPEN_EXISTING;
00159
00160 if (LF_ISSET(DB_OSO_DSYNC)) {
00161 F_SET(fhp, DB_FH_NOSYNC);
00162 attr |= FILE_FLAG_WRITE_THROUGH;
00163 }
00164
00165 if (LF_ISSET(DB_OSO_SEQ))
00166 attr |= FILE_FLAG_SEQUENTIAL_SCAN;
00167 else
00168 attr |= FILE_FLAG_RANDOM_ACCESS;
00169
00170 if (LF_ISSET(DB_OSO_TEMP))
00171 attr |= FILE_FLAG_DELETE_ON_CLOSE;
00172
00173
00174
00175
00176
00177
00178
00179 if (LF_ISSET(DB_OSO_DIRECT) && page_size != 0 && name[0] != '\0') {
00180 if (name[1] == ':') {
00181 drive = dbuf;
00182 _sntprintf(dbuf, sizeof(dbuf), _T("%c:\\"), tname[0]);
00183 } else
00184 drive = NULL;
00185
00186
00187
00188
00189
00190 if (GetDiskFreeSpace(drive, &cluster_size,
00191 §or_size, &free_clusters, &total_clusters) &&
00192 page_size % sector_size == 0)
00193 attr |= FILE_FLAG_NO_BUFFERING;
00194 }
00195
00196 for (nrepeat = 1;; ++nrepeat) {
00197 fhp->handle =
00198 CreateFile(tname, access, share, NULL, createflag, attr, 0);
00199 if (fhp->handle == INVALID_HANDLE_VALUE) {
00200
00201
00202
00203
00204
00205
00206 ret = __os_get_errno();
00207 if ((ret != ENFILE && ret != EMFILE && ret != ENOSPC) ||
00208 nrepeat > 3)
00209 goto err;
00210
00211 __os_sleep(dbenv, nrepeat * 2, 0);
00212 } else
00213 break;
00214 }
00215
00216 FREE_STRING(dbenv, tname);
00217
00218 F_SET(fhp, DB_FH_OPENED);
00219 *fhpp = fhp;
00220 return (0);
00221
00222 err: if (ret == 0)
00223 ret = __os_get_errno();
00224
00225 FREE_STRING(dbenv, tname);
00226 if (fhp != NULL)
00227 (void)__os_closehandle(dbenv, fhp);
00228 return (ret);
00229 }