~ubuntu-branches/ubuntu/edgy/rpm/edgy

« back to all changes in this revision

Viewing changes to db/os/DEBUG/os_open.c

  • Committer: Bazaar Package Importer
  • Author(s): Joey Hess
  • Date: 2002-01-22 20:56:57 UTC
  • Revision ID: james.westby@ubuntu.com-20020122205657-l74j50mr9z8ofcl5
Tags: upstream-4.0.3
ImportĀ upstreamĀ versionĀ 4.0.3

Show diffs side-by-side

added added

removed removed

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