/* 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 "fs.h" #include #include #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); }