File: cmsg.c

package info (click to toggle)
haskell-network 3.1.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 736 kB
  • sloc: sh: 3,264; haskell: 2,002; ansic: 536; makefile: 3
file content (97 lines) | stat: -rw-r--r-- 2,460 bytes parent folder | download
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
#include "HsNet.h"
#include <string.h>

#ifdef _WIN32

LPWSACMSGHDR cmsg_firsthdr(LPWSAMSG mhdr) {
  return (WSA_CMSG_FIRSTHDR(mhdr));
}

LPWSACMSGHDR cmsg_nxthdr(LPWSAMSG mhdr, LPWSACMSGHDR cmsg) {
  return (WSA_CMSG_NXTHDR(mhdr, cmsg));
}

unsigned char *cmsg_data(LPWSACMSGHDR cmsg) {
  return (WSA_CMSG_DATA(cmsg));
}

unsigned int cmsg_space(unsigned int l) {
  return (WSA_CMSG_SPACE(l));
}

unsigned int cmsg_len(unsigned int l) {
  return (WSA_CMSG_LEN(l));
}

static LPFN_WSASENDMSG ptr_SendMsg;
static LPFN_WSARECVMSG ptr_RecvMsg;
/* GUIDS to lookup WSASend/RecvMsg */
static GUID WSARecvMsgGUID = WSAID_WSARECVMSG;
static GUID WSASendMsgGUID = WSAID_WSASENDMSG;

int WINAPI
WSASendMsg (SOCKET s, LPWSAMSG lpMsg, DWORD flags,
            LPDWORD lpdwNumberOfBytesRecvd, LPWSAOVERLAPPED lpOverlapped,
            LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {

  if (!ptr_SendMsg) {
    DWORD len;
    if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
        &WSASendMsgGUID, sizeof(WSASendMsgGUID), &ptr_SendMsg,
        sizeof(ptr_SendMsg), &len, NULL, NULL) != 0)
      return -1;
  }

  return ptr_SendMsg (s, lpMsg, flags, lpdwNumberOfBytesRecvd, lpOverlapped,
                      lpCompletionRoutine);
}

/**
 * WSARecvMsg function
 */
int WINAPI
WSARecvMsg (SOCKET s, LPWSAMSG lpMsg, LPDWORD lpdwNumberOfBytesRecvd,
            LPWSAOVERLAPPED lpOverlapped,
            LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) {

  if (!ptr_RecvMsg) {
    DWORD len;
    if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
        &WSARecvMsgGUID, sizeof(WSARecvMsgGUID), &ptr_RecvMsg,
        sizeof(ptr_RecvMsg), &len, NULL, NULL) != 0)
      return -1;
  }

  int res = ptr_RecvMsg (s, lpMsg, lpdwNumberOfBytesRecvd, lpOverlapped,
                         lpCompletionRoutine);

  /*  If the msg was truncated then this pointer can be garbage.  */
  if (res == SOCKET_ERROR && GetLastError () == WSAEMSGSIZE)
     {
        lpMsg->Control.len = 0;
        lpMsg->Control.buf = NULL;
     }

  return res;
}
#else
struct cmsghdr *cmsg_firsthdr(struct msghdr *mhdr) {
  return (CMSG_FIRSTHDR(mhdr));
}

struct cmsghdr *cmsg_nxthdr(struct msghdr *mhdr, struct cmsghdr *cmsg) {
  return (CMSG_NXTHDR(mhdr, cmsg));
}

unsigned char *cmsg_data(struct cmsghdr *cmsg) {
  return (CMSG_DATA(cmsg));
}

size_t cmsg_space(size_t l) {
  return (CMSG_SPACE(l));
}

size_t cmsg_len(size_t l) {
  return (CMSG_LEN(l));
}
#endif /* _WIN32 */