diff options
author | Jeff Dike <jdike@addtoit.com> | 2007-05-06 17:51:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-07 15:13:01 -0400 |
commit | c65badbdf5dc117e45873e760f807063ad59a854 (patch) | |
tree | a83dd52066e3efef9b70c35bec8fccdf9db3d457 /arch/um | |
parent | c5e631cf65f4d6875efcd571275436f2964a8b48 (diff) |
uml: move SIGIO testing to sigio.c
This patch narrows the sigio interface. The boot-time SIGIO testing used to
be in start_up.c, which meant that pty_output_sigio and pty_close_sigio needed
to be global. By moving that code here, those can become static and the
declarations moved from user_util.h.
os_check_bugs is also here because it only does the SIGIO checking. If it
does more, it'll probably move back to start_up.c.
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/include/user_util.h | 3 | ||||
-rw-r--r-- | arch/um/os-Linux/sigio.c | 145 | ||||
-rw-r--r-- | arch/um/os-Linux/start_up.c | 145 |
3 files changed, 145 insertions, 148 deletions
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index b52bc4084830..df4869aa9406 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h | |||
@@ -51,9 +51,6 @@ extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; | |||
51 | extern unsigned long _unprotected_end; | 51 | extern unsigned long _unprotected_end; |
52 | extern unsigned long brk_start; | 52 | extern unsigned long brk_start; |
53 | 53 | ||
54 | extern int pty_output_sigio; | ||
55 | extern int pty_close_sigio; | ||
56 | |||
57 | extern void *add_signal_handler(int sig, void (*handler)(int)); | 54 | extern void *add_signal_handler(int sig, void (*handler)(int)); |
58 | extern int linux_main(int argc, char **argv); | 55 | extern int linux_main(int argc, char **argv); |
59 | extern void set_cmdline(char *cmd); | 56 | extern void set_cmdline(char *cmd); |
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 3fc43b33db66..c61d01bf46e4 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <termios.h> | 8 | #include <termios.h> |
9 | #include <pty.h> | 9 | #include <pty.h> |
10 | #include <signal.h> | 10 | #include <signal.h> |
11 | #include <fcntl.h> | ||
11 | #include <errno.h> | 12 | #include <errno.h> |
12 | #include <string.h> | 13 | #include <string.h> |
13 | #include <sched.h> | 14 | #include <sched.h> |
@@ -20,6 +21,7 @@ | |||
20 | #include "sigio.h" | 21 | #include "sigio.h" |
21 | #include "os.h" | 22 | #include "os.h" |
22 | #include "um_malloc.h" | 23 | #include "um_malloc.h" |
24 | #include "init.h" | ||
23 | 25 | ||
24 | /* Protected by sigio_lock(), also used by sigio_cleanup, which is an | 26 | /* Protected by sigio_lock(), also used by sigio_cleanup, which is an |
25 | * exitcall. | 27 | * exitcall. |
@@ -320,6 +322,10 @@ out_close1: | |||
320 | close(l_write_sigio_fds[1]); | 322 | close(l_write_sigio_fds[1]); |
321 | } | 323 | } |
322 | 324 | ||
325 | /* Changed during early boot */ | ||
326 | static int pty_output_sigio = 0; | ||
327 | static int pty_close_sigio = 0; | ||
328 | |||
323 | void maybe_sigio_broken(int fd, int read) | 329 | void maybe_sigio_broken(int fd, int read) |
324 | { | 330 | { |
325 | int err; | 331 | int err; |
@@ -357,3 +363,142 @@ static void sigio_cleanup(void) | |||
357 | } | 363 | } |
358 | 364 | ||
359 | __uml_exitcall(sigio_cleanup); | 365 | __uml_exitcall(sigio_cleanup); |
366 | |||
367 | /* Used as a flag during SIGIO testing early in boot */ | ||
368 | static volatile int got_sigio = 0; | ||
369 | |||
370 | static void __init handler(int sig) | ||
371 | { | ||
372 | got_sigio = 1; | ||
373 | } | ||
374 | |||
375 | struct openpty_arg { | ||
376 | int master; | ||
377 | int slave; | ||
378 | int err; | ||
379 | }; | ||
380 | |||
381 | static void openpty_cb(void *arg) | ||
382 | { | ||
383 | struct openpty_arg *info = arg; | ||
384 | |||
385 | info->err = 0; | ||
386 | if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) | ||
387 | info->err = -errno; | ||
388 | } | ||
389 | |||
390 | static int async_pty(int master, int slave) | ||
391 | { | ||
392 | int flags; | ||
393 | |||
394 | flags = fcntl(master, F_GETFL); | ||
395 | if(flags < 0) | ||
396 | return -errno; | ||
397 | |||
398 | if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || | ||
399 | (fcntl(master, F_SETOWN, os_getpid()) < 0)) | ||
400 | return -errno; | ||
401 | |||
402 | if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) | ||
403 | return -errno; | ||
404 | |||
405 | return(0); | ||
406 | } | ||
407 | |||
408 | static void __init check_one_sigio(void (*proc)(int, int)) | ||
409 | { | ||
410 | struct sigaction old, new; | ||
411 | struct openpty_arg pty = { .master = -1, .slave = -1 }; | ||
412 | int master, slave, err; | ||
413 | |||
414 | initial_thread_cb(openpty_cb, &pty); | ||
415 | if(pty.err){ | ||
416 | printk("openpty failed, errno = %d\n", -pty.err); | ||
417 | return; | ||
418 | } | ||
419 | |||
420 | master = pty.master; | ||
421 | slave = pty.slave; | ||
422 | |||
423 | if((master == -1) || (slave == -1)){ | ||
424 | printk("openpty failed to allocate a pty\n"); | ||
425 | return; | ||
426 | } | ||
427 | |||
428 | /* Not now, but complain so we now where we failed. */ | ||
429 | err = raw(master); | ||
430 | if (err < 0) | ||
431 | panic("check_sigio : __raw failed, errno = %d\n", -err); | ||
432 | |||
433 | err = async_pty(master, slave); | ||
434 | if(err < 0) | ||
435 | panic("tty_fds : sigio_async failed, err = %d\n", -err); | ||
436 | |||
437 | if(sigaction(SIGIO, NULL, &old) < 0) | ||
438 | panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); | ||
439 | new = old; | ||
440 | new.sa_handler = handler; | ||
441 | if(sigaction(SIGIO, &new, NULL) < 0) | ||
442 | panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); | ||
443 | |||
444 | got_sigio = 0; | ||
445 | (*proc)(master, slave); | ||
446 | |||
447 | close(master); | ||
448 | close(slave); | ||
449 | |||
450 | if(sigaction(SIGIO, &old, NULL) < 0) | ||
451 | panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); | ||
452 | } | ||
453 | |||
454 | static void tty_output(int master, int slave) | ||
455 | { | ||
456 | int n; | ||
457 | char buf[512]; | ||
458 | |||
459 | printk("Checking that host ptys support output SIGIO..."); | ||
460 | |||
461 | memset(buf, 0, sizeof(buf)); | ||
462 | |||
463 | while(os_write_file(master, buf, sizeof(buf)) > 0) ; | ||
464 | if(errno != EAGAIN) | ||
465 | panic("check_sigio : write failed, errno = %d\n", errno); | ||
466 | while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; | ||
467 | |||
468 | if(got_sigio){ | ||
469 | printk("Yes\n"); | ||
470 | pty_output_sigio = 1; | ||
471 | } | ||
472 | else if(n == -EAGAIN) printk("No, enabling workaround\n"); | ||
473 | else panic("check_sigio : read failed, err = %d\n", n); | ||
474 | } | ||
475 | |||
476 | static void tty_close(int master, int slave) | ||
477 | { | ||
478 | printk("Checking that host ptys support SIGIO on close..."); | ||
479 | |||
480 | close(slave); | ||
481 | if(got_sigio){ | ||
482 | printk("Yes\n"); | ||
483 | pty_close_sigio = 1; | ||
484 | } | ||
485 | else printk("No, enabling workaround\n"); | ||
486 | } | ||
487 | |||
488 | void __init check_sigio(void) | ||
489 | { | ||
490 | if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && | ||
491 | (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ | ||
492 | printk("No pseudo-terminals available - skipping pty SIGIO " | ||
493 | "check\n"); | ||
494 | return; | ||
495 | } | ||
496 | check_one_sigio(tty_output); | ||
497 | check_one_sigio(tty_close); | ||
498 | } | ||
499 | |||
500 | /* Here because it only does the SIGIO testing for now */ | ||
501 | void __init os_check_bugs(void) | ||
502 | { | ||
503 | check_sigio(); | ||
504 | } | ||
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 1244179e6c83..1540f21d6997 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -553,148 +553,3 @@ int __init parse_iomem(char *str, int *add) | |||
553 | out: | 553 | out: |
554 | return 1; | 554 | return 1; |
555 | } | 555 | } |
556 | |||
557 | |||
558 | /* Changed during early boot */ | ||
559 | int pty_output_sigio = 0; | ||
560 | int pty_close_sigio = 0; | ||
561 | |||
562 | /* Used as a flag during SIGIO testing early in boot */ | ||
563 | static volatile int got_sigio = 0; | ||
564 | |||
565 | static void __init handler(int sig) | ||
566 | { | ||
567 | got_sigio = 1; | ||
568 | } | ||
569 | |||
570 | struct openpty_arg { | ||
571 | int master; | ||
572 | int slave; | ||
573 | int err; | ||
574 | }; | ||
575 | |||
576 | static void openpty_cb(void *arg) | ||
577 | { | ||
578 | struct openpty_arg *info = arg; | ||
579 | |||
580 | info->err = 0; | ||
581 | if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) | ||
582 | info->err = -errno; | ||
583 | } | ||
584 | |||
585 | static int async_pty(int master, int slave) | ||
586 | { | ||
587 | int flags; | ||
588 | |||
589 | flags = fcntl(master, F_GETFL); | ||
590 | if(flags < 0) | ||
591 | return -errno; | ||
592 | |||
593 | if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || | ||
594 | (fcntl(master, F_SETOWN, os_getpid()) < 0)) | ||
595 | return -errno; | ||
596 | |||
597 | if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) | ||
598 | return -errno; | ||
599 | |||
600 | return(0); | ||
601 | } | ||
602 | |||
603 | static void __init check_one_sigio(void (*proc)(int, int)) | ||
604 | { | ||
605 | struct sigaction old, new; | ||
606 | struct openpty_arg pty = { .master = -1, .slave = -1 }; | ||
607 | int master, slave, err; | ||
608 | |||
609 | initial_thread_cb(openpty_cb, &pty); | ||
610 | if(pty.err){ | ||
611 | printk("openpty failed, errno = %d\n", -pty.err); | ||
612 | return; | ||
613 | } | ||
614 | |||
615 | master = pty.master; | ||
616 | slave = pty.slave; | ||
617 | |||
618 | if((master == -1) || (slave == -1)){ | ||
619 | printk("openpty failed to allocate a pty\n"); | ||
620 | return; | ||
621 | } | ||
622 | |||
623 | /* Not now, but complain so we now where we failed. */ | ||
624 | err = raw(master); | ||
625 | if (err < 0) | ||
626 | panic("check_sigio : __raw failed, errno = %d\n", -err); | ||
627 | |||
628 | err = async_pty(master, slave); | ||
629 | if(err < 0) | ||
630 | panic("tty_fds : sigio_async failed, err = %d\n", -err); | ||
631 | |||
632 | if(sigaction(SIGIO, NULL, &old) < 0) | ||
633 | panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); | ||
634 | new = old; | ||
635 | new.sa_handler = handler; | ||
636 | if(sigaction(SIGIO, &new, NULL) < 0) | ||
637 | panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); | ||
638 | |||
639 | got_sigio = 0; | ||
640 | (*proc)(master, slave); | ||
641 | |||
642 | close(master); | ||
643 | close(slave); | ||
644 | |||
645 | if(sigaction(SIGIO, &old, NULL) < 0) | ||
646 | panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); | ||
647 | } | ||
648 | |||
649 | static void tty_output(int master, int slave) | ||
650 | { | ||
651 | int n; | ||
652 | char buf[512]; | ||
653 | |||
654 | printk("Checking that host ptys support output SIGIO..."); | ||
655 | |||
656 | memset(buf, 0, sizeof(buf)); | ||
657 | |||
658 | while(os_write_file(master, buf, sizeof(buf)) > 0) ; | ||
659 | if(errno != EAGAIN) | ||
660 | panic("check_sigio : write failed, errno = %d\n", errno); | ||
661 | while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; | ||
662 | |||
663 | if(got_sigio){ | ||
664 | printk("Yes\n"); | ||
665 | pty_output_sigio = 1; | ||
666 | } | ||
667 | else if(n == -EAGAIN) printk("No, enabling workaround\n"); | ||
668 | else panic("check_sigio : read failed, err = %d\n", n); | ||
669 | } | ||
670 | |||
671 | static void tty_close(int master, int slave) | ||
672 | { | ||
673 | printk("Checking that host ptys support SIGIO on close..."); | ||
674 | |||
675 | close(slave); | ||
676 | if(got_sigio){ | ||
677 | printk("Yes\n"); | ||
678 | pty_close_sigio = 1; | ||
679 | } | ||
680 | else printk("No, enabling workaround\n"); | ||
681 | } | ||
682 | |||
683 | void __init check_sigio(void) | ||
684 | { | ||
685 | if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && | ||
686 | (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ | ||
687 | printk("No pseudo-terminals available - skipping pty SIGIO " | ||
688 | "check\n"); | ||
689 | return; | ||
690 | } | ||
691 | check_one_sigio(tty_output); | ||
692 | check_one_sigio(tty_close); | ||
693 | } | ||
694 | |||
695 | void os_check_bugs(void) | ||
696 | { | ||
697 | check_ptrace(); | ||
698 | check_sigio(); | ||
699 | } | ||
700 | |||