Ядро Linux в комментариях




Kernel/printk.c - часть 2


25836 asmlinkage int printk(const char *fmt, ...) 25837 { 25838 va_list args; 25839 int i; 25840 char *msg, *p, *buf_end; 25841 int line_feed; 25842 static signed char msg_level = -1; 25843 long flags; 25844 25845 spin_lock_irqsave(&console_lock, flags); 25846 va_start(args, fmt); 25847 /* hopefully i < sizeof(buf)-4 */ 25848 i = vsprintf(buf + 3, fmt, args); 25849 buf_end = buf + 3 + i; 25850 va_end(args); 25851 for (p = buf + 3; p < buf_end; p++) { 25852 msg = p; 25853 if (msg_level < 0) { 25854 if ( 25855 p[0] != '<' 25856 p[1] < '0' 25857 p[1] > '7' 25858 p[2] != '>' 25859 ) { 25860 p -= 3; 25861 p[0] = '<'; 25862 p[1] = default_message_loglevel + '0'; 25863 p[2] = '>'; 25864 } else 25865 msg += 3; 25866 msg_level = p[1] - '0'; 25867 } 25868 line_feed = 0; 25869 for (; p < buf_end; p++) { 25870 log_buf[(log_start+log_size) & (LOG_BUF_LEN-1)] 25871 = *p; 25872 if (log_size < LOG_BUF_LEN) 25873 log_size++; 25874 else { 25875 log_start++; 25876 log_start &= LOG_BUF_LEN-1; 25877 } 25878 logged_chars++; 25879 if (*p == '\n') { 25880 line_feed = 1; 25881 break; 25882 } 25883 } 25884 if (msg_level < console_loglevel && console_drivers){ 25885 struct console *c = console_drivers; 25886 while(c) { 25887 if ((c->flags & CON_ENABLED) && c->write) 25888 c->write(c, msg, p - msg + line_feed); 25889 c = c->next; 25890 } 25891 } 25892 if (line_feed) 25893 msg_level = -1; 25894 } 25895 spin_unlock_irqrestore(&console_lock, flags); 25896 wake_up_interruptible(&log_wait); 25897 return i; 25898 } 25899 25900 void console_print(const char *s) 25901 { 25902 struct console *c = console_drivers; 25903 int len = strlen(s); 25904 25905 while(c) { 25906 if ((c->flags & CON_ENABLED) && c->write) 25907 c->write(c, s, len); 25908 c = c->next; 25909 } 25910 } 25911 25912 void unblank_console(void) 25913 { 25914 struct console *c = console_drivers; 25915 while(c) { 25916 if ((c->flags & CON_ENABLED) && c->unblank) 25917 c->unblank(); 25918 c = c->next; 25919 } 25920 } 25921 25922 /* The console driver calls this routine during kernel 25923 * initialization to register the console printing 25924 * procedure with printk() and to print any messages that 25925 * were printed by the kernel before the console driver 25926 * was initialized. */ 25927 void register_console(struct console * console) 25928 { 25929 int i,j,len; 25930 int p = log_start; 25931 char buf[16]; 25932 signed char msg_level = -1; 25933 char *q; 25934 25935 /* See if we want to use this console driver. If we 25936 * didn't select a console we take the first one that 25937 * registers here. */ 25938 if (preferred_console < 0) { 25939 if (console->index < 0) 25940 console->index = 0; 25941 if (console->setup == NULL 25942 console->setup(console, NULL) == 0) { 25943 console->flags |= CON_ENABLED | CON_CONSDEV; 25944 preferred_console = 0; 25945 } 25946 } 25947 25948 /* See if this console matches one we selected on the 25949 * command line. */ 25950 for (i = 0; 25951 i < MAX_CMDLINECONSOLES && 25952 console_cmdline[i].name[0]; 25953 i++) { 25954 if (strcmp(console_cmdline[i].name, console->name)) 25955 continue; 25956 if (console->index >= 0 && 25957 console->index != console_cmdline[i].index) 25958 continue; 25959 if (console->index < 0) 25960 console->index = console_cmdline[i].index; 25961 if (console->setup && 25962 console->setup(console, 25963 console_cmdline[i].options) != 0) 25964 break; 25965 console->flags |= CON_ENABLED; 25966 console->index = console_cmdline[i].index; 25967 if (i == preferred_console) 25968 console->flags |= CON_CONSDEV; 25969 break; 25970 } 25971 25972 if (!(console->flags & CON_ENABLED)) 25973 return; 25974 25975 /* Put this console in the list - keep the preferred 25976 * driver at the head of the list. */ 25977 if ((console->flags & CON_CONSDEV) 25978 console_drivers == NULL) { 25979 console->next = console_drivers; 25980 console_drivers = console; 25981 } else { 25982 console->next = console_drivers->next; 25983 console_drivers->next = console; 25984 } 25985 if ((console->flags & CON_PRINTBUFFER) == 0) return; 25986 25987 /* Print out buffered log messages. */ 25988 for (i=0,j=0; i < log_size; i++) { 25989 buf[j++] = log_buf[p]; 25990 p++; p &= LOG_BUF_LEN-1; 25991 if (buf[j-1] != '\n' && i < log_size - 1 && 25992 j < sizeof(buf)-1) 25993 continue; 25994 buf[j] = 0; 25995 q = buf; 25996 len = j; 25997 if (msg_level < 0) { 25998 msg_level = buf[1] - '0'; 25999 q = buf + 3; 26000 len -= 3; 26001 } 26002 if (msg_level < console_loglevel) 26003 console->write(console, q, len); 26004 if (buf[j-1] == '\n') 26005 msg_level = -1; 26006 j = 0; 26007 } 26008 } 26009 26010 26011 int unregister_console(struct console * console) 26012 { 26013 struct console *a,*b; 26014 26015 if (console_drivers == console) { 26016 console_drivers=console->next; 26017 return (0); 26018 } 26019 for (a = console_drivers->next, b = console_drivers; 26020 a; b = a, a = b->next) { 26021 if (a == console) { 26022 b->next = a->next; 26023 return 0; 26024 } 26025 } 26026 26027 return (1); 26028 } 26029 26030 /* Write a message to a certain tty, not just the 26031 * console. This is used for messages that need to be 26032 * redirected to a specific tty. We don't put it into 26033 * the syslog queue right now maybe in the future if 26034 * really needed. */ 26035 void tty_write_message(struct tty_struct *tty, char *msg) 26036 { 26037 if (tty && tty->driver.write) 26038 tty->driver.write(tty, 0, msg, strlen(msg)); 26039 return; 26040 }




Содержание  Назад  Вперед