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

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1997, 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_open.c,v 11.21 2001/01/11 18:19:53 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. #endif
  16. #include "db_int.h"
  17. #ifdef HAVE_QNX
  18. static int __os_region_open __P((DB_ENV *, const char *, int, int, DB_FH *));
  19. #endif
  20. /*
  21.  * __os_open --
  22.  * Open a file.
  23.  *
  24.  * PUBLIC: int __os_open __P((DB_ENV *, const char *, u_int32_t, int, DB_FH *));
  25.  */
  26. int
  27. __os_open(dbenv, name, flags, mode, fhp)
  28. DB_ENV *dbenv;
  29. const char *name;
  30. u_int32_t flags;
  31. int mode;
  32. DB_FH *fhp;
  33. {
  34. int oflags, ret;
  35. oflags = 0;
  36. #if defined(O_BINARY)
  37. /*
  38.  * If there's a binary-mode open flag, set it, we never want any
  39.  * kind of translation.  Some systems do translations by default,
  40.  * e.g., with Cygwin, the default mode for an open() is set by the
  41.  * mode of the mount that underlies the file.
  42.  */
  43. oflags |= O_BINARY;
  44. #endif
  45. /*
  46.  * DB requires the POSIX 1003.1 semantic that two files opened at the
  47.  * same time with DB_OSO_CREATE/O_CREAT and DB_OSO_EXCL/O_EXCL flags
  48.  * set return an EEXIST failure in at least one.
  49.  */
  50. if (LF_ISSET(DB_OSO_CREATE))
  51. oflags |= O_CREAT;
  52. if (LF_ISSET(DB_OSO_EXCL))
  53. oflags |= O_EXCL;
  54. #if defined(O_DSYNC) && defined(XXX_NEVER_SET)
  55. /*
  56.  * !!!
  57.  * We should get better performance if we push the log files to disk
  58.  * immediately instead of waiting for the sync.  However, Solaris
  59.  * (and likely any other system based on the 4BSD filesystem releases),
  60.  * doesn't implement O_DSYNC correctly, only flushing data blocks and
  61.  * not inode or indirect blocks.
  62.  */
  63. if (LF_ISSET(DB_OSO_LOG))
  64. oflags |= O_DSYNC;
  65. #endif
  66. if (LF_ISSET(DB_OSO_RDONLY))
  67. oflags |= O_RDONLY;
  68. else
  69. oflags |= O_RDWR;
  70. if (LF_ISSET(DB_OSO_TRUNC))
  71. oflags |= O_TRUNC;
  72. #ifdef HAVE_QNX
  73. if (LF_ISSET(DB_OSO_REGION))
  74. return (__os_region_open(dbenv, name, oflags, mode, fhp));
  75. #endif
  76. /* Open the file. */
  77. if ((ret = __os_openhandle(dbenv, name, oflags, mode, fhp)) != 0)
  78. return (ret);
  79. /*
  80.  * Delete any temporary file.
  81.  *
  82.  * !!!
  83.  * There's a race here, where we've created a file and we crash before
  84.  * we can unlink it.  Temporary files aren't common in DB, regardless,
  85.  * it's not a security problem because the file is empty.  There's no
  86.  * reasonable way to avoid the race (playing signal games isn't worth
  87.  * the portability nightmare), so we just live with it.
  88.  */
  89. if (LF_ISSET(DB_OSO_TEMP))
  90. (void)__os_unlink(dbenv, name);
  91. return (0);
  92. }
  93. #ifdef HAVE_QNX
  94. /*
  95.  * __os_region_open --
  96.  * Open a shared memory region file using POSIX shm_open.
  97.  */
  98. static int
  99. __os_region_open(dbenv, name, oflags, mode, fhp)
  100. DB_ENV *dbenv;
  101. const char *name;
  102. int oflags;
  103. int mode;
  104. DB_FH *fhp;
  105. {
  106. int ret;
  107. char *newname;
  108. if ((ret = __os_shmname(dbenv, name, &newname)) != 0)
  109. goto err;
  110. memset(fhp, 0, sizeof(*fhp));
  111. fhp->fd = shm_open(newname, oflags, mode);
  112. if (fhp->fd == -1)
  113. ret = __os_get_errno();
  114. else {
  115. #ifdef HAVE_FCNTL_F_SETFD
  116. /* Deny file descriptor acces to any child process. */
  117. if (fcntl(fhp->fd, F_SETFD, 1) == -1) {
  118. ret = __os_get_errno();
  119. __db_err(dbenv, "fcntl(F_SETFD): %s", strerror(ret));
  120. __os_closehandle(fhp);
  121. } else
  122. #endif
  123. F_SET(fhp, DB_FH_VALID);
  124. }
  125. /*
  126.  * Once we have created the object, we don't need the name
  127.  * anymore.  Other callers of this will convert themselves.
  128.  */
  129. err:
  130. if (newname != NULL)
  131. __os_free(newname, 0);
  132. return (ret);
  133. }
  134. /*
  135.  * __os_shmname --
  136.  * Translate a pathname into a shm_open memory object name.
  137.  *
  138.  * PUBLIC: int __os_shmname __P((DB_ENV *, const char *, char **));
  139.  */
  140. int
  141. __os_shmname(dbenv, name, newnamep)
  142. DB_ENV *dbenv;
  143. const char *name;
  144. char **newnamep;
  145. {
  146. int ret;
  147. size_t size;
  148. char *p, *q, *tmpname;
  149. *newnamep = NULL;
  150. /*
  151.  * POSIX states that the name for a shared memory object
  152.  * may begin with a slash '/' and support for subsequent
  153.  * slashes is implementation-dependent.  The one implementation
  154.  * we know of right now, QNX, forbids subsequent slashes.
  155.  * We don't want to be parsing pathnames for '.' and '..' in
  156.  * the middle.  In order to allow easy conversion, just take
  157.  * the last component as the shared memory name.  This limits
  158.  * the namespace a bit, but makes our job a lot easier.
  159.  *
  160.  * We should not be modifying user memory, so we use our own.
  161.  * Caller is responsible for freeing the memory we give them.
  162.  */
  163. if ((ret = __os_strdup(dbenv, name, &tmpname)) != 0)
  164. return (ret);
  165. /*
  166.  * Skip over filename component.
  167.  * We set that separator to '' so that we can do another
  168.  * __db_rpath.  However, we immediately set it then to ':'
  169.  * so that we end up with the tailing directory:filename.
  170.  * We require a home directory component.  Return an error
  171.  * if there isn't one.
  172.  */
  173. p = __db_rpath(tmpname);
  174. if (p == NULL)
  175. return (EINVAL);
  176. if (p != tmpname) {
  177. *p = '';
  178. q = p;
  179. p = __db_rpath(tmpname);
  180. *q = ':';
  181. }
  182. if (p != NULL) {
  183. /*
  184.  * If we have a path component, copy and return it.
  185.  */
  186. ret = __os_strdup(dbenv, p, newnamep);
  187. __os_free(tmpname, 0);
  188. return (ret);
  189. }
  190. /*
  191.  * We were given just a directory name with no path components.
  192.  * Add a leading slash, and copy the remainder.
  193.  */
  194. size = strlen(tmpname) + 2;
  195. if ((ret = __os_malloc(dbenv, size, NULL, &p)) != 0)
  196. return (ret);
  197. p[0] = '/';
  198. memcpy(&p[1], tmpname, size-1);
  199. __os_free(tmpname, 0);
  200. *newnamep = p;
  201. return (0);
  202. }
  203. #endif