summaryrefslogtreecommitdiff
path: root/libphobos/libdruntime/core/sys/posix/sys/ioccom.d
blob: 424c8a823077bea96da0d3436ab76b580f1c3b6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * D header file for POSIX.
 *
 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
 */

module core.sys.posix.sys.ioccom;

version (Posix):

nothrow @nogc:

version (OSX)
{
    /* OSX ioctl's (based on FreeBSD) encode the command in the lower 16-bits
     * and the size of any in/out parameters in the lower 13 bits of the upper
     * 16-bits of a 32 bit unsigned integer. The high 3 bits of the upper
     * 16-bits encode the in/out status of the parameter.
     */
    enum uint IOCPARM_MASK = 0x1fff; // parameter length, at most 13 bits
    uint IOCPARM_LEN(uint x) // to extract the encoded parameter length
    {
        return ((x >> 16) & IOCPARM_MASK);
    }
    uint IOCBASECMD(uint x) // to extract the encoded command
    {
        return (x & ~(IOCPARM_MASK << 16));
    }
    uint IOCGROUP(uint x) // to extract the encoded group
    {
        return ((x >> 8) & 0xff);
    }

    enum uint IOCPARM_MAX = (IOCPARM_MASK + 1); // max size of ioctl args

    enum uint IOC_VOID = 0x20000000; // no parameters
    enum uint IOC_OUT = 0x40000000; // copy parameters back
    enum uint IOC_IN = 0x80000000; // copy parameters into
    enum uint IOC_INOUT = (IOC_IN | IOC_OUT); // copy parameter into and get back
    enum uint IOC_DIRMASK = 0xe0000000; // mask to extract above direction parameters

    // encode the ioctl info into 32 bits
    uint _IOC(T=typeof(null))(uint inorout, uint group, uint num, size_t len)
    {
        return (inorout | ((len & IOCPARM_MASK) << 16) | (group << 8) | num);
    }

    // encode a command with no parameters
    uint _IO(char g, int n)
    {
        return _IOC(IOC_VOID, cast(uint)g, cast(uint)n, cast(size_t)0);
    }
    // encode a command that returns info
    uint _IOR(T)(char g, int n)
    {
        return _IOC!(T)(IOC_OUT, cast(uint)g, cast(uint)n, T.sizeof);
    }
    // encode a command that takes info
    uint _IOW(T)(char g, int n)
    {
        return _IOC!(T)(IOC_IN, cast(uint)g, cast(uint)n, T.sizeof);
    }
    // encode a command that takes info and returns info
    uint _IOWR(T)(char g, int n)
    {
        return _IOC!(T)(IOC_INOUT, cast(uint)g, cast(uint)n, T.sizeof);
    }
}
else version (FreeBSD)
{
    /* FreeBSD ioctl's encode the command in the lower 16-bits
     * and the size of any in/out parameters in the lower 13 bits of the upper
     * 16-bits of a 32 bit unsigned integer. The high 3 bits of the upper
     * 16-bits encode the in/out status of the parameter.
     */
    enum uint IOCPARM_SHIFT = 13; // number of bits for ioctl size
    enum uint IOCPARM_MASK = ((1 << IOCPARM_SHIFT) - 1); // parameter length mask
    uint IOCPARM_LEN(uint x) // to extract the encoded parameter length
    {
        return ((x >> 16) & IOCPARM_MASK);
    }
    uint IOCBASECMD(uint x) // to extract the encoded command
    {
        return (x & ~(IOCPARM_MASK << 16));
    }
    uint IOCGROUP(uint x) // to extract the encoded group
    {
        return ((x >> 8) & 0xff);
    }

    enum uint IOCPARM_MAX = (1 << IOCPARM_SHIFT); // max size of ioctl args

    enum uint IOC_VOID = 0x20000000; // no parameters
    enum uint IOC_OUT = 0x40000000; // copy parameters back
    enum uint IOC_IN = 0x80000000; // copy parameters into
    enum uint IOC_INOUT = (IOC_IN | IOC_OUT);
    enum uint IOC_DIRMASK = (IOC_VOID|IOC_OUT|IOC_IN);

    // encode the ioctl info into 32 bits
    uint _IOC(uint inorout, uint group, uint num, size_t len)
    {
        return (inorout | ((len & IOCPARM_MASK) << 16) | (group << 8) | num);
    }

    // encode a command with no parameters
    uint _IO(char g, int n)
    {
        return _IOC(IOC_VOID, cast(uint)g, cast(uint)n, cast(size_t)0);
    }
    uint _IOWINT(char g, int n)
    {
        return _IOC(IOC_VOID, cast(uint)g, cast(uint)n, int.sizeof);
    }
    // encode a command that returns info
    uint _IOR(T)(char g, int n)
    {
        return _IOC(IOC_OUT, cast(uint)g, cast(uint)n, T.sizeof);
    }
    // encode a command that takes info
    uint _IOW(T)(char g, int n)
    {
        return _IOC(IOC_IN, cast(uint)g, cast(uint)n, T.sizeof);
    }
    // encode a command that takes info and returns info
    uint _IOWR(T)(char g, int n)
    {
        return _IOC(IOC_INOUT, cast(uint)g, cast(uint)n, T.sizeof);
    }
}