os_handle.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1998-2002
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: os_handle.c,v 11.28 2002/07/12 18:56:50 bostic Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <fcntl.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16. #endif
  17. #include "db_int.h"
  18. /*
  19.  * __os_openhandle --
  20.  * Open a file, using POSIX 1003.1 open flags.
  21.  *
  22.  * PUBLIC: int __os_openhandle __P((DB_ENV *, const char *, int, int, DB_FH *));
  23.  */
  24. int
  25. __os_openhandle(dbenv, name, flags, mode, fhp)
  26. DB_ENV *dbenv;
  27. const char *name;
  28. int flags, mode;
  29. DB_FH *fhp;
  30. {
  31. int ret, nrepeat;
  32. #ifdef HAVE_VXWORKS
  33. int newflags;
  34. #endif
  35. memset(fhp, 0, sizeof(*fhp));
  36. /* If the application specified an interface, use it. */
  37. if (DB_GLOBAL(j_open) != NULL) {
  38. if ((fhp->fd = DB_GLOBAL(j_open)(name, flags, mode)) == -1)
  39. return (__os_get_errno());
  40. F_SET(fhp, DB_FH_VALID);
  41. return (0);
  42. }
  43. for (nrepeat = 1; nrepeat < 4; ++nrepeat) {
  44. ret = 0;
  45. #ifdef HAVE_VXWORKS
  46. /*
  47.  * VxWorks does not support O_CREAT on open, you have to use
  48.  * creat() instead.  (It does not support O_EXCL or O_TRUNC
  49.  * either, even though they are defined "for future support".)
  50.  * We really want the POSIX behavior that if O_CREAT is set,
  51.  * we open if it exists, or create it if it doesn't exist.
  52.  * If O_CREAT is specified, single thread and try to open the
  53.  * file.  If successful, and O_EXCL return EEXIST.  If
  54.  * unsuccessful call creat and then end single threading.
  55.  */
  56. if (LF_ISSET(O_CREAT)) {
  57. DB_BEGIN_SINGLE_THREAD;
  58. newflags = flags & ~(O_CREAT | O_EXCL);
  59. if ((fhp->fd =
  60.     open(name, newflags, mode)) != -1) {
  61. if (LF_ISSET(O_EXCL)) {
  62. /*
  63.  * If we get here, we want O_EXCL
  64.  * create, and it exists.  Close and
  65.  * return EEXISTS.
  66.  */
  67. (void)close(fhp->fd);
  68. DB_END_SINGLE_THREAD;
  69. return (EEXIST);
  70. }
  71. /*
  72.  * XXX
  73.  * Assume any error means non-existence.
  74.  * Unfortunately return values (even for
  75.  * non-existence) are driver specific so
  76.  * there is no single error we can use to
  77.  * verify we truly got the equivalent of
  78.  * ENOENT.
  79.  */
  80. } else
  81. fhp->fd = creat(name, newflags);
  82. DB_END_SINGLE_THREAD;
  83. } else
  84. /* FALLTHROUGH */
  85. #endif
  86. #ifdef __VMS
  87. /*
  88.  * !!!
  89.  * Open with full sharing on VMS.
  90.  *
  91.  * We use these flags because they are the ones set by the VMS
  92.  * CRTL mmap() call when it opens a file, and we have to be
  93.  * able to open files that mmap() has previously opened, e.g.,
  94.  * when we're joining already existing DB regions.
  95.  */
  96. fhp->fd = open(name, flags, mode, "shr=get,put,upd,del,upi");
  97. #else
  98. fhp->fd = open(name, flags, mode);
  99. #endif
  100. if (fhp->fd == -1) {
  101. /*
  102.  * If it's a "temporary" error, we retry up to 3 times,
  103.  * waiting up to 12 seconds.  While it's not a problem
  104.  * if we can't open a database, an inability to open a
  105.  * log file is cause for serious dismay.
  106.  */
  107. ret = __os_get_errno();
  108. if (ret == ENFILE || ret == EMFILE || ret == ENOSPC) {
  109. (void)__os_sleep(dbenv, nrepeat * 2, 0);
  110. continue;
  111. }
  112. /*
  113.  * If it was an EINTR it's reasonable to retry
  114.  * immediately, and arbitrarily often.
  115.  */
  116. if (ret == EINTR) {
  117. --nrepeat;
  118. continue;
  119. }
  120. } else {
  121. #if defined(HAVE_FCNTL_F_SETFD)
  122. /* Deny file descriptor access to any child process. */
  123. if (fcntl(fhp->fd, F_SETFD, FD_CLOEXEC) == -1) {
  124. ret = __os_get_errno();
  125. __db_err(dbenv, "fcntl(F_SETFD): %s",
  126.     strerror(ret));
  127. (void)__os_closehandle(dbenv, fhp);
  128. } else
  129. #endif
  130. F_SET(fhp, DB_FH_VALID);
  131. }
  132. break;
  133. }
  134. return (ret);
  135. }
  136. /*
  137.  * __os_closehandle --
  138.  * Close a file.
  139.  *
  140.  * PUBLIC: int __os_closehandle __P((DB_ENV *, DB_FH *));
  141.  */
  142. int
  143. __os_closehandle(dbenv, fhp)
  144. DB_ENV *dbenv;
  145. DB_FH *fhp;
  146. {
  147. int ret;
  148. /* Don't close file descriptors that were never opened. */
  149. DB_ASSERT(F_ISSET(fhp, DB_FH_VALID) && fhp->fd != -1);
  150. do {
  151. ret = DB_GLOBAL(j_close) != NULL ?
  152.     DB_GLOBAL(j_close)(fhp->fd) : close(fhp->fd);
  153. } while (ret != 0 && (ret = __os_get_errno()) == EINTR);
  154. /* Unlink the file if we haven't already done so. */
  155. if (F_ISSET(fhp, DB_FH_UNLINK)) {
  156. (void)__os_unlink(dbenv, fhp->name);
  157. (void)__os_free(dbenv, fhp->name);
  158. }
  159. /*
  160.  * Smash the POSIX file descriptor -- it's never tested, but we want
  161.  * to catch any mistakes.
  162.  */
  163. fhp->fd = -1;
  164. F_CLR(fhp, DB_FH_VALID);
  165. return (ret);
  166. }