COHERENT manpages

This page displays the COHERENT manpage for ioctl() [Device-dependent control].

List of available manpages
Index


ioctl() -- System Call (libc)

Device-dependent control
#include <unistd.h>
#include <header.h>
ioctl(fd, command, arg)
int fd, command; char *arg;

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:

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

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

<sys/cdrom.h>
   Header file used to manipulate a CD-ROM device.  Unless otherwise noted,
   arg is ignored:

   CDROMPAUSE     Pause playing an audio CD.
   CDROMRESUME    Resume playing an audio CD.
   CDROMPLAYMSF   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.
   CDROMPLAYTRKIND
                  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.
   CDROMREADTOCHDR
                  Read the CD's  table-of-contents header.  arg points to a
                  structure of  type cdrom_tochdr into which  the header is
                  written.
   CDROMREADTOCENTRY
                  Read  an entry  from the  table-of-contents  header.  arg
                  points to  a structure of type  cdrom_tocentry into which
                  the entry is written.
   CDROMSTOP      Spin down the CD-ROM drive's motor.
   CDROMSTART     Turn on the CD-ROM drive's motor.
   CDROMEJECT     Eject the CD-ROM.  Note  that this does not work on every
                  variety of CD-ROM drive.
   CDROMVOLCTRL   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.
   CDROMSUBCHNL   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.
   CDROMREADMODE1 Read type-1  data.  arg points to  a structure into which
                  the data are written.
   CDROMREADMODE2 Read type-2  data.  arg points to  a structure into which
                  the data are written.

<sys/fdioctl.h>
   This header file is used with the floppy-disk drive:

   FDFORMAT       Format a  track on a  floppy disk.  arg points  to a two-
                  byte  array that  identifies, respectively,  the cylinder
                  and head to format.

<sys/hdioctl.h>
   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:

   HDGETA         Get drive attributes.
   HDSETA         Set drive attributes.
   HDGETIDEINFO   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.

<sys/null.h>
   This header file defines ioctls that examine system memory:

   NLFREE         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.
   NLIDLE         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.

<sys/sdioctl.h>
   The commands defined  in this header file are passed  to the driver aha,
   which manipulates Adaptec SCSI disks.  None does anything.

<sgtty.h>
   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:

   TIOCHPCL       Hang up on last close.
   TIOCGETP       Get modes (old gtty).
   TIOCSETP       Set modes (old stty).
   TIOCSETN       Set modes without delay or flush.
   TIOCEXCL       Set exclusive use.
   TIOCNXCL       Set non-exclusive use.
   TIOCFLUSH      Flush I/O queues.
   TIOCSETC       Set characters.
   TIOCGETC       Get characters.

<stropts.h>
   STREAMS commands.   arg points to  a STREAMS control block  that will be
   used to generate an M_IOCTL message.

   I_NREAD        Get message length, count.
   I_PUSH         Push named module.
   I_POP          Pop topmost module.
   I_LOOK         Get name of the topmost module.
   I_FLUSH        Flush read/write side.
   I_SRDOPT       Set stream head read mode.
   I_GRDOPT       Get stream head read mode.
   I_STR          Send ioctl() message downstream.
   I_SETSIG       Register for signal SIGPOLL.
   I_GETSIG       Return registered event mask.
   I_FIND         Locate named module on stream.
   I_LINK         Link two streams.
   I_UNLINK       Unlink two streams.
   I_RECVFD       Receive file descriptor from pipe.
   I_PEEK         Examine stream head data.
   I_SENDFD       Send file descriptor to pipe.

   The following commands are not covered by iBCS2:

   I_SWROPT       Set stream write mode.
   I_GWROPT       Get stream write mode.
   I_LIST         Get name of all modules/drivers.
   I_PLINK        Create persistent link.
   I_PUNLINK      Undo persistent link.
   I_FLUSHBAND    Flush priority band.
   I_CKBAND       Check for existence of priority band.
   I_GETBAND      Get band of first message.
   I_ATMARK       Check whether current message is marked.
   I_SETCLTIME    Set drain timeout for stream.
   I_GETCLTIME    Get the current close timeout.
   I_CANPUT       Check if band is writeable.

<sys/tape.h>
   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:

   T_ERASE        Erase tape.
   T_LOAD         Load.  Not used.
   T_RDSTAT       Read status.
   T_RST          Reset.
   T_RETENSION    Retension tape.
   T_RWD          Rewind tape.
   T_SBB          Space block backward -- move backward by arg blocks.  Not
                  used.
   T_SBF          Space Block  Forward -- move forward  by arg blocks.  Not
                  used.
   T_SBREC        Not used.
   T_SFB          Space Filemark Backward -- move backwards by arg files.
   T_SFF          Space Filemark Forward -- move forward by arg files.
   T_SFREC        Not used.
   T_TINIT        Not used.
   T_UNLOAD       Unload.  Not used.
   T_WRFILEM      Write file marks.  Not used.

<termio.h>
   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.

   TCGETA         Get terminal parameters.
   TCSETA         Set terminal parameters.
   TCSETAW        Wait for drain, set parameters.
   TCSETAF        Wait for drain, flush input, set parms.
   TCSBRK         Send 0.25-second break.

   The following commands also take arguments when called via ioctl():

   TCXONC         Start/stop control: An  argument of zero suspends output;
                  an argument of one restarts suspended output.

   TCFLSH         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.

<sys/vtkd.h>
   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.

   KDMAPDISP      Map the display into user space.
   KDSKBMODE      Toggle the scan code xlate.
   KDMEMDISP      Dump a byte of virtual or physical memory.
   KDGKBSTATE     Get the keyboard's shift state.
   KIOCINFO       Determine the workstation of the virtual terminal.
   KIOCSOUND      Start sound generation.
   KDGETLED       Get the state of the keyboard's LEDs.
   KDSETLED       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:

   KDENABIO       Allow the user process permission to perform input/output
                  operations  to all  available I/O  addresses.   The third
                  argument to ioctl() is ignored.
   KDDISABIO      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.
   KDADDIO        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.
   KDDELIO        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

device drivers,
exec,
getty,
header files,
libc,
open(),
read(),
sgtty,
stty(),
termio

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.

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.