We thought so. It's a constant battle to keep on top of all the latest bugs, isn't it? But thanks to Bugzilla, you now have some help. The Red Hat Bug Tracking System is a database of bugs in Linux products. It was developed at and has been customized to track bugs in Red Hat Linux products.
You can access any information about the known bugs in all releases of Red Hat Linux as well as find out how to fix them. Plus, you have a chance to be a hero by reporting any new bugs you may have found. (Of course, it helps your hero status to also offer a solution.)
So how can you access this great database? You know the drill: Register on the site and provide your e-mail address. It's free, and it gives you the opportunity to contribute to the open source movement by throwing in your two cents' worth. And you'll stay informed--who can ask for more?
Don't drive yourself nuts typing lengthy directory names, filenames, or command names. Let bash do it for you. Try typing a few characters of the name, and press [Tab] or [Ctrl]I. Chances are bash will be able to complete the item for you. If not, try pressing [Tab] or [Ctrl]I again. You'll see a list of possible completions. If you'd like to restrict the possibilities, you can request completions for filenames only by pressing [Alt]I, host names only by pressing [Alt]@, or user names only by pressing [Alt]~. To find command names only, press [Alt]!, and to find variable names only, press [Alt]$. If these commands don't work, your system may be set up so that these commands are mapped to [Esc] or some other key, such as the Command key on Power Macintosh systems. To view the current key assignments, take a look at /etc/inputrc (assignments for the whole system) and the .inputrc file in your home directory (assignments for your user account only).


Brave GNU World is a multilingual monthly column that provides information about internal developments of the GNU Project and GNU community. It is available online at
Alternatively, you can subscribe to a mailing list to be informed of new issues as soon as they are released.


The Display GhostScript System (DGS) provides a device-independent imaging model for displaying information and graphics on a screen, regardless of display-specific details like screen resolution and color issues. The imaging model of DGS uses the PostScript language, which has powerful graphics capabilities.
DGS is composed of a PostScript language interpreter called GhostScript, the client library, and the pswrap translator. The pswrap translator enables you to take PostScript programs and wrap them with a C function interface, thereby allowing your applications to call them directly. DGS is available at

RESUMPTIVE AND NONRESUMPTIVE EXCEPTION HANDLING In a resumptive exception handling model, after an exception has been handled, the program continues execution at the point where the exception was thrown. This is how Structured Exception Handling (SEH) works in C (note that SEH is a no-standard extension to ANSI C). On the other hand, the C++ standard exception handling model is nonresumptive. This means that program execution resumes at the next statement following the catch-block. The C++ program does not return to the point where the exception was thrown after that exception has been handled. This is a source of confusion among C++ novices, who mistakenly assume that the program automatically returns to the point from which an exception was thrown, but it doesn't.

THE COMMON UNIX PRINTING SYSTEM The Common UNIX Printing System (CUPS) provides a portable printing layer for various UNIX operating systems and Linux distributions. CUPS supports both the System V and Berkeley command-line interfaces. CUPS also includes a customized version of GNU GhostScript and an image file RIP that can be used to support non-PostScript printers. CUPS can be downloaded from

THE MIDGARD PROJECT The Midgard Project is responsible for the development of an open source application--the Midgard Application Server. The product consists of Midgard core libraries, a PHP-based Web Application Server for Apache platform, and Web-based administration tools. For further information and software download, visit the Midgard Web site at

WINMODEM ON LINUX? Although many Linux users balk at the idea of using Winmodem, it still has many useful applications on Linux: it can serve as an answering machine, pager interface, phone emulation, etc. The following Web site is dedicated to Winmodems on Linux. You can download related software, view a list of Winmodem chipsets, and find related links:

THE PHP SCRIPTING LANGUAGE PHP is an open source server-side, cross-platform, HTML-embedded scripting language. It enables you to create dynamic Web pages that are treated just like regular HTML pages. PHP's syntax is reminiscent of C. However, it is much simpler than C and it is free from the hassles of memory management and pointers. For more information, visit the PHP Web site at


VIM is an open source and enhanced version of vi, one of the standard text editors on UNIX. VIM features include unlimited undo, syntax coloring, split windows, visual selection, GUI support, and more. Besides Linux and Unix, VIM runs on many other operating systems, including BeOS, DOS, MacOS, OS/2, RiscOS, VMS, and Windows32. You can obtain further information about the VIM editor and download it from

PROJECT LINUX Project Linux is aimed at Linux users and the Open Source community in general. Starting November 8, the organization will present the following two Web sites: Get Linux and Open Talk. Get Linux provides information for people new to Linux. It will include a list of available distributions, reviews, and articles. The Open Talk section will host forums of discussion about all things relating to open source technologies. You can find the Project Linux Web site at

REENTRANT AND NONREENTRANT SIGNALS What happens when a signal is sent to a process that is already handling that signal? In theory, the kernel can interrupt the process and invoke the signal handler again. This approach requires that the signal handler can function properly if it is invoked while it is already executing. Such a handler is said to be reentrant. Writing reliable and efficient reentrant handlers is not a trivial task. Imagine what would happen if the signal handler locks a file, and at that point, the kernel interrupts it and invokes that handler once more. The second invocation will result in a deadlock because the handler infinitely waits for the lock to be released. The lock, however, cannot be released because the first handler call was suspended. In Linux, this situation doesn't occur, because the kernel withholds the signal until the process to which it is sent has finished handling the previous signal (the second signal is said to be pending). Only then is the pending signal sent to that process. This approach was chosen to avoid the complexities of reentrant signal handlers.

THE WINE COMPATIBILITY LAYER Wine is a Windows compatibility layer that facilitates porting of Windows sources to Unix and Linux. Wine also includes a program loader that enables unmodified Windows 3.1/95/NT binaries to execute under Intel Unix and Linux systems. Wine does not require Microsoft Windows, since it consists of 100 percent free code. It supports many Windows features, including multimedia and OLE DLLs reorganization, Clipboard, and support for Win16 and Win32 function calls. You can find more information about Wine and download it from

THE QUANDARIES OF FLOATING POINT NUMBERS People sometimes complain about the inaccuracy of floating point arithmetic. To demonstrate that, try the following program: #include int main() { float f1 = 2000.58; float f2 = 2000.0; printf("%f", f1 - f2); } On an Intel-based machine, this program prints 0.579956 instead of 0.58. More complex calculations yield higher inaccuracy. What is going on here? First, remember that rounding, approximation, and truncation are not the responsibility of a particular programming language or compiler. Rather, they depend on the hardware that your machine uses. Floating point numbers are merely an approximation based on the IEEE standard. On most machines, the type float occupies 32 bits. The IEEE standard for 32-bit floating point numbers requires that 1 bit be used for the sign representation, 8 bits for exponent, and the remaining 23 bits are for the mantissa. Since a mantissa always has the form 1.nnnn..., the leading 1 can be dropped, so there are actually 24 bits allocated for the mantissa. This 24-bit accuracy can have a deviation of plus or minus %0.0000062 from the original number. For higher accuracy, you can use the type double, which provides 53 bits of mantissa. This is more accurate than 24 bits, but you can never get absolute accuracy with built-in data types.

THE SAWMILL WINDOW MANAGER Sawmill is a highly configurable window manager for Linux and several Unix flavors. Its major advantage over the Enlightenment window manager is its minimal system requirements. Thus, it can run on Linux machines that have slow processors and minimal memory. Sawmill is distributed under the terms of the GNU GPL license. You can find more information on Sawmill and download it from

LINUX C++ MAILING LISTS The Linux C++ Mailing List was recently established. The purpose of this mailing list is to help and support Linux programmers who use C++. To subscribe to the list, send this e-mail with an empty subject and message:

You will receive a reply with further instructions on how to confirm your subscription, post messages, post replies, and unsubscribe from the list.

AVOID PASSING ARGUMENTS WITH SIDE EFFECTS Many of the ANSI C functions are in fact macros in disguise. routines, memset(), strcpy(), and other runtime library functions are examples of such macros in disguise. You should beware of passing expressions with a side effect as arguments to these functions, because the results may be undefined. Consider the following example: char buff[12]; int n = 0; memset(buff, ++n, sizeof(buff); /* ++n has a side-effect; bad idea */ If memset() happens to be a macro that passes its arguments to another function, the value of n may be incremented twice before it is used.

LINUX 2000 ORGANIZATION Linux 2000 Online is a resource site for Linux users--beginners and experienced alike. The site contains forums, links to portals, hardware and software vendors, and newsgroups from all over the world. The Linux 2000 Online site is at:

THE UTOPIX WEB SITE Utopix is a Web site dedicated to Linux and Windows users alike. It provides news from the Linux industry and promotes the adoption of Linux as a mainstream OS. The site offers a chat room, a forum, and online polls. You can find Utopix at:

UNDERSTANDING COPY-ON-WRITE When you invoke the fork() command, Linux creates a new process that is an exact copy of the existing one. When Linux instantiates the new process, it uses an optimization method called "copy-on-write." Instead of copying the memory block that contains the original process's attributes, the new process's attributes are mapped to the original memory block and marked as "read-only." When the new process changes any of its attributes, it attempts to write to that read-only memory block. Consequently, the exception handler allocates a new block of memory, copies the data into it, marks the newly allocated block as "write-enabled," and changes the mapping of the new process to it. Thus, no actual copy takes place as long as the new process doesn't change any of its attributes.

WHAT IS A SIDE EFFECT? In standard C and C++, a side effect is defined as a "change in the state of the execution environment." Modifying an object, accessing an object that is declared volatile, invoking an I/O function, or calling a function that does any of these operations are all side effects. The validity of many operations depends on the existence of a side effect (or lack thereof). The following are instances of side effects: volatile int n = 0; int j = 0; ++j; /* object modification */ j = n; /* two side effects: accessing a volatile object and modifying j */ printf( "hello world"); /* I/O function call */

CHECKING AVAILABLE RAM FROM THE COMMAND LINE Linux can highlight the available amount of RAM on a system at any given moment. Both command-line (text only) and GUI-type tools are available. The command-line tool for system RAM usage comes in two forms: dynamic and static. The dynamic tool is called Top (in fact, the command to execute this tool is top). Top offers two types of output. The system's resources are listed at the top of the output. These include CPU status, available RAM, and number and status of processes. The CPU status and available RAM are most helpful. The CPU status is broken into four categories: system, user, nice, and idle. System is the percentage of the CPU that the OS is currently using; user is the percentage of the CPU that the user-space programs are using; nice is the percentage of CPU being used by prioritized applications; and idle is the remaining percentage of the CPU. Should your system begin to show signs of slowing down, run top. If you consistently see the system CPU status at 15 percent or higher, you should check into the lower half of Top's output to see what's causing the problem. The lower portion of Top's output details every process running on the system. This is very handy when used to analyze the state of a system. Should the user see a high CPU percentage, he or she can look into the lower half of the output, determine what is causing the issue, and if necessary, terminate the process, thereby freeing up critical CPU cycles. Probably the most helpful listing in Top is the process identifier (PID). The PID is an integer assigned to a given process that allows the user to identify (for purposes of killing or restarting) that process.

CHECKING AVAILABLE RAM FROM THE KDE GUI The Gnome and KDE Linux GUI desktops offer graphical tools for viewing system resources. Both tools give the user exhaustive output on the particular system in question, and each tool has its own unique features. Today we'll discuss how to check available RAM from KDE's GUI, and next time we'll explain how to do so from Gnome's. Ktop is a very solid graphical tool for analyzing system resources. Ktop (also known as KDE Taskmanager) offers three different tabs within a single window: Process List, Process Tree, and Performance. The Process List tab is basically a simple representation of the lower half of the top command. Each process on the system is listed along with its PID, username, CPU, time running, status, and various memory indicators (amount used/shared/cached). The next tab, the Process Tree, is a very useful representation of the dependencies of a process. When a parent process spawns a child process, the Process Tree offers an Explorer-like view of this dependency. For example, when you run the command Ktop from a "Konsole," the Konsole is the parent of Ktop--the one is spawned from the other. The final tab is the Performance tab, which is simply a dynamic graphical representation of the system resources offered with the basic top command.

CHECKING SYSTEM RESOURCES On what operating system can you find both textual and graphical tools to check system resources? Linux, of course. While the Windows operating system offers the user just a few ways to check resources, Linux gives users several ways to test various resources. To check for percentage of used hard drive (or floppy disk) space, run the command df. You'll see something similar to: [jacula@lab3 jacula]$ df Filesystem Size Used Avail Use% Mounted On /dev/hda 3968M 576M 341M 63% / This output shows a particular dual-booting machine (only the Linux partition shows) with Linux residing on the hda3 partition. The numbers are self-explanatory, with the possible exception of Mounted On. This listing shows the point at which this partition starts. KDE has its own GUI tool for checking available disk space. KDiskFree gives the user a (somewhat) graphical representation of what the df command offers. This application can be found in the System submenu of the main K menu.

CHECKING AVAILABLE RAM FROM THE GNOME GUI Gnome has its own version of the front-end application for the top command. Gtop is a powerful application that takes Top to new levels. With a handsome interface, Gtop enables the user to kill processes with a right-click menu, to view all system resources (both dynamically and statically), to view system status (e.g., the machine's run time, load average, etc.), and to start and stop sampling the system. Unlike Ktop, Gtop (in typical Gnome fashion) allows the user to customize the look and feel AND the output of the application. Gtop can be run from the command line by typing gtop or from the Gnome main menu under the Utilities submenu (System Monitor is the name of the menu entry).


A simple way to start X (from the console boot prompt) and give yourself a nice viewable boot log is to create a simple startup shell script that will catalog the boot message output to a file.
This shell script, which we'll call logx, looks like this: #! /bin/bash cd ~/ startx > log_of_x 2>&1
Name this script logx and put it into a directory that lies in your $PATH. This will result in the logx command being global and executable by a user (chmod u+x logx).
When you're ready to log on at your console bash prompt, simply type logx and your GUI will begin. To view the newly created log, simply open the file log_of_x with your favorite text editor.


A virtual server is a scalable and highly available server built on a cluster of real servers. The architecture of the cluster is transparent to the end users, who see only a single virtual server. Thus, a virtual server offers a very high computation power as well as exceptionally high fault tolerance. You can find more info on this technology and its uses at:


The diff3 is useful when two people change a common file and create two independent versions thereof. Diff3 compares the original file, as well as the two files derived from it, all at once. Diff3's syntax is diff3 derived1 originalfile derived2 Where originalfile is the common ancestor from which derived1 and derived2 are derived.


The Geeknews site is devoted to reporting Linux-related technology news from around the Web. The site includes news flashes, reviews, and downloads of open source software tools. The Geeknews Web site is at:


The uCLinux (Linux Micro-controller, the lowercase u stands for the Greek letter "mu") project is a port of Linux 2.0 to embedded systems that don't have a memory management unit. The end goal of this project is to port Linux to handheld devices and embedded controllers that do not have a built-in memory management unit. uCLinux is an Open Source product distributed under the GNU Public License. For further info, visit the uCLinux Web site at:


REBOL (Relative Expression-Based Object Language) is a new, portable, general purpose, and efficient programming language for intercommunications and interoperability. The language supports almost 40 hardware platforms, including Win32, Solaris, various Unix flavors, Macintosh, and Linux. REBOL has a simple and intuitive structure with English-like syntax. You can find further info on REBOL at:


The command ls is a useful tool that allows you to view various information about files and directories. The basic use of ls is to list files within a directory--from within the directory, type ls (without arguments) and you'll get a content listing for that directory.
The ls command is, of course, potentially much more powerful than this basic application. For example, instead of jumping through your directory structure just to view directories' contents, use ls instead. Let's say you're in your home directory and want to list the contents of the /etc directory. Simply type ls /etc and you'll be rewarded with a content listing of the directory /etc.
The ls command has other power applications. Users can list all files by adding the -a flag (including hidden files) and list permissions and ownership of files with the -l flag.


After you've installed Linux, you'll notice that sound output doesn't work automatically. You must do a post-install configuration of either the proper sound driver or kernel module (depending on the Linux distribution you're using). With Red Hat Linux (both Mandrake and Macmillan), you'll have to run the sndconfig application. To run this simple app as root, type /usr/sbin/sndconfig and choose the proper driver and settings for your soundcard.
When dealing with a distribution such as Caldera, you'll have to run the COAS app as root (from the 'k' menu) and load the proper sound module into the kernel.


You often need to create an empty file for any number of reasons. Obviously, you can open your favorite text editor, create an empty file, and then save the file.
Linux, however, gives you a simpler alternative. Using the touch command, you can create an empty file (with user permissions and ownerships) to be used for any purpose. Let's say you need to create an empty file called check. To create the empty check file, enter the command touch check and voila--there's your empty file.


One compulsion for many users (a holdover from their Windows world) is the need for a graphical login screen. Linux offers such a beast (in various forms) that can be configured during install or upon running Xconfigurator. But it's best to avoid this temptation.
Why, you ask? The system you're using may find itself victim of a broken X server. Should this occur when your machine is configured to automatically boot to X, you'll have trouble dropping into the console to save yourself from impending doom. To avoid this, configure your system for a console login. With an automatic console login, you're immediately free to solve any sort of X problems that might come up.


A Loadable Kernel Module (LKM) can be added and removed while the system is running. Modern device drivers are written as LKMs. This form is a significant improvement over statically linked kernel device drivers because it eliminates the need to recompile, relink, and reinstall the kernel every time you modify any of its supported device drivers. Another advantage of LKMs is that they are not subjected to the GPL licensing rules because they are not linked into the kernel image.


Device drivers can be compiled and linked directly into the kernel. This type of driver is called a statically linked device driver. Such a driver is integrated into the kernel image and remains attached to it until the next time the kernel is rebuilt. This is not the preferred technique of writing device drivers because you need to recompile, relink, and reinstall the kernel every time you want to add, remove, or update a device driver. Still, in older versions of Linux, this technique was rather popular.


When booting a Linux system, you'll notice that a vast number of on-screen messages go flying by. This information can be critical in analyzing your system's boot process. In many instances (and many OSs), the speed at which these messages fly by hampers your ability to gather and retain any valuable information.
Linux, fortunately, has a solution to this problem. After a successful boot, go to a console terminal and run the command dmesg--you'll see thesame messages go flying by. If you'd like to examine them more closely, you can copy the output of the command to a file with the command dmesg > boot.message
Then, all that's left to do is view the newly created file, boot.message, with your favorite text editor. BURNING CDS WITH LINUX With blank CD-R discs selling for a buck or less, CD-R drives enable users to back up their data inexpensively--and what's more, any computer with a CD-ROM drive can read the burned disc, thanks to the cross-platform file system that CDs use. You can use this capability to create a very low-cost, cross-platform sneakernet that enables Linux users to exchange data files with their Windows- and Mac-using colleagues. Among Linux CD burners, the most popular is an X application called X-CD-Roast. However, its interface is rather confusing. Equally capable, but with a much better interface, is gcombust. Gcombust looks best in the GNOME desktop environment, but it will run on any X-capable system that's equipped with the GTK+ libraries. Copy and paste this URL into your browser: www.fh- CHANGING WINDOW MANAGERS IN GNOME The Gnome desktop environment allows users to change their window managers at will and on the fly. Although Gnome prefers to deal with "session management compliant" window managers, it will play well with nearly all the available WMs. To change the current WM in Gnome, simply go to the Control Center, open the Window Manager section, highlight the WM you wish to switch to, and click OK. If the WM you wish to switch to is not listed, click Add and provide the necessary information. (NOTE: This assumes the WM is properly installed.) When that's finished, you should have no problem making the switch. COPYING AND PASTING TEXT IN LINUX CONSOLE To copy and paste in Linux console, you'll rely on your mouse alone. So when you install (or configure) a two-button mouse, you'll need to set it for three-button emulation. In order to copy a block of text in your console emulator, simply highlight that text with the left mouse button. To paste, place the cursor where you want to reposition the text and click the left and right mouse buttons simultaneously--hence the need for three-button mouse emulation. If you have a three-button mouse (such as an IntelliMouse or other wheelmouse) you do not need three-button emulation. With a three-button mouse, pasting text is accomplished by simply clicking the middle mouse button (once your text is copied to the clipboard). CURING THE VIRTUAL DESKTOP BLUES After installing Red Hat Linux and GNOME, users may complain that their displays don't show the whole GNOME desktop; they must move the mouse toward the screen's edge to bring the rest of the desktop into view-- and that's true even if they've configured their window manager to use only one desktop area. Some users just hate this and give up on Linux in disgust. That's too bad, because there's a simple solution: Edit /etc/X11/XF86Config so that X doesn't use a virtual desktop that's larger than the display. In this file's Screen section, comment out any line that begins with Virtual by typing a hash mark [#] at the beginning of the line. If you don't find a line with a Virtual setting, look at the Modes line for each color depth. By default, most X servers automatically set the screen size to the largest size they find in this line. If the largest resolution listed on the Modes line is greater than the display's maximum resolution, delete the largest resolution. For example, if the display's maximum resolution is 1024 x 768, delete 1280 x 1024. Save the file and restart X, and you'll find that the desktop and screen are now the same size. DIAL-UP SIMPLICITY When you create your new dial-up account in Linux, make sure you click User May Activate/Deactivate. By clicking this button you avoid the issue of having to su to root to bring up your modem. With this option you can, from console, bring the modem up with /sbin/ifup ppp0 and bring it down with /sbin/ifdown ppp0 (that is, if your modem is connected to ppp0). DUAL BOOTING Want to dual boot between Linux and Windows 9x? Here's a tip that will save you a great deal of headache. Load Windows first! The Windows boot loader (this does not include the NT boot loader) is not intelligent enough to work with any other OS, and since the Linux Loader (LILO) is, it only makes sense to put it on last. So to set up a dual-booting machine, follow this tried-and-true formula: FOR THE GEEKS 1. Partition your hard drive so that you have a FAT partition (for Windows) taking up only a certain percentage of your hard space (this percentage will depend on whether the user prefers Linux or Windows). Once the partition for Windows is set, LEAVE THE REMAINING HARD SPACE UNPARTITIONED. Linux is smart enough to use all the remaining free space left after your Windows partition is created. 2. Install Windows 9x. 3. Install Linux and allow for LILO to be placed on the MBR. FOR THE NON-GEEKS 1. Install Windows. 2. Install Partition Magic and shrink your Windows partition to make room for Linux. 3. Install Linux and allow for LILO to be placed on the MBR. Simple enough. When you start up your machine, you will be greeted with the LILO: boot prompt. At this prompt, either hit [Enter] (to boot Linux) or type dos followed by [Enter] (to boot Windows). ERRATA Red Hat Linux offers up a great errata page from which users can download, for free of course, the latest security patches and updates for the Red Hat Linux distribution. On this site you'll want to take special notice of the Security Advisories and the Bug Fixes sections. Take caution, however. The Red Hat Errata site is in a constant state of busy! If you have problems getting packages, click Red Hat's convenient mirrors link. FRESHMEAT Need a Linux application? Browse on over to freshmeat, where you'll find categorized and searchable indices of the thousands of apps (both console- and X-based) available for Linux. Each day the main freshmeat page is updated to reflect new entries within its software map, so if you want to stay on top of the curve, this is the place to be! GRAPHICS WITH THE GIMP The Gnu Image Manipulation Project (GIMP) is one of the most powerful open source applications to date. Nearly rivaling Photoshop in its power and flexibility, the GIMP is an amazing testament to what the open source community can accomplish. The GIMP contains nearly all the features that make Photoshop the industry standard. From layering to plug-ins to original effects and lighting, the GIMP allows those with a bent for artistic creativity and design to happily flex their right-hemisphere muscles. HOST NAME RESOLUTION To allow your Linux machine to use host names for various networked machines, you simply have to add the new aliases to your /etc/hosts file. Let's assume that on your network you have three machines: Sammo (IP, Jackie (IP, and Maggie (, all of which are part of the .goofydragon net. To allow your machines to resolve the IP addresses to host names, you'll want to enter them into your hosts file as such: Sammo.goofydragon Sammo Jackie.goofydragon Jackie Maggie.goofydragon Maggie You'll have to edit and save this file as root. Once you save this file, you can test the settings by pinging each alias (e.g., ping Sammo). LAPTOP BATTERY MONITORS Both Gnome and KDE offer monitors for laptop battery states. Both applets show you the machine's current power source and give both graphical and textual representations of how much charge your battery has. For Gnome: Right-click the panel, select Add Applet, and choose Battery Charge Monitor from the Monitors menu. For KDE: From the main menu (k menu), go to the Settings menu and then to the Laptop submenu. From the Laptop submenu, choose the Battery Monitor, and it will automatically be placed on your panel. MOUNTING NFS AT THE COMMAND LINE Mounting an NFS (Network File System) from the command line is a very simple process. This tip assumes you have the NFS properly working on your Linux box and want to mount or unmount either an automounted partition or a partition that is available but not mounted. As root, you will mount the file system as you would mount any other device (only with different flags and mount points). So, type mount -t nfs DEVICE_TO_BE_MOUNTED DIRECTORY_WHERE_NFS_IS_TO_BE_MOUNTED. Notice the space between DEVICE_TO_BE_MOUNTED and DIRECTORY_WHERE_NFS_IS_TO_BE_MOUNTED, as this space is critical. Should you want to mount an NFS device over a network, you'd simply add the hostname of the remote device before DEVICE_TO_BE_MOUNTED and separate it by a colon [:]. So, if you want to mount DEVICE_TO_BE_MOUNTED on the remote host "Buffy," you'd type: mount -t nfs Buffy:DEVICE_TO_BE_MOUNTED DIRECTORY_WHERE_NFS_IS_TO_BE_MOUNTED as one line. To unmount these devices you'd simply run: unmount DIRECTORY_WHERE_NFS_IS_TO_BE_MOUNTED PROBLEMS WITH OLDER GNOME If you're using an older version of GNOME, you'll more than likely run into problems with "core dumping," and your log out button may no longer work. There are many reasons for this and one simple (but frustrating) solution. (To check which GNOME version you have, run rpm -q gnome-core. If the version number that's returned is prior to 1.0.7, you're running an old one.) Once you notice this behavior you need to remove the .gnome and .gnome- desktop directories, as well as the .ICE-authority file in your normal user account. By removing these you force GNOME to rebuild itself when the user logs back in. NOTE: This will cause you to have to completely reconfigure your personal GNOME desktop settings (including your panel settings), but it's a small price to pay for getting a modicum of stability back into your system. The best solution--upgrade to the latest GNOME, of course. USING TRANSPARENCIES IN CONSOLE WINDOWS Want to completely impress your friends with the amazing aesthetics of Linux? Use transparencies for your console windows. A number of different terminal window emulators handle transparent backgrounds very well. Of the console emulators, aterm, eterm, and gnome-terminal are the best at creating this look. With them, adding transparencies is as simple as calling the application with the tr argument. Each terminal emulator deals with the argument differently. With either aterm or eterm, you add the tr flag with a hyphen (-) as in aterm -tr or eterm - tr. For the gnome-terminal emulator, add transparencies with the plus symbol (+), as in gnome-terminal +tr. Aterm takes the transparencies one step further and adds the ability to tint your windows in various colors (a limited palette, mind you). So, to add a magenta tint to your transparent aterm window, type (in a console) aterm -tr -tint magenta. UPGRADING WITH RPM The Red Hat Package Manager (RPM) is one of the simplest and most powerful ways to update a Linux system. Although created by and for Red Hat Linux, RPM works with a number of distributions and has been worked into both the Gnome and KDE GUI applications. The easiest method of upgrading a package is doing it all at once. This allows for dependency checks on an entire array of packages. Let's say you want to upgrade your current Gnome package: Create a new directory called "rpms" and move all of your relevant Gnome .rpm files into this new directory. Once all your files are moved, cd into this new directory and run (as root) rpm -Uvh *rpm and, barring dependency errors, you'll see hash marks fly by as the packages are upgraded.


The bash command shell automatically executes the .profile file that is located in the user's default directory upon log in (.profile is similar to the autoexec.bat file in DOS). You can add aliases, environment variables, and hard links to your .profile file so that they remain defined permanently.


Standard C and C++ enable you to embed inline assembly code in your program. The reserved keyword "asm" takes a quoted string that is a native assembly directive. For example: asm ("nop"); is a no-operation assembly directive, and asm ("cli"); disables all interrupts. The __asm__ token is identical to asm. You can use __asm__ instead of standard asm if the latter conflicts with other identifiers in your program. Still, it is best to stick to the standard asm keyword whenever possible to ensure compatibility with other compilers and UNIX versions.


When upgrading your compiler, you may consider recompiling your kernel. The new compiler version may provide better optimizations and bug fixes so the overall performance gain can be significant. Note that this tweak is recommended for experienced users and that you should follow the documentation regarding kernel compilation that is included in your Linux distribution.


To avoid typing a long command that you use frequently, define an alias for it. For example, the following line: $ alias chkcode = 'gcc --fsynatx-only test.cxx' defines an alias chkcode, which is synonymous with the long-winded "gcc --fsynatx-only test.cxx" command.


The function alloca() allocates memory at runtime. Note, however, that unlike malloc() and calloc(), alloca() allocates memory from the stack, not from the heap. This is advantageous because the allocated memory is automatically released when the function that invoked alloca() exits. In the following example, alloca() is used to create a memory buffer that is automatically released when the function exits: int f() { char * p = (char *) alloca(12); /*allocate 10 bytes*/ if (p!=NULL) strcpy(p, "hello world"); } /*memory is reclaimed automatically*/ Note that alloca() is not defined by ANSI C.


In addition to statically linked kernel device drivers and loadable kernel modules, you can implement a device driver as a shared library. This is useful when the driver has specific timing requirements or privileges.


The Linux Kernel Crash Dump project attempts to provide a more reliable method of examining system failures after the machine recovers. The project contains kernel and user level code that is designed to save kernel memory information when the system crashes due to a software failure. When the system is rebooted, the saved kernel memory information can be recovered and analyzed to determine the cause of the failure. The documentation, source code, and RPMs of Linux Kernel Crash Dump are now available at:


Ncurses is an Open Source implementation of the traditional UNIX curses library. It provides a uniform, simple, and high-level interface for controlling the screen and capturing mouse and keyboard input. Ncurses beginners should notice that many of the library's functions take parameters of the type "chtype", rather than plain char. Such a character is also called a "pseudo character" because it is represented as an unsigned long integer, in which the low order eight bits hold the original character and the higher order bits carry additional information, such as video attributes.


Suppose you've just started to run a long process (a compilation of a huge program, for example) and you forgot to append an ampersand to that command. The task will run in the foreground, which means that you cannot type other commands in the shell prompt until that task finishes. You don't have to abort that task or wait for it to finish. Simply redirect the running task to the background as follows: press trl-Z, then type bg (for background), and press Enter. The command prompt will appear again, and the task will continue to run in the background.


KDbg is a graphical debugger interface to the GNU gdb debugger. It requires the KDE runtime libraries. Major features of KDbg include inspection of variable values in a concise tree structure, debugging of core dumps, attaching to running processes, conditional breakpoints, and function keys for frequent debugging commands. KDbg supports C and C++ and is an Open Source product. KDbg is available at:


LinuxOne Lite is a simplified version of Linux that has been especially crafted for first-time users. It is targeted at curious PC enthusiasts, educators, and students who are looking for a Linux version that is easy to set up and use. For example, unlike other distributions, LinuxOne Lite doesn't require that users know how to partition their hard disk. For further info and a free download, see:


When main() exits, either implicitly or explicitly (that is, by an explicit call to exit() or due to a return statement), it returns to the environment a status code that indicates successful or failed termination. Remember, though, that the return code is truncated to eight bits. Therefore, you should return only values in the range of -127 through 127.


The tiny COBOL project attempts to develop an open source COBOL compiler for Linux that is as close as possible to the COBOL-74 ANSI standard. For more information about this project, visit: ABIWORD--A FREE WORD PROCESSOR FOR LINUX AbiWord is a cross-platform word processor with a graphical user interface that can import Word files. It is available on Linux, UNIX, Win32, BeOS, and MacOS. AbiWord is an Open Source product distributed under the GNU GPL terms. You can find more info on AbiWord and download it from: BASH COMMAND PROMPTS The bash command shell uses different prompts to indicate what your user privileges are. For example, the default prompt for a root user is #, whereas a regular user's default prompt is $. You should pay attention to the bash prompt you get to avoid inadvertent deletion of files when you're logged in with super user privileges--and, in particular, after executing the su (switch user) command. DETECTING LOG ALTERATION Linux regularly monitors the activity of every user and process and logs that information. Crackers sometimes try to alter the system logs to hide their malicious activity. chkwtmp is a software tool that detects such alterations in wtmp and reports deleted entries in it. You can find more info on chkwtmp and download it from: INTRUSION DETECTION Intrusion detection is a relatively new methodology in the science of system security. In essence, it is based on the use of automated and intelligent software tools that detect intrusion attempts in real-time and then react accordingly. An Intrusion Detection System (IDS) can do one or more of the following when it detects such an attempt: - Page the system administrator. - Distribute misinformation. Linux can pretend to be an NT server, for instance, and mislead the attacker. - Act according to a set of predefined rules, for example: "terminate all processes and shut the system down when the attacker has a certain IP address." PLUGGABLE AUTHENTICATION MODULES Pluggable Authentication Modules (PAM) is a software library that was specifically designed for configuring authentication on a system. The PAM library is implemented on Linux and most flavors of Unix. It has a standard and rather intuitive interface for changing authentication information (such as a user's password) and authentication checks. You can read more about the PAM specifications and download the source code from: SHELL COMMAND AUTO-COMPLETION The bash shell command supports autocompletion. To complete the full name of a file that is located in the current directory, simply type the first letters of the file that uniquely identify that file. For example, suppose you have the following three files in the current directory: nightingale knight nite and you want to delete the file nightingale. First, type $ rm nig and press Tab. Because nightingale is the only file in the current directory that starts with the characters nig, the command shell automatically extends what you've just typed to $ rm nightingale Now you can press Enter to delete that file. TCP WRAPPERS AND NETWORK ACCESS CONTROL TCP Wrappers is one of the most widely used toolkits for enforcing network access control. If you own a recent Linux distribution version, you probably already have TCP Wrappers installed on your system. TCP Wrappers enables you to allow users and hosts to connect to one another selectively. For example, you can force a user to connect to a server from a particular machine by forcing him or her to have a particular IP address. By combining this restriction with the general username and password protection, you can get a higher level of system security. THE ENTROPY POOL The entropy pool stores random information from external events such as mouse clicks and keyboard keypresses. These random data can later be used by programs and scripts that need truly random and nonreplicable numbers. You can read the random numbers in the entropy pool from dev/random and dev/urandom devices. Whenever you read from any of these devices, a hash algorithm first manipulates the random data in the entropy pool and returns the resultant numbers. The random driver's code (located at drivers/char/random.c) contains extensive documentation on the generation of random numbers and the hash algorithm. "HELP! I SWITCHED OFF MY SYSTEM WITHOUT SHUTTING DOWN--AND IT SCRAMBLED MY DISK!" Try to refrain from saying "I told you so." OK, they flipped off the power switch instead of shutting down properly--and some data that should have been written to disk went to byte heaven. What's probably happening now is that the user's system is failing the boot-process filesystem check. Instead of continuing, Linux displays a command prompt and gives the user all kinds of frightening messages about horrible things wrong with various partitions. In most cases, the problems here aren't serious--but they're just serious enough that the filesystem checking utility (fsck) can't fix the problems the way it's configured to run during the boot sequence. Instead, fsck keeps its more radical tools in check until there's a human being around to confirm the somewhat more drastic measures that may be needed to fix the problems. Chances are good that the following procedure will get the system running smoothly again. First, make sure the damaged partitions are unmounted--don't ever run fsck on a mounted filesystem! If the problems were found on /dev/hda8, and this partition contains the native Linux filesystem, type the following: fsck -t ext2 /dev/hda8. This command runs in interactive mode, so you may need to approve some repairs; chances are good they won't destroy any critical data. Once you've restarted the system, all should be well. Now you can say, "Repeat after me: 'I promise to shut down my system properly!'" "I KNOW THAT FILE'S IN HERE SOMEWHERE!" You created a file just a few hours ago, and now you can't find it. You can search for it using text-mode utilities, but there's a GUI way, thanks to the KDE File Manager (kfm). What's more, it works almost exactly the way a similar feature works in Microsoft Windows. To search for a recently created file with kfm, select Find from the File menu (or press [Ctrl]F). Now you'll see the Kfind dialog box. In the Named text box, type the filename. In the Look In area, type the directory you want to search. (Be sure to select Include Subfolders if you think the file might be buried down there somewhere.) Now, click Date Modified, select Find All Files Created Or Modified, and select During The Previous 1 Day. Finally, do one of the following: * Click Start Search on the toolbar. * Choose Start Search from the File menu. * Press [Ctrl]F. "THIS EDGE FLIPPING IS DRIVING ME NUTS!" You'll often hear the above complaint from new users of the Red Hat Gnome/Enlightenment duo, which is configured by default with edge flipping enabled. In brief, edge flipping moves the focus to an adjacent desktop area when the user moves the pointer near the screen's edge. All too often, users don't actually want to jump to the adjacent desktop area; they just moved the pointer too close to the screen's edge. Because this feature can prove very frustrating to new users, you'd be wise to disable it--or at least introduce a much greater delay before edge flipping kicks in. You can perform the necessary modifications by accessing the Gnome Desktop Settings dialog box, choosing the Window Manager option, and running the configuration manager for Enlightenment. Just click Desktops and deselect the Enable option in the Edge Flip Resistance Area. Optionally, you can increase the edge flipping delay. DEFRAGMENTATION? FORGET IT Remember what it was like using Windows? Periodically, you'd find that your hard drive's performance would slow down considerably, and you'd be in for a time-consuming bout with a defragmentation utility. Your ex-Windows users are probably wondering when they'll have to go through this painful experience with their Linux systems, and they might even start nosing around, looking for a defragmentation utility. Tell them two things, and right away: first, it's rarely necessary to defragment a Linux filesystem; second, the defrag utility that's out is old, unsupported, and dangerous to use. Why isn't defragmentation necessary? You can thank the ext2 filesystem's advanced design, which proactively keeps the various segments of files together as much as possible. Consequently, fragmentation rarely causes the kind of performance degradation that's commonplace on Windows systems. DESKTOP PAGERS: NICE, IF YOU'VE GOT LOTS OF RAM The latest versions of Enlightenment and the KDE window manager offer a very cool desktop pager, which displays miniature graphical versions of all your system's desktop areas. For each area, you'll see a miniature version of the desktop, including the windows that you've positioned on-screen. By dragging these pager thumbnails, you can move them from one desktop area to the next. You can even choose an option that mimics the appearance of what's displayed in the window--as you can imagine, this looks very cool. After toying with a desktop pager for a while, though, you'll realize that this feature consumes system resources with the type of voracity normally encountered only with window managers or Netscape. I'm running the KDE desktop pager right now, and it's taken a 10 percent bite out of my CPU. What's more, it's consuming a whopping 10 MB of RAM. With the KDE pager, you can cut down the resource consumption significantly by switching to the plain display mode, but it isn't anywhere near as nifty. Maybe I will upgrade my system, after all. DIGITAL PHOTOGRAPHY THANKS TO gPHOTO Digital cameras are changing photography, especially in business settings. In real estate, for example, realtors can take a few snapshots and get that hot new listing up on the Web within a couple hours. Thanks to gPhoto, a GTK+ application, Linux is now a very good platform for digital photography--perhaps even an ideal one. One of the most impressive of all GTK+ applications, gPhoto is a beautifully designed, easy-to-use program, and it works with a whopping 90 cameras, including popular makes such as Agfa, Kodak, Nikon, Olympus, and Sony. Note, though, that gPhoto supports image downloads through a serial port. (USB support is coming to Linux, but it's not yet fully implemented.) A very cool gPhoto feature is an almost totally automatic Web gallery generator that creates HTML-encoded presentations, ready for uploading, that feature pix you've arranged for display. FIXING A FILE OWNERSHIP MESS On single-user Linux systems where users know the root password, they often get themselves into a fix by switching to superuser status and writing files to their home directories. The result? The files belong to root, not to the user. After switching back to their ordinary user account, users won't be able to delete or alter these files and may not realize why--and sometimes, they won't be able to run programs that require certain files to have the user's write or execute permissions. To fix the problem, you could right-click the files individually in the GNOME or KDE file managers and adjust the ownership settings one-by- one--but this task could very well take hours. If there was ever a good argument for switching to the shell, here it is: You can run the chown command with the -R (recursive) switch, which goes to work on every last file in the directory (and all associated subdirectories). To restore the correct file ownership for all the files in /home/suzanne and associated subdirectories, open a terminal window, switch to superuser, and type chown -R suzanne /home/suzanne. If you'd like to fix group ownership settings too, type a period after the username and type the group name, as in the following example: chown -R suzanne.users /home/suzanne. Sometimes, using the shell really is easier. FROM UPPERCASE TO LOWERCASE IN ONE EASY SCRIPT If you're importing lots of files from Windows, you'll wind up with all kinds of weird capitalization patterns in filenames--some are all uppercase, some are lowercase, and some combine the two. Because most Linux utilities list files in case-sensitive order, such anomalies can make directory listings look rather random. The following shell script cures the problem: $for file in * do name=$(echo $file | tr A-Z a-z) mv $file $name done To use this shell script, type the first line (for file in *) and press [Enter]; press [Enter] after typing each subsequent line as well. GETTING ALL YOUR CLOCKS IN A ROW Setting the time and date on a Windows or Mac system is simple enough: You just change the setting, and bingo! You see the correct time and date. On Linux, it's not quite so simple. Users may try to set the time and date using various utilities, only to find that their setting doesn't actually change what's displayed on-screen. Here's why. A Linux system actually has two clocks: the system clock and the hardware clock. On Linux, the system clock has absolutely nothing to do with hardware; it's a kernel utility, and the time it's tracking is lost when the power is shut off. Still, the system clock is the one that generates the time and date display that programs use. The hardware clock, in contrast, is the battery-powered time-keeping clock that's built into the computer's motherboard; it stores the time while your computer is switched off. When you start a Linux system, scripts run utilities that fetch the time and date from the hardware clock and synchronize this data with the system clock. Got it? Here's where users get into trouble. Time and date utilities sternly warn users against changing the system clock while their systems are running programs, and for good reason: Doing so could bring down time-synchronized programs. So they follow the time and date utility's advice and change the hardware clock--but this doesn't affect the on-screen time and date display. To keep users from getting frustrated, teach them the proper procedure: Before logging out, open a terminal window, switch to superuser, and type hwclock --set --date=newdate, where newdate is a quotation- enclosed string containing MM/DD/YY HH:MM, as in "05/21/03 12:56." After setting the hardware clock, users should restart their system. Voila! Both clocks are now in sync. GETTING BEYOND THE MPEG HERKY-JERKY No matter which OS you're running, PCs are far from ideal as a movie- viewing platform. Still, there are times when nothing short of full- motion video will do, even if it's visible only in a relatively small on-screen window. If you've tried running XAnim (an X movie player) or aKtion (a KDE player that relies on XAnim), you probably weren't impressed with the utilities' performance when playing MPEG videos. But there's a reason: The required video codecs can't be readily distributed in GPLed distributions of Linux due to licensing restrictions. Consequently, XAnim is running with only half of a brain. And believe me, it shows. Thanks to David Sweet, you can download a version of XAnim that's fully equipped with the needed codecs. Performance improves, but as you'll see, it still isn't anything to write home about. If you need MPEG movie-playing capabilities to get those essential points across to colleagues and customers, take a look at the shareware at MpegTV. You'll get Windows-Media-Player quality, and at $10 per seat, it's not going to break the bank. The software is free for personal or educational use. GETTING YOUR WINDOWS IN FOCUS Users migrating from a Windows or Mac OS may find default X window focus behaviors annoying. For example, the default version of Enlightenment that shipped with Red Hat 6.0 and 6.1 doesn't automatically move the focus to new windows when they appear on-screen; you can't type in the window until you click within it. To change these settings with Enlightenment, use the Enlightenment configuration editor (accessible from the GNOME desktop settings utility), click Behavior, and choose all the options that automatically move the focus to new windows when they appear on-screen. IT'S ONLY AS TRUE AS YOUR TYPE You can get TrueType fonts working on a Linux system, but there might not be much point in doing so: With X, what you see on-screen is not what you get at the printer. That's why AbiWord, Gnumeric, and StarOffice will cheerfully ignore the screen fonts you've installed unless there's a printer font that exactly matches the screen font. Why not forget installing TrueType support and convert all those pretty TrueType fonts into Typ1 format? It's easy, thanks to a very neat utility called ttf2pt1. After you download and install ttf2pt1, check out the README files and documentation; you'll find there's a script that automates the entire conversion process once you've made a few changes to the default configuration file. Alternatively, you can run the script on one font at a time. For example, type ttf2pt1 arial.ttf arial to transform the Arial font into the arial.pfa and arial.afm files that X applications need to display and print it. KDE CAN KILL, TOO (GETTING THE SKULL-AND-CROSSBONES POINTER) One nice thing about Enlightenment is the ease with which you can dispatch comatose processes--you just right-click the window close box to throw the equivalent of a kill switch. (This comes in very handy with Netscape, which goes belly-up with disconcerting frequency.) As you'll quickly discover with KDE, though, right-clicking a window close box won't kill it. But there is a deadly trick you can use. Just press [Ctrl][Alt][Esc], and a skull-and-crossbones pointer will appear on-screen. With this thing, you can kill anything you click. MANAGING FILES WITH THE K FILE MANAGER Even those partial to GNOME will concede that the GNOME File Manager leaves a great deal to be desired. File Manager's strength lies in its great drag-and-drop implementation, but users find that they can't use the standard clipboard commands--[Ctrl]C, [Ctrl]X, and [Ctrl]V--to copy or move files. One look at the KDE file manager, called kfm, is enough to see what you've been missing: It's fully the equal of the best file managers in the Windows and Mac worlds. In addition, it's loaded with cool features, including an option that displays Mac-like thumbnails for graphics files. Does kfm's superiority mean that it's advisable to switch from GNOME to KDE? That's not necessary, thanks to GNOME's ability to run KDE applications. If you've installed KDE, you can choose the K File Manager from the GNOME Main Menu--point to KDE Menus and choose Home Directory from the pop-up menu. Try it; you'll love it. (Note that the GNOME File Manager is slated for a major overhaul for version 2.0. Don't be surprised if the new GNOME utility looks a lot more like today's kfm.) RPM BLUES: WHERE OH WHERE DID MY NEW FILES GO? It's easy to install software with the Red Hat Package Manager (RPM)-- that is, it's easy once you've learned how to invoke the correct command. Generally, this syntax is rpm -ivh, followed by the package name. With this skill down, you're ready to install like mad. It's quite another thing, however, to figure out where all the program components wound up. Where's the configuration file? Where's the documentation? Where are the darned icons? If you're wondering where to find all this stuff, here's a nifty query command that displays a complete list of all the files that were installed with the package. Just run rpm -ql package-name to get an exhaustive listing of information. For example, rpm -ql enlightenment will display a complete list--a very lengthy list--of all the files installed with the Enlightenment window manager. You may prefer to route the output to the printer (rpm -ql package-name | lpr) or pass the less parameter (rpm -ql | less) so that the info is more convenient to read. SCANNING AND LINUX? IT'S SANE, AT LAST Formerly an oxymoron, the phrase "scanning with Linux" can now be discussed sensibly, thanks to the SANE project. SANE is essentially a library of scanner drivers and an API that application authors can use to communicate with scanning hardware. Now in a stable version 1.0, SANE supports a wide variety of scanners, including models made by Agfa, Apple, Canon, Epson, HP, MicroTek, Nikon, Polaroid, Tamarack, Umax, and more. Unlike the TWAIN interface common in Windows and Mac worlds, SANE separates the scanning interface from the code that connects to the scanner--a more logical and elegant approach. What's more, SANE enables network access to scanners, a development that could make Linux the platform of choice for scanning- intensive environments. Several graphics applications are designed to work with SANE; among them is Xsane, a front-end program for SANE that can also function as a GIMP plug-in. SHARPEN YOUR MAN-HUNTING SKILLS Man (manual) pages offer a tremendous repository of knowledge concerning Linux systems, and they're generally well prepared, thanks to the standard heading format to which every man page author must conform. But there's so many of them! Worse, few users know how to search for man pages in anything like an organized fashion. Here's a quick rundown. Use apropos to perform a substring search for man page titles and brief descriptions. For example, type: apropos time to see an on-screen list (automatically routed to less) of all the man pages that contain the string "time" in their titles or brief descriptions. If apropos doesn't bring home the big game, you can use the man command with the -K switch to search through the full text of all man pages accessible on the system. Because many man pages pertain to system calls, library calls, and other arcane things that probably don't interest the average user, you may wish to restrict the search to utilities or executables by specifying the appropriate section number (1 and 8, respectively). For example, the command man 1 -K file retrieves a list of all the man pages in Section 1 (utilities) that mention the word "file." You'll see a prompt asking if you'd like to see the first file that contains this word. Type y to view the file, n to skip to the next file (if any), or q to quit. TAKE A LITTLE PEEK AT /ETC/SERVICES--YOU'LL SLEEP BETTER One of the not-so-nice things about too many Linux distributions is their propensity to let naive users install all kinds of things that they shouldn't really be running, such as telnet, ftp, finger, and other easily exploited services. Sure, users could opt for the "Workstation" install, which is supposed to protect beginners from the dangers of a poorly configured server installation--but that's not what most beginners will choose if left to their own devices. The typical attitude is "Hey, I want it all!" So guess what? They're running sendmail, ftp (and of course, it's the older version with the wide-open security hole), and who knows what else. Make a friendly visit to every Linux user's office, log on as root, and have a look at /etc/services-- and put that nice, big hash mark [#] in front of every service that the user doesn't really need to run. THE CAPS LOCK ATTACK, OR, HERE'S ONE PROBLEM THAT'S EASY TO SOLVE The anguished voice on the other end of the phone says, "I can't log in. I've tried everything. I know my password. I even know my root password. The system won't accept either one! I can't get to my work! You got me into all this Linux stuff and now look, I'm dead!" Sounds serious, right? Chances are it's really very simple. Tell the anguished user, "Take a look at your keyboard. Do you see a little light next to the Caps Lock indicator? Ah, I thought so. Press the Caps Lock key, and try again." It's amazing how many users make this mistake. Just bear in mind that as a UNIX derivative, Linux is generally case-sensitive. It's often safe to assume that capitalization matters, unless you can prove that's not the case. Reflections on Multithreading by Danny Kalev While it is true that a multithreaded app is usually more responsive than a single-threaded one, programmers new to multithreading are often misled into thinking that a multithreaded app executes faster than a single-threaded one. This is not always the case, however. On a machine that has a single CPU, adding threads will usually increase the overall processing time. This is because the CPU instructions required to perform the scheduling and switching between threads add more overhead in terms of execution speed and application size. Of course, in interactive applications such as word processing, Web browsers, and graphical editors, multithreading is unavoidable; otherwise, the application may become annoyingly nonresponsive. However, processes that always run in the background usually execute faster as multithreaded applications on machines that have a single CPU. In some cases, even interactive applications can do well without threads if they run on a machine that has a single CPU. For instance, a text-based interactive calculator that accepts an expression and displays the result doesn't necessarily have to split the user interface logic and the number-crunching task into two separate threads. The time wasted in performing the context switch between those threads is probably longer than the time needed for parsing the expression and computing the result. Likewise, for applications that only run in the background, the use of threads may not be necessary. Only machines that have two or more processors offer true parallel processing. In this case, the overall processing time can be reduced by allocating a distinct processor to each thread. Web Browsers for Linux by Danny Kalev Currently, there are at least four Web browsers that run on Linux. This column is a quick overview of those browsers and their major advantages and weaknesses. - Netscape - Netscape is included with most Linux distributions. The latest version, Communicator 4.7, supports the latest standards, including HTML 4.0, XML, and CSS. However, its resource-gluttony and instability are two noticeable weaknesses. For acceptable performance, you need at least 64Mb of RAM and a Pentium 233 or higher. Netscape still crashes occasionally, although recent versions have shown continuous improvements in this respect. The latest version is available from Pros: fully-featured, supports the latest standards, free, includes a mail client. Cons: bulky, resource hungry, still unstable. - Mozilla - The Mozilla project has been working, over the past couple of years, on an Open Source Web browser. Originally, Mozilla relied on Netscape's legacy browsing engine, but later it was abandoned in favor of an entirely new engine written from scratch. Thus, Mozilla is independent of Netscape. M13, the latest release, is still an alpha version, yet fully-featured. Future releases, however, will add missing functionality. The latest binaries and source files are available from Pros: free, open source, graphical, written from scratch; includes a mail client. Cons: bulky, still unstable, not fully-featured. - Opera - Opera offers a small, fast, and efficient browser that performs satisfactorily, even on old PCs with vintage processors and little memory. The latest release, Opera for Linux 4.0a, is still an alpha version. While it offers an interesting alternative to the more cumbersome mainstream browsers, it's not free: a registered copy costs $35. Still, Opera's creators claim that the product offers incontestable qualities in terms of compactness and speed. You can download a 30-day trial version from and decide whether it's worth the price. Pros: small, fast, can run on old PCs. Cons: costs money, still a preview version. - Lynx - Lynx, a text-based Web browser, is included with most Linux distributions. What's the use of an age-old browser that displays only text without graphics? For some folks, this is a plus -- many sites are replete with ads, banners, and animation that take forever to download and consume precious bandwidth and connection time. Lynx filters out non-textual contents such as applets, images, animation, and audio files, thereby significantly decreasing download time. Pros: free, small, fast, and secure. Cons: displays only text, command line operated.
Using a Callback to Sort a Large File by Danny Kalev
Let's say you need to sort a large file containing 1.6 million records with 252 characters each (the file's size exceeds 400 megabytes). The file is encoded in EBCDIC (the character coding used on IBM mainframes instead of ASCII) and has to remain in this format. You can't use the "sort" command because it's inapplicable to EBCDIC files. Thus, there's no escape from writing a program to sort the file. Although writing a program that reads the entire file into a buffer and then performs in-memory sorting is a trivial task, this option is ruled out due to the file's size. Therefore, a different technique must be used. Instead of reading complete records into memory, the trick is to use a handle to represent each record. A typical handle is int, which occupies four bytes per record instead of 252. Now suppose you have exactly 1,600,000 records. First, allocate an array of 1,600,000 integers -- let's call it arr -- and fill it with ascending numbers: 0, 1, ....1,599,999. Each array element will represent a record. Next, use qsort() to sort the array. Qsort() takes four arguments: the address of the array's first element, the total number of elements in the array, the size of an element, and most important -- a pointer to a user-defined callback function that compares two elements and returns 0 if the elements are equal, a positive value if the first elements should come after the second, or a negative value otherwise. Here's the second trick: don't compare the two integers received from qsort() in your callback function. Instead, read the records with the corresponding indices, i.e., for the integers 100 and 101, your function will retrieve the 100th and 101st records from the file (using fseek() and fread()), compare these records, and return 0 if they are equal, a positive value if record 100 should come after record 101, or a negative value otherwise. When qsort() ends, arr[0] will contain the index of the record that should come first in a sorted file, arr[1] will contain the index of the subsequent record, etc. Note that up until now, the file has remained intact; we manipulated only the array. To actually sort the file, open it again and create another empty file. Write a loop that traverses the entire array and, on each iteration, read arr[n], retrieve the nth record from the nonsorted file, and copy that record to the new, empty file. Your task is accomplished after you've reached the last element in arr. *Note: The last code sample in the previous newsletter had a misspelled function name. The function name 'callback' should be changed to 'caller'. Here's the correct version: int main() { p = func; caller(p); /* pass address of func() */ }
Function Pointers and Callbacks by Danny Kalev
C programmers often need to use callbacks. In this article I discuss the fundamentals of function pointers and show how to use them to implement callbacks. This discussion is a preview to next week's newsletter, which will show how to write a program that sorts a huge file. A callback function is one that isn't invoked explicitly by the programmer; the responsibility for its invocation is delegated to another function that receives its address. To implement a callback, you need to define an appropriate function pointer. Although the syntax is a bit arcane, a function pointer declaration is very similar to a function declaration. For example, the following declaration: void f(); declares a function called f that takes no arguments and doesn't return a value. A pointer to such a function has the following type: void (*) (); Let's parse it. The asterisk in parentheses is the nucleus of a function pointer declaration. Two additional constituents are the function's return type, which appears on the left and is "void" in our example, and a parameter list enclosed in the rightmost parentheses. In our case, the parameter list is empty because f() takes no arguments. Note that we didn't create a pointer variable here -- we only declared the type of such a variable. A pointer variable, of course, has a name. Here is an example of a matching pointer variable: void (*p) (); p is a pointer to a function that returns void and takes no arguments. The name of a pointer variable appears on the right of the asterisk, inside the parentheses. We now assign a value to p. A value is simply a name of a function that has a matching signature (a function's signature consists of its return value and parameter list), for example: void func() { /* do something */ } p = func; You can assign a different value to p as long as that value is the address of a function with the same signature. Now we can pass p to another function, caller(), which will call the function to which p points: void caller( void(*ptr)() ) { ptr(); /* call the function to which points */ } int main() { p = func; callback(p); /* pass address of func() */ } If you assign a different value to p, caller() will invoke a different callback function, without having to know the name of the actual function being called.
Using Uuencode And Uudecode To Transfer Binary Files by Danny Kalev
Although the most convenient method of transferring a binary file is to send it as an email attachment, there are certain conditions for which you may need to use an alternative technique. To send and receive an attachment, both the sender and the recipient's mail clients must support the MIME protocol. However, legacy mail utilities such as Unix "mail" don't support this protocol. Furthermore, for security reasons, some gateways deliberately block binary file attachments, allowing only plain-text messages to be sent through them. Thus, even if both the sender and handler can handle a binary file, it might still be impossible to send it as an attachment. In situations like these, you can send the binary file by email using uuencode translation. The uuencode utility creates an ASCII-encoded version of the original binary file. The resultant ASCII file is about one third larger than the original. You can view a uuencode file in vi, emacs, or any similar text editor. Because a uuencode file contains plain text, you can send it to a mail client that can't handle attachments. The recipient, in turn, will decode this file to reconstitute the original binary file. For this purpose, the uuencode and uudecode commands are used. Here's an example of this process: Suppose you want to send a compressed file archive called myapp.tar.gz to and you know that Bustopher doesn't have a mail client that supports attachments. First, uuencode myapp.tar.gz like this: (See the code in EXAMPLE 1 at the following url) Let's parse this command carefully: the first parameter is the file being uuencoded. The second parameter is the name the reconstituted file will have when the recipient uudecodes it (you can use any name you like). Finally, the greater-than sign writes the output into a file called myapp.uue. Note that, by default, uuencode files have a .uue extension. Once you have created the uuencode file, you can send it to Bustopher like this: (See the code in EXAMPLE 2 at the following url) And when Bustopher receives the email, he will decode it like this: (See the code in EXAMPLE 3 at the following url) This command will reconstitute the file myapp.tar.gz from myapp.uue and store it in the current directory. Remember that uuencode does not encrypt files; it merely converts them to ASCII so they can be transferred as plain text. If you wish to protect your emails from eavesdroppers, you should also use a dedicated encryption utility.
Wildcards and Command History by Danny Kalev
My previous column discussed filename auto-completion. In this column, I will show two more useful techniques that can save you a lot of keystrokes -- namely filename wildcards and command history. - Wildcards - The bash command shell accepts two characters as filename wildcards -- an asterisk and a question mark. You can use these wildcards when you need to perform operations on a group of files, e.g., copying, compressing or deleting a directory. The ? character matches any single character in a filename. Suppose the current directory contains the following files: inventory.tmp inventory.bmp inventory.dat You wish to delete inventory.tmp and inventory.bmp at once, while retaining inventory.dat. Type the following command: $ rm inventory.?mp Consequently, the shell command will delete the files inventory.tmp and inventory.bmp. If you wish to delete any file called "inventory" that has a three letter extension, use the following command: $ rm inventory.??? The wildcard * is less restrictive than ?. It matches any number of characters (including zero). For instance, if the current directory contains the following files: vir.exe virus.exe dialer.exe shapes.plx then, to delete the files vir.exe and virus.exe, type the following command: $ rm vir*.exe To remove all the files in the current directory, use the following command: $ rm *.* - Command History - The bash command shell remembers the commands you've typed recently. You can retrieve these commands by pressing the up and down keys. Pressing the up key retrieves the most recent command you typed; repeat this step to navigate the contents of earlier commands. Command history retrieval is useful when you want to repeat the same operation several times. You may also edit the contents of the previously typed commands using the right and left keys. For example, to uudecode the following files in a sequence: picture1.uue picture2.uue First type the following command: uudecode picture1.uue The uudecode utility will decode the file. Next, press the up key. The previous command will appear again. Move with the right key until the cursor is located on the number 1, type "2", and the command will change to: uudecode picture2.uue now press Enter.
File Permissions by Danny Kalev
A file has an owner and a set of permissions. Linux associates three categories of users with each file: an owner (the user who owns the file), a group (the group of users to which the owner belongs), and others (all the rest). For each category, three types of permissions exist: read, write, and execute. Thus, you can selectively control who can read, write, and execute the file. Suppose we have only one file in the current directory called "bonuses" whose owner is susie. To see the permissions of the current directory's files, use the following command: ls -l The command displays the files in six columns. The first column shows the files' permissions, which appear as a string of ten characters. For example: -rw-r----- The first character tells whether the listed file is a directory. It can have two values: - if it's an ordinary file, or the letter 'd' if it's a directory. In our example, the file "bonuses" is an ordinary file. Therefore, the string begins with a minus sign. The following nine letters are divided into three parts: user's permissions, group's permissions, and others' permissions. Each part has three characters, and each character can have one of four values: 'r', 'w', 'x', '-'. In our example, the first three characters after the initial directory letter are "rw-". These are the user's permissions. In this case, susie can read the file and write to it. The final minus indicates that she can't execute the file (execute permission can be given to any file. However, it makes sense only when the file is a program). The next three Characters, "---", are the group's permissions. In this case, users of the group can't read the file, write to it, or execute it. The final three letters are the permissions granted to other users. Again, these users don't have any permissions. - Changing File Permissions - The "chmod" command changes a file's permissions. It takes a permission string and the name of the file(s) whose permissions are changed. Suppose susie wants to grant herself execute permission on a file called "solitaire". She can do that by typing the following command: chmod u+x solitaire The string "u+x" grants execute permission to the owner. To revoke this permission, simply use - instead of +: chmod u-x solitaire You can change permission for the owner, group, and others simultaneously. The following command removes read and write access from all the users: chmod ogu-rw solitaire Likewise, you can grant execute permission to all users like this: chmod ogu+x solitaire
Launching A New Process From A Running Process by Danny Kalev
The exec() family of functions defines six different forms of launching a program from another program. All these functions do the same thing -- they replace the currently running process (the terms "program" and "process" are interchangeable). If they succeed, they never return (because the process that invoked them is no longer running). If they fail, they return -1 to their caller and store the error code in errno. Note that unlike ordinary function calls, which return to their caller, exec() functions supersede the running process. It's as if you stopped the currently running process and launched another one. Here are their prototypes: int execl(const char * file, const char *arg0,..., const char *argn, NULL); int execle(const char * file, const char *arg0,..., const char *argn, NULL, const char **env); int execlp(const char * file, const char *arg0,..., const char *argn, NULL); int execv(const char * file, const char **argv); int execve(const char * file, const char **argv, const char **env); int execvp(const char * file, const char **argv); Each function takes a name of an executable file or its path name as the first argument. Traditionally, the following arg0 contains the name of the program being launched (it's identical to the first argument). The rest are additional command-line arguments that are passed to the launched program. Only execve() is a system call under Linux. The others are implemented as wrapper functions that ultimately call execve(). The affixes 'l', 'p', 'e', and 'v' in a function's name indicate the following attributes: l - indicates that the arg0, arg1, etc. are passed as separate arguments rather than as a single array. v - indicates that the arguments are packed in a single array. p - indicates that if an explicit path wasn't provided and the program wasn't found in the current directory, the function searches for the program in the directories specified in the PATH environment variable. e - indicates whether the function gets a different environment instead of inheriting the parent's environment. In the following example, the program launches a new program called "copy" using execl(): #include int main() { execl("copy", /*program to be invoked*/ "copy", /*traditionally, argv[0] is the name of the program*/ "source.txt", /* argv[1] passed to the called program*/ "target.txt", /*argv[2] passed to the called program */ NULL /*indicates end of argument list */ ); printf("failed to launch copy"); /* we get here only if execl() failed */ }
Controlling A Process's Resource Limit by Danny Kalev
The likelihood of a system crash caused by an ill-behaved process is very small on Linux because each process has well-defined resource limits and because the kernel usually doesn't allow a process to access memory outside of its address space. However, an on-the-loose process might still degrade the system's overall performance if it consumes scarce resources injudiciously. For example, a process that consumes huge amounts of memory or opens numerous files simultaneously can effect the performance of other running processes. To ensure that system's performance isn't affected by such a wanton process, you can limit its resource consumption. The kernel constantly monitors a process's resource consumption and guarantees that it doesn't exceed them. There are two types of limits: hard limits and soft limits. A process may reduce its hard limits but it cannot raise them -- only a super user can raise hard limits. Soft limits are the limits actually enforced by kernel. They may be equal to or lower than the process's hard limits, but they may not exceed them. Which resources can you limit? The following are the most important limits that system administrators and users can set: - Total CPU time (in seconds) used by the process. - The maximum number of open files. For each open file, the system maintains an entry of file attributes and associated I/O buffers. These resources are released when the file is closed. By limiting the number of simultaneously open files, you can minimize the possibility of I/O bottlenecks. - The maximum number of child processes. This limit controls the number of children a given process can have at any time. Note, however, that each child process may spawn its own children; therefore, this limit doesn't control the total number of a process's descendants. - The maximum amount of memory that a process can lock. To ensure that a specific region of mapped memory is never swapped, a process can explicitly lock it. This limit controls the total size of a process's locked memory. - The maximum amount of RAM used. If the process exceeds this limit, memory swapping occurs. Optimal setting of process limits is one of the crucial factors in performance tuning and the health of the systems. You can obtain the current limits of a process and set them using the system calls getrlimit() and setrlimit(), respectively. These functions and their related data structures and constants are declared in "sys/resource.h".
Implementing Multiprocessing with fork() By Danny Kalev
This column continues last week's discussion by showing how to launch a child process from a running process while keeping the parent process running. Before we do that, however, here's some background on concurrency in Linux. Concurrency comes in two flavors: threads and multiprocessing. Threads are lightweight code sections that execute concurrently, sharing a single process. They have common address space, data, and resource limits. In multiprocessing, two or more processes run concurrently. They usually interact with each other using some form of interprocess communication, such as shared memory or sockets. To achieve rudimentary multiprocessing, you need to make the parent process stick around while its newly spawned child process executes. For this purpose, you have to use the fork() function. (In contrast, the exec() function launches a new process from a running process, but replaces the running process.) The fork() function has the following prototype: pid_t fork(void); fork() creates a new process and returns its pid to the parent process. The newly spawned process is an exact copy of the parent process but it has its own address space. The child process immediately calls one of the exec() functions to run a new program while the parent process continues to run. Usually the two steps are implemented as a single if statement whose condition has a fork() call. The body of the if statement includes an exec() call. The trick is that the parent skips the if statement's body and proceeds to the next statement, whereas the child process executes the commands in body of the if statement. Here's a concrete example of when to use multiprocessing. Suppose you have a Web browser that loads a Web page containing a mailto: link. When a visitor clicks on this link, the Web browser launches a mail client while the browser keeps loading the Web page. #include #include #include int main() { /* Web browser application */ if (fork()) { /* this block is executed by child process; skipped by parent */ execl("mail", "mail", email_address, NULL); printf("error, could not launch mail client"); } get_web_page(); /* executed by the parent process */ }
Most tips are from TipWorld - :The Internet's #1 Source for Computer Tips, News, and Gossip
Danny Kalev is a system analyst and software engineer with more than 10 years of experience, specializing in C++ and object-oriented analysis and design on various platforms including VMS, DOS, Windows, Unix, and Linux. His technical interests involve code optimization, networking, and distributed computing. He is also a member of the ANSI C++ standardization committee and the author of ANSI/ISO C++ Professional Programmer's Handbook (Que, 1999). Contact him at