Per-CPU VFS Namecache Effectiveness Statistics:
[dragonfly.git] / sys / emulation / svr4 / svr4_stat.c
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  * $FreeBSD: src/sys/svr4/svr4_stat.c,v 1.6 1999/12/08 12:00:48 newton Exp $
29  * $DragonFly: src/sys/emulation/svr4/Attic/svr4_stat.c,v 1.9 2003/11/20 06:05:30 dillon Exp $
30  */
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/kernel.h>
38 #include <sys/unistd.h>
39 #include <sys/time.h>
40 #include <sys/sysctl.h>
41 #include <sys/sysproto.h>
42
43 #include <vm/vm.h>
44
45 #include <netinet/in.h>
46
47 #include "svr4.h"
48 #include "svr4_types.h"
49 #include "svr4_signal.h"
50 #include "svr4_proto.h"
51 #include "svr4_util.h"
52 #include "svr4_stat.h"
53 #include "svr4_ustat.h"
54 #include "svr4_utsname.h"
55 #include "svr4_systeminfo.h"
56 #include "svr4_socket.h"
57 #include "svr4_time.h"
58 #if defined(NOTYET)
59 #include "svr4_fuser.h"
60 #endif
61
62 #ifdef sparc
63 /* 
64  * Solaris-2.4 on the sparc has the old stat call using the new
65  * stat data structure...
66  */
67 # define SVR4_NO_OSTAT
68 #endif
69
70 struct svr4_ustat_args {
71         struct sysmsg           sysmsg;
72         svr4_dev_t              dev;
73         struct svr4_ustat * name;
74 };
75
76 static void bsd_to_svr4_xstat (struct stat *, struct svr4_xstat *);
77 static void bsd_to_svr4_stat64 (struct stat *, struct svr4_stat64 *);
78 int svr4_ustat (struct svr4_ustat_args *);
79 static int svr4_to_bsd_pathconf (int);
80
81 /*
82  * SVR4 uses named pipes as named sockets, so we tell programs
83  * that sockets are named pipes with mode 0
84  */
85 #define BSD_TO_SVR4_MODE(mode) (S_ISSOCK(mode) ? S_IFIFO : (mode))
86
87
88 #ifndef SVR4_NO_OSTAT
89 static void bsd_to_svr4_stat (struct stat *, struct svr4_stat *);
90
91 static void
92 bsd_to_svr4_stat(st, st4)
93         struct stat             *st;
94         struct svr4_stat        *st4;
95 {
96         memset(st4, 0, sizeof(*st4));
97         st4->st_dev = bsd_to_svr4_odev_t(st->st_dev);
98         st4->st_ino = st->st_ino;
99         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
100         st4->st_nlink = st->st_nlink;
101         st4->st_uid = st->st_uid;
102         st4->st_gid = st->st_gid;
103         st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev);
104         st4->st_size = st->st_size;
105         st4->st_atim = st->st_atimespec.tv_sec;
106         st4->st_mtim = st->st_mtimespec.tv_sec;
107         st4->st_ctim = st->st_ctimespec.tv_sec;
108 }
109 #endif
110
111
112 static void
113 bsd_to_svr4_xstat(st, st4)
114         struct stat             *st;
115         struct svr4_xstat       *st4;
116 {
117         memset(st4, 0, sizeof(*st4));
118         st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
119         st4->st_ino = st->st_ino;
120         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
121         st4->st_nlink = st->st_nlink;
122         st4->st_uid = st->st_uid;
123         st4->st_gid = st->st_gid;
124         st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
125         st4->st_size = st->st_size;
126         st4->st_atim = st->st_atimespec;
127         st4->st_mtim = st->st_mtimespec;
128         st4->st_ctim = st->st_ctimespec;
129         st4->st_blksize = st->st_blksize;
130         st4->st_blocks = st->st_blocks;
131         strcpy(st4->st_fstype, "unknown");
132 }
133
134
135 static void
136 bsd_to_svr4_stat64(st, st4)
137         struct stat             *st;
138         struct svr4_stat64      *st4;
139 {
140         memset(st4, 0, sizeof(*st4));
141         st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
142         st4->st_ino = st->st_ino;
143         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
144         st4->st_nlink = st->st_nlink;
145         st4->st_uid = st->st_uid;
146         st4->st_gid = st->st_gid;
147         st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
148         st4->st_size = st->st_size;
149         st4->st_atim = st->st_atimespec;
150         st4->st_mtim = st->st_mtimespec;
151         st4->st_ctim = st->st_ctimespec;
152         st4->st_blksize = st->st_blksize;
153         st4->st_blocks = st->st_blocks;
154         strcpy(st4->st_fstype, "unknown");
155 }
156
157 int
158 svr4_sys_stat(struct svr4_sys_stat_args *uap)
159 {
160         struct thread *td = curthread;
161         struct stat             st;
162         struct svr4_stat        svr4_st;
163         struct stat_args        cup;
164         int                     error;
165         caddr_t sg = stackgap_init();
166
167         CHECKALTEXIST(&sg, SCARG(uap, path));
168
169         SCARG(&cup, path) = SCARG(uap, path);
170         SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
171         cup.sysmsg_result = 0;
172
173         if ((error = stat(&cup)) != 0)
174                 return error;
175
176         if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
177                 return error;
178
179         uap->sysmsg_result = cup.sysmsg_result;
180
181         bsd_to_svr4_stat(&st, &svr4_st);
182
183         if (S_ISSOCK(st.st_mode))
184                 (void) svr4_add_socket(td, SCARG(uap, path), &st);
185
186         if ((error = copyout(&svr4_st, SCARG(uap, ub), sizeof svr4_st)) != 0)
187                 return error;
188
189         return 0;
190 }
191
192
193 int
194 svr4_sys_lstat(struct svr4_sys_lstat_args *uap)
195 {
196         struct thread *td = curthread;
197         struct stat             st;
198         struct svr4_stat        svr4_st;
199         struct lstat_args       cup;
200         int                     error;
201         caddr_t                 sg = stackgap_init();
202
203         CHECKALTEXIST(&sg, SCARG(uap, path));
204
205         SCARG(&cup, path) = SCARG(uap, path);
206         SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
207         cup.sysmsg_result = 0;
208
209         if ((error = lstat(&cup)) != 0)
210                 return error;
211
212         if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
213                 return error;
214
215         uap->sysmsg_result = cup.sysmsg_result;
216
217         bsd_to_svr4_stat(&st, &svr4_st);
218
219         if (S_ISSOCK(st.st_mode))
220                 (void) svr4_add_socket(td, SCARG(uap, path), &st);
221
222         if ((error = copyout(&svr4_st, SCARG(uap, ub), sizeof svr4_st)) != 0)
223                 return error;
224
225         return 0;
226 }
227
228
229 int
230 svr4_sys_fstat(struct svr4_sys_fstat_args *uap)
231 {
232         struct stat             st;
233         struct svr4_stat        svr4_st;
234         struct fstat_args       cup;
235         int                     error;
236         caddr_t                 sg = stackgap_init();
237
238         SCARG(&cup, fd) = SCARG(uap, fd);
239         SCARG(&cup, sb) = stackgap_alloc(&sg, sizeof(struct stat));
240         cup.sysmsg_result = 0;
241
242         if ((error = fstat(&cup)) != 0)
243                 return error;
244
245         if ((error = copyin(SCARG(&cup, sb), &st, sizeof st)) != 0)
246                 return error;
247
248         uap->sysmsg_result = cup.sysmsg_result;
249
250         bsd_to_svr4_stat(&st, &svr4_st);
251
252         if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
253                 return error;
254
255         return 0;
256 }
257
258
259 int
260 svr4_sys_xstat(struct svr4_sys_xstat_args *uap)
261 {
262         struct stat             st;
263         struct svr4_xstat       svr4_st;
264         struct stat_args        cup;
265         int                     error;
266
267         caddr_t sg = stackgap_init();
268         CHECKALTEXIST(&sg, SCARG(uap, path));
269
270         SCARG(&cup, path) = SCARG(uap, path);
271         SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
272         cup.sysmsg_result = 0;
273
274         if ((error = stat(&cup)) != 0)
275                 return error;
276
277         if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
278                 return error;
279
280         uap->sysmsg_result = cup.sysmsg_result;
281
282         bsd_to_svr4_xstat(&st, &svr4_st);
283
284 #if defined(SOCKET_NOTYET)
285         if (S_ISSOCK(st.st_mode))
286                 (void) svr4_add_socket(p, SCARG(uap, path), &st);
287 #endif
288
289         if ((error = copyout(&svr4_st, SCARG(uap, ub), sizeof svr4_st)) != 0)
290                 return error;
291
292         return 0;
293 }
294
295 int
296 svr4_sys_lxstat(struct svr4_sys_lxstat_args *uap)
297 {
298         struct stat             st;
299         struct svr4_xstat       svr4_st;
300         struct lstat_args       cup;
301         int                     error;
302         caddr_t sg = stackgap_init();
303         CHECKALTEXIST(&sg, SCARG(uap, path));
304
305         SCARG(&cup, path) = SCARG(uap, path);
306         SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
307         cup.sysmsg_result = 0;
308
309         if ((error = lstat(&cup)) != 0)
310                 return error;
311
312         if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
313                 return error;
314
315         uap->sysmsg_result = cup.sysmsg_result;
316
317         bsd_to_svr4_xstat(&st, &svr4_st);
318
319 #if defined(SOCKET_NOTYET)
320         if (S_ISSOCK(st.st_mode))
321                 (void) svr4_add_socket(p, SCARG(uap, path), &st);
322 #endif
323         if ((error = copyout(&svr4_st, SCARG(uap, ub), sizeof svr4_st)) != 0)
324                 return error;
325
326         return 0;
327 }
328
329
330 int
331 svr4_sys_fxstat(struct svr4_sys_fxstat_args *uap)
332 {
333         struct stat             st;
334         struct svr4_xstat       svr4_st;
335         struct fstat_args       cup;
336         int                     error;
337
338         caddr_t sg = stackgap_init();
339
340         SCARG(&cup, fd) = SCARG(uap, fd);
341         SCARG(&cup, sb) = stackgap_alloc(&sg, sizeof(struct stat));
342         cup.sysmsg_result = 0;
343
344         if ((error = fstat(&cup)) != 0)
345                 return error;
346
347         if ((error = copyin(SCARG(&cup, sb), &st, sizeof st)) != 0)
348                 return error;
349
350         uap->sysmsg_result = cup.sysmsg_result;
351
352         bsd_to_svr4_xstat(&st, &svr4_st);
353
354         if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
355                 return error;
356
357         return 0;
358 }
359
360 int
361 svr4_sys_stat64(struct svr4_sys_stat64_args *uap)
362 {
363         struct thread *td = curthread;
364         struct stat             st;
365         struct svr4_stat64      svr4_st;
366         struct stat_args        cup;
367         int                     error;
368         caddr_t                 sg = stackgap_init();
369
370         CHECKALTEXIST(&sg, SCARG(uap, path));
371
372         SCARG(&cup, path) = SCARG(uap, path);
373         SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
374         cup.sysmsg_result = 0;
375
376         if ((error = stat(&cup)) != 0)
377                 return error;
378
379         if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
380                 return error;
381
382         uap->sysmsg_result = cup.sysmsg_result;
383
384         bsd_to_svr4_stat64(&st, &svr4_st);
385
386         if (S_ISSOCK(st.st_mode))
387                 (void) svr4_add_socket(td, SCARG(uap, path), &st);
388
389         if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
390                 return error;
391
392         return 0;
393 }
394
395
396 int
397 svr4_sys_lstat64(struct svr4_sys_lstat64_args *uap)
398 {
399         struct thread *td = curthread;
400         struct stat             st;
401         struct svr4_stat64      svr4_st;
402         struct stat_args        cup;
403         int                     error;
404         caddr_t                 sg = stackgap_init();
405
406         CHECKALTEXIST(&sg, (char *) SCARG(uap, path));
407
408         SCARG(&cup, path) = SCARG(uap, path);
409         SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
410         cup.sysmsg_result = 0;
411
412         if ((error = lstat((struct lstat_args *)&cup)) != 0)
413                 return error;
414
415         if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
416                 return error;
417
418         uap->sysmsg_result = cup.sysmsg_result;
419
420         bsd_to_svr4_stat64(&st, &svr4_st);
421
422         if (S_ISSOCK(st.st_mode))
423                 (void) svr4_add_socket(td, SCARG(uap, path), &st);
424
425         if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
426                 return error;
427
428         return 0;
429 }
430
431
432 int
433 svr4_sys_fstat64(struct svr4_sys_fstat64_args *uap)
434 {
435         struct stat             st;
436         struct svr4_stat64      svr4_st;
437         struct fstat_args       cup;
438         int                     error;
439         caddr_t sg = stackgap_init();
440
441         SCARG(&cup, fd) = SCARG(uap, fd);
442         SCARG(&cup, sb) = stackgap_alloc(&sg, sizeof(struct stat));
443         cup.sysmsg_result = 0;
444
445         if ((error = fstat(&cup)) != 0)
446                 return error;
447
448         if ((error = copyin(SCARG(&cup, sb), &st, sizeof st)) != 0)
449                 return error;
450
451         uap->sysmsg_result = cup.sysmsg_result;
452
453         bsd_to_svr4_stat64(&st, &svr4_st);
454
455         if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
456                 return error;
457
458         return 0;
459 }
460
461
462 int
463 svr4_ustat(struct svr4_ustat_args *uap)
464 {
465         struct svr4_ustat       us;
466         int                     error;
467
468         memset(&us, 0, sizeof us);
469
470         /*
471          * XXX: should set f_tfree and f_tinode at least
472          * How do we translate dev -> fstat? (and then to svr4_ustat)
473          */
474         if ((error = copyout(&us, SCARG(uap, name), sizeof us)) != 0)
475                 return (error);
476
477         return 0;
478 }
479
480 /*extern char ostype[], hostname[], osrelease[], version[], machine[];*/
481
482 int
483 svr4_sys_uname(struct svr4_sys_uname_args *uap)
484 {
485         struct svr4_utsname     sut;
486         
487         memset(&sut, 0, sizeof(sut));
488
489         strncpy(sut.sysname, ostype, sizeof(sut.sysname));
490         sut.sysname[sizeof(sut.sysname) - 1] = '\0';
491
492         strncpy(sut.nodename, hostname, sizeof(sut.nodename));
493         sut.nodename[sizeof(sut.nodename) - 1] = '\0';
494
495         strncpy(sut.release, osrelease, sizeof(sut.release));
496         sut.release[sizeof(sut.release) - 1] = '\0';
497
498         strncpy(sut.version, version, sizeof(sut.version));
499         sut.version[sizeof(sut.version) - 1] = '\0';
500
501         strncpy(sut.machine, machine, sizeof(sut.machine));
502         sut.machine[sizeof(sut.machine) - 1] = '\0';
503
504         return copyout((caddr_t) &sut, (caddr_t) SCARG(uap, name),
505                        sizeof(struct svr4_utsname));
506 }
507
508 int
509 svr4_sys_systeminfo(struct svr4_sys_systeminfo_args *uap)
510 {
511         char            *str = NULL;
512         int             error = 0;
513         register_t      *retval = &uap->sysmsg_result;
514         size_t          len = 0;
515         char            buf[1];   /* XXX NetBSD uses 256, but that seems
516                                      like awfully excessive kstack usage
517                                      for an empty string... */
518         u_int           rlen = SCARG(uap, len);
519
520         switch (SCARG(uap, what)) {
521         case SVR4_SI_SYSNAME:
522                 str = ostype;
523                 break;
524
525         case SVR4_SI_HOSTNAME:
526                 str = hostname;
527                 break;
528
529         case SVR4_SI_RELEASE:
530                 str = osrelease;
531                 break;
532
533         case SVR4_SI_VERSION:
534                 str = version;
535                 break;
536
537         case SVR4_SI_MACHINE:
538                 str = machine;
539                 break;
540
541         case SVR4_SI_ARCHITECTURE:
542                 str = machine;
543                 break;
544
545         case SVR4_SI_HW_SERIAL:
546                 str = "0";
547                 break;
548
549         case SVR4_SI_HW_PROVIDER:
550                 str = ostype;
551                 break;
552
553         case SVR4_SI_SRPC_DOMAIN:
554                 str = domainname;
555                 break;
556
557         case SVR4_SI_PLATFORM:
558 #ifdef __i386__
559                 str = "i86pc";
560 #else
561                 str = "unknown";
562 #endif
563                 break;
564
565         case SVR4_SI_KERB_REALM:
566                 str = "unsupported";
567                 break;
568 #if defined(WHY_DOES_AN_EMULATOR_WANT_TO_SET_HOSTNAMES)
569         case SVR4_SI_SET_HOSTNAME:
570                 if ((error = suser(td)) != 0)
571                         return error;
572                 name = KERN_HOSTNAME;
573                 return kern_sysctl(&name, 1, 0, 0, SCARG(uap, buf), rlen, p);
574
575         case SVR4_SI_SET_SRPC_DOMAIN:
576                 if ((error = suser(td)) != 0)
577                         return error;
578                 name = KERN_NISDOMAINNAME;
579                 return kern_sysctl(&name, 1, 0, 0, SCARG(uap, buf), rlen, p);
580 #else
581         case SVR4_SI_SET_HOSTNAME:
582         case SVR4_SI_SET_SRPC_DOMAIN:
583                 /* FALLTHROUGH */
584 #endif
585         case SVR4_SI_SET_KERB_REALM:
586                 return 0;
587
588         default:
589                 DPRINTF(("Bad systeminfo command %d\n", SCARG(uap, what)));
590                 return ENOSYS;
591         }
592
593         if (str) {
594                 len = strlen(str) + 1;
595                 if (len > rlen)
596                         len = rlen;
597
598                 if (SCARG(uap, buf)) {
599                         error = copyout(str, SCARG(uap, buf), len);
600                         if (error)
601                                 return error;
602                         /* make sure we are NULL terminated */
603                         buf[0] = '\0';
604                         error = copyout(buf, &(SCARG(uap, buf)[len - 1]), 1);
605                 }
606                 else
607                         error = 0;
608         }
609         /* XXX NetBSD has hostname setting stuff here.  Why would an emulator
610            want to do that? */
611
612         *retval = len;
613         return error;
614 }
615
616 int
617 svr4_sys_utssys(struct svr4_sys_utssys_args *uap)
618 {
619         switch (SCARG(uap, sel)) {
620         case 0:         /* uname(2)  */
621                 {
622                         struct svr4_sys_uname_args ua;
623                         int error;
624
625                         SCARG(&ua, name) = SCARG(uap, a1);
626                         ua.sysmsg_result = 0;
627                         error = svr4_sys_uname(&ua);
628                         uap->sysmsg_result = ua.sysmsg_result;
629                         return(error);
630                 }
631
632         case 2:         /* ustat(2)  */
633                 {
634                         struct svr4_ustat_args ua;
635                         int error;
636
637                         SCARG(&ua, dev) = (svr4_dev_t) SCARG(uap, a2);
638                         SCARG(&ua, name) = SCARG(uap, a1);
639                         ua.sysmsg_result = 0;
640                         error = svr4_ustat(&ua);
641                         uap->sysmsg_result = ua.sysmsg_result;
642                         return(error);
643                 }
644
645         case 3:         /* fusers(2) */
646                 return ENOSYS;
647
648         default:
649                 return ENOSYS;
650         }
651         return ENOSYS;
652 }
653
654
655 int
656 svr4_sys_utime(struct svr4_sys_utime_args *uap)
657 {
658         struct svr4_utimbuf ub;
659         struct timeval tbuf[2];
660         struct utimes_args ap;
661         int error;
662         caddr_t sg = stackgap_init();
663         void *ttp;
664
665         CHECKALTEXIST(&sg, SCARG(uap, path));
666         SCARG(&ap, path) = SCARG(uap, path);
667         if (SCARG(uap, ubuf) != NULL) {
668                 if ((error = copyin(SCARG(uap, ubuf), &ub, sizeof(ub))) != 0)
669                         return error;
670                 tbuf[0].tv_sec = ub.actime;
671                 tbuf[0].tv_usec = 0;
672                 tbuf[1].tv_sec = ub.modtime;
673                 tbuf[1].tv_usec = 0;
674                 ttp = stackgap_alloc(&sg, sizeof(tbuf));
675                 error = copyout(tbuf, ttp, sizeof(tbuf));
676                 if (error)
677                         return error;
678                 SCARG(&ap, tptr) = ttp;
679         } else {
680                 SCARG(&ap, tptr) = NULL;
681         }
682         ap.sysmsg_result = 0;
683         error = utimes(&ap);
684         uap->sysmsg_result = ap.sysmsg_result;
685         return(error);
686 }
687
688
689 int
690 svr4_sys_utimes(struct svr4_sys_utimes_args *uap)
691 {
692         caddr_t sg = stackgap_init();
693         CHECKALTEXIST(&sg, SCARG(uap, path));
694         return utimes((struct utimes_args *)uap);
695 }
696
697 static int
698 svr4_to_bsd_pathconf(name)
699         int name;
700 {
701         switch (name) {
702         case SVR4_PC_LINK_MAX:
703                 return _PC_LINK_MAX;
704
705         case SVR4_PC_MAX_CANON:
706                 return _PC_MAX_CANON;
707
708         case SVR4_PC_MAX_INPUT:
709                 return _PC_MAX_INPUT;
710
711         case SVR4_PC_NAME_MAX:
712                 return _PC_NAME_MAX;
713
714         case SVR4_PC_PATH_MAX:
715                 return _PC_PATH_MAX;
716
717         case SVR4_PC_PIPE_BUF:
718                 return _PC_PIPE_BUF;
719
720         case SVR4_PC_NO_TRUNC:
721                 return _PC_NO_TRUNC;
722
723         case SVR4_PC_VDISABLE:
724                 return _PC_VDISABLE;
725
726         case SVR4_PC_CHOWN_RESTRICTED:
727                 return _PC_CHOWN_RESTRICTED;
728         case SVR4_PC_SYNC_IO:
729 #if defined(_PC_SYNC_IO)
730                 return _PC_SYNC_IO;
731 #else
732                 return 0;
733 #endif
734         case SVR4_PC_ASYNC_IO:
735         case SVR4_PC_PRIO_IO:
736                 /* Not supported */
737                 return 0;
738
739         default:
740                 /* Invalid */
741                 return -1;
742         }
743 }
744
745
746 int
747 svr4_sys_pathconf(struct svr4_sys_pathconf_args *uap)
748 {
749         caddr_t         sg = stackgap_init();
750         register_t      *retval = &uap->sysmsg_result;
751
752         CHECKALTEXIST(&sg, SCARG(uap, path));
753
754         SCARG(uap, name) = svr4_to_bsd_pathconf(SCARG(uap, name));
755
756         switch (SCARG(uap, name)) {
757         case -1:
758                 *retval = -1;
759                 return EINVAL;
760         case 0:
761                 *retval = 0;
762                 return 0;
763         default:
764                 return pathconf((struct pathconf_args *)uap);
765         }
766 }
767
768
769 int
770 svr4_sys_fpathconf(struct svr4_sys_fpathconf_args *uap)
771 {
772         register_t      *retval = &uap->sysmsg_result;
773
774         SCARG(uap, name) = svr4_to_bsd_pathconf(SCARG(uap, name));
775
776         switch (SCARG(uap, name)) {
777         case -1:
778                 *retval = -1;
779                 return EINVAL;
780         case 0:
781                 *retval = 0;
782                 return 0;
783         default:
784                 return fpathconf((struct fpathconf_args *)uap);
785         }
786 }