diff --git a/servers/vfs/Makefile b/servers/vfs/Makefile index 3521d95a4..f69576458 100644 --- a/servers/vfs/Makefile +++ b/servers/vfs/Makefile @@ -17,7 +17,7 @@ OBJ = main.o open.o read.o write.o pipe.o dmap.o \ path.o device.o mount.o link.o exec.o \ filedes.o stadir.o protect.o time.o \ lock.o misc.o utility.o select.o timers.o table.o \ - vnode.o vmnt.o request.o + vnode.o vmnt.o request.o kputc.o # build local binary install all build: $(SERVER) diff --git a/servers/vfs/kputc.c b/servers/vfs/kputc.c new file mode 100644 index 000000000..92e5495eb --- /dev/null +++ b/servers/vfs/kputc.c @@ -0,0 +1,149 @@ +/* A server must occasionally print some message. It uses a simple version of + * printf() found in the system lib that calls kputc() to output characters. + * Printing is done with a call to the kernel, and not by going through FS. + * + * This routine can only be used by servers and device drivers. The kernel + * must define its own kputc(). Note that the log driver also defines its own + * kputc() to directly call the TTY instead of going through this library. + */ + +#include "sysutil.h" +#include "proto.h" +#include "glo.h" + +#define OVERFLOW_STR "[...]\n" + +#define PRINTPROCS (sizeof(procs)/sizeof(procs[0])) + +static char print_buf[80]; /* output is buffered here */ + +int kputc_use_private_grants= 0; + +static int buf_count = 0; /* # characters in the buffer */ +static int buf_offset = 0; /* Start of current line in buffer */ +static int procs[] = OUTPUT_PROCS_ARRAY; +static cp_grant_id_t printgrants[PRINTPROCS]; +static int procbusy[PRINTPROCS]; +static int do_flush = FALSE; +static int overflow = FALSE; + +/*===========================================================================* + * kputc * + *===========================================================================*/ +void kputc(c) +int c; +{ +/* Accumulate another character. If 0 or buffer full, print it. */ + int p; + message m; + + static int firstprint = 1; + + if (c == 0) + { + if (buf_count > buf_offset) + do_flush= TRUE; + } + else if (buf_count >= sizeof(print_buf)) + { + overflow= TRUE; + if (buf_count > buf_offset) + do_flush= TRUE; + } + else + print_buf[buf_count++] = c; + + if (!do_flush || buf_offset != 0) + return; + + buf_offset= buf_count; + if (kputc_use_private_grants) + { + for (p= 0; p buf_offset) + { + memmove(&print_buf[0], &print_buf[buf_offset], + buf_count-buf_offset); + } + buf_count -= buf_offset; + buf_offset= 0; + if (overflow) + { + if (buf_count + sizeof(OVERFLOW_STR) > sizeof(print_buf)) + buf_count= sizeof(print_buf)-sizeof(OVERFLOW_STR); + overflow= FALSE; + do_flush= FALSE; + printf("%s", OVERFLOW_STR); + } + kputc(0); +}