Cover V02, I02
Listing 1


Turning Numlock On

Larry Reznick

The enhanced IBM keyboard found on 386 and better systems separates the arrows and other special control keys from the numeric keypad. For fast numeric entry from the keypad, I prefer to keep the Numlock key on and use those separated arrow keys. When I log in on UNIX systems, however, Numlock typically is off. This is not much of a problem -- I just press the key to turn it on.

On some versions of UNIX, such as SCO and Venix (a real-time version of Interactive UNIX), once Numlock is turned on, it is on for all the virtual terminals and stays on even when I logout (which means I don't have to turn it on the next time I log in). But on others, such as Esix, I can turn Numlock on only for the virtual terminal I've logged in on --the setting doesn't apply to any others on the same console keyboard, and it resets when I logout, which means I must turn it on separately for each vt and for each login.

I can understand the logic of this, given that different virtual terminals might have differing needs. It did become inconvenient, for example, when I was editing a file on SCO and needed CapsLock, then switched to another vt to do something completely different and had CapsLock still on. In this case, however, I wanted to set Numlock permanently, since I wanted that keypad on all the time, every time I logged in.

I checked the hardware man page on the keyboard(7), hoping to find an ioctl() call that would let me force Numlock on. No such luck. But, cross-referencing to display(7) revealed KDSETLED, the ioctl() to turn Numlock on. Although KDSETLED affected only the one tty at a time -- and then only if it was a vt or the console -- it suited my purpose, since I could put it into my .login file to start up every time.

numlock.c (Listing 1) begins by checking that there are two arguments on the command line, the second being the name of the tty device that needs Numlock on. If the second argument is not there, the program quits with a usage message. The expected command line is the program's name followed by the full path of the tty device. That is most easily determined by using the following command line:

numlock `tty`

since the tty program gets the current tty device's name.

If the argument is present, it is validated as referring to either the console or a virtual terminal (Esix uses vt in the name -- change the vt reference if your UNIX uses something else). The strstr() function finds the relevant part of the name no matter what else is in the pathname. If the tty is not either the console or a virtual terminal, the program quits with an advisory message.

The program next opens the tty device for writing. This has to be done with the low-level open() function, because ioctl() only works with file descriptors, which are simple int types, not with the file pointers. The program then calls ioctl(), telling it to use KDSETLED and name the Numlock flag. (Other keys can be set this same way by using different flag names in the third parameter. Multiple keys can be set by OR-ing the flags together using a single vertical bar '|'.) If ioctl() fails, the program notifies the user.

This simple program, once placed in the .login file, turns my Numlock on every time I log in, so I don't have to worry about it. If I log in over the modem or from one of the other terminals, it tells me that Numlock cannot do its work, but does no harm.

About the Author

Larry Reznick has been programming professionally since 1978. He is currently working on systems programming in UNIX and DOS. He teaches C language courses at American River College in Sacramento. He can be reached via email at: rezbook!reznick@csusac.ecs.csus.ed.