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
s10_fstatat(sysret_t * rval,int fd,const char * path,struct stat * sb,int flags)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
s10_stat(sysret_t * rval,const char * path,struct stat * sb)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
s10_lstat(sysret_t * rval,const char * path,struct stat * sb)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
s10_fstat(sysret_t * rval,int filedes,struct stat * sb)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
s10_fstatat64(sysret_t * rval,int fd,const char * path,struct stat64 * sb,int flags)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
s10_stat64(sysret_t * rval,const char * path,struct stat64 * sb)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
s10_lstat64(sysret_t * rval,const char * path,struct stat64 * sb)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
s10_fstat64(sysret_t * rval,int filedes,struct stat64 * sb)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
s10_openat(sysret_t * rval,int fd,const char * path,int oflag,mode_t mode)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
s10_open(sysret_t * rval,char * path,int oflag,mode_t mode)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
s10_creat(sysret_t * rval,char * path,mode_t mode)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
s10_openat64(sysret_t * rval,int fd,const char * path,int oflag,mode_t mode)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
s10_open64(sysret_t * rval,char * path,int oflag,mode_t mode)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
s10_creat64(sysret_t * rval,char * path,mode_t mode)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
s10_fork1(sysret_t * rval)158 s10_fork1(sysret_t *rval)
159 {
160 	return (__systemcall(rval, SYS_forksys + 1024, 0, 0));
161 }
162 
163 int
s10_forkall(sysret_t * rval)164 s10_forkall(sysret_t *rval)
165 {
166 	return (__systemcall(rval, SYS_forksys + 1024, 1, 0));
167 }
168 
169 int
s10_dup(sysret_t * rval,int fd)170 s10_dup(sysret_t *rval, int fd)
171 {
172 	return (__systemcall(rval, SYS_fcntl + 1024, fd, F_DUPFD, 0));
173 }
174 
175 int
s10_poll(sysret_t * rval,struct pollfd * fds,nfds_t nfd,int timeout)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
s10_lwp_mutex_lock(sysret_t * rval,void * mp)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
s10_lwp_sema_wait(sysret_t * rval,void * sp)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
s10_chmod(sysret_t * rval,const char * name,mode_t mode)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
s10_fchmod(sysret_t * rval,int filedes,mode_t mode)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
s10_fchownat(sysret_t * rval,int fd,const char * name,uid_t uid,gid_t gid,int flag)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
s10_chown(sysret_t * rval,const char * name,uid_t uid,gid_t gid)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
s10_lchown(sysret_t * rval,const char * name,uid_t uid,gid_t gid)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
s10_fchown(sysret_t * rval,int filedes,uid_t uid,gid_t gid)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
s10_mkdir(sysret_t * rval,const char * dname,int dmode)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
s10_mknod(sysret_t * rval,const char * fname,int fmode,dev_t dev)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
s10_link(sysret_t * rval,const char * path1,const char * path2)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
s10_unlinkat(sysret_t * rval,int fd,const char * name,int flags)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
s10_unlink(sysret_t * rval,const char * name)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
s10_rmdir(sysret_t * rval,const char * name)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
s10_renameat(sysret_t * rval,int oldfd,const char * oldname,int newfd,const char * newname)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
s10_rename(sysret_t * rval,const char * oldname,const char * newname)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
s10_symlink(sysret_t * rval,const char * path1,const char * path2)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
s10_readlink(sysret_t * rval,const char * path,char * buf,size_t bufsize)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
s10_faccessat(sysret_t * rval,int fd,const char * fname,int amode,int flag)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
s10_access(sysret_t * rval,const char * fname,int amode)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
s10_utime(sysret_t * rval,const char * path,const struct utimbuf * times)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, &ltimes, 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
s10_utimes(sysret_t * rval,const char * path,const struct timeval times[2])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
s10_futimesat(sysret_t * rval,int fd,const char * path,const struct timeval times[2])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
s10_xstat(sysret_t * rval,int version,const char * path,struct stat * statb)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
s10_lxstat(sysret_t * rval,int version,const char * path,struct stat * statb)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
s10_fxstat(sysret_t * rval,int version,int fd,struct stat * statb)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
s10_xmknod(sysret_t * rval,int version,const char * path,mode_t mode,dev_t dev)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
s10_fsat(sysret_t * rval,int code,uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t arg4,uintptr_t arg5)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
s10_umount(sysret_t * rval,const char * path)524 s10_umount(sysret_t *rval, const char *path)
525 {
526 	return (__systemcall(rval, SYS_umount2 + 1024, path, 0));
527 }
528