1 /** 2 * D header file for POSIX. 3 * 4 * Copyright: Public Domain 5 * License: Public Domain 6 * Authors: Sean Kelly 7 * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition 8 */ 9 module tango.stdc.posix.sys.socket; 10 11 private import tango.stdc.posix.config; 12 public import tango.stdc.posix.sys.types; // for ssize_t, size_t 13 public import tango.stdc.posix.sys.uio; // for iovec 14 public import tango.sys.consts.socket; 15 extern (C): 16 17 // 18 // Required 19 // 20 /* 21 socklen_t 22 sa_family_t 23 24 struct sockaddr 25 { 26 sa_family_t sa_family; 27 char sa_data[]; 28 } 29 30 struct sockaddr_storage 31 { 32 sa_family_t ss_family; 33 } 34 35 struct msghdr 36 { 37 void* msg_name; 38 socklen_t msg_namelen; 39 struct iovec* msg_iov; 40 int msg_iovlen; 41 void* msg_control; 42 socklen_t msg_controllen; 43 int msg_flags; 44 } 45 46 struct iovec {} // from tango.stdc.posix.sys.uio 47 48 struct cmsghdr 49 { 50 socklen_t cmsg_len; 51 int cmsg_level; 52 int cmsg_type; 53 } 54 55 SCM_RIGHTS 56 57 CMSG_DATA(cmsg) 58 CMSG_NXTHDR(mhdr,cmsg) 59 CMSG_FIRSTHDR(mhdr) 60 61 struct linger 62 { 63 int l_onoff; 64 int l_linger; 65 } 66 67 SOCK_DGRAM 68 SOCK_SEQPACKET 69 SOCK_STREAM 70 71 SOL_SOCKET 72 73 SO_ACCEPTCONN 74 SO_BROADCAST 75 SO_DEBUG 76 SO_DONTROUTE 77 SO_ERROR 78 SO_KEEPALIVE 79 SO_LINGER 80 SO_OOBINLINE 81 SO_RCVBUF 82 SO_RCVLOWAT 83 SO_RCVTIMEO 84 SO_REUSEADDR 85 SO_SNDBUF 86 SO_SNDLOWAT 87 SO_SNDTIMEO 88 SO_TYPE 89 90 SOMAXCONN 91 92 MSG_CTRUNC 93 MSG_DONTROUTE 94 MSG_EOR 95 MSG_OOB 96 MSG_PEEK 97 MSG_TRUNC 98 MSG_WAITALL 99 100 AF_INET 101 AF_UNIX 102 AF_UNSPEC 103 104 SHUT_RD 105 SHUT_RDWR 106 SHUT_WR 107 108 int accept(int, sockaddr*, socklen_t*); 109 int bind(int, in sockaddr*, socklen_t); 110 int connect(int, in sockaddr*, socklen_t); 111 int getpeername(int, sockaddr*, socklen_t*); 112 int getsockname(int, sockaddr*, socklen_t*); 113 int getsockopt(int, int, int, void*, socklen_t*); 114 int listen(int, int); 115 ssize_t recv(int, void*, size_t, int); 116 ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); 117 ssize_t recvmsg(int, msghdr*, int); 118 ssize_t send(int, in void*, size_t, int); 119 ssize_t sendmsg(int, in msghdr*, int); 120 ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); 121 int setsockopt(int, int, int, in void*, socklen_t); 122 int shutdown(int, int); 123 int socket(int, int, int); 124 int sockatmark(int); 125 int socketpair(int, int, int, int[2]); 126 */ 127 128 version( linux ) 129 { 130 alias uint socklen_t; 131 alias ushort sa_family_t; 132 133 struct sockaddr 134 { 135 sa_family_t sa_family; 136 byte[14] sa_data; 137 } 138 139 private enum : size_t 140 { 141 _SS_SIZE = 128, 142 _SS_PADSIZE = _SS_SIZE - (c_ulong.sizeof * 2) 143 } 144 145 struct sockaddr_storage 146 { 147 sa_family_t ss_family; 148 c_ulong __ss_align; 149 byte[_SS_PADSIZE] __ss_padding; 150 } 151 152 struct msghdr 153 { 154 void* msg_name; 155 socklen_t msg_namelen; 156 iovec* msg_iov; 157 size_t msg_iovlen; 158 void* msg_control; 159 size_t msg_controllen; 160 int msg_flags; 161 } 162 163 struct cmsghdr 164 { 165 size_t cmsg_len; 166 int cmsg_level; 167 int cmsg_type; 168 static if( false /* (!is( __STRICT_ANSI__ ) && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L */ ) 169 { 170 ubyte[1] __cmsg_data; 171 } 172 } 173 174 static if( false /* (!is( __STRICT_ANSI__ ) && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L */ ) 175 { 176 extern (D) ubyte[1] CMSG_DATA( cmsghdr* cmsg ) { return cmsg.__cmsg_data; } 177 } 178 else 179 { 180 extern (D) ubyte* CMSG_DATA( cmsghdr* cmsg ) { return cast(ubyte*)( cmsg + 1 ); } 181 } 182 183 private cmsghdr* __cmsg_nxthdr(msghdr*, cmsghdr*); 184 alias __cmsg_nxthdr CMSG_NXTHDR; 185 186 extern (D) size_t CMSG_FIRSTHDR( msghdr* mhdr ) 187 { 188 return ( mhdr.msg_controllen >= cmsghdr.sizeof 189 ? cast(size_t) mhdr.msg_control 190 : cast(size_t) 0 ); 191 } 192 193 struct linger 194 { 195 int l_onoff; 196 int l_linger; 197 } 198 199 int accept(int, sockaddr*, socklen_t*); 200 int bind(int, in sockaddr*, socklen_t); 201 int connect(int, in sockaddr*, socklen_t); 202 int getpeername(int, sockaddr*, socklen_t*); 203 int getsockname(int, sockaddr*, socklen_t*); 204 int getsockopt(int, int, int, void*, socklen_t*); 205 int listen(int, int); 206 ssize_t recv(int, void*, size_t, int); 207 ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); 208 ssize_t recvmsg(int, msghdr*, int); 209 ssize_t send(int, in void*, size_t, int); 210 ssize_t sendmsg(int, in msghdr*, int); 211 ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); 212 int setsockopt(int, int, int, in void*, socklen_t); 213 int shutdown(int, int); 214 int socket(int, int, int); 215 int sockatmark(int); 216 int socketpair(int, int, int, int[2]); 217 } 218 else version(OSX) 219 { 220 alias uint socklen_t; 221 alias ubyte sa_family_t; 222 223 struct sockaddr 224 { 225 ubyte sa_len; 226 sa_family_t sa_family; 227 byte[14] sa_data; 228 } 229 230 private enum : size_t 231 { 232 _SS_PAD1 = long.sizeof - ubyte.sizeof - sa_family_t.sizeof, 233 _SS_PAD2 = 128 - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1 - long.sizeof 234 } 235 236 struct sockaddr_storage 237 { 238 ubyte ss_len; 239 sa_family_t ss_family; 240 byte[_SS_PAD1] __ss_pad1; 241 long __ss_align; 242 byte[_SS_PAD2] __ss_pad2; 243 } 244 245 struct msghdr 246 { 247 void* msg_name; 248 socklen_t msg_namelen; 249 iovec* msg_iov; 250 int msg_iovlen; 251 void* msg_control; 252 socklen_t msg_controllen; 253 int msg_flags; 254 } 255 256 struct cmsghdr 257 { 258 socklen_t cmsg_len; 259 int cmsg_level; 260 int cmsg_type; 261 } 262 263 /+ 264 CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ 265 ALIGN(sizeof(struct cmsghdr))) 266 CMSG_NXTHDR(mhdr, cmsg) \ 267 (((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len) + \ 268 ALIGN(sizeof(struct cmsghdr)) > \ 269 (unsigned char *)(mhdr)->msg_control +(mhdr)->msg_controllen) ? \ 270 (struct cmsghdr *)0 /* NULL */ : \ 271 (struct cmsghdr *)((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len))) 272 CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control) 273 +/ 274 275 struct linger 276 { 277 int l_onoff; 278 int l_linger; 279 } 280 281 int accept(int, sockaddr*, socklen_t*); 282 int bind(int, in sockaddr*, socklen_t); 283 int connect(int, in sockaddr*, socklen_t); 284 int getpeername(int, sockaddr*, socklen_t*); 285 int getsockname(int, sockaddr*, socklen_t*); 286 int getsockopt(int, int, int, void*, socklen_t*); 287 int listen(int, int); 288 ssize_t recv(int, void*, size_t, int); 289 ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); 290 ssize_t recvmsg(int, msghdr*, int); 291 ssize_t send(int, in void*, size_t, int); 292 ssize_t sendmsg(int, in msghdr*, int); 293 ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); 294 int setsockopt(int, int, int, in void*, socklen_t); 295 int shutdown(int, int); 296 int socket(int, int, int); 297 int sockatmark(int); 298 int socketpair(int, int, int, int[2]); 299 } 300 else version( FreeBSD ) 301 { 302 alias uint socklen_t; 303 alias ubyte sa_family_t; 304 305 struct sockaddr 306 { 307 ubyte sa_len; 308 sa_family_t sa_family; 309 byte[14] sa_data; 310 } 311 312 private 313 { 314 const _SS_ALIGNSIZE = long.sizeof; 315 const uint _SS_MAXSIZE = 128; 316 const _SS_PAD1SIZE = _SS_ALIGNSIZE - ubyte.sizeof - sa_family_t.sizeof; 317 const _SS_PAD2SIZE = _SS_MAXSIZE - ubyte.sizeof - sa_family_t.sizeof - _SS_PAD1SIZE - _SS_ALIGNSIZE; 318 } 319 320 struct sockaddr_storage 321 { 322 ubyte ss_len; 323 sa_family_t ss_family; 324 byte[_SS_PAD1SIZE] __ss_pad1; 325 long __ss_align; 326 byte[_SS_PAD2SIZE] __ss_pad2; 327 } 328 329 struct msghdr 330 { 331 void* msg_name; 332 socklen_t msg_namelen; 333 iovec* msg_iov; 334 int msg_iovlen; 335 void* msg_control; 336 socklen_t msg_controllen; 337 int msg_flags; 338 } 339 340 struct cmsghdr 341 { 342 socklen_t cmsg_len; 343 int cmsg_level; 344 int cmsg_type; 345 } 346 347 /+ 348 CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ 349 ALIGN(sizeof(struct cmsghdr))) 350 CMSG_NXTHDR(mhdr, cmsg) \ 351 (((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len) + \ 352 ALIGN(sizeof(struct cmsghdr)) > \ 353 (unsigned char *)(mhdr)->msg_control +(mhdr)->msg_controllen) ? \ 354 (struct cmsghdr *)0 /* NULL */ : \ 355 (struct cmsghdr *)((unsigned char *)(cmsg) + ALIGN((cmsg)->cmsg_len))) 356 CMSG_FIRSTHDR(mhdr) ((struct cmsghdr *)(mhdr)->msg_control) 357 +/ 358 359 struct linger 360 { 361 int l_onoff; 362 int l_linger; 363 } 364 365 int accept(int, sockaddr*, socklen_t*); 366 int bind(int, in sockaddr*, socklen_t); 367 int connect(int, in sockaddr*, socklen_t); 368 int getpeername(int, sockaddr*, socklen_t*); 369 int getsockname(int, sockaddr*, socklen_t*); 370 int getsockopt(int, int, int, void*, socklen_t*); 371 int listen(int, int); 372 ssize_t recv(int, void*, size_t, int); 373 ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); 374 ssize_t recvmsg(int, msghdr*, int); 375 ssize_t send(int, in void*, size_t, int); 376 ssize_t sendmsg(int, in msghdr*, int); 377 ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); 378 int setsockopt(int, int, int, in void*, socklen_t); 379 int shutdown(int, int); 380 int socket(int, int, int); 381 int sockatmark(int); 382 int socketpair(int, int, int, int[2]); 383 } 384 else version( solaris ) 385 { 386 alias uint socklen_t; 387 alias ushort sa_family_t; 388 389 struct sockaddr 390 { 391 sa_family_t sa_family; 392 char[14] sa_data; 393 } 394 395 private 396 { 397 alias double sockaddr_maxalign_t; 398 const _SS_ALIGNSIZE = sockaddr_maxalign_t.sizeof; 399 const _SS_MAXSIZE = 256; 400 const _SS_PAD1SIZE = _SS_ALIGNSIZE - sa_family_t.sizeof; 401 const _SS_PAD2SIZE = _SS_MAXSIZE - (sa_family_t.sizeof + _SS_PAD1SIZE + _SS_ALIGNSIZE); 402 } 403 404 struct sockaddr_storage 405 { 406 sa_family_t ss_family; /* Address family */ 407 /* Following fields are implementation specific */ 408 char[_SS_PAD1SIZE] _ss_pad1; 409 sockaddr_maxalign_t _ss_align; 410 char[_SS_PAD2SIZE] _ss_pad2; 411 } 412 413 struct msghdr 414 { 415 void* msg_name; 416 socklen_t msg_namelen; 417 iovec* msg_iov; 418 int msg_iovlen; 419 void* msg_control; 420 socklen_t msg_controllen; 421 int msg_flags; 422 } 423 424 struct iovec {} // from tango.stdc.posix.sys.uio 425 426 struct cmsghdr 427 { 428 socklen_t cmsg_len; 429 int cmsg_level; 430 int cmsg_type; 431 } 432 433 private 434 { 435 const _CMSG_DATA_ALIGNMENT = int.sizeof; 436 version (X86) const _CMSG_HDR_ALIGNMENT = 4; 437 else version(X86_64) const _CMSG_HDR_ALIGNMENT = 4; 438 else /* SPARC */ const _CMSG_HDR_ALIGNMENT = 8; 439 440 extern (D) 441 { 442 private ubyte* _CMSG_DATA_ALIGN(cmsghdr* x) { 443 return cast(ubyte*)((cast(size_t)x + _CMSG_DATA_ALIGNMENT - 1) & ~(_CMSG_DATA_ALIGNMENT - 1)); 444 } 445 private size_t _CMSG_HDR_ALIGN(cmsghdr* x) { 446 return (cast(size_t)x + _CMSG_HDR_ALIGNMENT - 1) & ~(_CMSG_HDR_ALIGNMENT - 1); 447 } 448 } 449 } 450 451 extern (D) ubyte* CMSG_DATA( cmsghdr* cmsg ) { return cast(ubyte*)_CMSG_DATA_ALIGN( cmsg + 1 ); } 452 453 extern (D) cmsghdr* CMSG_FIRSTHDR( msghdr* mhdr ) 454 { 455 return mhdr.msg_controllen >= cmsghdr.sizeof 456 ? cast(cmsghdr*) mhdr.msg_control 457 : null; 458 } 459 460 extern (D) cmsghdr* CMSG_NXTHDR( msghdr* m, cmsghdr* c ) 461 { 462 /* Hurrah for unreadable C macros! */ 463 464 if(c is null) return CMSG_FIRSTHDR(m); 465 466 size_t aligned_cmsg = _CMSG_HDR_ALIGN(c); 467 return 468 (aligned_cmsg + c.cmsg_len + cmsghdr.sizeof) > (cast(size_t)m.msg_control + m.msg_controllen) 469 ? null 470 : cast(cmsghdr*)(aligned_cmsg + c.cmsg_len); 471 } 472 473 struct linger 474 { 475 int l_onoff; 476 int l_linger; 477 } 478 479 480 int accept(int, sockaddr*, socklen_t*); 481 int bind(int, in sockaddr*, socklen_t); 482 int connect(int, in sockaddr*, socklen_t); 483 int getpeername(int, sockaddr*, socklen_t*); 484 int getsockname(int, sockaddr*, socklen_t*); 485 int getsockopt(int, int, int, void*, socklen_t*); 486 int listen(int, int); 487 ssize_t recv(int, void*, size_t, int); 488 ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*); 489 ssize_t recvmsg(int, msghdr*, int); 490 ssize_t send(int, in void*, size_t, int); 491 ssize_t sendmsg(int, in msghdr*, int); 492 ssize_t sendto(int, in void*, size_t, int, in sockaddr*, socklen_t); 493 int setsockopt(int, int, int, in void*, socklen_t); 494 int shutdown(int, int); 495 int socket(int, int, int); 496 int sockatmark(int); 497 int socketpair(int, int, int, int[2]); 498 }