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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
/*
* Copyright (c) 1997-1998, 2000 University of Utah and the Flux Group.
* All rights reserved.
*
* This file is part of the Flux OSKit. The OSKit is free software, also known
* as "open source;" you can redistribute it and/or modify it under the terms
* of the GNU General Public License (GPL), version 2, as published by the Free
* Software Foundation (FSF). To explore alternate licensing terms, contact
* the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
*
* The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have
* received a copy of the GPL along with the OSKit; see the file COPYING. If
* not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
*/
#include <oskit/console.h>
#include <oskit/dev/dev.h>
#include "native.h"
#include "support.h"
extern int threads_initialized;
/*
* Put stdin in NBIO/ASYNC mode so that console input does not block
* in the kernel. We want to use the threaded_fd stuff, but that uses
* osenv_sleep, which requires that the process lock is taken. Well,
* the stdio functions are not provided as a COM object that can be
* wrapped like other device drivers, so the process lock *might not*
* be taken when we get here. So, take and release the lock as
* necessary so that we can use the already existing threaded_fd
* stuff. What a hack!
*
* stdout is left in blocking mode since printf is called from interrupt
* level all over the place, so we cannot allow a context switch to happen.
*/
void
stdio_init()
{
void stdio_interrupt();
struct sigaction sa;
sigset_t set;
NATIVEOS(sigemptyset)(&set);
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
sa.sa_mask = set;
if (NATIVEOS(sigaction)(SIGIO, &sa, 0) < 0) {
perror("installing SIGIO handler");
exit(0);
}
set_async_fd(0);
set_signal_handler(SIGINT,
(void (*)(int,int,struct sigcontext*))stdio_interrupt);
}
/*
* Why is there a SIGINT catcher? Well, interrupting a process with an
* NBIO and/or ASYNC stdin/stdout while running inside an emacs shell
* buffer causes that shell to go nuts. This is almost certainly a feature
* of FreeBSD emacs or the shell, but I'm not inclined to go find out why ...
*/
void
stdio_interrupt()
{
void stdio_exit(void);
stdio_exit();
_exit(1);
}
/*
* On normal exit, turn off NBIO/ASYNC mode so that the emacs shell does
* not go nuts.
*/
void
stdio_exit()
{
unset_async_fd(0);
}
int
console_puts(const char *str)
{
int rc;
int len = strlen(str);
if ((rc = console_putbytes(str, len)) == EOF)
return EOF;
else
return console_putchar('\n');
}
int
console_putchar(int c)
{
unsigned char foo = (unsigned char) c;
return console_putbytes(&foo, 1);
}
int
console_getchar()
{
int rc;
unsigned char foo;
if (! threads_initialized) {
rc = NATIVEOS(read)(0, &foo, 1);
}
else {
int locked = osenv_process_locked();
if (! locked)
osenv_process_lock();
rc = threaded_read(0, &foo, 1);
if (! locked)
osenv_process_unlock();
}
if (rc <= 0)
return EOF;
else
return (int) foo;
}
/*
* Added to improve console output performance.
*/
int
console_putbytes(const char *str, int len)
{
int rc = 0;
int enabled = osenv_intr_enabled();
if (enabled)
osenv_intr_disable();
while (len) {
rc = NATIVEOS(write)(1, str, len);
if (rc < 0) {
if (errno == EAGAIN)
continue;
break;
}
len -= rc;
str += rc;
}
if (enabled)
osenv_intr_enable();
if (rc < 0)
return EOF;
else
return 0;
}
void
base_console_init(int argc, char **argv)
{
console_putbytes("base_console_init called!",
strlen("base_console_init called!"));
}
|