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 (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <unistd.h> 29 #include <fcntl.h> 30 #include <utime.h> 31 #include <errno.h> 32 #include <sys/types.h> 33 #include <sys/stat.h> 34 #include <sys/time.h> 35 #include <sys/poll.h> 36 #include <sys/file.h> 37 #include <sys/syscall.h> 38 39 #include <s10_brand.h> 40 #include <brand_misc.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 int 208 s10_chmod(sysret_t *rval, const char *name, mode_t mode) 209 { 210 return (__systemcall(rval, SYS_fchmodat + 1024, 211 AT_FDCWD, name, mode, 0)); 212 } 213 214 int 215 s10_fchmod(sysret_t *rval, int filedes, mode_t mode) 216 { 217 return (__systemcall(rval, SYS_fchmodat + 1024, 218 filedes, NULL, mode, 0)); 219 } 220 221 static int 222 s10_fchownat(sysret_t *rval, 223 int fd, const char *name, uid_t uid, gid_t gid, int flag) 224 { 225 return (__systemcall(rval, SYS_fchownat + 1024, 226 fd, name, uid, gid, flag)); 227 } 228 229 int 230 s10_chown(sysret_t *rval, const char *name, uid_t uid, gid_t gid) 231 { 232 return (__systemcall(rval, SYS_fchownat + 1024, 233 AT_FDCWD, name, uid, gid, 0)); 234 } 235 236 int 237 s10_lchown(sysret_t *rval, const char *name, uid_t uid, gid_t gid) 238 { 239 return (__systemcall(rval, SYS_fchownat + 1024, 240 AT_FDCWD, name, uid, gid, AT_SYMLINK_NOFOLLOW)); 241 } 242 243 int 244 s10_fchown(sysret_t *rval, int filedes, uid_t uid, gid_t gid) 245 { 246 return (__systemcall(rval, SYS_fchownat + 1024, 247 filedes, NULL, uid, gid, 0)); 248 } 249 250 int 251 s10_mkdir(sysret_t *rval, const char *dname, int dmode) 252 { 253 return (__systemcall(rval, SYS_mkdirat + 1024, 254 AT_FDCWD, dname, dmode)); 255 } 256 257 int 258 s10_mknod(sysret_t *rval, const char *fname, int fmode, dev_t dev) 259 { 260 return (__systemcall(rval, SYS_mknodat + 1024, 261 AT_FDCWD, fname, fmode, dev)); 262 } 263 264 int 265 s10_link(sysret_t *rval, const char *path1, const char *path2) 266 { 267 return (__systemcall(rval, SYS_linkat + 1024, 268 AT_FDCWD, path1, AT_FDCWD, path2, 0)); 269 } 270 271 static int 272 s10_unlinkat(sysret_t *rval, int fd, const char *name, int flags) 273 { 274 return (__systemcall(rval, SYS_unlinkat + 1024, 275 fd, name, flags)); 276 } 277 278 int 279 s10_unlink(sysret_t *rval, const char *name) 280 { 281 return (__systemcall(rval, SYS_unlinkat + 1024, 282 AT_FDCWD, name, 0)); 283 } 284 285 int 286 s10_rmdir(sysret_t *rval, const char *name) 287 { 288 return (__systemcall(rval, SYS_unlinkat + 1024, 289 AT_FDCWD, name, AT_REMOVEDIR)); 290 } 291 292 static int 293 s10_renameat(sysret_t *rval, 294 int oldfd, const char *oldname, int newfd, const char *newname) 295 { 296 return (__systemcall(rval, SYS_renameat + 1024, 297 oldfd, oldname, newfd, newname)); 298 } 299 300 int 301 s10_rename(sysret_t *rval, const char *oldname, const char *newname) 302 { 303 return (__systemcall(rval, SYS_renameat + 1024, 304 AT_FDCWD, oldname, AT_FDCWD, newname)); 305 } 306 307 int 308 s10_symlink(sysret_t *rval, const char *path1, const char *path2) 309 { 310 return (__systemcall(rval, SYS_symlinkat + 1024, 311 path1, AT_FDCWD, path2)); 312 } 313 314 int 315 s10_readlink(sysret_t *rval, const char *path, char *buf, size_t bufsize) 316 { 317 return (__systemcall(rval, SYS_readlinkat + 1024, 318 AT_FDCWD, path, buf, bufsize)); 319 } 320 321 static int 322 s10_faccessat(sysret_t *rval, int fd, const char *fname, int amode, int flag) 323 { 324 return (__systemcall(rval, SYS_faccessat + 1024, 325 fd, fname, amode, flag)); 326 } 327 328 int 329 s10_access(sysret_t *rval, const char *fname, int amode) 330 { 331 return (__systemcall(rval, SYS_faccessat + 1024, 332 AT_FDCWD, fname, amode, 0)); 333 } 334 335 int 336 s10_utime(sysret_t *rval, const char *path, const struct utimbuf *times) 337 { 338 struct utimbuf ltimes; 339 timespec_t ts[2]; 340 timespec_t *tsp; 341 342 if (times == NULL) { 343 tsp = NULL; 344 } else { 345 if (brand_uucopy(times, <imes, sizeof (ltimes)) != 0) 346 return (EFAULT); 347 ts[0].tv_sec = ltimes.actime; 348 ts[0].tv_nsec = 0; 349 ts[1].tv_sec = ltimes.modtime; 350 ts[1].tv_nsec = 0; 351 tsp = ts; 352 } 353 354 return (__systemcall(rval, SYS_utimesys + 1024, 1, 355 AT_FDCWD, path, tsp, 0)); 356 } 357 358 int 359 s10_utimes(sysret_t *rval, const char *path, const struct timeval times[2]) 360 { 361 struct timeval ltimes[2]; 362 timespec_t ts[2]; 363 timespec_t *tsp; 364 365 if (times == NULL) { 366 tsp = NULL; 367 } else { 368 if (brand_uucopy(times, ltimes, sizeof (ltimes)) != 0) 369 return (EFAULT); 370 ts[0].tv_sec = ltimes[0].tv_sec; 371 ts[0].tv_nsec = ltimes[0].tv_usec * 1000; 372 ts[1].tv_sec = ltimes[1].tv_sec; 373 ts[1].tv_nsec = ltimes[1].tv_usec * 1000; 374 tsp = ts; 375 } 376 377 return (__systemcall(rval, SYS_utimesys + 1024, 1, 378 AT_FDCWD, path, tsp, 0)); 379 } 380 381 static int 382 s10_futimesat(sysret_t *rval, 383 int fd, const char *path, const struct timeval times[2]) 384 { 385 struct timeval ltimes[2]; 386 timespec_t ts[2]; 387 timespec_t *tsp; 388 389 if (times == NULL) { 390 tsp = NULL; 391 } else { 392 if (brand_uucopy(times, ltimes, sizeof (ltimes)) != 0) 393 return (EFAULT); 394 ts[0].tv_sec = ltimes[0].tv_sec; 395 ts[0].tv_nsec = ltimes[0].tv_usec * 1000; 396 ts[1].tv_sec = ltimes[1].tv_sec; 397 ts[1].tv_nsec = ltimes[1].tv_usec * 1000; 398 tsp = ts; 399 } 400 401 if (path == NULL) 402 return (__systemcall(rval, SYS_utimesys + 1024, 0, fd, tsp)); 403 404 return (__systemcall(rval, SYS_utimesys + 1024, 1, fd, path, tsp, 0)); 405 } 406 407 #if defined(__x86) 408 409 /* ARGSUSED */ 410 int 411 s10_xstat(sysret_t *rval, int version, const char *path, struct stat *statb) 412 { 413 #if defined(__amd64) 414 return (EINVAL); 415 #else 416 if (version != _STAT_VER) 417 return (EINVAL); 418 return (__systemcall(rval, SYS_fstatat + 1024, 419 AT_FDCWD, path, statb, 0)); 420 #endif 421 } 422 423 /* ARGSUSED */ 424 int 425 s10_lxstat(sysret_t *rval, int version, const char *path, struct stat *statb) 426 { 427 #if defined(__amd64) 428 return (EINVAL); 429 #else 430 if (version != _STAT_VER) 431 return (EINVAL); 432 return (__systemcall(rval, SYS_fstatat + 1024, 433 AT_FDCWD, path, statb, AT_SYMLINK_NOFOLLOW)); 434 #endif 435 } 436 437 /* ARGSUSED */ 438 int 439 s10_fxstat(sysret_t *rval, int version, int fd, struct stat *statb) 440 { 441 #if defined(__amd64) 442 return (EINVAL); 443 #else 444 if (version != _STAT_VER) 445 return (EINVAL); 446 return (__systemcall(rval, SYS_fstatat + 1024, 447 fd, NULL, statb, 0)); 448 #endif 449 } 450 451 /* ARGSUSED */ 452 int 453 s10_xmknod(sysret_t *rval, int version, const char *path, 454 mode_t mode, dev_t dev) 455 { 456 #if defined(__amd64) 457 return (EINVAL); 458 #else 459 if (version != _MKNOD_VER) 460 return (EINVAL); 461 return (__systemcall(rval, SYS_mknodat + 1024, 462 AT_FDCWD, path, mode, dev)); 463 #endif 464 } 465 466 #endif /* __x86 */ 467 468 /* 469 * This is the fsat() system call trap in s10. 470 * It has been removed in the current system. 471 */ 472 int 473 s10_fsat(sysret_t *rval, 474 int code, uintptr_t arg1, uintptr_t arg2, 475 uintptr_t arg3, uintptr_t arg4, uintptr_t arg5) 476 { 477 switch (code) { 478 case 0: /* openat */ 479 return (s10_openat(rval, (int)arg1, 480 (const char *)arg2, (int)arg3, (mode_t)arg4)); 481 case 1: /* openat64 */ 482 #if defined(_LP64) 483 return (EINVAL); 484 #else 485 return (s10_openat64(rval, (int)arg1, 486 (const char *)arg2, (int)arg3, (mode_t)arg4)); 487 #endif 488 case 2: /* fstatat64 */ 489 #if defined(_LP64) 490 return (EINVAL); 491 #else 492 return (s10_fstatat64(rval, (int)arg1, 493 (const char *)arg2, (struct stat64 *)arg3, (int)arg4)); 494 #endif 495 case 3: /* fstatat */ 496 return (s10_fstatat(rval, (int)arg1, 497 (const char *)arg2, (struct stat *)arg3, (int)arg4)); 498 case 4: /* fchownat */ 499 return (s10_fchownat(rval, (int)arg1, (char *)arg2, 500 (uid_t)arg3, (gid_t)arg4, (int)arg5)); 501 case 5: /* unlinkat */ 502 return (s10_unlinkat(rval, (int)arg1, (char *)arg2, 503 (int)arg3)); 504 case 6: /* futimesat */ 505 return (s10_futimesat(rval, (int)arg1, 506 (const char *)arg2, (const struct timeval *)arg3)); 507 case 7: /* renameat */ 508 return (s10_renameat(rval, (int)arg1, (char *)arg2, 509 (int)arg3, (char *)arg4)); 510 case 8: /* faccessat */ 511 return (s10_faccessat(rval, (int)arg1, (char *)arg2, 512 (int)arg3, (int)arg4)); 513 case 9: /* openattrdirat */ 514 return (s10_openat(rval, (int)arg1, 515 (const char *)arg2, FXATTRDIROPEN, 0)); 516 } 517 return (EINVAL); 518 } 519 520 /* 521 * Interposition upon SYS_umount 522 */ 523 int 524 s10_umount(sysret_t *rval, const char *path) 525 { 526 return (__systemcall(rval, SYS_umount2 + 1024, path, 0)); 527 } 528