Sophie

Sophie

distrib > Mandriva > current > i586 > media > contrib-release > by-pkgid > afdcfc364877ff5b5fc90cad008e9a19 > files > 10

lkmpg-1.1.0-15mdv2010.0.noarch.rpm

<HTML
><HEAD
><TITLE
>Replacing Printks</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="The Linux Kernel Module Programming Guide"
HREF="book1.htm"><LINK
REL="PREVIOUS"
TITLE="Blocking Processes"
HREF="c1012.htm"><LINK
REL="NEXT"
TITLE="Scheduling Tasks"
HREF="c1149.htm"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>The Linux Kernel Module Programming Guide</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="c1012.htm"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c1149.htm"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="AEN1115"
></A
>Chapter 10. Replacing Printks</H1
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="AEN1117"
></A
>Replacing <TT
CLASS="FUNCTION"
>printk</TT
></H1
><A
NAME="AEN1120"
></A
><P
>In <A
HREF="x49.htm#USINGX"
>the Section called <I
>Using X</I
> in Chapter 1</A
>, I said that X and kernel module programming don't mix.  That's true for developing kernel
	modules, but in actual use, you want to be able to send messages to whichever
	tty<A
NAME="AEN1125"
HREF="#FTN.AEN1125"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
> the command to load the
	module came from.</P
><A
NAME="AEN1129"
></A
><A
NAME="AEN1131"
></A
><A
NAME="AEN1134"
></A
><A
NAME="AEN1136"
></A
><P
>The way this is done is by using <TT
CLASS="VARNAME"
>current</TT
>, a pointer to the currently running task, to get the current
	task's <SPAN
CLASS="STRUCTNAME"
>tty</SPAN
> structure.  Then, we look inside that <SPAN
CLASS="STRUCTNAME"
>tty</SPAN
> structure to find a
	pointer to a string write function, which we use to write a string to the tty.</P
><A
NAME="AEN1143"
></A
><DIV
CLASS="EXAMPLE"
><A
NAME="AEN1146"
></A
><P
><B
>Example 10-1. print_string.c</B
></P
><PRE
CLASS="PROGRAMLISTING"
>/*  print_string.c - Send output to the tty you're running on, regardless of whether it's
 *     through X11, telnet, etc.  We do this by printing the string to the tty associated
 *     with the current task.
 */
#include &#60;linux/kernel.h&#62;
#include &#60;linux/module.h&#62;
#include &#60;linux/sched.h&#62;    // For current
#include &#60;linux/tty.h&#62;      // For the tty declarations
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Peter Jay Salzman");


void print_string(char *str)
{
   struct tty_struct *my_tty;
   my_tty = current-&#62;tty;           // The tty for the current task

   /* If my_tty is NULL, the current task has no tty you can print to (this is possible,
    * for example, if it's a daemon).  If so, there's nothing we can do.
    */
   if (my_tty != NULL) { 

      /* my_tty-&#62;driver is a struct which holds the tty's functions, one of which (write)
       * is used to write strings to the tty.  It can be used to take a string either
       * from the user's memory segment or the kernel's memory segment.
       *
       * The function's 1st parameter is the tty to write to, because the same function
       * would normally be used for all tty's of a certain type.  The 2nd parameter
       * controls whether the function receives a string from kernel memory (false, 0) or
       * from user memory (true, non zero).  The 3rd parameter is a pointer to a string.
       * The 4th parameter is the length of the string.
       */
      (*(my_tty-&#62;driver).write)(
         my_tty,                 // The tty itself
         0,                      // We don't take the string from user space
         str,                    // String
         strlen(str));           // Length

      /* ttys were originally hardware devices, which (usually) strictly followed the
       * ASCII standard.  In ASCII, to move to a new line you need two characters, a
       * carriage return and a line feed.  On Unix, the ASCII line feed is used for both
       * purposes - so we can't just use \n, because it wouldn't have a carriage return
       * and the next line will start at the column right after the line feed. 
       *
       * BTW, this is why text files are different between Unix and MS Windows.  In CP/M
       * and its derivatives, like MS-DOS and MS Windows, the ASCII standard was strictly
       * adhered to, and therefore a newline requirs both a LF and a CR.
       */
      (*(my_tty-&#62;driver).write)(my_tty, 0, "\015\012", 2);
   }
}


int print_string_init(void)
{
   print_string("The module has been inserted.  Hello world!");
   return 0;
}


void print_string_exit(void)
{
   print_string("The module has been removed.  Farewell world!");
}  


module_init(print_string_init);
module_exit(print_string_exit);</PRE
></DIV
></DIV
></DIV
><H3
CLASS="FOOTNOTES"
>Notes</H3
><TABLE
BORDER="0"
CLASS="FOOTNOTES"
WIDTH="100%"
><TR
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="5%"
><A
NAME="FTN.AEN1125"
HREF="c1115.htm#AEN1125"
><SPAN
CLASS="footnote"
>[1]</SPAN
></A
></TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
WIDTH="95%"
><P
><SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>T</I
></SPAN
>ele<SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>ty</I
></SPAN
>pe, originally a combination keyboard-printer used to
	communicate with a Unix system, and today an abstraction for the text stream used for a Unix program, whether it's a physical
	terminal, an xterm on an X display, a network connection used with telnet, etc.</P
></TD
></TR
></TABLE
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="c1012.htm"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.htm"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c1149.htm"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Blocking Processes</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Scheduling Tasks</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>