1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// The entire file is wrapped in this #if. We do this so this .cc file can be 6// compiled, even on a non-Windows build. 7#if defined(WIN32) 8 9#include "nacl_io/kernel_wrap.h" 10#include <errno.h> 11#include <fcntl.h> 12#include <stdarg.h> 13#include <stdlib.h> 14#include <string.h> 15#include <sys/types.h> // This must be included before <sys/stat.h>. 16#include <sys/stat.h> 17#include "nacl_io/kernel_intercept.h" 18 19#include <windows.h> 20 21namespace { 22 23template <typename SrcStat, typename DstStat> 24void CopyStat(const SrcStat* src, DstStat* dst) { 25 memset(dst, 0, sizeof(DstStat)); 26 dst->st_dev = src->st_dev; 27 dst->st_ino = src->st_ino; 28 dst->st_mode = src->st_mode; 29 dst->st_nlink = src->st_nlink; 30 dst->st_uid = src->st_uid; 31 dst->st_gid = src->st_gid; 32 dst->st_rdev = src->st_rdev; 33 dst->st_size = src->st_size; 34 dst->st_atime = src->st_atime; 35 dst->st_mtime = src->st_mtime; 36 dst->st_ctime = src->st_ctime; 37} 38 39} // namespace 40 41EXTERN_C_BEGIN 42 43// This needs to be included because it is defined in read.c, which we wish to 44// override. Define with dummy values for now... though this seems like it will 45// break ftelli64/fgetpos/fstream. 46char _lookuptrailbytes[256] = {0}; 47 48int _access(const char* path, int amode) { 49 return ki_access(path, amode); 50} 51 52int _chdir(const char* path) { 53 return ki_chdir(path); 54} 55 56int _chmod(const char* path, mode_t mode) { 57 return ki_chmod(path, mode); 58} 59 60int _close(int fd) { 61 return ki_close(fd); 62} 63 64int _close_nolock(int fd) { 65 return ki_close(fd); 66} 67 68int _dup(int oldfd) { 69 return ki_dup(oldfd); 70} 71 72int _dup2(int oldfd, int newfd) { 73 return ki_dup2(oldfd, newfd); 74} 75 76int _fstat32(int fd, struct _stat32* buf) { 77 struct stat ki_buf; 78 int res = ki_fstat(fd, &ki_buf); 79 CopyStat(&ki_buf, buf); 80 return res; 81} 82 83int _fstat64(int fd, struct _stat64* buf) { 84 struct stat ki_buf; 85 int res = ki_fstat(fd, &ki_buf); 86 CopyStat(&ki_buf, buf); 87 return res; 88} 89 90int _fstat32i64(int fd, struct _stat32i64* buf) { 91 struct stat ki_buf; 92 int res = ki_fstat(fd, &ki_buf); 93 CopyStat(&ki_buf, buf); 94 return res; 95} 96 97int _fstat64i32(int fd, struct _stat64i32* buf) { 98 struct stat ki_buf; 99 int res = ki_fstat(fd, &ki_buf); 100 CopyStat(&ki_buf, buf); 101 return res; 102} 103 104char* _getcwd(char* buf, int size) { 105 return ki_getcwd(buf, size); 106} 107 108int _isatty(int fd) { 109 return ki_isatty(fd); 110} 111 112off_t _lseek(int fd, off_t offset, int whence) { 113 return ki_lseek(fd, offset, whence); 114} 115 116int _mkdir(const char* path) { 117 return ki_mkdir(path, 0777); 118} 119 120int _open(const char* path, int oflag, ...) { 121#if 0 122 // TODO(binji): ki_open should use the pmode parameter. When it does, this 123 // will be necessary to add in. 124 va_list list; 125 int pmode = 0; 126 if (oflag & _O_CREAT) { 127 va_start(list, oflag); 128 pmode = va_arg(list, int); 129 va_end(list); 130 } 131#endif 132 return ki_open(path, oflag); 133} 134 135int _sopen(const char* path, int oflag, int shflag) { 136 return ki_open(path, oflag); 137} 138 139errno_t _sopen_s(int* pfh, const char* path, int oflag, int shflag, int pmode) { 140 *pfh = ki_open(path, oflag); 141 return (*pfh < 0) ? errno : 0; 142} 143 144int _read(int fd, void* buf, size_t nbyte) { 145 if (!ki_is_initialized()) 146 return 0; 147 148 return ki_read(fd, buf, nbyte); 149} 150 151int _read_nolock(int fd, void* buf, size_t nbyte) { 152 if (!ki_is_initialized()) 153 return 0; 154 155 return ki_read(fd, buf, nbyte); 156} 157 158int _rmdir(const char* path) { 159 return ki_rmdir(path); 160} 161 162int setenv(const char* name, const char* value, int overwrite) { 163 if (0 == overwrite && NULL != getenv(name)) { 164 return 0; 165 } 166 errno_t result = _putenv_s(name, value); 167 if (result != 0) { 168 errno = result; 169 return -1; 170 } else { 171 return 0; 172 } 173} 174 175int _stat32(const char* path, struct _stat32* buf) { 176 struct stat ki_buf; 177 int res = ki_stat(path, &ki_buf); 178 CopyStat(&ki_buf, buf); 179 return res; 180} 181 182int _stat64(const char* path, struct _stat64* buf) { 183 struct stat ki_buf; 184 int res = ki_stat(path, &ki_buf); 185 CopyStat(&ki_buf, buf); 186 return res; 187} 188 189int _stat64i32(const char* path, struct _stat64i32* buf) { 190 struct stat ki_buf; 191 int res = ki_stat(path, &ki_buf); 192 CopyStat(&ki_buf, buf); 193 return res; 194} 195 196int _stat32i64(const char* path, struct _stat32i64* buf) { 197 struct stat ki_buf; 198 int res = ki_stat(path, &ki_buf); 199 CopyStat(&ki_buf, buf); 200 return res; 201} 202 203int _unlink(const char* path) { 204 return ki_unlink(path); 205} 206 207int _utime(const char* filename, const struct utimbuf* times) { 208 return ki_utime(filename, times); 209} 210 211int _write(int fd, const void* buf, size_t nbyte) { 212 if (!ki_is_initialized()) 213 return 0; 214 215 return ki_write(fd, buf, nbyte); 216} 217 218 219// "real" functions, i.e. the unwrapped original functions. On Windows we don't 220// wrap, so the real functions aren't accessible. In most cases, we just fail. 221 222int _real_close(int fd) { 223 return ENOSYS; 224} 225 226int _real_fstat(int fd, struct stat *buf) { 227 return 0; 228} 229 230int _real_getdents(int fd, void* nacl_buf, size_t nacl_count, size_t *nread) { 231 return ENOSYS; 232} 233 234int _real_lseek(int fd, off_t offset, int whence, off_t* new_offset) { 235 return ENOSYS; 236} 237 238int _real_mkdir(const char* pathname, mode_t mode) { 239 return ENOSYS; 240} 241 242int _real_mmap(void** addr, size_t length, int prot, int flags, int fd, 243 off_t offset) { 244 return ENOSYS; 245} 246 247int _real_munmap(void* addr, size_t length) { 248 return ENOSYS; 249} 250 251int _real_open(const char* pathname, int oflag, mode_t cmode, int* newfd) { 252 return ENOSYS; 253} 254 255int _real_open_resource(const char* file, int* fd) { 256 return ENOSYS; 257} 258 259int _real_read(int fd, void *buf, size_t count, size_t *nread) { 260 *nread = count; 261 return 0; 262} 263 264int _real_rmdir(const char* pathname) { 265 return ENOSYS; 266} 267 268int _real_write(int fd, const void *buf, size_t count, size_t *nwrote) { 269 *nwrote = count; 270 return 0; 271} 272 273#define USECS_FROM_WIN_TO_TO_UNIX_EPOCH 11644473600000LL 274uint64_t usec_since_epoch() { 275 FILETIME ft; 276 ULARGE_INTEGER ularge; 277 GetSystemTimeAsFileTime(&ft); 278 279 ularge.LowPart = ft.dwLowDateTime; 280 ularge.HighPart = ft.dwHighDateTime; 281 282 // Truncate to usec resolution. 283 return ularge.QuadPart / 10; 284} 285 286// Do nothing for Windows, we replace the library at link time. 287void kernel_wrap_init() { 288} 289 290void kernel_wrap_uninit() { 291} 292 293EXTERN_C_END 294 295#endif // defined(WIN32) 296 297