ioctl
函數名: ioctl
功 能: 控制I/O設備
用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]);
include/asm/ioctl.h中定義的宏的注釋:
#define _IOC_NRBITS 8 //序數(number)字段的字位寬度,8bits
#define _IOC_TYPEBITS 8 //幻數(type)字段的字位寬度,8bits
#define _IOC_SIZEBITS 14 //大小(size)字段的字位寬度,14bits
#define _IOC_DIRBITS 2 //方向(direction)字段的字位寬度,2bits
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) //序數字段的掩碼,0x000000FF
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) //幻數字段的掩碼,0x000000FF
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) //大小字段的掩碼,0x00003FFF
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) //方向字段的掩碼,0x00000003
#define _IOC_NRSHIFT 0 //序數字段在整個字段中的位移,0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) //幻數字段的位移,8
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) //大小字段的位移,16
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) //方向字段的位移,30
/*
* Direction bits.
*/
#define _IOC_NONE 0U //沒有數據傳輸
#define _IOC_WRITE 1U //向設備寫入數據,驅動程序必須從用戶空間讀入數據
#define _IOC_READ 2U //從設備中讀取數據,驅動程序必須向用戶空間寫入數據
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
/*
* used to create numbers
*/
//構造無參數的命令編號
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
//構造從驅動程序中讀取數據的命令編號
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
//用於向驅動程序寫入數據命令
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
//用於雙向傳輸
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
/*
*used to decode ioctl numbers..
*/
//從命令參數中解析出數據方向,即寫進還是讀出
#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
//從命令參數中解析出幻數type
#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
//從命令參數中解析出序數number
#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
//從命令參數中解析出用戶數據大小
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
/* ...and for the drivers/sound files... */
#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
程序例:
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
int main(void) {
..int stat;
/* use func 8 to determine if the default drive is removable */
..stat = ioctl(0, 8, 0, 0);
..if (!stat)
....printf("Drive %c is removable.\n", getdisk() + 'A');
..else
....printf("Drive %c is not removable.\n", getdisk() + 'A');
..return 0;
}