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 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <unistd.h> 30 #include <fcntl.h> 31 #include <utime.h> 32 #include <errno.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <sys/time.h> 36 #include <sys/poll.h> 37 #include <sys/file.h> 38 #include <sys/syscall.h> 39 40 #include <s10_brand.h> 41 #include <s10_misc.h> 42 43 /* 44 * This file contains the emulation functions for all of the 45 * obsolete system call traps that existed in Solaris 10 but 46 * that have been deleted in the current version of Solaris. 47 */ 48 49 static int 50 s10_fstatat(sysret_t *rval, 51 int fd, const char *path, struct stat *sb, int flags) 52 { 53 return (__systemcall(rval, SYS_fstatat + 1024, 54 fd, path, sb, flags)); 55 } 56 57 int 58 s10_stat(sysret_t *rval, const char *path, struct stat *sb) 59 { 60 return (__systemcall(rval, SYS_fstatat + 1024, 61 AT_FDCWD, path, sb, 0)); 62 } 63 64 int 65 s10_lstat(sysret_t *rval, const char *path, struct stat *sb) 66 { 67 return (__systemcall(rval, SYS_fstatat + 1024, 68 AT_FDCWD, path, sb, AT_SYMLINK_NOFOLLOW)); 69 } 70 71 int 72 s10_fstat(sysret_t *rval, int filedes, struct stat *sb) 73 { 74 return (__systemcall(rval, SYS_fstatat + 1024, 75 filedes, NULL, sb, 0)); 76 } 77 78 #if !defined(_LP64) 79 80 static int 81 s10_fstatat64(sysret_t *rval, 82 int fd, const char *path, struct stat64 *sb, int flags) 83 { 84 return (__systemcall(rval, SYS_fstatat64 + 1024, 85 fd, path, sb, flags)); 86 } 87 88 int 89 s10_stat64(sysret_t *rval, const char *path, struct stat64 *sb) 90 { 91 return (__systemcall(rval, SYS_fstatat64 + 1024, 92 AT_FDCWD, path, sb, 0)); 93 } 94 95 int 96 s10_lstat64(sysret_t *rval, const char *path, struct stat64 *sb) 97 { 98 return (__systemcall(rval, SYS_fstatat64 + 1024, 99 AT_FDCWD, path, sb, AT_SYMLINK_NOFOLLOW)); 100 } 101 102 int 103 s10_fstat64(sysret_t *rval, int filedes, struct stat64 *sb) 104 { 105 return (__systemcall(rval, SYS_fstatat64 + 1024, 106 filedes, NULL, sb, 0)); 107 } 108 109 #endif /* !_LP64 */ 110 111 static int 112 s10_openat(sysret_t *rval, int fd, const char *path, int oflag, mode_t mode) 113 { 114 return (__systemcall(rval, SYS_openat + 1024, 115 fd, path, oflag, mode)); 116 } 117 118 int 119 s10_open(sysret_t *rval, char *path, int oflag, mode_t mode) 120 { 121 return (__systemcall(rval, SYS_openat + 1024, 122 AT_FDCWD, path, oflag, mode)); 123 } 124 125 int 126 s10_creat(sysret_t *rval, char *path, mode_t mode) 127 { 128 return (__systemcall(rval, SYS_openat + 1024, 129 AT_FDCWD, path, O_WRONLY | O_CREAT | O_TRUNC, mode)); 130 } 131 132 #if !defined(_LP64) 133 134 static int 135 s10_openat64(sysret_t *rval, int fd, const char *path, int oflag, mode_t mode) 136 { 137 return (__systemcall(rval, SYS_openat64 + 1024, 138 fd, path, oflag, mode)); 139 } 140 141 int 142 s10_open64(sysret_t *rval, char *path, int oflag, mode_t mode) 143 { 144 return (__systemcall(rval, SYS_openat64 + 1024, 145 AT_FDCWD, path, oflag, mode)); 146 } 147 148 int 149 s10_creat64(sysret_t *rval, char *path, mode_t mode) 150 { 151 return (__systemcall(rval, SYS_openat64 + 1024, 152 AT_FDCWD, path, O_WRONLY | O_CREAT | O_TRUNC, mode)); 153 } 154 155 #endif /* !_LP64 */ 156 157 int 158 s10_fork1(sysret_t *rval) 159 { 160 return (__systemcall(rval, SYS_forksys + 1024, 0, 0)); 161 } 162 163 int 164 s10_forkall(sysret_t *rval) 165 { 166 return (__systemcall(rval, SYS_forksys + 1024, 1, 0)); 167 } 168 169 int 170 s10_dup(sysret_t *rval, int fd) 171 { 172 return (__systemcall(rval, SYS_fcntl + 1024, fd, F_DUPFD, 0)); 173 } 174 175 int 176 s10_poll(sysret_t *rval, struct pollfd *fds, nfds_t nfd, int timeout) 177 { 178 timespec_t ts; 179 timespec_t *tsp; 180 181 if (timeout < 0) 182 tsp = NULL; 183 else { 184 ts.tv_sec = timeout / MILLISEC; 185 ts.tv_nsec = (timeout % MILLISEC) * MICROSEC; 186 tsp = &ts; 187 } 188 189 return (__systemcall(rval, SYS_pollsys + 1024, 190 fds, nfd, tsp, NULL)); 191 } 192 193 int 194 s10_lwp_mutex_lock(sysret_t *rval, void *mp) 195 { 196 return (__systemcall(rval, SYS_lwp_mutex_timedlock + 1024, 197 mp, NULL, 0)); 198 } 199 200 int 201 s10_lwp_sema_wait(sysret_t *rval, void *sp) 202 { 203 return (__systemcall(rval, SYS_lwp_sema_timedwait + 1024, 204 sp, NULL, 0)); 205 } 206 207 static int 208 s10_fchownat(sysret_t *rval, 209 int fd, const char *name, uid_t uid, gid_t gid, int flags) 210 { 211 return (__systemcall(rval, SYS_fchownat + 1024, 212 fd, name, uid, gid, flags)); 213 } 214 215 int 216 s10_chown(sysret_t *rval, const char *name, uid_t uid, gid_t gid) 217 { 218 return (__systemcall(rval, SYS_fchownat + 1024, 219 AT_FDCWD, name, uid, gid, 0)); 220 } 221 222 int 223 s10_lchown(sysret_t *rval, const char *name, uid_t uid, gid_t gid) 224 { 225 return (__systemcall(rval, SYS_fchownat + 1024, 226 AT_FDCWD, name, uid, gid, AT_SYMLINK_NOFOLLOW)); 227 } 228 229 int 230 s10_fchown(sysret_t *rval, int filedes, uid_t uid, gid_t gid) 231 { 232 return (__systemcall(rval, SYS_fchownat + 1024, 233 filedes, NULL, uid, gid, 0)); 234 } 235 236 static int 237 s10_unlinkat(sysret_t *rval, int fd, const char *name, int flags) 238 { 239 return (__systemcall(rval, SYS_unlinkat + 1024, 240 fd, name, flags)); 241 } 242 243 int 244 s10_unlink(sysret_t *rval, const char *name) 245 { 246 return (__systemcall(rval, SYS_unlinkat + 1024, 247 AT_FDCWD, name, 0)); 248 } 249 250 int 251 s10_rmdir(sysret_t *rval, const char *name) 252 { 253 return (__systemcall(rval, SYS_unlinkat + 1024, 254 AT_FDCWD, name, AT_REMOVEDIR)); 255 } 256 257 static int 258 s10_renameat(sysret_t *rval, 259 int oldfd, const char *oldname, int newfd, const char *newname) 260 { 261 return (__systemcall(rval, SYS_renameat + 1024, 262 oldfd, oldname, newfd, newname)); 263 } 264 265 int 266 s10_rename(sysret_t *rval, const char *oldname, const char *newname) 267 { 268 return (__systemcall(rval, SYS_renameat + 1024, 269 AT_FDCWD, oldname, AT_FDCWD, newname)); 270 } 271 272 static int 273 s10_faccessat(sysret_t *rval, int fd, const char *fname, int amode, int flag) 274 { 275 return (__systemcall(rval, SYS_faccessat + 1024, 276 fd, fname, amode, flag)); 277 } 278 279 int 280 s10_access(sysret_t *rval, const char *fname, int amode) 281 { 282 return (__systemcall(rval, SYS_faccessat + 1024, 283 AT_FDCWD, fname, amode, 0)); 284 } 285 286 int 287 s10_utime(sysret_t *rval, const char *path, const struct utimbuf *times) 288 { 289 struct utimbuf ltimes; 290 timespec_t ts[2]; 291 timespec_t *tsp; 292 293 if (times == NULL) { 294 tsp = NULL; 295 } else { 296 if (s10_uucopy(times, <imes, sizeof (ltimes)) != 0) 297 return (EFAULT); 298 ts[0].tv_sec = ltimes.actime; 299 ts[0].tv_nsec = 0; 300 ts[1].tv_sec = ltimes.modtime; 301 ts[1].tv_nsec = 0; 302 tsp = ts; 303 } 304 305 return (__systemcall(rval, SYS_utimesys + 1024, 1, 306 AT_FDCWD, path, tsp, 0)); 307 } 308 309 int 310 s10_utimes(sysret_t *rval, const char *path, const struct timeval times[2]) 311 { 312 struct timeval ltimes[2]; 313 timespec_t ts[2]; 314 timespec_t *tsp; 315 316 if (times == NULL) { 317 tsp = NULL; 318 } else { 319 if (s10_uucopy(times, ltimes, sizeof (ltimes)) != 0) 320 return (EFAULT); 321 ts[0].tv_sec = ltimes[0].tv_sec; 322 ts[0].tv_nsec = ltimes[0].tv_usec * 1000; 323 ts[1].tv_sec = ltimes[1].tv_sec; 324 ts[1].tv_nsec = ltimes[1].tv_usec * 1000; 325 tsp = ts; 326 } 327 328 return (__systemcall(rval, SYS_utimesys + 1024, 1, 329 AT_FDCWD, path, tsp, 0)); 330 } 331 332 static int 333 s10_futimesat(sysret_t *rval, 334 int fd, const char *path, const struct timeval times[2]) 335 { 336 struct timeval ltimes[2]; 337 timespec_t ts[2]; 338 timespec_t *tsp; 339 340 if (times == NULL) { 341 tsp = NULL; 342 } else { 343 if (s10_uucopy(times, ltimes, sizeof (ltimes)) != 0) 344 return (EFAULT); 345 ts[0].tv_sec = ltimes[0].tv_sec; 346 ts[0].tv_nsec = ltimes[0].tv_usec * 1000; 347 ts[1].tv_sec = ltimes[1].tv_sec; 348 ts[1].tv_nsec = ltimes[1].tv_usec * 1000; 349 tsp = ts; 350 } 351 352 if (path == NULL) 353 return (__systemcall(rval, SYS_utimesys + 1024, 0, fd, tsp)); 354 355 return (__systemcall(rval, SYS_utimesys + 1024, 1, fd, path, tsp, 0)); 356 } 357 358 #if defined(__x86) 359 360 /* ARGSUSED */ 361 int 362 s10_xstat(sysret_t *rval, int version, const char *path, struct stat *statb) 363 { 364 #if defined(__amd64) 365 return (EINVAL); 366 #else 367 if (version != _STAT_VER) 368 return (EINVAL); 369 return (__systemcall(rval, SYS_fstatat + 1024, 370 AT_FDCWD, path, statb, 0)); 371 #endif 372 } 373 374 /* ARGSUSED */ 375 int 376 s10_lxstat(sysret_t *rval, int version, const char *path, struct stat *statb) 377 { 378 #if defined(__amd64) 379 return (EINVAL); 380 #else 381 if (version != _STAT_VER) 382 return (EINVAL); 383 return (__systemcall(rval, SYS_fstatat + 1024, 384 AT_FDCWD, path, statb, AT_SYMLINK_NOFOLLOW)); 385 #endif 386 } 387 388 /* ARGSUSED */ 389 int 390 s10_fxstat(sysret_t *rval, int version, int fd, struct stat *statb) 391 { 392 #if defined(__amd64) 393 return (EINVAL); 394 #else 395 if (version != _STAT_VER) 396 return (EINVAL); 397 return (__systemcall(rval, SYS_fstatat + 1024, 398 fd, NULL, statb, 0)); 399 #endif 400 } 401 402 /* ARGSUSED */ 403 int 404 s10_xmknod(sysret_t *rval, int version, const char *path, 405 mode_t mode, dev_t dev) 406 { 407 #if defined(__amd64) 408 return (EINVAL); 409 #else 410 if (version != _MKNOD_VER) 411 return (EINVAL); 412 return (__systemcall(rval, SYS_mknod + 1024, path, mode, dev)); 413 #endif 414 } 415 416 #endif /* __x86 */ 417 418 /* 419 * This is the fsat() system call trap in s10. 420 * It has been removed in the current system. 421 */ 422 int 423 s10_fsat(sysret_t *rval, 424 int code, uintptr_t arg1, uintptr_t arg2, 425 uintptr_t arg3, uintptr_t arg4, uintptr_t arg5) 426 { 427 switch (code) { 428 case 0: /* openat */ 429 return (s10_openat(rval, (int)arg1, 430 (const char *)arg2, (int)arg3, (mode_t)arg4)); 431 case 1: /* openat64 */ 432 #if defined(_LP64) 433 return (EINVAL); 434 #else 435 return (s10_openat64(rval, (int)arg1, 436 (const char *)arg2, (int)arg3, (mode_t)arg4)); 437 #endif 438 case 2: /* fstatat64 */ 439 #if defined(_LP64) 440 return (EINVAL); 441 #else 442 return (s10_fstatat64(rval, (int)arg1, 443 (const char *)arg2, (struct stat64 *)arg3, (int)arg4)); 444 #endif 445 case 3: /* fstatat */ 446 return (s10_fstatat(rval, (int)arg1, 447 (const char *)arg2, (struct stat *)arg3, (int)arg4)); 448 case 4: /* fchownat */ 449 return (s10_fchownat(rval, (int)arg1, (char *)arg2, 450 (uid_t)arg3, (gid_t)arg4, (int)arg5)); 451 case 5: /* unlinkat */ 452 return (s10_unlinkat(rval, (int)arg1, (char *)arg2, 453 (int)arg3)); 454 case 6: /* futimesat */ 455 return (s10_futimesat(rval, (int)arg1, 456 (const char *)arg2, (const struct timeval *)arg3)); 457 case 7: /* renameat */ 458 return (s10_renameat(rval, (int)arg1, (char *)arg2, 459 (int)arg3, (char *)arg4)); 460 case 8: /* faccessat */ 461 return (s10_faccessat(rval, (int)arg1, (char *)arg2, 462 (int)arg3, (int)arg4)); 463 case 9: /* openattrdirat */ 464 return (s10_openat(rval, (int)arg1, 465 (const char *)arg2, FXATTRDIROPEN, 0)); 466 } 467 return (EINVAL); 468 } 469 470 /* 471 * Interposition upon SYS_umount 472 */ 473 int 474 s10_umount(sysret_t *rval, const char *path) 475 { 476 return (__systemcall(rval, SYS_umount2 + 1024, path, 0)); 477 } 478