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