OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2015 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 #include <fcntl.h> |
| 7 #include <sys/stat.h> |
| 8 #include <unistd.h> |
| 9 #include <limits.h> |
| 10 #include <dirent.h> |
| 11 #include <errno.h> |
| 12 #include <stdlib.h> |
| 13 #include <stdio.h> |
| 14 |
| 15 // xgetcwd is pulled from toybox lib/xwrap.c |
| 16 static char *xgetcwd(void) { |
| 17 char *buf = (char*)malloc(sizeof(char) * (PATH_MAX+1)); |
| 18 if (buf == NULL) { |
| 19 fprintf(stderr, "malloc failed\n"); |
| 20 exit(1); |
| 21 } |
| 22 buf = getcwd(buf, PATH_MAX+1); |
| 23 if (!buf) { |
| 24 perror("xgetcwd"); |
| 25 exit(1); |
| 26 } |
| 27 return buf; |
| 28 } |
| 29 |
| 30 // The following functions are pulled from toybox nacl.patch |
| 31 #define _AT_WRAP_START(A) \ |
| 32 int fchdir_err = 0; \ |
| 33 char *save = xgetcwd(); \ |
| 34 if (!save) { \ |
| 35 perror("fd_wrapper_"A); \ |
| 36 exit(1); \ |
| 37 } \ |
| 38 if (dirfd != AT_FDCWD) { \ |
| 39 fchdir_err = fchdir(dirfd); \ |
| 40 if (fchdir_err == -1) \ |
| 41 perror("fchdir"); \ |
| 42 } |
| 43 |
| 44 #define _AT_WRAP_END(A) \ |
| 45 if (dirfd != AT_FDCWD) chdir(save); \ |
| 46 free(save); |
| 47 |
| 48 int openat(int dirfd, const char *pathname, int flags, ...) { |
| 49 _AT_WRAP_START("openat") |
| 50 printf("New dir is: %s\n", xgetcwd()); |
| 51 int fd = open(pathname, flags); |
| 52 _AT_WRAP_END("openat") |
| 53 return fd; |
| 54 } |
| 55 |
| 56 int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags) { |
| 57 // We are going to ignore flags here. |
| 58 //if (flags) perror_exit("fstatat_flags"); |
| 59 _AT_WRAP_START("fstatat") |
| 60 int result; |
| 61 if (flags & AT_SYMLINK_NOFOLLOW) |
| 62 result = lstat(pathname, buf); |
| 63 else |
| 64 result = stat(pathname, buf); |
| 65 _AT_WRAP_END("fstatat") |
| 66 return result; |
| 67 } |
| 68 |
| 69 int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags) { |
| 70 // We are going to ignore flags here. |
| 71 //if (flags) perror_exit("fchmodat_flags"); |
| 72 _AT_WRAP_START("fchmodat") |
| 73 int result = chmod(pathname, mode); |
| 74 _AT_WRAP_END("fchmodat") |
| 75 return result; |
| 76 } |
| 77 |
| 78 int readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) { |
| 79 _AT_WRAP_START("readlinkat") |
| 80 int result = readlink(pathname, buf, bufsiz); |
| 81 _AT_WRAP_END("readlinkat") |
| 82 return result; |
| 83 } |
| 84 |
| 85 int unlinkat(int dirfd, const char *pathname, int flags) { |
| 86 // We are going to ignore flags here. |
| 87 //if (flags) perror_exit("unlinkat_flags"); |
| 88 _AT_WRAP_START("unlinkat") |
| 89 int result; |
| 90 if(flags & AT_REMOVEDIR) { |
| 91 result = rmdir(pathname); |
| 92 } else { |
| 93 result = unlink(pathname); |
| 94 } |
| 95 _AT_WRAP_END("unlinkat") |
| 96 return result; |
| 97 } |
| 98 |
| 99 int faccessat(int dirfd, const char *pathname, int mode, int flags) { |
| 100 //if (flags) perror_exit("faccessat_flags"); |
| 101 _AT_WRAP_START("faccessat") |
| 102 int result = access(pathname, mode); |
| 103 _AT_WRAP_END("faccessat") |
| 104 return result; |
| 105 } |
| 106 |
| 107 DIR *fdopendir(int dirfd) { |
| 108 _AT_WRAP_START("fdopendir") |
| 109 DIR *dir; |
| 110 if (fchdir_err) { |
| 111 perror("fdopendir: "); |
| 112 } |
| 113 dir = opendir("."); |
| 114 _AT_WRAP_END("fdopendir") |
| 115 return dir; |
| 116 } |
| 117 |
| 118 int mkdirat(int dirfd, const char *pathname, mode_t mode) { |
| 119 _AT_WRAP_START("mkdirat") |
| 120 int result = mkdir(pathname, mode); |
| 121 _AT_WRAP_END("mkdirat") |
| 122 return result; |
| 123 } |
| 124 |
| 125 int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev) { |
| 126 fprintf(stderr, "mknod not supported\n"); |
| 127 return 1; |
| 128 } |
| 129 |
| 130 int fchownat(int dirfd, const char *pathname, uid_t owner, |
| 131 gid_t group, int flags) { |
| 132 _AT_WRAP_START("fchownat") |
| 133 int result = chown(pathname, owner, group); |
| 134 _AT_WRAP_END("fchownat") |
| 135 return result; |
| 136 } |
| 137 |
| 138 int symlinkat(const char *oldpath, int dirfd, const char *newpath) { |
| 139 _AT_WRAP_START("symlinkat") |
| 140 int result = symlink(oldpath, newpath); |
| 141 _AT_WRAP_END("symlinkat") |
| 142 return result; |
| 143 } |
| 144 |
| 145 int linkat(int olddirfd, const char *oldpath, |
| 146 int newdirfd, const char *newpath, int flags) { |
| 147 int result; |
| 148 if ((oldpath[0] == '/') && (newpath[0] == '/')) { |
| 149 result = link(oldpath, newpath); |
| 150 } else { |
| 151 errno = EINVAL; |
| 152 result = -1; |
| 153 } |
| 154 // We do not support double linking. |
| 155 return result; |
| 156 } |
OLD | NEW |