1/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <portability.h>
18#include <unistd.h>
19#include <fcntl.h>
20#include <stdarg.h>
21#include <portability.h>
22#include <fcntl_portable.h>
23#include <filefd_portable.h>
24
25#define PORTABLE_TAG "open_portable"
26#include <log_portable.h>
27
28
29#if O_CREAT_PORTABLE==O_CREAT
30#error Bad build environment
31#endif
32
33
34static inline int open_flags_pton(int flags)
35{
36    int mipsflags = flags & O_ACCMODE_PORTABLE;
37
38    ALOGV("%s(flags:0x%x) {", __func__, flags);
39
40    if (flags & O_CREAT_PORTABLE)
41        mipsflags |= O_CREAT;
42    if (flags & O_EXCL_PORTABLE)
43        mipsflags |= O_EXCL;
44    if (flags & O_NOCTTY_PORTABLE)
45        mipsflags |= O_NOCTTY;
46    if (flags & O_TRUNC_PORTABLE)
47        mipsflags |= O_TRUNC;
48    if (flags & O_APPEND_PORTABLE)
49        mipsflags |= O_APPEND;
50    if (flags & O_NONBLOCK_PORTABLE)
51        mipsflags |= O_NONBLOCK;
52    if (flags & O_SYNC_PORTABLE)
53        mipsflags |= O_SYNC;
54    if (flags & FASYNC_PORTABLE)
55        mipsflags |= FASYNC;
56    if (flags & O_DIRECT_PORTABLE)
57        mipsflags |= O_DIRECT;
58    if (flags & O_LARGEFILE_PORTABLE)
59        mipsflags |= O_LARGEFILE;
60    if (flags & O_DIRECTORY_PORTABLE)
61        mipsflags |= O_DIRECTORY;
62    if (flags & O_NOFOLLOW_PORTABLE)
63        mipsflags |= O_NOFOLLOW;
64    if (flags & O_NOATIME_PORTABLE)
65        mipsflags |= O_NOATIME;
66    if (flags & O_NDELAY_PORTABLE)
67        mipsflags |= O_NDELAY;
68
69    ALOGV("%s: return(mipsflags:0x%x); }", __func__, mipsflags);
70    return mipsflags;
71}
72
73
74extern int  __open(const char*, int, int);
75
76int WRAP(open)(const char *pathname, int flags, ...)
77{
78    mode_t  mode = 0;
79    int native_flags;
80    int fd;
81
82    ALOGV(" ");
83    ALOGV("%s(pathname:%p, flags:0x%x, ...) {", __func__,
84              pathname,    flags);
85
86    flags |= O_LARGEFILE_PORTABLE;
87
88    if (flags & O_CREAT_PORTABLE) {
89        va_list  args;
90
91        va_start(args, flags);
92        mode = (mode_t) va_arg(args, int);
93        va_end(args);
94    }
95
96    native_flags = open_flags_pton(flags);
97
98    fd = __open(pathname, native_flags, mode);
99    if (fd == -1) {
100        /* Can't print pathname as a string, might be bogus */
101        ALOGV("%s: fd = %d = __open(pathname:%p, native_flags:0x%x, mode:0x%x);", __func__,
102                   fd,              pathname,    native_flags,      mode);
103    } else {
104        if (flags & O_CLOEXEC) {
105            filefd_CLOEXEC_enabled(fd);
106        } else {
107            filefd_CLOEXEC_disabled(fd);
108        }
109    }
110    ALOGV("%s: return(fd:%d); }", __func__, fd);
111    return fd;
112}
113
114
115extern int  __openat(int, const char*, int, int);
116
117int WRAP(openat)(int dirfd, const char *pathname, int flags, ...)
118{
119    mode_t  mode = 0;
120    int native_flags;
121    int fd;
122
123    ALOGV(" ");
124    ALOGV("%s(dirfd:%d, pathname:0x%p, flags:0x%x, ...) {", __func__,
125              dirfd,    pathname,      flags);
126
127    flags |= O_LARGEFILE_PORTABLE;
128
129    if (flags & O_CREAT_PORTABLE) {
130        va_list  args;
131
132        va_start(args, flags);
133        mode = (mode_t) va_arg(args, int);
134        va_end(args);
135    }
136
137    native_flags = open_flags_pton(flags);
138
139    fd = __openat(dirfd, pathname, native_flags, mode);
140
141    if (fd == -1) {
142        ALOGV("%s: fd = %d = __open(pathname:0x%p, native_flags:0x%x, mode:0x%d);", __func__,
143                   fd,              pathname,      native_flags,      mode);
144    } else {
145        if (flags & O_CLOEXEC) {
146            filefd_CLOEXEC_enabled(fd);
147        } else {
148            filefd_CLOEXEC_disabled(fd);
149        }
150    }
151    ALOGV("%s: return(fd:%d); }", __func__, fd);
152    return fd;
153}
154