1 /*-
2  * Copyright (c) 1998 Mark Newton
3  * Copyright (c) 1994 Christos Zoulas
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD: stable/10/sys/compat/svr4/svr4_stat.c 225617 2011-09-16 13:58:51Z kmacy $");
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/proc.h>
35 #include <sys/stat.h>
36 #include <sys/filedesc.h>
37 #include <sys/jail.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
40 #include <sys/namei.h>
41 #include <sys/unistd.h>
42 #include <sys/time.h>
43 #include <sys/syscallsubr.h>
44 #include <sys/sysctl.h>
45 #include <sys/sysproto.h>
46 #include <sys/un.h>
47 
48 #include <vm/vm.h>
49 
50 #include <netinet/in.h>
51 
52 #include <compat/svr4/svr4.h>
53 #include <compat/svr4/svr4_types.h>
54 #include <compat/svr4/svr4_signal.h>
55 #include <compat/svr4/svr4_proto.h>
56 #include <compat/svr4/svr4_util.h>
57 #include <compat/svr4/svr4_stat.h>
58 #include <compat/svr4/svr4_ustat.h>
59 #include <compat/svr4/svr4_utsname.h>
60 #include <compat/svr4/svr4_systeminfo.h>
61 #include <compat/svr4/svr4_socket.h>
62 #include <compat/svr4/svr4_time.h>
63 #if defined(NOTYET)
64 #include "svr4_fuser.h"
65 #endif
66 
67 #ifdef sparc
68 /*
69  * Solaris-2.4 on the sparc has the old stat call using the new
70  * stat data structure...
71  */
72 # define SVR4_NO_OSTAT
73 #endif
74 
75 struct svr4_ustat_args {
76 	svr4_dev_t		dev;
77 	struct svr4_ustat * name;
78 };
79 
80 static void bsd_to_svr4_xstat(struct stat *, struct svr4_xstat *);
81 static void bsd_to_svr4_stat64(struct stat *, struct svr4_stat64 *);
82 int svr4_ustat(struct thread *, struct svr4_ustat_args *);
83 static int svr4_to_bsd_pathconf(int);
84 
85 /*
86  * SVR4 uses named pipes as named sockets, so we tell programs
87  * that sockets are named pipes with mode 0
88  */
89 #define BSD_TO_SVR4_MODE(mode) (S_ISSOCK(mode) ? S_IFIFO : (mode))
90 
91 
92 #ifndef SVR4_NO_OSTAT
93 static void bsd_to_svr4_stat(struct stat *, struct svr4_stat *);
94 
95 static void
bsd_to_svr4_stat(st,st4)96 bsd_to_svr4_stat(st, st4)
97 	struct stat		*st;
98 	struct svr4_stat 	*st4;
99 {
100 	memset(st4, 0, sizeof(*st4));
101 	st4->st_dev = bsd_to_svr4_odev_t(st->st_dev);
102 	st4->st_ino = st->st_ino;
103 	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
104 	st4->st_nlink = st->st_nlink;
105 	st4->st_uid = st->st_uid;
106 	st4->st_gid = st->st_gid;
107 	st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev);
108 	st4->st_size = st->st_size;
109 	st4->st_atim = st->st_atim.tv_sec;
110 	st4->st_mtim = st->st_mtim.tv_sec;
111 	st4->st_ctim = st->st_ctim.tv_sec;
112 }
113 #endif
114 
115 
116 static void
bsd_to_svr4_xstat(st,st4)117 bsd_to_svr4_xstat(st, st4)
118 	struct stat		*st;
119 	struct svr4_xstat	*st4;
120 {
121 	memset(st4, 0, sizeof(*st4));
122 	st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
123 	st4->st_ino = st->st_ino;
124 	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
125 	st4->st_nlink = st->st_nlink;
126 	st4->st_uid = st->st_uid;
127 	st4->st_gid = st->st_gid;
128 	st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
129 	st4->st_size = st->st_size;
130 	st4->st_atim = st->st_atim;
131 	st4->st_mtim = st->st_mtim;
132 	st4->st_ctim = st->st_ctim;
133 	st4->st_blksize = st->st_blksize;
134 	st4->st_blocks = st->st_blocks;
135 	strcpy(st4->st_fstype, "unknown");
136 }
137 
138 
139 static void
bsd_to_svr4_stat64(st,st4)140 bsd_to_svr4_stat64(st, st4)
141 	struct stat		*st;
142 	struct svr4_stat64	*st4;
143 {
144 	memset(st4, 0, sizeof(*st4));
145 	st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
146 	st4->st_ino = st->st_ino;
147 	st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
148 	st4->st_nlink = st->st_nlink;
149 	st4->st_uid = st->st_uid;
150 	st4->st_gid = st->st_gid;
151 	st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
152 	st4->st_size = st->st_size;
153 	st4->st_atim = st->st_atim;
154 	st4->st_mtim = st->st_mtim;
155 	st4->st_ctim = st->st_ctim;
156 	st4->st_blksize = st->st_blksize;
157 	st4->st_blocks = st->st_blocks;
158 	strcpy(st4->st_fstype, "unknown");
159 }
160 
161 int
svr4_sys_stat(td,uap)162 svr4_sys_stat(td, uap)
163 	struct thread *td;
164 	struct svr4_sys_stat_args *uap;
165 {
166 	struct svr4_stat svr4_st;
167 	struct stat st;
168 	char *path;
169 	int error;
170 
171 	CHECKALTEXIST(td, uap->path, &path);
172 
173 	error = kern_stat(td, path, UIO_SYSSPACE, &st);
174 	free(path, M_TEMP);
175 	if (error)
176 		return (error);
177 	bsd_to_svr4_stat(&st, &svr4_st);
178 
179 	if (S_ISSOCK(st.st_mode))
180 		(void) svr4_add_socket(td, uap->path, &st);
181 
182 	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
183 }
184 
185 
186 int
svr4_sys_lstat(td,uap)187 svr4_sys_lstat(td, uap)
188 	struct thread *td;
189 	struct svr4_sys_lstat_args *uap;
190 {
191 	struct svr4_stat svr4_st;
192 	struct stat st;
193 	char *path;
194 	int error;
195 
196 	CHECKALTEXIST(td, uap->path, &path);
197 
198 	error = kern_lstat(td, path, UIO_SYSSPACE, &st);
199 	free(path, M_TEMP);
200 	if (error)
201 		return (error);
202 	bsd_to_svr4_stat(&st, &svr4_st);
203 
204 	if (S_ISSOCK(st.st_mode))
205 		(void) svr4_add_socket(td, uap->path, &st);
206 
207 	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
208 }
209 
210 
211 int
svr4_sys_fstat(td,uap)212 svr4_sys_fstat(td, uap)
213 	struct thread *td;
214 	struct svr4_sys_fstat_args *uap;
215 {
216 	struct svr4_stat svr4_st;
217 	struct stat st;
218 	int error;
219 
220 
221 	error = kern_fstat(td, uap->fd, &st);
222 	if (error)
223 		return (error);
224 	bsd_to_svr4_stat(&st, &svr4_st);
225 	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
226 }
227 
228 
229 int
svr4_sys_xstat(td,uap)230 svr4_sys_xstat(td, uap)
231 	struct thread *td;
232 	struct svr4_sys_xstat_args *uap;
233 {
234 	struct svr4_xstat svr4_st;
235 	struct stat st;
236 	char *path;
237 	int error;
238 
239 	CHECKALTEXIST(td, uap->path, &path);
240 
241 	error = kern_stat(td, path, UIO_SYSSPACE, &st);
242 	free(path, M_TEMP);
243 	if (error)
244 		return (error);
245 
246 	bsd_to_svr4_xstat(&st, &svr4_st);
247 
248 #if defined(SOCKET_NOTYET)
249 	if (S_ISSOCK(st.st_mode))
250 		(void) svr4_add_socket(td, uap->path, &st);
251 #endif
252 
253 	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
254 }
255 
256 int
svr4_sys_lxstat(td,uap)257 svr4_sys_lxstat(td, uap)
258 	struct thread *td;
259 	struct svr4_sys_lxstat_args *uap;
260 {
261 	struct svr4_xstat svr4_st;
262 	struct stat st;
263 	char *path;
264 	int error;
265 
266 	CHECKALTEXIST(td, uap->path, &path);
267 
268 	error = kern_lstat(td, path, UIO_SYSSPACE, &st);
269 	free(path, M_TEMP);
270 	if (error)
271 		return (error);
272 
273 	bsd_to_svr4_xstat(&st, &svr4_st);
274 
275 #if defined(SOCKET_NOTYET)
276 	if (S_ISSOCK(st.st_mode))
277 		(void) svr4_add_socket(td, uap->path, &st);
278 #endif
279 	return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
280 }
281 
282 
283 int
svr4_sys_fxstat(td,uap)284 svr4_sys_fxstat(td, uap)
285 	struct thread *td;
286 	struct svr4_sys_fxstat_args *uap;
287 {
288 	struct svr4_xstat svr4_st;
289 	struct stat st;
290 	int error;
291 
292 
293 	error = kern_fstat(td, uap->fd, &st);
294 	if (error)
295 		return (error);
296 	bsd_to_svr4_xstat(&st, &svr4_st);
297 	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
298 }
299 
300 int
svr4_sys_stat64(td,uap)301 svr4_sys_stat64(td, uap)
302 	struct thread *td;
303 	struct svr4_sys_stat64_args *uap;
304 {
305 	struct svr4_stat64 svr4_st;
306 	struct stat st;
307 	char *path;
308 	int error;
309 
310 	CHECKALTEXIST(td, uap->path, &path);
311 
312 	error = kern_stat(td, path, UIO_SYSSPACE, &st);
313 	free(path, M_TEMP);
314 	if (error)
315 		return (error);
316 
317 	bsd_to_svr4_stat64(&st, &svr4_st);
318 
319 	if (S_ISSOCK(st.st_mode))
320 		(void) svr4_add_socket(td, uap->path, &st);
321 
322 	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
323 }
324 
325 
326 int
svr4_sys_lstat64(td,uap)327 svr4_sys_lstat64(td, uap)
328 	struct thread *td;
329 	struct svr4_sys_lstat64_args *uap;
330 {
331 	struct svr4_stat64 svr4_st;
332 	struct stat st;
333 	char *path;
334 	int error;
335 
336 	CHECKALTEXIST(td, uap->path, &path);
337 
338 	error = kern_lstat(td, path, UIO_SYSSPACE, &st);
339 	free(path, M_TEMP);
340 	if (error)
341 		return (error);
342 
343 	bsd_to_svr4_stat64(&st, &svr4_st);
344 
345 	if (S_ISSOCK(st.st_mode))
346 		(void) svr4_add_socket(td, uap->path, &st);
347 
348 	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
349 }
350 
351 
352 int
svr4_sys_fstat64(td,uap)353 svr4_sys_fstat64(td, uap)
354 	struct thread *td;
355 	struct svr4_sys_fstat64_args *uap;
356 {
357 	struct svr4_stat64 svr4_st;
358 	struct stat st;
359 	int error;
360 
361 	error = kern_fstat(td, uap->fd, &st);
362 	if (error)
363 		return (error);
364 	bsd_to_svr4_stat64(&st, &svr4_st);
365 	return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
366 }
367 
368 
369 int
svr4_ustat(td,uap)370 svr4_ustat(td, uap)
371 	struct thread *td;
372 	struct svr4_ustat_args *uap;
373 {
374 	struct svr4_ustat	us;
375 	int			error;
376 
377 	memset(&us, 0, sizeof us);
378 
379 	/*
380          * XXX: should set f_tfree and f_tinode at least
381          * How do we translate dev -> fstat? (and then to svr4_ustat)
382          */
383 	if ((error = copyout(&us, uap->name, sizeof us)) != 0)
384 		return (error);
385 
386 	return 0;
387 }
388 
389 /*extern char ostype[], osrelease[], version[], machine[];*/
390 
391 int
svr4_sys_uname(td,uap)392 svr4_sys_uname(td, uap)
393 	struct thread *td;
394 	struct svr4_sys_uname_args *uap;
395 {
396 	struct svr4_utsname	sut;
397 
398 	memset(&sut, 0, sizeof(sut));
399 
400 	strlcpy(sut.sysname, ostype, sizeof(sut.sysname));
401 	getcredhostname(td->td_ucred, sut.nodename, sizeof(sut.nodename));
402 	strlcpy(sut.release, osrelease, sizeof(sut.release));
403 	strlcpy(sut.version, version, sizeof(sut.version));
404 	strlcpy(sut.machine, machine, sizeof(sut.machine));
405 
406 	return copyout((caddr_t) &sut, (caddr_t) uap->name,
407 		       sizeof(struct svr4_utsname));
408 }
409 
410 int
svr4_sys_systeminfo(td,uap)411 svr4_sys_systeminfo(td, uap)
412 	struct thread *td;
413 	struct svr4_sys_systeminfo_args *uap;
414 {
415 	char		*str = NULL;
416 	int		error = 0;
417 	register_t	*retval = td->td_retval;
418 	u_long		hostid;
419 	size_t		len = 0;
420 	char		buf[MAXHOSTNAMELEN];
421 	u_int		rlen = uap->len;
422 
423 	switch (uap->what) {
424 	case SVR4_SI_SYSNAME:
425 		str = ostype;
426 		break;
427 
428 	case SVR4_SI_HOSTNAME:
429 		getcredhostname(td->td_ucred, buf, sizeof(buf));
430 		str = buf;
431 		break;
432 
433 	case SVR4_SI_RELEASE:
434 		str = osrelease;
435 		break;
436 
437 	case SVR4_SI_VERSION:
438 		str = version;
439 		break;
440 
441 	case SVR4_SI_MACHINE:
442 		str = machine;
443 		break;
444 
445 	case SVR4_SI_ARCHITECTURE:
446 		str = machine;
447 		break;
448 
449 	case SVR4_SI_ISALIST:
450 #if defined(__sparc__)
451 		str = "sparcv9 sparcv9-fsmuld sparcv8 sparcv8-fsmuld sparcv7 sparc";
452 #elif defined(__i386__)
453 		str = "i386";
454 #elif defined(__amd64__)
455 		str = "amd64";
456 #else
457 		str = "unknown";
458 #endif
459 		break;
460 
461 	case SVR4_SI_HW_SERIAL:
462 		getcredhostid(td->td_ucred, &hostid);
463 		snprintf(buf, sizeof(buf), "%lu", hostid);
464 		str = buf;
465 		break;
466 
467 	case SVR4_SI_HW_PROVIDER:
468 		str = ostype;
469 		break;
470 
471 	case SVR4_SI_SRPC_DOMAIN:
472 		getcreddomainname(td->td_ucred, buf, sizeof(buf));
473 		str = buf;
474 		break;
475 
476 	case SVR4_SI_PLATFORM:
477 #if defined(__i386__)
478 		str = "i86pc";
479 #else
480 		str = "unknown";
481 #endif
482 		break;
483 
484 	case SVR4_SI_KERB_REALM:
485 		str = "unsupported";
486 		break;
487 #if defined(WHY_DOES_AN_EMULATOR_WANT_TO_SET_HOSTNAMES)
488 	case SVR4_SI_SET_HOSTNAME:
489 		name = KERN_HOSTNAME;
490 		return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
491 
492 	case SVR4_SI_SET_SRPC_DOMAIN:
493 		name = KERN_NISDOMAINNAME;
494 		return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
495 #else
496 	case SVR4_SI_SET_HOSTNAME:
497         case SVR4_SI_SET_SRPC_DOMAIN:
498 		/* FALLTHROUGH */
499 #endif
500 	case SVR4_SI_SET_KERB_REALM:
501 		return 0;
502 
503 	default:
504 		DPRINTF(("Bad systeminfo command %d\n", uap->what));
505 		return ENOSYS;
506 	}
507 
508 	if (str) {
509 		len = strlen(str) + 1;
510 		if (len > rlen)
511 			len = rlen;
512 
513 		if (uap->buf) {
514 			error = copyout(str, uap->buf, len);
515 			if (error)
516 				return error;
517 			/* make sure we are NULL terminated */
518 			buf[0] = '\0';
519 			error = copyout(buf, &(uap->buf[len - 1]), 1);
520 		}
521 		else
522 			error = 0;
523 	}
524 	/* XXX NetBSD has hostname setting stuff here.  Why would an emulator
525 	   want to do that? */
526 
527 	*retval = len;
528 	return error;
529 }
530 
531 int
svr4_sys_utssys(td,uap)532 svr4_sys_utssys(td, uap)
533 	struct thread *td;
534 	struct svr4_sys_utssys_args *uap;
535 {
536 	switch (uap->sel) {
537 	case 0:		/* uname(2)  */
538 		{
539 			struct svr4_sys_uname_args ua;
540 			ua.name = uap->a1;
541 			return svr4_sys_uname(td, &ua);
542 		}
543 
544 	case 2:		/* ustat(2)  */
545 		{
546 			struct svr4_ustat_args ua;
547 			ua.dev = (svr4_dev_t) uap->a2;
548 			ua.name = uap->a1;
549 			return svr4_ustat(td, &ua);
550 		}
551 
552 	case 3:		/* fusers(2) */
553 		return ENOSYS;
554 
555 	default:
556 		return ENOSYS;
557 	}
558 	return ENOSYS;
559 }
560 
561 
562 int
svr4_sys_utime(td,uap)563 svr4_sys_utime(td, uap)
564 	struct thread *td;
565 	struct svr4_sys_utime_args *uap;
566 {
567 	struct svr4_utimbuf ub;
568 	struct timeval tbuf[2], *tp;
569 	char *path;
570 	int error;
571 
572 	if (uap->ubuf != NULL) {
573 		error = copyin(uap->ubuf, &ub, sizeof(ub));
574 		if (error)
575 			return (error);
576 		tbuf[0].tv_sec = ub.actime;
577 		tbuf[0].tv_usec = 0;
578 		tbuf[1].tv_sec = ub.modtime;
579 		tbuf[1].tv_usec = 0;
580 		tp = tbuf;
581 	} else
582 		tp = NULL;
583 
584 	CHECKALTEXIST(td, uap->path, &path);
585 	error = kern_utimes(td, path, UIO_SYSSPACE, tp, UIO_SYSSPACE);
586 	free(path, M_TEMP);
587 	return (error);
588 }
589 
590 
591 int
svr4_sys_utimes(td,uap)592 svr4_sys_utimes(td, uap)
593 	struct thread *td;
594 	struct svr4_sys_utimes_args *uap;
595 {
596 	char *path;
597 	int error;
598 
599 	CHECKALTEXIST(td, uap->path, &path);
600 	error = kern_utimes(td, path, UIO_SYSSPACE, uap->tptr, UIO_USERSPACE);
601 	free(path, M_TEMP);
602 	return (error);
603 }
604 
605 static int
svr4_to_bsd_pathconf(name)606 svr4_to_bsd_pathconf(name)
607 	int name;
608 {
609 	switch (name) {
610 	case SVR4_PC_LINK_MAX:
611 	    	return _PC_LINK_MAX;
612 
613 	case SVR4_PC_MAX_CANON:
614 		return _PC_MAX_CANON;
615 
616 	case SVR4_PC_MAX_INPUT:
617 		return _PC_MAX_INPUT;
618 
619 	case SVR4_PC_NAME_MAX:
620 		return _PC_NAME_MAX;
621 
622 	case SVR4_PC_PATH_MAX:
623 		return _PC_PATH_MAX;
624 
625 	case SVR4_PC_PIPE_BUF:
626 		return _PC_PIPE_BUF;
627 
628 	case SVR4_PC_NO_TRUNC:
629 		return _PC_NO_TRUNC;
630 
631 	case SVR4_PC_VDISABLE:
632 		return _PC_VDISABLE;
633 
634 	case SVR4_PC_CHOWN_RESTRICTED:
635 		return _PC_CHOWN_RESTRICTED;
636 	case SVR4_PC_SYNC_IO:
637 #if defined(_PC_SYNC_IO)
638 		return _PC_SYNC_IO;
639 #else
640 		return 0;
641 #endif
642 	case SVR4_PC_ASYNC_IO:
643 	case SVR4_PC_PRIO_IO:
644 		/* Not supported */
645 		return 0;
646 
647 	default:
648 		/* Invalid */
649 		return -1;
650 	}
651 }
652 
653 
654 int
svr4_sys_pathconf(td,uap)655 svr4_sys_pathconf(td, uap)
656 	struct thread *td;
657 	struct svr4_sys_pathconf_args *uap;
658 {
659 	char *path;
660 	int error, name;
661 
662 	name = svr4_to_bsd_pathconf(uap->name);
663 
664 	switch (name) {
665 	case -1:
666 		td->td_retval[0] = -1;
667 		return (EINVAL);
668 	case 0:
669 		td->td_retval[0] = 0;
670 		return (0);
671 	default:
672 		CHECKALTEXIST(td, uap->path, &path);
673 		error = kern_pathconf(td, path, UIO_SYSSPACE, name, FOLLOW);
674 		free(path, M_TEMP);
675 		return (error);
676 	}
677 }
678 
679 
680 int
svr4_sys_fpathconf(td,uap)681 svr4_sys_fpathconf(td, uap)
682 	struct thread *td;
683 	struct svr4_sys_fpathconf_args *uap;
684 {
685         register_t	*retval = td->td_retval;
686 
687 	uap->name = svr4_to_bsd_pathconf(uap->name);
688 
689 	switch (uap->name) {
690 	case -1:
691 		*retval = -1;
692 		return EINVAL;
693 	case 0:
694 		*retval = 0;
695 		return 0;
696 	default:
697 		return sys_fpathconf(td, (struct fpathconf_args *)uap);
698 	}
699 }
700