10.1. Replacing printk

In Section 1.2.1.2, 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[1] the command to load the module came from.

The way this is done is by using current, a pointer to the currently running task, to get the current task's tty structure. Then, we look inside that tty structure to find a pointer to a string write function, which we use to write a string to the tty.

Example 10-1. print_string.c

/* a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html print_string.c - Send output to the tty we're running on, regardless if it's a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html through X11, telnet, etc. We do this by printing the string to the tty a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html associated with the current task. figures/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/sched.h> /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var For current figures/ #include <linux/tty.h> /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var For the tty declarations figures/ #include <linux/version.h> /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var For LINUX_VERSION_CODE figures/ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Jay Salzman"); static void print_string(char *str) { struct tty_struct *my_tty; /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html tty struct went into signal struct in 2.6.6 figures/ #if ( LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,5) ) /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html The tty for the current task figures/ my_tty = current->tty; #else /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html The tty for the current task, for 2.6.6+ kernels figures/ my_tty = current->signal->tty; #endif /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html If my_tty is NULL, the current task has no tty you can print to a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html (ie, if it's a daemon). If so, there's nothing we can do. figures/ if (my_tty != NULL) { /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html my_tty->driver is a struct which holds the tty's functions, a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html one of which (write) is used to write strings to the tty. a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html It can be used to take a string either from the user's or a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html kernel's memory segment. a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html The function's 1st parameter is the tty to write to, a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html because the same function would normally be used for all a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html tty's of a certain type. The 2nd parameter controls a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html whether the function receives a string from kernel a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html memory (false, 0) or from user memory (true, non zero). a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html BTW: this param has been removed in Kernels > 2.6.9 a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html The (2nd) 3rd parameter is a pointer to a string. a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html The (3rd) 4th parameter is the length of the string. a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html As you will see below, sometimes it's necessary to use a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html preprocessor stuff to create code that works for different a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html kernel versions. The (naive) approach we've taken here a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html does not scale well. The right way to deal with this a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html is described in section 2 of a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html linux/Documentation/SubmittingPatches figures/ ((my_tty->driver)->write) (my_tty, /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var The tty itself figures/ #if ( LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9) ) 0, /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var Don't take the string from user space figures/ #endif str, /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var String figures/ strlen(str)); /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var Length figures/ /apps /backup /bin /boot /data /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt /proc /root /sbin /selinux /srv /sys /tftpboot /tmp /usr /var a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html ttys were originally hardware devices, which (usually) a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html strictly followed the ASCII standard. In ASCII, to move to a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html a new line you need two characters, a carriage return and a a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html line feed. On Unix, the ASCII line feed is used for both a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html purposes - so we can't just use \n, because it wouldn't have a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html a carriage return and the next line will start at the a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html column right after the line feed. a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html This is why text files are different between Unix and a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html MS Windows. In CP/M and derivatives, like MS-DOS and a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html MS Windows, the ASCII standard was strictly adhered to, a1387.htm a1387.html a1403.htm a1403.html book1.htm c1050.htm c1050.html c1159.htm c1159.html c119.htm c119.html c1209.htm c1209.html c1254.htm c1324.htm c1324.html c1350.htm c1350.html c38.htm c38.html c425.htm c425.html c567.htm c567.html c708.htm c708.html c885.htm c885.html c890.htm c890.html c976.htm c976.html doc-index.html f25.htm f25.html figures hello2.html i1413.htm index.html interrupthandlers.html ln16.html TXT_lkmpg.html x1052.html x1161.html x1194.htm x1194.html x1211.html x121.html x1256.html x1326.html x1352.html x1389.html x1405.html x181.htm x181.html x217.htm x245.htm x245.html x279.htm x279.html x27.html x30.htm x30.html x323.htm x323.html x351.htm x351.html x35.htm x35.html x380.htm x380.html x40.html x427.html x44.htm x44.html x569.html x710.html x769.htm x769.html x810.htm x810.html x861.htm x861.html x887.html x892.html x978.html and therefore a newline requirs both a LF and a CR. figures/ #if ( LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9) ) ((my_tty->driver)->write) (my_tty, 0, "\015\012", 2); #else ((my_tty->driver)->write) (my_tty, "\015\012", 2); #endif } } static int __init print_string_init(void) { print_string("The module has been inserted. Hello world!"); return 0; } static void __exit print_string_exit(void) { print_string("The module has been removed. Farewell world!"); } module_init(print_string_init); module_exit(print_string_exit);

Notes

[1]

Teletype, 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.