ioctl()" -- System Call (libc)" "
Device-dependent control
##iinncclluuddee &&lltt;;uunniissttdd..hh&&ggtt;;
##iinncclluuddee &&lltt;;_h_e_a_d_e_r..hh&&ggtt;;
iiooccttll((_f_d,, _c_o_m_m_a_n_d,, _a_r_g))
iinntt _f_d,, _c_o_m_m_a_n_d;; cchhaarr **_a_r_g;;
ioctl() lets you interact directly with a
device driver. You can use it to set or retrieve parameters
for devices (line printers, communications lines,
terminals), and non-standard spacing operations for tape
drives.
ioctl() acts upon the block-special file or
character-special file associated with the file descriptor
fd. command points to the specific
request.
header names the header file that defines symbolic
commands for the device you wish to manipulate. Using the
symbolic command definitions from the header files promotes
device independence within each device type. A complete
list of symbolic commands appears below.
arg passes a buffer of information (defined by
structures in the appropriate header files) to the driver.
For any command not needing additional information,
this argument should be NULL.
Some ioctl() requests work on all files,
and are not passed to any driver.
ioctl() returns -1 on errors, such as a bad
file descriptor. Because the call is device dependent,
almost any other error could be returned.
Commands
The following gives the commands that can be used with
ioctl(), as extracted from COHERENT's header
files. Please note the following caveats:
- +o
- New drivers are being added continually to COHERENT,
both by Mark Williams Company and by users and third-party
vendors. You should regard the following list as being
tentative at best.
- +o
- Because the commands and arguments with with
ioctl() are unique to COHERENT's suite of
device drivers, ioctl() is one of the least
portable of all system calls. If you want your code to run
on multiple operating systems, you should use
ioctl() judiciously.
- &&lltt;;ssyyss//ccddrroomm..hh&&ggtt;;
- Header file used to manipulate a CD-ROM device. Unless
otherwise noted, arg is ignored:
- CCDDRROOMMPPAAUUSSEE
- Pause playing an audio CD.
- CCDDRROOMMRREESSUUMMEE
- Resume playing an audio CD.
- CCDDRROOMMPPLLAAYYMMSSFF
- Play an audio CD at a given minute-second frame (MSF)
address. arg points to an array of six bytes that
give the MSF address.
- CCDDRROOMMPPLLAAYYTTRRKKIINNDD
- Play a track on an audio CD. arg points to an
array of four bytes that give, respectively, the start
track, the start index, the end track, and the end index of
the track to be played.
- CCDDRROOMMRREEAADDTTOOCCHHDDRR
- Read the CD's table-of-contents header. arg
points to a structure of type cdrom_tochdr
into which the header is written.
- CCDDRROOMMRREEAADDTTOOCCEENNTTRRYY
- Read an entry from the table-of-contents header.
arg points to a structure of type
cdrom_tocentry into which the entry is
written.
- CCDDRROOMMSSTTOOPP
- Spin down the CD-ROM drive's motor.
- CCDDRROOMMSSTTAARRTT
- Turn on the CD-ROM drive's motor.
- CCDDRROOMMEEJJEECCTT
- Eject the CD-ROM. Note that this does not work on
every variety of CD-ROM drive.
- CCDDRROOMMVVOOLLCCTTRRLL
- Control the volume on an audio CD. arg points
to an array of four bytes that, respectively, set the the
volume on channels zero through three.
- CCDDRROOMMSSUUBBCCHHNNLL
- Read data about a sub-channel. arg points to
a structure of type cdrom_subchnl into
which the information about the sub-channel is written.
- CCDDRROOMMRREEAADDMMOODDEE11
- Read type-1 data. arg points to a structure
into which the data are written.
- CCDDRROOMMRREEAADDMMOODDEE22
- Read type-2 data. arg points to a structure
into which the data are written.
- &&lltt;;ssyyss//ffddiiooccttll..hh&&ggtt;;
- This header file is used with the floppy-disk drive:
- FFDDFFOORRMMAATT
- Format a track on a floppy disk. arg points
to a two-byte array that identifies, respectively, the
cylinder and head to format.
- &&lltt;;ssyyss//hhddiiooccttll..hh&&ggtt;;
- This header file is used with AT-style hard-disk drives
(i.e., IDE, ESDI, MFM, or RLL disks). arg gives
the address in user memory where drive attributes reside, or
to which they should be written:
- HHDDGGEETTAA
- Get drive attributes.
- HHDDSSEETTAA
- Set drive attributes.
- HHDDGGEETTIIDDEEIINNFFOO
- Get the attributes of an IDE drive. arg
should point to a copy of the structure
ide_info; this call to
ioctl() initializes the structure with the
requested information.
- &&lltt;;ssyyss//nnuullll..hh&&ggtt;;
- This header file defines ioctls that
examine system memory:
- NNLLFFRREEEE
- Read the amounts of memory on your system that are
available and free. arg gives the address of an
object of type FREEMEM, which is defined in
header file <null.h>. This type is an
array of two longs: the first receives the
amount of available memory, and the second the amount of
free memory. For an example of a program that uses this
ioctl(), see the Lexicon entry for
freemem.
- NNLLIIDDLLEE
- Read the system's idle time. arg points to an
array of two longs. The first
long receives system's idle ticks; the
second, the number of ticks since system startup. From
reading these values repeatedly, you can compute the changes
in system idle time and time since startup, and so see what
the system's load is. For an example of how to this call to
ioctl(), see the Lexicon entry for
idle.
- &&lltt;;ssyyss//ssddiiooccttll..hh&&ggtt;;
- The commands defined in this header file are passed to
the driver aha, which manipulates Adaptec SCSI
disks. None does anything.
- &&lltt;;ssggttttyy..hh&&ggtt;;
- The following commands are used with the
sgtty method of controlling terminal
devices. They are documented in more detail in the Lexicon
entry for sgtty. arg points to a
structure of type sgttyb, which is defined in
that header file:
- TTIIOOCCHHPPCCLL
- Hang up on last close.
- TTIIOOCCGGEETTPP
- Get modes (old ggttttyy).
- TTIIOOCCSSEETTPP
- Set modes (old ssttttyy).
- TTIIOOCCSSEETTNN
- Set modes without delay or flush.
- TTIIOOCCEEXXCCLL
- Set exclusive use.
- TTIIOOCCNNXXCCLL
- Set non-exclusive use.
- TTIIOOCCFFLLUUSSHH
- Flush I/O queues.
- TTIIOOCCSSEETTCC
- Set characters.
- TTIIOOCCGGEETTCC
- Get characters.
- &&lltt;;ssttrrooppttss..hh&&ggtt;;
- STREAMS commands. arg points to a STREAMS
control block that will be used to generate an
M_IOCTL message.
- II__NNRREEAADD
- Get message length, count.
- II__PPUUSSHH
- Push named module.
- II__PPOOPP
- Pop topmost module.
- II__LLOOOOKK
- Get name of the topmost module.
- II__FFLLUUSSHH
- Flush read/write side.
- II__SSRRDDOOPPTT
- Set stream head read mode.
- II__GGRRDDOOPPTT
- Get stream head read mode.
- II__SSTTRR
- Send ioctl() message downstream.
- II__SSEETTSSIIGG
- Register for signal SIGPOLL.
- II__GGEETTSSIIGG
- Return registered event mask.
- II__FFIINNDD
- Locate named module on stream.
- II__LLIINNKK
- Link two streams.
- II__UUNNLLIINNKK
- Unlink two streams.
- II__RREECCVVFFDD
- Receive file descriptor from pipe.
- II__PPEEEEKK
- Examine stream head data.
- II__SSEENNDDFFDD
- Send file descriptor to pipe.
-
- The following commands are not covered by iBCS2:
- II__SSWWRROOPPTT
- Set stream write mode.
- II__GGWWRROOPPTT
- Get stream write mode.
- II__LLIISSTT
- Get name of all modules/drivers.
- II__PPLLIINNKK
- Create persistent link.
- II__PPUUNNLLIINNKK
- Undo persistent link.
- II__FFLLUUSSHHBBAANNDD
- Flush priority band.
- II__CCKKBBAANNDD
- Check for existence of priority band.
- II__GGEETTBBAANNDD
- Get band of first message.
- II__AATTMMAARRKK
- Check whether current message is marked.
- II__SSEETTCCLLTTIIMMEE
- Set drain timeout for stream.
- II__GGEETTCCLLTTIIMMEE
- Get the current close timeout.
- II__CCAANNPPUUTT
- Check if band is writeable.
- &&lltt;;ssyyss//ttaappee..hh&&ggtt;;
- Header file for interfacing with magnetic-tape devices.
arg points to an area in user space that holds
additional information for the tape device. A tape driver
may recognize any of the following ioctl()
commands:
- TT__EERRAASSEE
- Erase tape.
- TT__LLOOAADD
- Load. Not used.
- TT__RRDDSSTTAATT
- Read status.
- TT__RRSSTT
- Reset.
- TT__RREETTEENNSSIIOONN
- Retension tape.
- TT__RRWWDD
- Rewind tape.
- TT__SSBBBB
- Space block backward -- move backward by arg
blocks. Not used.
- TT__SSBBFF
- Space Block Forward -- move forward by arg
blocks. Not used.
- TT__SSBBRREECC
- Not used.
- TT__SSFFBB
- Space Filemark Backward -- move backwards by
arg files.
- TT__SSFFFF
- Space Filemark Forward -- move forward by arg
files.
- TT__SSFFRREECC
- Not used.
- TT__TTIINNIITT
- Not used.
- TT__UUNNLLOOAADD
- Unload. Not used.
- TT__WWRRFFIILLEEMM
- Write file marks. Not used.
- &&lltt;;tteerrmmiioo..hh&&ggtt;;
- The following commands are used with the
termio method of controlling a terminal.
They are documented in more detail in the Lexicon entry for
termio. arg points to a structure of
type sgttyb, which is described above.
- TTCCGGEETTAA
- Get terminal parameters.
- TTCCSSEETTAA
- Set terminal parameters.
- TTCCSSEETTAAWW
- Wait for drain, set parameters.
- TTCCSSEETTAAFF
- Wait for drain, flush input, set parms.
- TTCCSSBBRRKK
- Send 0.25-second break.
-
- The following commands also take arguments when called
via ioctl():
- TTCCXXOONNCC
- Start/stop control: An argument of zero suspends
output; an argument of one restarts suspended output.
- TTCCFFLLSSHH
- Flush queues: An argument of zero flushes the input
queue; an argument of one flushes the output queue; and an
argument of two flushes both queues.
- &&lltt;;ssyyss//vvttkkdd..hh&&ggtt;;
- This header file defines commands used with the
keyboard driver. arg points to a structure of type
sgttyb, which is defined in header file
sgtty.h.
- KKDDMMAAPPDDIISSPP
- Map the display into user space.
- KKDDSSKKBBMMOODDEE
- Toggle the scan code xxllaattee.
- KKDDMMEEMMDDIISSPP
- Dump a byte of virtual or physical memory.
- KKDDGGKKBBSSTTAATTEE
- Get the keyboard's shift state.
- KKIIOOCCIINNFFOO
- Determine the workstation of the virtual terminal.
- KKIIOOCCSSOOUUNNDD
- Start sound generation.
- KKDDGGEETTLLEEDD
- Get the state of the keyboard's LEDs.
- KKDDSSEETTLLEEDD
- Set the state of the LEDs.
-
- The following four ioctl() commands
allow user programs to perform I/O instructions directly,
rather than going through the system-call interface and
having the kernel perform the I/O. The most common need for
these functions is in window managers and similar
applications, where the usual kernel interface would be
unacceptably slow.
-
- Normally, any user program that attempts to execute I/O
instructions directly to hardware will get an immediate
SIGSEGV and be terminated. Use of the
commands below allow user-level programs to perform I/O
without being terminated. The I/O operations are available
through functions inb(), outb(),
etc., which are present in the kernel-support library
/etc/conf/lib/k386.a and are documented in
the manual to the COHERENT Device Driver Kit.
-
- Access to any of these functions may be restricted to
the superuser on some systems:
- KKDDEENNAABBIIOO
- Allow the user process permission to perform
input/output operations to all available I/O addresses. The
third argument to ioctl() is ignored.
- KKDDDDIISSAABBIIOO
- Prohibit user processes from performing input/output
operations to all available I/O addresses. The third
argument to ioctl() is ignored. It is
normal for direct I/O to ports to be disallowed at user
level. The main reason for this call is to undo the effect
of preceding KDENABIO or
KDADDIO calls.
- KKDDAADDDDIIOO
- Allow user-level I/O to a port. The third argument to
ioctl() is an unsigned
short that gives the single address value of the
port.
- KKDDDDEELLIIOO
- Disallow user-level I/O to a port. The third argument
to ioctl() is an unsigned
short that gives the single address value of the
port.
-
- It is normal for direct I/O to ports to be disallowed
at user level. The main reason for this call is to undo the
effect of preceding KDADDIO calls.
Example
The following program, by Udo Munk, demonstrates how to use
ioctl() to read a mouse plugged into a
serial port. It takes one argument, the name of the port
you wish to check.
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <termio.h>
char *mouse;
int mouse_fd;
struct termio old_tty, new_tty;
/* do the right thing by signals */
sig_handler()
{
ioctl(mouse_fd, TCSETAF, &old_tty);
exit(EXIT_SUCCESS);
}
/* cry and die */
void fatal(message)
char *message;
{
fprintf (stderr, "%s\n", message);
exit(EXIT_FAILURE);
}
/* run the whole shebang */
main(argc, argv)
int argc; char **argv;
{
struct pollfd fds[1];
if (argc != 2)
fatal ("Usage: findmouse /dev/com[1-4]pl");
if (strncmp(argv[1], "/dev/com1pl", 11) &&
strncmp(argv[1], "/dev/com2pl", 11) &&
strncmp(argv[1], "/dev/com3pl", 11) &&
strncmp(argv[1], "/dev/com4pl", 11))
fatal ("Usage: findmouse /dev/com[1-4]pl");
mouse = argv[1];
signal(SIGINT, sig_handler);
signal(SIGQUIT, sig_handler);
signal(SIGHUP, sig_handler);
fprintf(stdout, "Trying to open %s ...\n", mouse);
if ((mouse_fd = open(mouse, O_RDONLY)) < 0)
fatal ("Cannot open this device.");
fprintf(stdout, "Success.\n");
fprintf(stdout, "Trying to read line mode of %s ...\n", mouse);
if (ioctl(mouse_fd, TCGETA, &old_tty) < 0)
fatal ("Cannot read this device'ss line mode.");
fprintf(stdout, "Success.\n");
new_tty = old_tty;
new_tty.c_cflag &= ~(CBAUD | HUPCL);
new_tty.c_cflag |= CLOCAL | B1200;
new_tty.c_iflag = IGNBRK;
new_tty.c_oflag = new_tty.c_lflag = 0;
/*
* VMIN = 0, VTIME = 0 has the same effect as setting O_NDELAY on the
* input line.
*/
new_tty.c_cc[VMIN] = 0;
new_tty.c_cc[VTIME] = 0;
/* Set up to poll the input line. */
fds->fd = mouse_fd;
fds->events = POLLIN;
fprintf(stdout, "Trying to set new line mode for %s ...\n", mouse);
if (ioctl(mouse_fd, TCSETAF, &new_tty) < 0)
fatal ("Cannot set new tty line mode");
fprintf(stdout, "Success.\n");
fprintf(stdout, "\nI'm reading from %s. To exit, type <ctrl-C>.\n",
mouse);
fprintf(stdout,
"If you see stuff on the screen when you move the mouse,\n");
fprintf(stdout,
"then you have found the mouse port.\n");
fprintf(stdout, "\nNow wiggle your mouse:\n");
for (;;) {
size_t read_count;
unsigned char mousebuf [128];
/* Block waiting for mouse input. */
if (poll (fds, 1, -1) < 0)
break;
/* Drain input in large chunks until it becomes time to block. */
while ((read_count = read (mouse_fd, mousebuf,
sizeof (mousebuf))) != 0) {
unsigned char * scan = mousebuf;
do
printf ("%02x ", * scan ++);
while (-- read_count != 0);
fflush (stdout);
}
}
}
See Also
Notes
The type of the arg to ioctl() is
declared as char * mainly to improve
portability. In most cases, the actual argument type will
be something like struct sgttyb *, depending
on the device and command. The actual argument should be
cast to type char * to ensure cross-machine
portability.
A
Under COHERENT 286, the main header file for
ioctl() is <sgtty.h>.
This header file is also included with COHERENT 386 for
compatibility with older applications.