Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / src / untrusted / nacl / sys_private.c
1 /*
2  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 /*
8  * This file defines various POSIX-like functions directly using NaCl
9  * syscall trampolines.  For normal application use, these are defined
10  * instead using the IRT function tables.  Here we're defining the versions
11  * to be used inside the IRT itself, and in various local tests that do not
12  * use the IRT.
13  *
14  * We define these all in one file so that we can be sure that we get
15  * them all defined here and won't have any stragglers brought in from
16  * the normal C libraries, where we'd get the IRT-based versions instead.
17  * Since the first thing in the link (../stubs/crt1.x) forces a reference
18  * to _exit, we can be sure that this file will be brought in first.
19  */
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <sched.h>
24 #include <stdarg.h>
25 #include <stdint.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include <sys/types.h>
29 #include <sys/mman.h>
30
31 #include "native_client/src/include/elf32.h"
32 #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h"
33
34 struct dirent;
35 struct stat;
36 struct timeval;
37 struct timespec;
38
39 static int errno_call(int error) {
40   if (error) {
41     errno = -error;
42     return -1;
43   }
44   return 0;
45 }
46
47 static int errno_value_call(int rv) {
48   if (rv < 0) {
49     errno = -rv;
50     return -1;
51   }
52   return rv;
53 }
54
55 void _exit(int status) {
56   NACL_SYSCALL(exit)(status);
57   while (1) *(volatile int *) 0 = 0;  /* Crash.  */
58 }
59
60 int gettimeofday(struct timeval *tv, void *tz) {
61   return errno_call(NACL_SYSCALL(gettimeofday)(tv, NULL));
62 }
63
64 clock_t clock(void) {
65   return NACL_SYSCALL(clock)();
66 }
67
68 int nanosleep(const struct timespec *req, struct timespec *rem) {
69   return errno_call(NACL_GC_WRAP_SYSCALL(NACL_SYSCALL(nanosleep)(req, rem)));
70 }
71
72 int clock_getres(clockid_t clk_id, struct timespec *res) {
73   return errno_call(NACL_SYSCALL(clock_getres)(clk_id, res));
74 }
75
76 int clock_gettime(clockid_t clk_id, struct timespec *tp) {
77   return errno_call(NACL_SYSCALL(clock_gettime)(clk_id, tp));
78 }
79
80 int sched_yield(void) {
81   return errno_call(NACL_GC_WRAP_SYSCALL(NACL_SYSCALL(sched_yield)()));
82 }
83
84 long int sysconf(int name) {
85   int value;
86   int error = NACL_SYSCALL(sysconf)(name, &value);
87   if (error < 0) {
88     errno = -error;
89     return -1L;
90   }
91   return value;
92 }
93
94 void *mmap(void *start, size_t length, int prot, int flags,
95            int fd, off_t offset) {
96   uint32_t rv = (uintptr_t) NACL_SYSCALL(mmap)(start, length, prot, flags,
97                                                fd, &offset);
98   if ((uint32_t) rv > 0xffff0000u) {
99     errno = -(int32_t) rv;
100     return MAP_FAILED;
101   }
102   return (void *) (uintptr_t) rv;
103 }
104
105 int munmap(void *start, size_t length) {
106   return errno_call(NACL_SYSCALL(munmap)(start, length));
107 }
108
109 int mprotect(void *start, size_t length, int prot) {
110   return errno_call(NACL_SYSCALL(mprotect)(start, length, prot));
111 }
112
113 int open(char const *pathname, int oflag, ...) {
114   mode_t cmode;
115   va_list ap;
116
117   if (oflag & O_CREAT) {
118     va_start(ap, oflag);
119     cmode = va_arg(ap, mode_t);
120     va_end(ap);
121   } else {
122     cmode = 0;
123   }
124
125   return errno_value_call(NACL_GC_WRAP_SYSCALL(
126       NACL_SYSCALL(open)(pathname, oflag, cmode)));
127 }
128
129 int close(int fd) {
130   return errno_call(NACL_SYSCALL(close)(fd));
131 }
132
133 int read(int fd, void *buf, size_t count) {
134   return errno_value_call(NACL_GC_WRAP_SYSCALL(
135       NACL_SYSCALL(read)(fd, buf, count)));
136 }
137
138 int write(int fd, const void *buf, size_t count) {
139   return errno_value_call(NACL_GC_WRAP_SYSCALL(
140       NACL_SYSCALL(write)(fd, buf, count)));
141 }
142
143 int pread(int fd, void *buf, size_t count, off_t offset) {
144   return errno_value_call(NACL_GC_WRAP_SYSCALL(
145       NACL_SYSCALL(pread)(fd, buf, count, &offset)));
146 }
147
148 int pwrite(int fd, const void *buf, size_t count, off_t offset) {
149   return errno_value_call(NACL_GC_WRAP_SYSCALL(
150       NACL_SYSCALL(pwrite)(fd, buf, count, &offset)));
151 }
152
153 off_t lseek(int fd, off_t offset, int whence) {
154   int error = NACL_SYSCALL(lseek)(fd, &offset, whence);
155   if (error) {
156     errno = -error;
157     return -1;
158   }
159   return offset;
160 }
161
162 int dup(int fd) {
163   return errno_value_call(NACL_SYSCALL(dup)(fd));
164 }
165
166 int dup2(int oldfd, int newfd) {
167   return errno_value_call(NACL_SYSCALL(dup2)(oldfd, newfd));
168 }
169
170 int fstat(int fd, struct stat *st) {
171   return errno_call(NACL_SYSCALL(fstat)(fd, st));
172 }
173
174 int stat(const char *file, struct stat *st) {
175   return errno_call(NACL_SYSCALL(stat)(file, st));
176 }
177
178 int getdents(int fd, struct dirent *buf, size_t count) {
179   return errno_value_call(NACL_GC_WRAP_SYSCALL(
180       NACL_SYSCALL(getdents)(fd, buf, count)));
181 }
182
183 int isatty(int fd) {
184   int result = NACL_SYSCALL(isatty)(fd);
185   if (result < 0) {
186     errno = -result;
187     return 0;
188   }
189   return result;
190 }
191
192 int getpid(void) {
193   return errno_value_call(NACL_SYSCALL(getpid)());
194 }
195
196 int mkdir(const char *path, int mode) {
197   return errno_call(NACL_SYSCALL(mkdir)(path, mode));
198 }
199
200 int rmdir(const char *path) {
201   return errno_call(NACL_SYSCALL(rmdir)(path));
202 }
203
204 int chdir(const char *path) {
205   return errno_call(NACL_SYSCALL(chdir)(path));
206 }
207
208 char *getcwd(char *buffer, size_t len) {
209   int retval = NACL_SYSCALL(getcwd)(buffer, len);
210   if (retval != 0) {
211     errno = -retval;
212     return NULL;
213   }
214
215   return buffer;
216 }
217
218 int unlink(const char *path) {
219   return errno_call(NACL_SYSCALL(unlink)(path));
220 }
221
222 int truncate(const char *path, off_t length) {
223   return errno_call(NACL_SYSCALL(truncate)(path, &length));
224 }
225
226 int lstat(const char *file, struct stat *st) {
227   return errno_call(NACL_SYSCALL(lstat)(file, st));
228 }
229
230 int link(const char *oldpath, const char *newpath) {
231   return errno_call(NACL_SYSCALL(link)(oldpath, newpath));
232 }
233
234 int rename(const char *oldpath, const char* newpath) {
235   return errno_call(NACL_SYSCALL(rename)(oldpath, newpath));
236 }
237
238 int symlink(const char *oldpath, const char* newpath) {
239   return errno_call(NACL_SYSCALL(symlink)(oldpath, newpath));
240 }
241
242 int chmod(const char *path, mode_t mode) {
243   return errno_call(NACL_SYSCALL(chmod)(path, mode));
244 }
245
246 int access(const char *path, int amode) {
247   return errno_call(NACL_SYSCALL(access)(path, amode));
248 }
249
250 int readlink(const char *path, char *buf, int bufsize) {
251   return errno_value_call(NACL_SYSCALL(readlink)(path, buf, bufsize));
252 }
253
254 int utimes(const char *path, const struct timeval times[2]) {
255   return errno_value_call(NACL_SYSCALL(utimes)(path, times));
256 }
257
258 /*
259  * This is a stub since _start will call it but we don't want to
260  * do the normal initialization.
261  */
262 void __libnacl_irt_init(Elf32_auxv_t *auxv) {
263 }
264
265 /*
266  * These have to be weak because the IRT defines its own versions.
267  */
268 __attribute__((weak)) int nacl_tls_init(void *thread_ptr) {
269   return -NACL_SYSCALL(tls_init)(thread_ptr);
270 }
271
272 __attribute__((weak)) void *nacl_tls_get(void) {
273   return NACL_SYSCALL(tls_get)();
274 }