root/kernel/printk.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_syslog
  2. printk
  3. register_console

   1 /*
   2  *  linux/kernel/printk.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  *
   6  * Modified to make sys_syslog() more flexible: added commands to
   7  * return the last 4k of kernel messages, regardless of whether
   8  * they've been read or not.  Added option to suppress kernel printk's
   9  * to the console.  Added hook for sending the console messages
  10  * elsewhere, in preparation for a serial line console (someday).
  11  * Ted Ts'o, 2/11/93.
  12  */
  13 
  14 #include <stdarg.h>
  15 
  16 #include <asm/segment.h>
  17 #include <asm/system.h>
  18 
  19 #include <linux/errno.h>
  20 #include <linux/sched.h>
  21 #include <linux/kernel.h>
  22 
  23 #define LOG_BUF_LEN     4096
  24 
  25 static char buf[1024];
  26 
  27 extern int vsprintf(char * buf, const char * fmt, va_list args);
  28 extern void console_print(const char *);
  29 
  30 static void (*console_print_proc)(const char *) = 0;
  31 static char log_buf[LOG_BUF_LEN];
  32 static unsigned long log_start = 0;
  33 static unsigned long logged_chars = 0;
  34 unsigned long log_size = 0;
  35 int log_to_console = 1;
  36 struct wait_queue * log_wait = NULL;
  37 
  38 /*
  39  * Commands to sys_syslog:
  40  *
  41  *      0 -- Close the log.  Currently a NOP.
  42  *      1 -- Open the log. Currently a NOP.
  43  *      2 -- Read from the log.
  44  *      3 -- Read up to the last 4k of messages in the ring buffer.
  45  *      4 -- Read and clear last 4k of messages in the ring buffer
  46  *      5 -- Clear ring buffer.
  47  *      6 -- Disable printk's to console
  48  *      7 -- Enable printk's to console
  49  */
  50 extern "C" int sys_syslog(int type, char * buf, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52         unsigned long i, j, count;
  53         int do_clear = 0;
  54         char c;
  55 
  56         if ((type != 3) && !suser())
  57                 return -EPERM;
  58         switch (type) {
  59                 case 0:         /* Close log */
  60                         return 0;
  61                 case 1:         /* Open log */
  62                         return 0;
  63                 case 2:         /* Read from log */
  64                         if (!buf || len < 0)
  65                                 return -EINVAL;
  66                         if (!len)
  67                                 return 0;
  68                         verify_area(VERIFY_WRITE,buf,len);
  69                         while (!log_size) {
  70                                 if (current->signal & ~current->blocked)
  71                                         return -ERESTARTSYS;
  72                                 cli();
  73                                 if (!log_size)
  74                                         interruptible_sleep_on(&log_wait);
  75                                 sti();
  76                         }
  77                         i = 0;
  78                         cli();
  79                         while (log_size && i < len) {
  80                                 cli();
  81                                 c = *((char *) log_buf+log_start);
  82                                 log_start++;
  83                                 log_size--;
  84                                 log_start &= LOG_BUF_LEN-1;
  85                                 sti();
  86                                 put_fs_byte(c,buf);
  87                                 buf++;
  88                                 i++;
  89                         }
  90                         sti();
  91                         return i;
  92                 case 4:         /* Read/clear last 4k of kernel messages */
  93                         do_clear = 1; 
  94                 case 3:         /* Read last 4k of kernel messages */
  95                         if (!buf || len < 0)
  96                                 return -EINVAL;
  97                         if (!len)
  98                                 return 0;
  99                         verify_area(VERIFY_WRITE,buf,len);
 100                         count = len;
 101                         if (count > LOG_BUF_LEN)
 102                                 count = LOG_BUF_LEN;
 103                         if (count > logged_chars)
 104                                 count = logged_chars;
 105                         j = log_start + log_size - count;
 106                         for (i = 0; i < count; i++) {
 107                                 c = *((char *) log_buf + (j++ & LOG_BUF_LEN-1));
 108                                 put_fs_byte(c, buf++);
 109                         }
 110                         if (do_clear)
 111                                 logged_chars = 0;
 112                         return i;
 113                 case 5:         /* Clear ring buffer */
 114                         logged_chars = 0;
 115                         return 0;
 116                 case 6:         /* Disable logging to console */
 117                         log_to_console = 0;
 118                         return 0;
 119                 case 7:         /* Enable logging to console */
 120                         log_to_console = 1;
 121                         return 0;
 122         }
 123         return -EINVAL;
 124 }
 125                         
 126 
 127 extern "C" int printk(const char *fmt, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         va_list args;
 130         int i,j;
 131 
 132         va_start(args, fmt);
 133         i=vsprintf(buf,fmt,args);
 134         va_end(args);
 135         for (j = 0; j < i ; j++) {
 136                 log_buf[(log_start+log_size) & LOG_BUF_LEN-1] = buf[j];
 137                 if (log_size < LOG_BUF_LEN)
 138                         log_size++;
 139                 else
 140                         log_start++;
 141                 logged_chars++;
 142         }
 143         wake_up_interruptible(&log_wait);
 144         if (log_to_console && console_print_proc)
 145                 (*console_print_proc)(buf);
 146         return i;
 147 }
 148 
 149 /*
 150  * The console driver calls this routine during kernel initialization
 151  * to register the console printing procedure with printk() and to
 152  * print any messages that were printed by the kernel before the
 153  * console priver was initialized.
 154  */
 155 void register_console(void (*proc)(const char *))
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157         int     i,j;
 158         int     p = log_start;
 159         char    buf[16];
 160 
 161         console_print_proc = proc;
 162 
 163         for (i=0,j=0; i < log_size; i++) {
 164                 buf[j++] = log_buf[p];
 165                 p++; p &= LOG_BUF_LEN-1;
 166                 if (j < sizeof(buf)-1)
 167                         continue;
 168                 buf[j] = 0;
 169                 (*proc)(buf);
 170                 j = 0;
 171         }
 172         buf[j] = 0;
 173         (*proc)(buf);
 174 }

/* [previous][next][first][last][top][bottom][index][help] */