os_handle.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1998, 1999, 2000
  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.19 2000/11/30 00:58:42 ubell 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. #include "os_jump.h"
  19. /*
  20.  * __os_openhandle --
  21.  * Open a file, using POSIX 1003.1 open flags.
  22.  *
  23.  * PUBLIC: int __os_openhandle __P((DB_ENV *, const char *, int, int, DB_FH *));
  24.  */
  25. int
  26. __os_openhandle(dbenv, name, flags, mode, fhp)
  27. DB_ENV *dbenv;
  28. const char *name;
  29. int flags, mode;
  30. DB_FH *fhp;
  31. {
  32. int ret, nrepeat;
  33. #ifdef HAVE_VXWORKS
  34. int newflags;
  35. #endif
  36. memset(fhp, 0, sizeof(*fhp));
  37. /* If the application specified an interface, use it. */
  38. if (__db_jump.j_open != NULL) {
  39. if ((fhp->fd = __db_jump.j_open(name, flags, mode)) == -1)
  40. return (__os_get_errno());
  41. F_SET(fhp, DB_FH_VALID);
  42. return (0);
  43. }
  44. for (ret = 0, nrepeat = 1; nrepeat < 4; ++nrepeat) {
  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.  * If O_EXCL is specified, single thread and try to open the
  51.  * file.  If successful, return EEXIST.  Otherwise, call creat
  52.  * and then end single threading.
  53.  */
  54. if (LF_ISSET(O_CREAT)) {
  55. DB_BEGIN_SINGLE_THREAD;
  56. newflags = flags & ~(O_CREAT | O_EXCL);
  57. if (LF_ISSET(O_EXCL)) {
  58. if ((fhp->fd =
  59.     open(name, newflags, mode)) != -1) {
  60. /*
  61.  * If we get here, we want O_EXCL
  62.  * create, and it exists.  Close and
  63.  * return EEXISTS.
  64.  */
  65. (void)close(fhp->fd);
  66. DB_END_SINGLE_THREAD;
  67. return (EEXIST);
  68. }
  69. /*
  70.  * XXX
  71.  * Assume any error means non-existence.
  72.  * Unfortunately return values (even for
  73.  * non-existence) are driver specific so
  74.  * there is no single error we can use to
  75.  * verify we truly got the equivalent of
  76.  * ENOENT.
  77.  */
  78. }
  79. fhp->fd = creat(name, newflags);
  80. DB_END_SINGLE_THREAD;
  81. } else
  82. /* FALLTHROUGH */
  83. #endif
  84. #ifdef __VMS
  85. /*
  86.  * !!!
  87.  * Open with full sharing on VMS.
  88.  *
  89.  * We use these flags because they are the ones set by the VMS
  90.  * CRTL mmap() call when it opens a file, and we have to be
  91.  * able to open files that mmap() has previously opened, e.g.,
  92.  * when we're joining already existing DB regions.
  93.  */
  94. fhp->fd = open(name, flags, mode, "shr=get,put,upd,del,upi");
  95. #else
  96. fhp->fd = open(name, flags, mode);
  97. #endif
  98. if (fhp->fd == -1) {
  99. /*
  100.  * If it's a "temporary" error, we retry up to 3 times,
  101.  * waiting up to 12 seconds.  While it's not a problem
  102.  * if we can't open a database, an inability to open a
  103.  * log file is cause for serious dismay.
  104.  */
  105. ret = __os_get_errno();
  106. if (ret == ENFILE || ret == EMFILE || ret == ENOSPC) {
  107. (void)__os_sleep(dbenv, nrepeat * 2, 0);
  108. continue;
  109. }
  110. } else {
  111. #if defined(HAVE_FCNTL_F_SETFD)
  112. /* Deny file descriptor access to any child process. */
  113. if (fcntl(fhp->fd, F_SETFD, 1) == -1) {
  114. ret = __os_get_errno();
  115. __db_err(dbenv, "fcntl(F_SETFD): %s",
  116.     strerror(ret));
  117. (void)__os_closehandle(fhp);
  118. } else
  119. #endif
  120. F_SET(fhp, DB_FH_VALID);
  121. }
  122. break;
  123. }
  124. return (ret);
  125. }
  126. /*
  127.  * __os_closehandle --
  128.  * Close a file.
  129.  *
  130.  * PUBLIC: int __os_closehandle __P((DB_FH *));
  131.  */
  132. int
  133. __os_closehandle(fhp)
  134. DB_FH *fhp;
  135. {
  136. int ret;
  137. /* Don't close file descriptors that were never opened. */
  138. DB_ASSERT(F_ISSET(fhp, DB_FH_VALID) && fhp->fd != -1);
  139. ret = __db_jump.j_close != NULL ?
  140.     __db_jump.j_close(fhp->fd) : close(fhp->fd);
  141. /*
  142.  * Smash the POSIX file descriptor -- it's never tested, but we want
  143.  * to catch any mistakes.
  144.  */
  145. fhp->fd = -1;
  146. F_CLR(fhp, DB_FH_VALID);
  147. return (ret == 0 ? 0 : __os_get_errno());
  148. }