This source file includes following definitions.
- convert_from_freebsd_mount_type
- freebsd_sys_mount
- freebsd_sys_open
- compat_43_freebsd_sys_creat
- freebsd_sys_link
- freebsd_sys_unlink
- freebsd_sys_chdir
- freebsd_sys_mknod
- freebsd_sys_chmod
- freebsd_sys_chown
- freebsd_sys_unmount
- freebsd_sys_access
- freebsd_sys_chflags
- compat_43_freebsd_sys_stat
- compat_43_freebsd_sys_lstat
- freebsd_sys_revoke
- freebsd_sys_symlink
- freebsd_sys_readlink
- freebsd_sys_execve
- freebsd_sys_chroot
- freebsd_sys_rename
- compat_43_freebsd_sys_truncate
- freebsd_sys_mkfifo
- freebsd_sys_mkdir
- freebsd_sys_rmdir
- statfs_to_freebsd_statfs
- freebsd_sys_statfs
- freebsd_sys_fstatfs
- freebsd_sys_getfsstat
- freebsd_sys_getfh
- freebsd_sys_stat
- freebsd_sys_lstat
- freebsd_sys_pathconf
- freebsd_sys_truncate
- freebsd_sys_fcntl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/namei.h>
40 #include <sys/proc.h>
41 #include <sys/file.h>
42 #include <sys/stat.h>
43 #include <sys/filedesc.h>
44 #include <sys/ioctl.h>
45 #include <sys/kernel.h>
46 #include <sys/vnode.h>
47 #include <sys/mount.h>
48 #include <sys/malloc.h>
49
50 #include <sys/syscallargs.h>
51
52 #include <compat/freebsd/freebsd_signal.h>
53 #include <compat/freebsd/freebsd_syscallargs.h>
54 #include <compat/freebsd/freebsd_util.h>
55
56 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
57
58 const char freebsd_emul_path[] = "/emul/freebsd";
59
60 static char * convert_from_freebsd_mount_type(int);
61 void statfs_to_freebsd_statfs(struct proc *, struct mount *, struct statfs *, struct freebsd_statfs *);
62
63 struct freebsd_statfs {
64 long f_spare2;
65 long f_bsize;
66 long f_iosize;
67 long f_blocks;
68 long f_bfree;
69 long f_bavail;
70 long f_files;
71 long f_ffree;
72 fsid_t f_fsid;
73 uid_t f_owner;
74 int f_type;
75 int f_flags;
76 long f_syncwrites;
77 long f_asyncwrites;
78 char f_fstypename[MFSNAMELEN];
79 char f_mntonname[MNAMELEN];
80 char f_mntfromname[MNAMELEN];
81 };
82
83 static char *
84 convert_from_freebsd_mount_type(type)
85 int type;
86 {
87 static char *freebsd_mount_type[] = {
88 NULL,
89 "ffs",
90 "nfs",
91 "mfs",
92 "msdos",
93 "lfs",
94 "lofs",
95 "fdesc",
96 "portal",
97 "null",
98 "umap",
99 "kernfs",
100 "procfs",
101 "afs",
102 "cd9660",
103 "union",
104 NULL,
105 #if 0
106 "adosfs",
107 #endif
108 };
109
110 if (type < 0 || type >= ARRAY_LENGTH(freebsd_mount_type))
111 return (NULL);
112 return (freebsd_mount_type[type]);
113 }
114
115 int
116 freebsd_sys_mount(p, v, retval)
117 struct proc *p;
118 void *v;
119 register_t *retval;
120 {
121 struct freebsd_sys_mount_args
122
123
124
125
126 *uap = v;
127 int error;
128 char *type, *s;
129 caddr_t sg = stackgap_init(p->p_emul);
130 struct sys_mount_args bma;
131
132 if ((type = convert_from_freebsd_mount_type(SCARG(uap, type))) == NULL)
133 return ENODEV;
134 s = stackgap_alloc(&sg, MFSNAMELEN + 1);
135 if ((error = copyout(type, s, strlen(type) + 1)) != 0)
136 return error;
137 SCARG(&bma, type) = s;
138 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
139 SCARG(&bma, path) = SCARG(uap, path);
140 SCARG(&bma, flags) = SCARG(uap, flags);
141 SCARG(&bma, data) = SCARG(uap, data);
142 return sys_mount(p, &bma, retval);
143 }
144
145
146
147
148
149
150
151
152
153 int
154 freebsd_sys_open(p, v, retval)
155 struct proc *p;
156 void *v;
157 register_t *retval;
158 {
159 struct freebsd_sys_open_args
160
161
162
163 *uap = v;
164 caddr_t sg = stackgap_init(p->p_emul);
165
166 if (SCARG(uap, flags) & O_CREAT)
167 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
168 else
169 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
170 return sys_open(p, uap, retval);
171 }
172
173 int
174 compat_43_freebsd_sys_creat(p, v, retval)
175 struct proc *p;
176 void *v;
177 register_t *retval;
178 {
179 struct compat_43_freebsd_sys_creat_args
180
181
182 *uap = v;
183 caddr_t sg = stackgap_init(p->p_emul);
184
185 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
186 return compat_43_sys_creat(p, uap, retval);
187 }
188
189 int
190 freebsd_sys_link(p, v, retval)
191 struct proc *p;
192 void *v;
193 register_t *retval;
194 {
195 struct freebsd_sys_link_args
196
197
198 *uap = v;
199 caddr_t sg = stackgap_init(p->p_emul);
200
201 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
202 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
203 return sys_link(p, uap, retval);
204 }
205
206 int
207 freebsd_sys_unlink(p, v, retval)
208 struct proc *p;
209 void *v;
210 register_t *retval;
211 {
212 struct freebsd_sys_unlink_args
213
214 *uap = v;
215 caddr_t sg = stackgap_init(p->p_emul);
216
217 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
218 return sys_unlink(p, uap, retval);
219 }
220
221 int
222 freebsd_sys_chdir(p, v, retval)
223 struct proc *p;
224 void *v;
225 register_t *retval;
226 {
227 struct freebsd_sys_chdir_args
228
229 *uap = v;
230 caddr_t sg = stackgap_init(p->p_emul);
231
232 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
233 return sys_chdir(p, uap, retval);
234 }
235
236 int
237 freebsd_sys_mknod(p, v, retval)
238 struct proc *p;
239 void *v;
240 register_t *retval;
241 {
242 struct freebsd_sys_mknod_args
243
244
245
246 *uap = v;
247 caddr_t sg = stackgap_init(p->p_emul);
248
249 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
250 return sys_mknod(p, uap, retval);
251 }
252
253 int
254 freebsd_sys_chmod(p, v, retval)
255 struct proc *p;
256 void *v;
257 register_t *retval;
258 {
259 struct freebsd_sys_chmod_args
260
261
262 *uap = v;
263 caddr_t sg = stackgap_init(p->p_emul);
264
265 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
266 return sys_chmod(p, uap, retval);
267 }
268
269 int
270 freebsd_sys_chown(p, v, retval)
271 struct proc *p;
272 void *v;
273 register_t *retval;
274 {
275 struct freebsd_sys_chown_args
276
277
278
279 *uap = v;
280 caddr_t sg = stackgap_init(p->p_emul);
281
282 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
283 return sys_chown(p, uap, retval);
284 }
285
286 int
287 freebsd_sys_unmount(p, v, retval)
288 struct proc *p;
289 void *v;
290 register_t *retval;
291 {
292 struct freebsd_sys_unmount_args
293
294
295 *uap = v;
296 caddr_t sg = stackgap_init(p->p_emul);
297
298 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
299 return sys_unmount(p, uap, retval);
300 }
301
302 int
303 freebsd_sys_access(p, v, retval)
304 struct proc *p;
305 void *v;
306 register_t *retval;
307 {
308 struct freebsd_sys_access_args
309
310
311 *uap = v;
312 caddr_t sg = stackgap_init(p->p_emul);
313
314 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
315 return sys_access(p, uap, retval);
316 }
317
318 int
319 freebsd_sys_chflags(p, v, retval)
320 struct proc *p;
321 void *v;
322 register_t *retval;
323 {
324 struct freebsd_sys_chflags_args
325
326
327 *uap = v;
328 caddr_t sg = stackgap_init(p->p_emul);
329
330 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
331 return sys_chflags(p, uap, retval);
332 }
333
334 int
335 compat_43_freebsd_sys_stat(p, v, retval)
336 struct proc *p;
337 void *v;
338 register_t *retval;
339 {
340 struct compat_43_freebsd_sys_stat_args
341
342
343 *uap = v;
344 caddr_t sg = stackgap_init(p->p_emul);
345
346 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
347 return compat_43_sys_stat(p, uap, retval);
348 }
349
350 int
351 compat_43_freebsd_sys_lstat(p, v, retval)
352 struct proc *p;
353 void *v;
354 register_t *retval;
355 {
356 struct compat_43_freebsd_sys_lstat_args
357
358
359 *uap = v;
360 caddr_t sg = stackgap_init(p->p_emul);
361
362 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
363 return compat_43_sys_lstat(p, uap, retval);
364 }
365
366 int
367 freebsd_sys_revoke(p, v, retval)
368 struct proc *p;
369 void *v;
370 register_t *retval;
371 {
372 struct freebsd_sys_revoke_args
373
374 *uap = v;
375 caddr_t sg = stackgap_init(p->p_emul);
376
377 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
378 return sys_revoke(p, uap, retval);
379 }
380
381 int
382 freebsd_sys_symlink(p, v, retval)
383 struct proc *p;
384 void *v;
385 register_t *retval;
386 {
387 struct freebsd_sys_symlink_args
388
389
390 *uap = v;
391 caddr_t sg = stackgap_init(p->p_emul);
392
393 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
394 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
395 return sys_symlink(p, uap, retval);
396 }
397
398 int
399 freebsd_sys_readlink(p, v, retval)
400 struct proc *p;
401 void *v;
402 register_t *retval;
403 {
404 struct freebsd_sys_readlink_args
405
406
407
408 *uap = v;
409 caddr_t sg = stackgap_init(p->p_emul);
410
411 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
412 return sys_readlink(p, uap, retval);
413 }
414
415 int
416 freebsd_sys_execve(p, v, retval)
417 struct proc *p;
418 void *v;
419 register_t *retval;
420 {
421 struct freebsd_sys_execve_args
422
423
424
425 *uap = v;
426 struct sys_execve_args ap;
427 caddr_t sg;
428
429 sg = stackgap_init(p->p_emul);
430 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
431
432 SCARG(&ap, path) = SCARG(uap, path);
433 SCARG(&ap, argp) = SCARG(uap, argp);
434 SCARG(&ap, envp) = SCARG(uap, envp);
435
436 return sys_execve(p, &ap, retval);
437 }
438
439 int
440 freebsd_sys_chroot(p, v, retval)
441 struct proc *p;
442 void *v;
443 register_t *retval;
444 {
445 struct freebsd_sys_chroot_args
446
447 *uap = v;
448 caddr_t sg = stackgap_init(p->p_emul);
449
450 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
451 return sys_chroot(p, uap, retval);
452 }
453
454 int
455 freebsd_sys_rename(p, v, retval)
456 struct proc *p;
457 void *v;
458 register_t *retval;
459 {
460 struct freebsd_sys_rename_args
461
462
463 *uap = v;
464 caddr_t sg = stackgap_init(p->p_emul);
465
466 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
467 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
468 return sys_rename(p, uap, retval);
469 }
470
471 int
472 compat_43_freebsd_sys_truncate(p, v, retval)
473 struct proc *p;
474 void *v;
475 register_t *retval;
476 {
477 struct compat_43_freebsd_sys_truncate_args
478
479
480 *uap = v;
481 caddr_t sg = stackgap_init(p->p_emul);
482
483 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
484 return compat_43_sys_truncate(p, uap, retval);
485 }
486
487 int
488 freebsd_sys_mkfifo(p, v, retval)
489 struct proc *p;
490 void *v;
491 register_t *retval;
492 {
493 struct freebsd_sys_mkfifo_args
494
495
496 *uap = v;
497 caddr_t sg = stackgap_init(p->p_emul);
498
499 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
500 return sys_mkfifo(p, uap, retval);
501 }
502
503 int
504 freebsd_sys_mkdir(p, v, retval)
505 struct proc *p;
506 void *v;
507 register_t *retval;
508 {
509 struct freebsd_sys_mkdir_args
510
511
512 *uap = v;
513 caddr_t sg = stackgap_init(p->p_emul);
514
515 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
516 return sys_mkdir(p, uap, retval);
517 }
518
519 int
520 freebsd_sys_rmdir(p, v, retval)
521 struct proc *p;
522 void *v;
523 register_t *retval;
524 {
525 struct freebsd_sys_rmdir_args
526
527 *uap = v;
528 caddr_t sg = stackgap_init(p->p_emul);
529
530 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
531 return sys_rmdir(p, uap, retval);
532 }
533
534
535
536
537 void
538 statfs_to_freebsd_statfs(p, mp, sp, fsp)
539 struct proc *p;
540 struct mount *mp;
541 struct statfs *sp;
542 struct freebsd_statfs *fsp;
543 {
544 fsp->f_bsize = sp->f_bsize;
545 fsp->f_iosize = sp->f_iosize;
546 fsp->f_blocks = sp->f_blocks;
547 fsp->f_bfree = sp->f_bfree;
548 fsp->f_bavail = sp->f_bavail;
549 fsp->f_files = sp->f_files;
550 fsp->f_ffree = sp->f_ffree;
551
552 if (suser(p, 0))
553 fsp->f_fsid.val[0] = fsp->f_fsid.val[1] = 0;
554 else
555 bcopy(&sp->f_fsid, &fsp->f_fsid, sizeof(fsp->f_fsid));
556 fsp->f_owner = sp->f_owner;
557 fsp->f_type = mp->mnt_vfc->vfc_typenum;
558 fsp->f_flags = sp->f_flags;
559 fsp->f_syncwrites = sp->f_syncwrites;
560 fsp->f_asyncwrites = sp->f_asyncwrites;
561 bcopy(sp->f_fstypename, fsp->f_fstypename, MFSNAMELEN);
562 bcopy(sp->f_mntonname, fsp->f_mntonname, MNAMELEN);
563 bcopy(sp->f_mntfromname, fsp->f_mntfromname, MNAMELEN);
564 }
565
566
567
568
569
570 int
571 freebsd_sys_statfs(p, v, retval)
572 struct proc *p;
573 void *v;
574 register_t *retval;
575 {
576 register struct freebsd_sys_statfs_args
577
578
579 *uap = v;
580 register struct mount *mp;
581 register struct statfs *sp;
582 struct freebsd_statfs fsb;
583 int error;
584 struct nameidata nd;
585 caddr_t sg = stackgap_init(p->p_emul);
586
587 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
588 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
589 if ((error = namei(&nd)) != 0)
590 return (error);
591 mp = nd.ni_vp->v_mount;
592 sp = &mp->mnt_stat;
593 vrele(nd.ni_vp);
594 if ((error = VFS_STATFS(mp, sp, p)) != 0)
595 return (error);
596 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
597
598 statfs_to_freebsd_statfs(p, mp, sp, &fsb);
599 return (copyout((caddr_t)&fsb, (caddr_t)SCARG(uap, buf), sizeof(fsb)));
600 }
601
602
603
604
605
606 int
607 freebsd_sys_fstatfs(p, v, retval)
608 struct proc *p;
609 void *v;
610 register_t *retval;
611 {
612 register struct freebsd_sys_fstatfs_args
613
614
615 *uap = v;
616 struct file *fp;
617 struct mount *mp;
618 register struct statfs *sp;
619 struct freebsd_statfs fsb;
620 int error;
621
622 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
623 return (error);
624 mp = ((struct vnode *)fp->f_data)->v_mount;
625 sp = &mp->mnt_stat;
626 error = VFS_STATFS(mp, sp, p);
627 FRELE(fp);
628 if (error)
629 return (error);
630 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
631
632 statfs_to_freebsd_statfs(p, mp, sp, &fsb);
633 return (copyout((caddr_t)&fsb, (caddr_t)SCARG(uap, buf), sizeof(fsb)));
634 }
635
636
637
638
639 int
640 freebsd_sys_getfsstat(p, v, retval)
641 struct proc *p;
642 void *v;
643 register_t *retval;
644 {
645 register struct freebsd_sys_getfsstat_args
646
647
648
649 *uap = v;
650 register struct mount *mp, *nmp;
651 register struct statfs *sp;
652 struct freebsd_statfs fsb;
653 caddr_t sfsp;
654 long count, maxcount;
655 int error, flags = SCARG(uap, flags);
656
657 maxcount = SCARG(uap, bufsize) / sizeof(struct freebsd_statfs);
658 sfsp = (caddr_t)SCARG(uap, buf);
659 count = 0;
660
661 for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
662 mp = nmp) {
663 if (vfs_busy(mp, VB_READ|VB_NOWAIT)) {
664 nmp = CIRCLEQ_NEXT(mp, mnt_list);
665 continue;
666 }
667 if (sfsp && count < maxcount) {
668 sp = &mp->mnt_stat;
669
670
671 if (flags != MNT_NOWAIT &&
672 flags != MNT_LAZY &&
673 (flags == MNT_WAIT ||
674 flags == 0) &&
675 (error = VFS_STATFS(mp, sp, p))) {
676 nmp = CIRCLEQ_NEXT(mp, mnt_list);
677 vfs_unbusy(mp);
678 continue;
679 }
680 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
681
682 statfs_to_freebsd_statfs(p, mp, sp, &fsb);
683 error = copyout((caddr_t)&fsb, sfsp, sizeof(fsb));
684 if (error) {
685 vfs_unbusy(mp);
686 return (error);
687 }
688 sfsp += sizeof(fsb);
689 }
690 count++;
691 nmp = CIRCLEQ_NEXT(mp, mnt_list);
692 vfs_unbusy(mp);
693 }
694
695 if (sfsp && count > maxcount)
696 *retval = maxcount;
697 else
698 *retval = count;
699
700 return (0);
701 }
702
703 #ifdef NFSCLIENT
704 int
705 freebsd_sys_getfh(p, v, retval)
706 struct proc *p;
707 void *v;
708 register_t *retval;
709 {
710 struct freebsd_sys_getfh_args
711
712
713 *uap = v;
714 caddr_t sg = stackgap_init(p->p_emul);
715
716 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname));
717 return sys_getfh(p, uap, retval);
718 }
719 #endif
720
721 int
722 freebsd_sys_stat(p, v, retval)
723 struct proc *p;
724 void *v;
725 register_t *retval;
726 {
727 struct freebsd_sys_stat_args
728
729
730 *uap = v;
731 caddr_t sg = stackgap_init(p->p_emul);
732
733 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
734 return compat_35_sys_stat(p, uap, retval);
735 }
736
737 int
738 freebsd_sys_lstat(p, v, retval)
739 struct proc *p;
740 void *v;
741 register_t *retval;
742 {
743 struct freebsd_sys_lstat_args
744
745
746 *uap = v;
747 caddr_t sg = stackgap_init(p->p_emul);
748
749 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
750 return compat_35_sys_lstat(p, uap, retval);
751 }
752
753 int
754 freebsd_sys_pathconf(p, v, retval)
755 struct proc *p;
756 void *v;
757 register_t *retval;
758 {
759 struct freebsd_sys_pathconf_args
760
761
762 *uap = v;
763 caddr_t sg = stackgap_init(p->p_emul);
764
765 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
766 return sys_pathconf(p, uap, retval);
767 }
768
769 int
770 freebsd_sys_truncate(p, v, retval)
771 struct proc *p;
772 void *v;
773 register_t *retval;
774 {
775 struct freebsd_sys_truncate_args
776
777
778
779 *uap = v;
780 caddr_t sg = stackgap_init(p->p_emul);
781
782 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
783 return sys_truncate(p, uap, retval);
784 }
785
786
787
788
789
790 int
791 freebsd_sys_fcntl(p, v, retval)
792 struct proc *p;
793 void *v;
794 register_t *retval;
795 {
796 struct freebsd_sys_fcntl_args
797
798
799
800 *uap = v;
801 int fd, cmd, error;
802 struct filedesc *fdp;
803 struct file *fp;
804
805 fd = SCARG(uap, fd);
806 cmd = SCARG(uap, cmd);
807
808 switch (cmd) {
809 case F_GETOWN:
810 case F_SETOWN:
811
812 fdp = p->p_fd;
813 if ((fp = fd_getfile(fdp, fd)) == NULL)
814 return (EBADF);
815 if (fp->f_type == DTYPE_PIPE) {
816 FREF(fp);
817 error = (*fp->f_ops->fo_ioctl)(fp,
818 cmd == F_GETOWN ? SIOCGPGRP : SIOCSPGRP,
819 (caddr_t)&SCARG(uap, arg), p);
820 FRELE(fp);
821 return (error);
822 }
823 break;
824 }
825
826 return (sys_fcntl(p, uap, retval));
827 }
828