1 /**
2  * D header file for POSIX.
3  *
4  * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
5  */
6 
7 module core.sys.posix.sys.ioccom;
8 
9 version (OSX)
10     version = Darwin;
11 else version (iOS)
12     version = Darwin;
13 else version (TVOS)
14     version = Darwin;
15 else version (WatchOS)
16     version = Darwin;
17 
18 version (Posix):
19 
20 nothrow @nogc:
21 
22 version (Darwin)
23 {
24     /* OSX ioctl's (based on FreeBSD) encode the command in the lower 16-bits
25      * and the size of any in/out parameters in the lower 13 bits of the upper
26      * 16-bits of a 32 bit unsigned integer. The high 3 bits of the upper
27      * 16-bits encode the in/out status of the parameter.
28      */
29     enum uint IOCPARM_MASK = 0x1fff; // parameter length, at most 13 bits
30     uint IOCPARM_LEN(uint x) // to extract the encoded parameter length
31     {
32         return ((x >> 16) & IOCPARM_MASK);
33     }
34     uint IOCBASECMD(uint x) // to extract the encoded command
35     {
36         return (x & ~(IOCPARM_MASK << 16));
37     }
38     uint IOCGROUP(uint x) // to extract the encoded group
39     {
40         return ((x >> 8) & 0xff);
41     }
42 
43     enum uint IOCPARM_MAX = (IOCPARM_MASK + 1); // max size of ioctl args
44 
45     enum uint IOC_VOID = 0x20000000; // no parameters
46     enum uint IOC_OUT = 0x40000000; // copy parameters back
47     enum uint IOC_IN = 0x80000000; // copy parameters into
48     enum uint IOC_INOUT = (IOC_IN | IOC_OUT); // copy parameter into and get back
49     enum uint IOC_DIRMASK = 0xe0000000; // mask to extract above direction parameters
50 
51     // encode the ioctl info into 32 bits
52     uint _IOC(T=typeof(null))(uint inorout, uint group, uint num, size_t len)
53     {
54         return (inorout | ((len & IOCPARM_MASK) << 16) | (group << 8) | num);
55     }
56 
57     // encode a command with no parameters
58     uint _IO(char g, int n)
59     {
60         return _IOC(IOC_VOID, cast(uint)g, cast(uint)n, cast(size_t)0);
61     }
62     // encode a command that returns info
63     uint _IOR(T)(char g, int n)
64     {
65         return _IOC!(T)(IOC_OUT, cast(uint)g, cast(uint)n, T.sizeof);
66     }
67     // encode a command that takes info
68     uint _IOW(T)(char g, int n)
69     {
70         return _IOC!(T)(IOC_IN, cast(uint)g, cast(uint)n, T.sizeof);
71     }
72     // encode a command that takes info and returns info
73     uint _IOWR(T)(char g, int n)
74     {
75         return _IOC!(T)(IOC_INOUT, cast(uint)g, cast(uint)n, T.sizeof);
76     }
77 }
78 else version (FreeBSD)
79 {
80     /* FreeBSD ioctl's encode the command in the lower 16-bits
81      * and the size of any in/out parameters in the lower 13 bits of the upper
82      * 16-bits of a 32 bit unsigned integer. The high 3 bits of the upper
83      * 16-bits encode the in/out status of the parameter.
84      */
85     enum uint IOCPARM_SHIFT = 13; // number of bits for ioctl size
86     enum uint IOCPARM_MASK = ((1 << IOCPARM_SHIFT) - 1); // parameter length mask
87     uint IOCPARM_LEN(uint x) // to extract the encoded parameter length
88     {
89         return ((x >> 16) & IOCPARM_MASK);
90     }
91     uint IOCBASECMD(uint x) // to extract the encoded command
92     {
93         return (x & ~(IOCPARM_MASK << 16));
94     }
95     uint IOCGROUP(uint x) // to extract the encoded group
96     {
97         return ((x >> 8) & 0xff);
98     }
99 
100     enum uint IOCPARM_MAX = (1 << IOCPARM_SHIFT); // max size of ioctl args
101 
102     enum uint IOC_VOID = 0x20000000; // no parameters
103     enum uint IOC_OUT = 0x40000000; // copy parameters back
104     enum uint IOC_IN = 0x80000000; // copy parameters into
105     enum uint IOC_INOUT = (IOC_IN | IOC_OUT);
106     enum uint IOC_DIRMASK = (IOC_VOID|IOC_OUT|IOC_IN);
107 
108     // encode the ioctl info into 32 bits
109     uint _IOC(uint inorout, uint group, uint num, size_t len)
110     {
111         return (inorout | ((len & IOCPARM_MASK) << 16) | (group << 8) | num);
112     }
113 
114     // encode a command with no parameters
115     uint _IO(char g, int n)
116     {
117         return _IOC(IOC_VOID, cast(uint)g, cast(uint)n, cast(size_t)0);
118     }
119     uint _IOWINT(char g, int n)
120     {
121         return _IOC(IOC_VOID, cast(uint)g, cast(uint)n, int.sizeof);
122     }
123     // encode a command that returns info
124     uint _IOR(T)(char g, int n)
125     {
126         return _IOC(IOC_OUT, cast(uint)g, cast(uint)n, T.sizeof);
127     }
128     // encode a command that takes info
129     uint _IOW(T)(char g, int n)
130     {
131         return _IOC(IOC_IN, cast(uint)g, cast(uint)n, T.sizeof);
132     }
133     // encode a command that takes info and returns info
134     uint _IOWR(T)(char g, int n)
135     {
136         return _IOC(IOC_INOUT, cast(uint)g, cast(uint)n, T.sizeof);
137     }
138 }
139 else version (OpenBSD)
140 {
141     /* OpenBSD ioctl's encode the command in the lower 16-bits
142      * and the size of any in/out parameters in the lower 13 bits of the upper
143      * 16-bits of a 32 bit unsigned integer. The high 3 bits of the upper
144      * 16-bits encode the in/out status of the parameter.
145      */
146     enum uint IOCPARM_MASK = 0x1fff; // parameter length mask
147     uint IOCPARM_LEN(uint x) // to extract the encoded parameter length
148     {
149         return ((x >> 16) & IOCPARM_MASK);
150     }
151     uint IOCBASECMD(uint x) // to extract the encoded command
152     {
153         return (x & ~(IOCPARM_MASK << 16));
154     }
155     uint IOCGROUP(uint x) // to extract the encoded group
156     {
157         return ((x >> 8) & 0xff);
158     }
159 
160     enum uint IOCPARM_MAX = (1 << 12); // max size of ioctl args
161 
162     enum uint IOC_VOID = 0x20000000; // no parameters
163     enum uint IOC_OUT = 0x40000000; // copy parameters back
164     enum uint IOC_IN = 0x80000000; // copy parameters into
165     enum uint IOC_INOUT = (IOC_IN | IOC_OUT);
166     enum uint IOC_DIRMASK = 0xe0000000;
167 
168     // encode the ioctl info into 32 bits
169     uint _IOC(uint inorout, uint group, uint num, size_t len)
170     {
171         return (inorout | ((len & IOCPARM_MASK) << 16) | (group << 8) | num);
172     }
173 
174     // encode a command with no parameters
175     uint _IO(char g, int n)
176     {
177         return _IOC(IOC_VOID, cast(uint)g, cast(uint)n, cast(size_t)0);
178     }
179     // encode a command that returns info
180     uint _IOR(T)(char g, int n)
181     {
182         return _IOC(IOC_OUT, cast(uint)g, cast(uint)n, T.sizeof);
183     }
184     // encode a command that takes info
185     uint _IOW(T)(char g, int n)
186     {
187         return _IOC(IOC_IN, cast(uint)g, cast(uint)n, T.sizeof);
188     }
189     // encode a command that takes info and returns info
190     uint _IOWR(T)(char g, int n)
191     {
192         return _IOC(IOC_INOUT, cast(uint)g, cast(uint)n, T.sizeof);
193     }
194 }