aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/start_up.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/start_up.c')
-rw-r--r--arch/um/os-Linux/start_up.c173
1 files changed, 26 insertions, 147 deletions
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 5178eba9afa5..79471f85eb89 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -17,10 +17,10 @@
17#include <sys/time.h> 17#include <sys/time.h>
18#include <sys/wait.h> 18#include <sys/wait.h>
19#include <sys/mman.h> 19#include <sys/mman.h>
20#include <sys/resource.h>
20#include <asm/unistd.h> 21#include <asm/unistd.h>
21#include <asm/page.h> 22#include <asm/page.h>
22#include <sys/types.h> 23#include <sys/types.h>
23#include "user_util.h"
24#include "kern_util.h" 24#include "kern_util.h"
25#include "user.h" 25#include "user.h"
26#include "signal_kern.h" 26#include "signal_kern.h"
@@ -329,8 +329,32 @@ static void __init check_ptrace(void)
329 329
330extern void check_tmpexec(void); 330extern void check_tmpexec(void);
331 331
332void os_early_checks(void) 332static void __init check_coredump_limit(void)
333{ 333{
334 struct rlimit lim;
335 int err = getrlimit(RLIMIT_CORE, &lim);
336
337 if(err){
338 perror("Getting core dump limit");
339 return;
340 }
341
342 printf("Core dump limits :\n\tsoft - ");
343 if(lim.rlim_cur == RLIM_INFINITY)
344 printf("NONE\n");
345 else printf("%lu\n", lim.rlim_cur);
346
347 printf("\thard - ");
348 if(lim.rlim_max == RLIM_INFINITY)
349 printf("NONE\n");
350 else printf("%lu\n", lim.rlim_max);
351}
352
353void __init os_early_checks(void)
354{
355 /* Print out the core dump limits early */
356 check_coredump_limit();
357
334 check_ptrace(); 358 check_ptrace();
335 359
336 /* Need to check this early because mmapping happens before the 360 /* Need to check this early because mmapping happens before the
@@ -528,148 +552,3 @@ int __init parse_iomem(char *str, int *add)
528 out: 552 out:
529 return 1; 553 return 1;
530} 554}
531
532
533/* Changed during early boot */
534int pty_output_sigio = 0;
535int pty_close_sigio = 0;
536
537/* Used as a flag during SIGIO testing early in boot */
538static volatile int got_sigio = 0;
539
540static void __init handler(int sig)
541{
542 got_sigio = 1;
543}
544
545struct openpty_arg {
546 int master;
547 int slave;
548 int err;
549};
550
551static void openpty_cb(void *arg)
552{
553 struct openpty_arg *info = arg;
554
555 info->err = 0;
556 if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
557 info->err = -errno;
558}
559
560static int async_pty(int master, int slave)
561{
562 int flags;
563
564 flags = fcntl(master, F_GETFL);
565 if(flags < 0)
566 return -errno;
567
568 if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
569 (fcntl(master, F_SETOWN, os_getpid()) < 0))
570 return -errno;
571
572 if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
573 return -errno;
574
575 return(0);
576}
577
578static void __init check_one_sigio(void (*proc)(int, int))
579{
580 struct sigaction old, new;
581 struct openpty_arg pty = { .master = -1, .slave = -1 };
582 int master, slave, err;
583
584 initial_thread_cb(openpty_cb, &pty);
585 if(pty.err){
586 printk("openpty failed, errno = %d\n", -pty.err);
587 return;
588 }
589
590 master = pty.master;
591 slave = pty.slave;
592
593 if((master == -1) || (slave == -1)){
594 printk("openpty failed to allocate a pty\n");
595 return;
596 }
597
598 /* Not now, but complain so we now where we failed. */
599 err = raw(master);
600 if (err < 0)
601 panic("check_sigio : __raw failed, errno = %d\n", -err);
602
603 err = async_pty(master, slave);
604 if(err < 0)
605 panic("tty_fds : sigio_async failed, err = %d\n", -err);
606
607 if(sigaction(SIGIO, NULL, &old) < 0)
608 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
609 new = old;
610 new.sa_handler = handler;
611 if(sigaction(SIGIO, &new, NULL) < 0)
612 panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
613
614 got_sigio = 0;
615 (*proc)(master, slave);
616
617 close(master);
618 close(slave);
619
620 if(sigaction(SIGIO, &old, NULL) < 0)
621 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
622}
623
624static void tty_output(int master, int slave)
625{
626 int n;
627 char buf[512];
628
629 printk("Checking that host ptys support output SIGIO...");
630
631 memset(buf, 0, sizeof(buf));
632
633 while(os_write_file(master, buf, sizeof(buf)) > 0) ;
634 if(errno != EAGAIN)
635 panic("check_sigio : write failed, errno = %d\n", errno);
636 while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
637
638 if(got_sigio){
639 printk("Yes\n");
640 pty_output_sigio = 1;
641 }
642 else if(n == -EAGAIN) printk("No, enabling workaround\n");
643 else panic("check_sigio : read failed, err = %d\n", n);
644}
645
646static void tty_close(int master, int slave)
647{
648 printk("Checking that host ptys support SIGIO on close...");
649
650 close(slave);
651 if(got_sigio){
652 printk("Yes\n");
653 pty_close_sigio = 1;
654 }
655 else printk("No, enabling workaround\n");
656}
657
658void __init check_sigio(void)
659{
660 if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
661 (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
662 printk("No pseudo-terminals available - skipping pty SIGIO "
663 "check\n");
664 return;
665 }
666 check_one_sigio(tty_output);
667 check_one_sigio(tty_close);
668}
669
670void os_check_bugs(void)
671{
672 check_ptrace();
673 check_sigio();
674}
675