1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/errno.h> 28 #include <sys/fcntl.h> 29 #include <sys/stat.h> 30 #include <sys/vnode.h> 31 #include <sys/vfs.h> 32 #include <sys/time.h> 33 #include <sys/systm.h> 34 #include <sys/debug.h> 35 36 extern int openat(int, char *, int, int); 37 extern int renameat(int, char *, int, char *); 38 extern int unlinkat(int, char *, int); 39 extern int fchownat(int, char *, uid_t, gid_t, int); 40 extern int fstatat(int, char *, struct stat *, int); 41 extern int futimesat(int, char *, struct timeval *); 42 extern int faccessat(int, char *, int, int); 43 extern int openattrdirat(int, char *); 44 #if defined(_SYSCALL32_IMPL) || defined(_ILP32) 45 extern int fstatat64_32(int, char *, struct stat64_32 *, int); 46 extern int fstatat32(int, char *, struct stat32 *, int); 47 extern int openat32(int, char *, int, int); 48 extern int fstatat64(int, char *, struct stat64 *, int); 49 extern int openat64(int, char *, int, int); 50 extern int fstatat64_32(int, char *, struct stat64_32 *, int); 51 #endif 52 53 54 /* 55 * Handle all of the *at system calls 56 * 57 * subcodes: 58 * 0 - openat 59 * 1 - openat64 60 * 2 - fstatat64 61 * 3 - fstatat 62 * 4 - fchownat 63 * 5 - unlinkat 64 * 6 - futimesat 65 * 7 - renameat 66 * 8 - faccessat 67 * 9 - openattrdirat 68 * 69 * The code for handling the at functionality exists in the file where the 70 * base syscall is defined. For example openat is in open.c 71 */ 72 73 #if defined(_SYSCALL32_IMPL) || defined(_ILP32) 74 75 int 76 fsat32(int code, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, 77 uintptr_t arg4, uintptr_t arg5) 78 { 79 switch (code) { 80 81 case 0: /* openat */ 82 #if defined(_LP64) 83 return (openat32((int)arg1, (char *)arg2, 84 (int)arg3, (int)arg4)); 85 #else 86 return (openat((int)arg1, (char *)arg2, 87 (int)arg3, (int)arg4)); 88 #endif 89 case 1: /* openat64 */ 90 return (openat64((int)arg1, (char *)arg2, 91 (int)arg3, (int)arg4)); 92 case 2: /* fstatat64 */ 93 #if defined(_LP64) 94 return (fstatat64_32((int)arg1, (char *)arg2, 95 (struct stat64_32 *)arg3, (int)arg4)); 96 #else 97 return (fstatat64((int)arg1, (char *)arg2, 98 (struct stat64 *)arg3, (int)arg4)); 99 #endif 100 case 3: /* fstatat */ 101 #if defined(_LP64) 102 return (fstatat32((int)arg1, (char *)arg2, 103 (struct stat32 *)arg3, (int)arg4)); 104 #else 105 return (fstatat((int)arg1, (char *)arg2, 106 (struct stat *)arg3, (int)arg4)); 107 #endif 108 case 4: /* fchownat */ 109 return (fchownat((int)arg1, (char *)arg2, 110 (uid_t)arg3, (gid_t)arg4, (int)arg5)); 111 case 5: /* unlinkat */ 112 return (unlinkat((int)arg1, (char *)arg2, (int)arg3)); 113 case 6: /* futimesat */ 114 return (futimesat((int)arg1, 115 (char *)arg2, (struct timeval *)arg3)); 116 case 7: /* renameat */ 117 return (renameat((int)arg1, (char *)arg2, (int)arg3, 118 (char *)arg4)); 119 case 8: /* faccessat */ 120 return (faccessat((int)arg1, (char *)arg2, (int)arg3, 121 (int)arg4)); 122 case 9: /* openattrdirat */ 123 return (openattrdirat((int)arg1, (char *)arg2)); 124 default: 125 return (set_errno(EINVAL)); 126 } 127 } 128 129 #endif 130 131 /* 132 * For 64 kernels, use fsat64 133 */ 134 135 #if defined(_LP64) 136 137 int 138 fsat64(int code, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, 139 uintptr_t arg4, uintptr_t arg5) 140 { 141 switch (code) { 142 143 case 0: /* openat */ 144 return (openat((int)arg1, (char *)arg2, 145 (int)arg3, (int)arg4)); 146 case 1: /* openat64 */ 147 return (set_errno(ENOSYS)); 148 case 2: /* fstatat64 */ 149 return (set_errno(ENOSYS)); 150 case 3: /* fstatat */ 151 return (fstatat((int)arg1, (char *)arg2, 152 (struct stat *)arg3, (int)arg4)); 153 case 4: /* fchownat */ 154 return (fchownat((int)arg1, (char *)arg2, 155 (uid_t)arg3, (gid_t)arg4, (int)arg5)); 156 case 5: /* unlinkat */ 157 return (unlinkat((int)arg1, (char *)arg2, (int)arg3)); 158 case 6: /* futimesat */ 159 return (futimesat((int)arg1, 160 (char *)arg2, (struct timeval *)arg3)); 161 case 7: /* renameat */ 162 return (renameat((int)arg1, (char *)arg2, (int)arg3, 163 (char *)arg4)); 164 case 8: /* faccessat */ 165 return (faccessat((int)arg1, (char *)arg2, (int)arg3, 166 (int)arg4)); 167 case 9: /* openattrdirat */ 168 return (openattrdirat((int)arg1, (char *)arg2)); 169 default: 170 return (set_errno(EINVAL)); 171 } 172 } 173 #endif 174