This source file includes following definitions.
- bsd_to_linux_wstat
- linux_sys_waitpid
- linux_sys_wait4
- linux_sys_setresgid16
- linux_sys_getresgid16
- linux_sys_setresuid16
- linux_sys_getresuid16
- linux_sys_break
- linux_sys_brk
- linux_sys_time
- bsd_to_linux_statfs
- linux_sys_statfs
- linux_sys_fstatfs
- linux_sys_uname
- linux_sys_olduname
- linux_sys_oldolduname
- linux_sys_mmap
- linux_sys_mmap2
- linux_to_bsd_mmap_args
- linux_sys_mremap
- linux_sys_times
- linux_sys_pipe
- linux_sys_alarm
- linux_sys_utime
- linux_sys_readdir
- linux_readdir_callback
- linux_sys_getdents64
- linux_sys_getdents
- getdents_common
- linux_sys_oldselect
- linux_sys_select
- linux_select1
- linux_sys_getpgid
- linux_sys_personality
- linux_sys_setreuid16
- linux_sys_setregid16
- linux_sys_getsid
- linux_sys___sysctl
- linux_sys_setfsuid
- linux_sys_getfsuid
- linux_sys_nice
- linux_sys_stime
- linux_sys_getpid
- linux_sys_getuid
- linux_sys_getgid
- linux_sys_sysinfo
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
38
39
40
41
42
43
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/namei.h>
48 #include <sys/proc.h>
49 #include <sys/dirent.h>
50 #include <sys/file.h>
51 #include <sys/stat.h>
52 #include <sys/filedesc.h>
53 #include <sys/ioctl.h>
54 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #include <sys/mbuf.h>
57 #include <sys/mman.h>
58 #include <sys/mount.h>
59 #include <sys/ptrace.h>
60 #include <sys/resource.h>
61 #include <sys/resourcevar.h>
62 #include <sys/signal.h>
63 #include <sys/signalvar.h>
64 #include <sys/socket.h>
65 #include <sys/time.h>
66 #include <sys/times.h>
67 #include <sys/vnode.h>
68 #include <sys/uio.h>
69 #include <sys/wait.h>
70 #include <sys/utsname.h>
71 #include <sys/unistd.h>
72
73 #include <sys/syscallargs.h>
74
75 #include <uvm/uvm_extern.h>
76
77 #include <compat/linux/linux_types.h>
78 #include <compat/linux/linux_fcntl.h>
79 #include <compat/linux/linux_misc.h>
80 #include <compat/linux/linux_mmap.h>
81 #include <compat/linux/linux_sched.h>
82 #include <compat/linux/linux_signal.h>
83 #include <compat/linux/linux_syscallargs.h>
84 #include <compat/linux/linux_util.h>
85 #include <compat/linux/linux_dirent.h>
86 #include <compat/linux/linux_emuldata.h>
87
88 #include <compat/common/compat_dir.h>
89
90
91 static void bsd_to_linux_statfs(struct statfs *, struct linux_statfs *);
92 int linux_select1(struct proc *, register_t *, int, fd_set *,
93 fd_set *, fd_set *, struct timeval *);
94 static int getdents_common(struct proc *, void *, register_t *, int);
95 static void linux_to_bsd_mmap_args(struct sys_mmap_args *,
96 const struct linux_sys_mmap2_args *);
97
98
99
100
101
102
103 void
104 bsd_to_linux_wstat(status)
105 int *status;
106 {
107
108 if (WIFSIGNALED(*status))
109 *status = (*status & ~0177) |
110 bsd_to_linux_sig[WTERMSIG(*status)];
111 else if (WIFSTOPPED(*status))
112 *status = (*status & ~0xff00) |
113 (bsd_to_linux_sig[WSTOPSIG(*status)] << 8);
114 }
115
116
117
118
119 int
120 linux_sys_waitpid(p, v, retval)
121 struct proc *p;
122 void *v;
123 register_t *retval;
124 {
125 struct linux_sys_waitpid_args
126
127
128
129 *uap = v;
130 struct sys_wait4_args linux_w4a;
131
132 SCARG(&linux_w4a, pid) = SCARG(uap, pid);
133 SCARG(&linux_w4a, status) = SCARG(uap, status);
134 SCARG(&linux_w4a, options) = SCARG(uap, options);
135 SCARG(&linux_w4a, rusage) = NULL;
136
137 return (linux_sys_wait4(p, &linux_w4a, retval));
138 }
139
140
141
142
143
144
145 int
146 linux_sys_wait4(p, v, retval)
147 struct proc *p;
148 void *v;
149 register_t *retval;
150 {
151 struct linux_sys_wait4_args
152
153
154
155
156 *uap = v;
157 struct sys_wait4_args w4a;
158 int error, *status, tstat, linux_options, options;
159 caddr_t sg;
160
161 if (SCARG(uap, status) != NULL) {
162 sg = stackgap_init(p->p_emul);
163 status = (int *) stackgap_alloc(&sg, sizeof status);
164 } else
165 status = NULL;
166
167 linux_options = SCARG(uap, options);
168 options = 0;
169 if (linux_options &
170 ~(LINUX_WAIT4_WNOHANG|LINUX_WAIT4_WUNTRACED|LINUX_WAIT4_WCLONE))
171 return (EINVAL);
172
173 if (linux_options & LINUX_WAIT4_WNOHANG)
174 options |= WNOHANG;
175 if (linux_options & LINUX_WAIT4_WUNTRACED)
176 options |= WUNTRACED;
177 if (linux_options & LINUX_WAIT4_WCLONE)
178 options |= WALTSIG;
179
180 SCARG(&w4a, pid) = SCARG(uap, pid);
181 SCARG(&w4a, status) = status;
182 SCARG(&w4a, options) = options;
183 SCARG(&w4a, rusage) = SCARG(uap, rusage);
184
185 if ((error = sys_wait4(p, &w4a, retval)))
186 return error;
187
188 atomic_clearbits_int(&p->p_siglist, sigmask(SIGCHLD));
189
190 if (status != NULL) {
191 if ((error = copyin(status, &tstat, sizeof tstat)))
192 return error;
193
194 bsd_to_linux_wstat(&tstat);
195 return copyout(&tstat, SCARG(uap, status), sizeof tstat);
196 }
197
198 return 0;
199 }
200
201 int
202 linux_sys_setresgid16(p, v, retval)
203 struct proc *p;
204 void *v;
205 register_t *retval;
206 {
207 struct linux_sys_setresgid16_args
208
209
210
211 *uap = v;
212 struct sys_setresgid_args nuap;
213 u_int16_t rgid, egid, sgid;
214
215 rgid = SCARG(uap, rgid);
216 SCARG(&nuap, rgid) = (rgid == (u_int16_t)-1) ? (gid_t)-1 : rgid;
217 egid = SCARG(uap, egid);
218 SCARG(&nuap, egid) = (egid == (u_int16_t)-1) ? (gid_t)-1 : egid;
219 sgid = SCARG(uap, sgid);
220 SCARG(&nuap, sgid) = (sgid == (u_int16_t)-1) ? (gid_t)-1 : sgid;
221
222 return sys_setresgid(p, &nuap, retval);
223 }
224
225 int
226 linux_sys_getresgid16(p, v, retval)
227 struct proc *p;
228 void *v;
229 register_t *retval;
230 {
231 struct linux_sys_getresgid16_args
232
233
234
235 *uap = v;
236 struct sys_getresgid_args nuap;
237
238 SCARG(&nuap, rgid) = (gid_t *)SCARG(uap, rgid);
239 SCARG(&nuap, egid) = (gid_t *)SCARG(uap, egid);
240 SCARG(&nuap, sgid) = (gid_t *)SCARG(uap, sgid);
241
242 return sys_getresgid(p, &nuap, retval);
243 }
244
245 int
246 linux_sys_setresuid16(p, v, retval)
247 struct proc *p;
248 void *v;
249 register_t *retval;
250 {
251 struct linux_sys_setresuid16_args
252
253
254
255 *uap = v;
256 struct sys_setresuid_args nuap;
257 u_int16_t ruid, euid, suid;
258
259 ruid = SCARG(uap, ruid);
260 SCARG(&nuap, ruid) = (ruid == (u_int16_t)-1) ? (uid_t)-1 : ruid;
261 euid = SCARG(uap, euid);
262 SCARG(&nuap, euid) = (euid == (u_int16_t)-1) ? (uid_t)-1 : euid;
263 suid = SCARG(uap, suid);
264 SCARG(&nuap, suid) = (suid == (u_int16_t)-1) ? (uid_t)-1 : suid;
265
266 return sys_setresuid(p, &nuap, retval);
267 }
268
269 int
270 linux_sys_getresuid16(p, v, retval)
271 struct proc *p;
272 void *v;
273 register_t *retval;
274 {
275 struct linux_sys_getresuid16_args
276
277
278
279 *uap = v;
280 struct sys_getresuid_args nuap;
281
282 SCARG(&nuap, ruid) = (uid_t *)SCARG(uap, ruid);
283 SCARG(&nuap, euid) = (uid_t *)SCARG(uap, euid);
284 SCARG(&nuap, suid) = (uid_t *)SCARG(uap, suid);
285
286 return sys_getresuid(p, &nuap, retval);
287 }
288
289
290
291
292
293 int
294 linux_sys_break(p, v, retval)
295 struct proc *p;
296 void *v;
297 register_t *retval;
298 {
299 #if 0
300 struct linux_sys_brk_args
301
302 *uap = v;
303 #endif
304
305 return ENOSYS;
306 }
307
308
309
310
311
312 int
313 linux_sys_brk(p, v, retval)
314 struct proc *p;
315 void *v;
316 register_t *retval;
317 {
318 struct linux_sys_brk_args
319
320 *uap = v;
321 char *nbrk = SCARG(uap, nsize);
322 struct sys_obreak_args oba;
323 struct vmspace *vm = p->p_vmspace;
324 struct linux_emuldata *ed = (struct linux_emuldata*)p->p_emuldata;
325
326 SCARG(&oba, nsize) = nbrk;
327
328 if ((caddr_t) nbrk > vm->vm_daddr && sys_obreak(p, &oba, retval) == 0)
329 ed->p_break = (char*)nbrk;
330 else
331 nbrk = ed->p_break;
332
333 retval[0] = (register_t)nbrk;
334
335 return 0;
336 }
337
338
339
340
341
342 int
343 linux_sys_time(p, v, retval)
344 struct proc *p;
345 void *v;
346 register_t *retval;
347 {
348 struct linux_sys_time_args
349
350 *uap = v;
351 struct timeval atv;
352 linux_time_t tt;
353 int error;
354
355 microtime(&atv);
356
357 tt = atv.tv_sec;
358 if (SCARG(uap, t) && (error = copyout(&tt, SCARG(uap, t), sizeof tt)))
359 return error;
360
361 retval[0] = tt;
362 return 0;
363 }
364
365
366
367
368
369
370
371 static void
372 bsd_to_linux_statfs(bsp, lsp)
373 struct statfs *bsp;
374 struct linux_statfs *lsp;
375 {
376
377
378
379
380
381
382 if (!strcmp(bsp->f_fstypename, MOUNT_FFS) ||
383 !strcmp(bsp->f_fstypename, MOUNT_MFS))
384 lsp->l_ftype = 0x11954;
385 else if (!strcmp(bsp->f_fstypename, MOUNT_NFS))
386 lsp->l_ftype = 0x6969;
387 else if (!strcmp(bsp->f_fstypename, MOUNT_MSDOS))
388 lsp->l_ftype = 0x4d44;
389 else if (!strcmp(bsp->f_fstypename, MOUNT_PROCFS))
390 lsp->l_ftype = 0x9fa0;
391 else if (!strcmp(bsp->f_fstypename, MOUNT_EXT2FS))
392 lsp->l_ftype = 0xef53;
393 else if (!strcmp(bsp->f_fstypename, MOUNT_CD9660))
394 lsp->l_ftype = 0x9660;
395 else if (!strcmp(bsp->f_fstypename, MOUNT_NCPFS))
396 lsp->l_ftype = 0x6969;
397 else
398 lsp->l_ftype = -1;
399
400 lsp->l_fbsize = bsp->f_bsize;
401 lsp->l_fblocks = bsp->f_blocks;
402 lsp->l_fbfree = bsp->f_bfree;
403 lsp->l_fbavail = bsp->f_bavail;
404 lsp->l_ffiles = bsp->f_files;
405 lsp->l_fffree = bsp->f_ffree;
406 lsp->l_ffsid.val[0] = bsp->f_fsid.val[0];
407 lsp->l_ffsid.val[1] = bsp->f_fsid.val[1];
408 lsp->l_fnamelen = MAXNAMLEN;
409 }
410
411
412
413
414 int
415 linux_sys_statfs(p, v, retval)
416 struct proc *p;
417 void *v;
418 register_t *retval;
419 {
420 struct linux_sys_statfs_args
421
422
423 *uap = v;
424 struct statfs btmp, *bsp;
425 struct linux_statfs ltmp;
426 struct sys_statfs_args bsa;
427 caddr_t sg;
428 int error;
429
430 sg = stackgap_init(p->p_emul);
431 bsp = (struct statfs *) stackgap_alloc(&sg, sizeof (struct statfs));
432
433 LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
434
435 SCARG(&bsa, path) = SCARG(uap, path);
436 SCARG(&bsa, buf) = bsp;
437
438 if ((error = sys_statfs(p, &bsa, retval)))
439 return error;
440
441 if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp)))
442 return error;
443
444 bsd_to_linux_statfs(&btmp, <mp);
445
446 return copyout((caddr_t) <mp, (caddr_t) SCARG(uap, sp), sizeof ltmp);
447 }
448
449 int
450 linux_sys_fstatfs(p, v, retval)
451 struct proc *p;
452 void *v;
453 register_t *retval;
454 {
455 struct linux_sys_fstatfs_args
456
457
458 *uap = v;
459 struct statfs btmp, *bsp;
460 struct linux_statfs ltmp;
461 struct sys_fstatfs_args bsa;
462 caddr_t sg;
463 int error;
464
465 sg = stackgap_init(p->p_emul);
466 bsp = (struct statfs *) stackgap_alloc(&sg, sizeof (struct statfs));
467
468 SCARG(&bsa, fd) = SCARG(uap, fd);
469 SCARG(&bsa, buf) = bsp;
470
471 if ((error = sys_fstatfs(p, &bsa, retval)))
472 return error;
473
474 if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp)))
475 return error;
476
477 bsd_to_linux_statfs(&btmp, <mp);
478
479 return copyout((caddr_t) <mp, (caddr_t) SCARG(uap, sp), sizeof ltmp);
480 }
481
482
483
484
485
486
487
488 int
489 linux_sys_uname(p, v, retval)
490 struct proc *p;
491 void *v;
492 register_t *retval;
493 {
494 struct linux_sys_uname_args
495
496 *uap = v;
497 extern char hostname[], machine[], domainname[];
498 struct linux_utsname luts;
499 int len;
500 char *cp;
501
502 strlcpy(luts.l_sysname, ostype, sizeof(luts.l_sysname));
503 strlcpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
504 strlcpy(luts.l_release, osrelease, sizeof(luts.l_release));
505 strlcpy(luts.l_version, version, sizeof(luts.l_version));
506 strlcpy(luts.l_machine, machine, sizeof(luts.l_machine));
507 strlcpy(luts.l_domainname, domainname, sizeof(luts.l_domainname));
508
509
510 len = sizeof(luts.l_version);
511 for (cp = luts.l_version; len--; ++cp)
512 if (*cp == '\n' || *cp == '\t')
513 *cp = (len > 1) ? ' ' : '\0';
514
515 return copyout(&luts, SCARG(uap, up), sizeof(luts));
516 }
517
518 int
519 linux_sys_olduname(p, v, retval)
520 struct proc *p;
521 void *v;
522 register_t *retval;
523 {
524 struct linux_sys_uname_args
525
526 *uap = v;
527 extern char hostname[], machine[];
528 struct linux_oldutsname luts;
529 int len;
530 char *cp;
531
532 strlcpy(luts.l_sysname, ostype, sizeof(luts.l_sysname));
533 strlcpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
534 strlcpy(luts.l_release, osrelease, sizeof(luts.l_release));
535 strlcpy(luts.l_version, version, sizeof(luts.l_version));
536 strlcpy(luts.l_machine, machine, sizeof(luts.l_machine));
537
538
539 len = sizeof(luts.l_version);
540 for (cp = luts.l_version; len--; ++cp)
541 if (*cp == '\n' || *cp == '\t')
542 *cp = (len > 1) ? ' ' : '\0';
543
544 return copyout(&luts, SCARG(uap, up), sizeof(luts));
545 }
546
547 int
548 linux_sys_oldolduname(p, v, retval)
549 struct proc *p;
550 void *v;
551 register_t *retval;
552 {
553 struct linux_sys_uname_args
554
555 *uap = v;
556 extern char hostname[], machine[];
557 struct linux_oldoldutsname luts;
558 int len;
559 char *cp;
560
561 strlcpy(luts.l_sysname, ostype, sizeof(luts.l_sysname));
562 strlcpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
563 strlcpy(luts.l_release, osrelease, sizeof(luts.l_release));
564 strlcpy(luts.l_version, version, sizeof(luts.l_version));
565 strlcpy(luts.l_machine, machine, sizeof(luts.l_machine));
566
567
568 len = sizeof(luts.l_version);
569 for (cp = luts.l_version; len--; ++cp)
570 if (*cp == '\n' || *cp == '\t')
571 *cp = (len > 1) ? ' ' : '\0';
572
573 return copyout(&luts, SCARG(uap, up), sizeof(luts));
574 }
575
576
577
578
579
580
581 int
582 linux_sys_mmap(p, v, retval)
583 struct proc *p;
584 void *v;
585 register_t *retval;
586 {
587 struct linux_sys_mmap_args
588
589 *uap = v;
590 struct linux_mmap lmap;
591 struct linux_sys_mmap2_args nlmap;
592 struct sys_mmap_args cma;
593 int error;
594
595 if ((error = copyin(SCARG(uap, lmp), &lmap, sizeof lmap)))
596 return error;
597
598 if (lmap.lm_pos & PAGE_MASK)
599 return EINVAL;
600
601
602 SCARG(&nlmap,addr) = (unsigned long)lmap.lm_addr;
603 SCARG(&nlmap,len) = lmap.lm_len;
604 SCARG(&nlmap,prot) = lmap.lm_prot;
605 SCARG(&nlmap,flags) = lmap.lm_flags;
606 SCARG(&nlmap,fd) = lmap.lm_fd;
607 SCARG(&nlmap,offset) = (unsigned)lmap.lm_pos;
608
609 linux_to_bsd_mmap_args(&cma, &nlmap);
610 SCARG(&cma, pos) = (off_t)SCARG(&nlmap, offset);
611
612 return sys_mmap(p, &cma, retval);
613 }
614
615
616
617
618
619
620
621
622
623
624 int
625 linux_sys_mmap2(p, v, retval)
626 struct proc *p;
627 void *v;
628 register_t *retval;
629 {
630 struct linux_sys_mmap2_args
631
632
633
634
635
636
637 *uap = v;
638 struct sys_mmap_args cma;
639
640 linux_to_bsd_mmap_args(&cma, uap);
641 SCARG(&cma, pos) = ((off_t)SCARG(uap, offset)) << PAGE_SHIFT;
642
643 return sys_mmap(p, &cma, retval);
644 }
645
646 static void
647 linux_to_bsd_mmap_args(cma, uap)
648 struct sys_mmap_args *cma;
649 const struct linux_sys_mmap2_args *uap;
650 {
651 int flags = MAP_TRYFIXED, fl = SCARG(uap, flags);
652
653 flags |= cvtto_bsd_mask(fl, LINUX_MAP_SHARED, MAP_SHARED);
654 flags |= cvtto_bsd_mask(fl, LINUX_MAP_PRIVATE, MAP_PRIVATE);
655 flags |= cvtto_bsd_mask(fl, LINUX_MAP_FIXED, MAP_FIXED);
656 flags |= cvtto_bsd_mask(fl, LINUX_MAP_ANON, MAP_ANON);
657
658
659 SCARG(cma, addr) = (void *)SCARG(uap, addr);
660 SCARG(cma, len) = SCARG(uap, len);
661 SCARG(cma, prot) = SCARG(uap, prot);
662 if (SCARG(cma, prot) & VM_PROT_WRITE)
663 SCARG(cma, prot) |= VM_PROT_READ;
664 SCARG(cma, flags) = flags;
665 SCARG(cma, fd) = flags & MAP_ANON ? -1 : SCARG(uap, fd);
666 SCARG(cma, pad) = 0;
667 }
668
669 int
670 linux_sys_mremap(p, v, retval)
671 struct proc *p;
672 void *v;
673 register_t *retval;
674 {
675
676 struct linux_sys_mremap_args
677
678
679
680
681 *uap = v;
682 struct sys_munmap_args mua;
683 size_t old_size, new_size;
684 int error;
685
686 old_size = round_page(SCARG(uap, old_size));
687 new_size = round_page(SCARG(uap, new_size));
688
689
690
691
692 if (new_size > old_size) {
693
694
695
696
697
698
699 *retval = 0;
700 return (ENOMEM);
701 }
702
703
704
705 if (new_size < old_size) {
706 SCARG(&mua, addr) = (caddr_t)SCARG(uap, old_address) + new_size;
707 SCARG(&mua, len) = old_size - new_size;
708 error = sys_munmap(p, &mua, retval);
709 *retval = error ? 0 : (register_t)SCARG(uap, old_address);
710 return (error);
711 }
712
713
714
715
716 *retval = (register_t)SCARG(uap, old_address);
717 return (0);
718
719 }
720
721
722
723
724
725
726 #define CLK_TCK 100
727 #define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
728
729 int
730 linux_sys_times(p, v, retval)
731 struct proc *p;
732 void *v;
733 register_t *retval;
734 {
735 struct linux_sys_times_args
736
737 *uap = v;
738 struct timeval t;
739 struct linux_tms ltms;
740 struct rusage ru;
741 int error;
742
743 calcru(p, &ru.ru_utime, &ru.ru_stime, NULL);
744 ltms.ltms_utime = CONVTCK(ru.ru_utime);
745 ltms.ltms_stime = CONVTCK(ru.ru_stime);
746
747 ltms.ltms_cutime = CONVTCK(p->p_stats->p_cru.ru_utime);
748 ltms.ltms_cstime = CONVTCK(p->p_stats->p_cru.ru_stime);
749
750 if ((error = copyout(<ms, SCARG(uap, tms), sizeof ltms)))
751 return error;
752
753 microuptime(&t);
754
755 retval[0] = ((linux_clock_t)(CONVTCK(t)));
756 return 0;
757 }
758
759
760
761
762
763 int
764 linux_sys_pipe(p, v, retval)
765 struct proc *p;
766 void *v;
767 register_t *retval;
768 {
769 struct linux_sys_pipe_args
770
771 *uap = v;
772 int error;
773 int pfds[2];
774 #ifdef __i386__
775 int reg_edx = retval[1];
776 #endif
777
778 if ((error = sys_opipe(p, 0, retval))) {
779 #ifdef __i386__
780 retval[1] = reg_edx;
781 #endif
782 return error;
783 }
784
785
786
787 pfds[0] = retval[0];
788 pfds[1] = retval[1];
789 if ((error = copyout(pfds, SCARG(uap, pfds), 2 * sizeof (int)))) {
790 #ifdef __i386__
791 retval[1] = reg_edx;
792 #endif
793 fdrelease(p, retval[0]);
794 fdrelease(p, retval[1]);
795 return error;
796 }
797
798 retval[0] = 0;
799 #ifdef __i386__
800 retval[1] = reg_edx;
801 #endif
802 return 0;
803 }
804
805
806
807
808
809 int
810 linux_sys_alarm(p, v, retval)
811 struct proc *p;
812 void *v;
813 register_t *retval;
814 {
815 struct linux_sys_alarm_args
816
817 *uap = v;
818 int s;
819 struct itimerval *itp, it;
820 struct timeval tv;
821 int timo;
822
823 itp = &p->p_realtimer;
824 s = splclock();
825
826
827
828 getmicrouptime(&tv);
829 timeout_del(&p->p_realit_to);
830 timerclear(&itp->it_interval);
831 if (timerisset(&itp->it_value) &&
832 timercmp(&itp->it_value, &tv, >))
833 timersub(&itp->it_value, &tv, &itp->it_value);
834
835
836
837 retval[0] = itp->it_value.tv_sec;
838 if (itp->it_value.tv_usec)
839 retval[0]++;
840
841
842
843
844 if (SCARG(uap, secs) == 0) {
845 timerclear(&itp->it_value);
846 splx(s);
847 return 0;
848 }
849
850
851
852
853 timerclear(&it.it_interval);
854 it.it_value.tv_sec = SCARG(uap, secs);
855 it.it_value.tv_usec = 0;
856 if (itimerfix(&it.it_value) || itimerfix(&it.it_interval)) {
857 splx(s);
858 return (EINVAL);
859 }
860
861 if (timerisset(&it.it_value)) {
862 timo = tvtohz(&it.it_value);
863 timeradd(&it.it_value, &tv, &it.it_value);
864 timeout_add(&p->p_realit_to, timo);
865 }
866 p->p_realtimer = it;
867 splx(s);
868
869 return 0;
870 }
871
872
873
874
875
876 int
877 linux_sys_utime(p, v, retval)
878 struct proc *p;
879 void *v;
880 register_t *retval;
881 {
882 struct linux_sys_utime_args
883
884
885 *uap = v;
886 caddr_t sg;
887 int error;
888 struct sys_utimes_args ua;
889 struct timeval tv[2], *tvp;
890 struct linux_utimbuf lut;
891
892 sg = stackgap_init(p->p_emul);
893 tvp = (struct timeval *) stackgap_alloc(&sg, sizeof(tv));
894 LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
895
896 SCARG(&ua, path) = SCARG(uap, path);
897
898 if (SCARG(uap, times) != NULL) {
899 if ((error = copyin(SCARG(uap, times), &lut, sizeof lut)))
900 return error;
901 tv[0].tv_usec = tv[1].tv_usec = 0;
902 tv[0].tv_sec = lut.l_actime;
903 tv[1].tv_sec = lut.l_modtime;
904 if ((error = copyout(tv, tvp, sizeof tv)))
905 return error;
906 SCARG(&ua, tptr) = tvp;
907 }
908 else
909 SCARG(&ua, tptr) = NULL;
910
911 return sys_utimes(p, &ua, retval);
912 }
913
914
915
916
917
918
919
920
921
922
923 int
924 linux_sys_readdir(p, v, retval)
925 struct proc *p;
926 void *v;
927 register_t *retval;
928 {
929 struct linux_sys_readdir_args
930
931
932
933 *uap = v;
934
935 SCARG(uap, count) = 1;
936
937 return linux_sys_getdents(p, uap, retval);
938 }
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954 int linux_readdir_callback(void *, struct dirent *, off_t);
955
956 struct linux_readdir_callback_args {
957 caddr_t outp;
958 int resid;
959 int oldcall;
960 int is64bit;
961 };
962
963 int
964 linux_readdir_callback(arg, bdp, cookie)
965 void *arg;
966 struct dirent *bdp;
967 off_t cookie;
968 {
969 struct linux_dirent64 idb64;
970 struct linux_dirent idb;
971 struct linux_readdir_callback_args *cb = arg;
972 int linux_reclen;
973 int error;
974
975 if (cb->oldcall == 2)
976 return (ENOMEM);
977
978 linux_reclen = (cb->is64bit) ?
979 LINUX_RECLEN(&idb64, bdp->d_namlen) :
980 LINUX_RECLEN(&idb, bdp->d_namlen);
981
982 if (cb->resid < linux_reclen)
983 return (ENOMEM);
984
985 if (cb->is64bit) {
986 idb64.d_ino = (linux_ino64_t)bdp->d_fileno;
987 idb64.d_off = (linux_off64_t)cookie;
988 idb64.d_reclen = (u_short)linux_reclen;
989 idb64.d_type = bdp->d_type;
990 strlcpy(idb64.d_name, bdp->d_name, sizeof(idb64.d_name));
991 error = copyout((caddr_t)&idb64, cb->outp, linux_reclen);
992 } else {
993 idb.d_ino = (linux_ino_t)bdp->d_fileno;
994 if (cb->oldcall) {
995
996
997
998
999 idb.d_off = (linux_off_t)linux_reclen;
1000 idb.d_reclen = (u_short)bdp->d_namlen;
1001 } else {
1002 idb.d_off = (linux_off_t)cookie;
1003 idb.d_reclen = (u_short)linux_reclen;
1004 }
1005 strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
1006 error = copyout((caddr_t)&idb, cb->outp, linux_reclen);
1007 }
1008 if (error)
1009 return (error);
1010
1011
1012 cb->outp += linux_reclen;
1013 cb->resid -= linux_reclen;
1014
1015 if (cb->oldcall == 1)
1016 ++cb->oldcall;
1017
1018 return (0);
1019 }
1020
1021 int
1022 linux_sys_getdents64(p, v, retval)
1023 struct proc *p;
1024 void *v;
1025 register_t *retval;
1026 {
1027 return getdents_common(p, v, retval, 1);
1028 }
1029
1030 int
1031 linux_sys_getdents(p, v, retval)
1032 struct proc *p;
1033 void *v;
1034 register_t *retval;
1035 {
1036 return getdents_common(p, v, retval, 0);
1037 }
1038
1039 static int
1040 getdents_common(p, v, retval, is64bit)
1041 struct proc *p;
1042 void *v;
1043 register_t *retval;
1044 int is64bit;
1045 {
1046 struct linux_sys_getdents_args
1047
1048
1049
1050 *uap = v;
1051 struct linux_readdir_callback_args args;
1052 struct file *fp;
1053 int error;
1054 int nbytes = SCARG(uap, count);
1055
1056 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
1057 return (error);
1058
1059 if (nbytes == 1) {
1060
1061 if (is64bit) {
1062 FRELE(fp);
1063 return (EINVAL);
1064 }
1065 nbytes = sizeof(struct linux_dirent);
1066 args.oldcall = 1;
1067 } else {
1068 args.oldcall = 0;
1069 }
1070
1071 args.resid = nbytes;
1072 args.outp = (caddr_t)SCARG(uap, dirent);
1073 args.is64bit = is64bit;
1074
1075 if ((error = readdir_with_callback(fp, &fp->f_offset, nbytes,
1076 linux_readdir_callback, &args)) != 0)
1077 goto exit;
1078
1079 *retval = nbytes - args.resid;
1080
1081 exit:
1082 FRELE(fp);
1083 return (error);
1084 }
1085
1086
1087
1088
1089
1090
1091 int
1092 linux_sys_oldselect(p, v, retval)
1093 struct proc *p;
1094 void *v;
1095 register_t *retval;
1096 {
1097 struct linux_sys_oldselect_args
1098
1099 *uap = v;
1100 struct linux_select ls;
1101 int error;
1102
1103 if ((error = copyin(SCARG(uap, lsp), &ls, sizeof(ls))))
1104 return error;
1105
1106 return linux_select1(p, retval, ls.nfds, ls.readfds, ls.writefds,
1107 ls.exceptfds, ls.timeout);
1108 }
1109
1110
1111
1112
1113
1114
1115 int
1116 linux_sys_select(p, v, retval)
1117 struct proc *p;
1118 void *v;
1119 register_t *retval;
1120 {
1121 struct linux_sys_select_args
1122
1123
1124
1125
1126
1127 *uap = v;
1128
1129 return linux_select1(p, retval, SCARG(uap, nfds), SCARG(uap, readfds),
1130 SCARG(uap, writefds), SCARG(uap, exceptfds), SCARG(uap, timeout));
1131 }
1132
1133
1134
1135
1136
1137
1138
1139 int
1140 linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout)
1141 struct proc *p;
1142 register_t *retval;
1143 int nfds;
1144 fd_set *readfds, *writefds, *exceptfds;
1145 struct timeval *timeout;
1146 {
1147 struct sys_select_args bsa;
1148 struct timeval tv0, tv1, utv, *tvp;
1149 caddr_t sg;
1150 int error;
1151
1152 SCARG(&bsa, nd) = nfds;
1153 SCARG(&bsa, in) = readfds;
1154 SCARG(&bsa, ou) = writefds;
1155 SCARG(&bsa, ex) = exceptfds;
1156 SCARG(&bsa, tv) = timeout;
1157
1158
1159
1160
1161
1162 if (timeout) {
1163 if ((error = copyin(timeout, &utv, sizeof(utv))))
1164 return error;
1165 if (itimerfix(&utv)) {
1166
1167
1168
1169
1170 sg = stackgap_init(p->p_emul);
1171 tvp = stackgap_alloc(&sg, sizeof(utv));
1172 utv.tv_sec += utv.tv_usec / 1000000;
1173 utv.tv_usec %= 1000000;
1174 if (utv.tv_usec < 0) {
1175 utv.tv_sec -= 1;
1176 utv.tv_usec += 1000000;
1177 }
1178 if (utv.tv_sec < 0)
1179 timerclear(&utv);
1180 if ((error = copyout(&utv, tvp, sizeof(utv))))
1181 return error;
1182 SCARG(&bsa, tv) = tvp;
1183 }
1184 microtime(&tv0);
1185 }
1186
1187 error = sys_select(p, &bsa, retval);
1188 if (error) {
1189
1190
1191
1192
1193 if (error == ERESTART)
1194 error = EINTR;
1195 return error;
1196 }
1197
1198 if (timeout) {
1199 if (*retval) {
1200
1201
1202
1203
1204
1205
1206 microtime(&tv1);
1207 timersub(&tv1, &tv0, &tv1);
1208 timersub(&utv, &tv1, &utv);
1209 if (utv.tv_sec < 0)
1210 timerclear(&utv);
1211 } else
1212 timerclear(&utv);
1213 if ((error = copyout(&utv, timeout, sizeof(utv))))
1214 return error;
1215 }
1216
1217 return 0;
1218 }
1219
1220
1221
1222
1223
1224 int
1225 linux_sys_getpgid(p, v, retval)
1226 struct proc *p;
1227 void *v;
1228 register_t *retval;
1229 {
1230 struct linux_sys_getpgid_args
1231
1232 *uap = v;
1233 struct proc *targp;
1234
1235 if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != p->p_pid) {
1236 if ((targp = pfind(SCARG(uap, pid))) == 0)
1237 return ESRCH;
1238 }
1239 else
1240 targp = p;
1241
1242 retval[0] = targp->p_pgid;
1243 return 0;
1244 }
1245
1246
1247
1248
1249
1250
1251
1252 int
1253 linux_sys_personality(p, v, retval)
1254 struct proc *p;
1255 void *v;
1256 register_t *retval;
1257 {
1258 struct linux_sys_personality_args
1259
1260 *uap = v;
1261
1262 if (SCARG(uap, per) != 0)
1263 return EINVAL;
1264 retval[0] = 0;
1265 return 0;
1266 }
1267
1268
1269
1270
1271 int
1272 linux_sys_setreuid16(p, v, retval)
1273 struct proc *p;
1274 void *v;
1275 register_t *retval;
1276 {
1277 struct linux_sys_setreuid16_args
1278
1279
1280 *uap = v;
1281 struct sys_setreuid_args bsa;
1282
1283 SCARG(&bsa, ruid) = ((linux_uid_t)SCARG(uap, ruid) == (linux_uid_t)-1) ?
1284 (uid_t)-1 : SCARG(uap, ruid);
1285 SCARG(&bsa, euid) = ((linux_uid_t)SCARG(uap, euid) == (linux_uid_t)-1) ?
1286 (uid_t)-1 : SCARG(uap, euid);
1287
1288 return sys_setreuid(p, &bsa, retval);
1289 }
1290
1291 int
1292 linux_sys_setregid16(p, v, retval)
1293 struct proc *p;
1294 void *v;
1295 register_t *retval;
1296 {
1297 struct linux_sys_setregid16_args
1298
1299
1300 *uap = v;
1301 struct sys_setregid_args bsa;
1302
1303 SCARG(&bsa, rgid) = ((linux_gid_t)SCARG(uap, rgid) == (linux_gid_t)-1) ?
1304 (uid_t)-1 : SCARG(uap, rgid);
1305 SCARG(&bsa, egid) = ((linux_gid_t)SCARG(uap, egid) == (linux_gid_t)-1) ?
1306 (uid_t)-1 : SCARG(uap, egid);
1307
1308 return sys_setregid(p, &bsa, retval);
1309 }
1310
1311 int
1312 linux_sys_getsid(p, v, retval)
1313 struct proc *p;
1314 void *v;
1315 register_t *retval;
1316 {
1317 struct linux_sys_getsid_args
1318
1319 *uap = v;
1320 struct proc *p1;
1321 pid_t pid;
1322
1323 pid = (pid_t)SCARG(uap, pid);
1324
1325 if (pid == 0) {
1326 retval[0] = (int)p->p_session;
1327 return 0;
1328 }
1329
1330 p1 = pfind((int)pid);
1331 if (p1 == NULL)
1332 return ESRCH;
1333
1334 retval[0] = (int)p1->p_session;
1335 return 0;
1336 }
1337
1338 int
1339 linux_sys___sysctl(p, v, retval)
1340 struct proc *p;
1341 void *v;
1342 register_t *retval;
1343 {
1344 struct linux_sys___sysctl_args
1345
1346 *uap = v;
1347 struct linux___sysctl ls;
1348 struct sys___sysctl_args bsa;
1349 int error;
1350
1351 if ((error = copyin(SCARG(uap, lsp), &ls, sizeof ls)))
1352 return error;
1353 SCARG(&bsa, name) = ls.name;
1354 SCARG(&bsa, namelen) = ls.namelen;
1355 SCARG(&bsa, old) = ls.old;
1356 SCARG(&bsa, oldlenp) = ls.oldlenp;
1357 SCARG(&bsa, new) = ls.new;
1358 SCARG(&bsa, newlen) = ls.newlen;
1359
1360 return sys___sysctl(p, &bsa, retval);
1361 }
1362
1363
1364
1365
1366
1367 int
1368 linux_sys_setfsuid(p, v, retval)
1369 struct proc *p;
1370 void *v;
1371 register_t *retval;
1372 {
1373 struct linux_sys_setfsuid_args
1374
1375 *uap = v;
1376 uid_t uid;
1377
1378 uid = SCARG(uap, uid);
1379 if (p->p_cred->p_ruid != uid)
1380 return sys_nosys(p, v, retval);
1381 else
1382 return (0);
1383 }
1384
1385 int
1386 linux_sys_getfsuid(p, v, retval)
1387 struct proc *p;
1388 void *v;
1389 register_t *retval;
1390 {
1391 return sys_getuid(p, v, retval);
1392 }
1393
1394
1395 int
1396 linux_sys_nice(p, v, retval)
1397 struct proc *p;
1398 void *v;
1399 register_t *retval;
1400 {
1401 struct linux_sys_nice_args
1402
1403 *uap = v;
1404 struct sys_setpriority_args bsa;
1405
1406 SCARG(&bsa, which) = PRIO_PROCESS;
1407 SCARG(&bsa, who) = 0;
1408 SCARG(&bsa, prio) = SCARG(uap, incr);
1409 return sys_setpriority(p, &bsa, retval);
1410 }
1411
1412 int
1413 linux_sys_stime(p, v, retval)
1414 struct proc *p;
1415 void *v;
1416 register_t *retval;
1417 {
1418 struct linux_sys_time_args
1419
1420 *uap = v;
1421 struct timespec ats;
1422 linux_time_t tt;
1423 int error;
1424
1425 if ((error = suser(p, 0)) != 0)
1426 return (error);
1427
1428 if ((error = copyin(SCARG(uap, t), &tt, sizeof(tt))) != 0)
1429 return (error);
1430
1431 ats.tv_sec = tt;
1432 ats.tv_nsec = 0;
1433
1434 error = settime(&ats);
1435
1436 return (error);
1437 }
1438
1439 int
1440 linux_sys_getpid(p, v, retval)
1441 struct proc *p;
1442 void *v;
1443 register_t *retval;
1444 {
1445
1446 *retval = p->p_pid;
1447 return (0);
1448 }
1449
1450 int
1451 linux_sys_getuid(p, v, retval)
1452 struct proc *p;
1453 void *v;
1454 register_t *retval;
1455 {
1456
1457 *retval = p->p_cred->p_ruid;
1458 return (0);
1459 }
1460
1461 int
1462 linux_sys_getgid(p, v, retval)
1463 struct proc *p;
1464 void *v;
1465 register_t *retval;
1466 {
1467
1468 *retval = p->p_cred->p_rgid;
1469 return (0);
1470 }
1471
1472
1473
1474
1475
1476
1477 int
1478 linux_sys_sysinfo(p, v, retval)
1479 struct proc *p;
1480 void *v;
1481 register_t *retval;
1482 {
1483 struct linux_sys_sysinfo_args
1484
1485 *uap = v;
1486 struct linux_sysinfo si;
1487 struct loadavg *la;
1488 extern int bufpages;
1489 struct timeval tv;
1490
1491 getmicrouptime(&tv);
1492 si.uptime = tv.tv_sec;
1493 la = &averunnable;
1494 si.loads[0] = la->ldavg[0] * LINUX_SYSINFO_LOADS_SCALE / la->fscale;
1495 si.loads[1] = la->ldavg[1] * LINUX_SYSINFO_LOADS_SCALE / la->fscale;
1496 si.loads[2] = la->ldavg[2] * LINUX_SYSINFO_LOADS_SCALE / la->fscale;
1497 si.totalram = ctob(physmem);
1498 si.freeram = uvmexp.free * uvmexp.pagesize;
1499 si.sharedram = 0;
1500 si.bufferram = bufpages * PAGE_SIZE;
1501 si.totalswap = uvmexp.swpages * PAGE_SIZE;
1502 si.freeswap = (uvmexp.swpages - uvmexp.swpginuse) * PAGE_SIZE;
1503 si.procs = nprocs;
1504
1505 si.totalbig = 0;
1506 si.freebig = 0;
1507 si.mem_unit = 1;
1508
1509 return (copyout(&si, SCARG(uap, sysinfo), sizeof(si)));
1510 }