File: unix-sockets.c

package info (click to toggle)
r-cran-processx 3.8.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,068 kB
  • sloc: ansic: 6,485; sh: 13; makefile: 2
file content (151 lines) | stat: -rw-r--r-- 3,134 bytes parent folder | download | duplicates (2)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

#include "unix-sockets.h"

PROCESSX_STATIC int processx_socket_connect(const char *filename,
                                            processx_socket_t *pxsocket) {
#ifdef _WIN32
  HANDLE hnd;
  SECURITY_ATTRIBUTES sa;
  DWORD access = GENERIC_READ | GENERIC_WRITE;
  DWORD attr = FILE_ATTRIBUTE_NORMAL;

  sa.nLength = sizeof(sa);
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE;

  hnd = CreateFileA(
    filename,
    access,
    0,
    &sa,
    OPEN_EXISTING,
    attr,
    NULL
  );

  if (hnd == INVALID_HANDLE_VALUE) {
    return -1;
  } else {
    *pxsocket = hnd;
    return 0;
  }

#else
  struct sockaddr_un addr;
  int fd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (fd == -1) {
    return -1;
  }
  memset(&addr, 0, sizeof(struct sockaddr_un));
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, filename, sizeof(addr.sun_path) - 1);

  int ret = connect(
    fd,
    (struct sockaddr *) &addr,
    sizeof(struct sockaddr_un)
  );

  if (ret == -1) {
    return -1;
  }

  *pxsocket = fd;
  return 0;

#endif
}

PROCESSX_STATIC ssize_t processx_socket_read(processx_socket_t *pxsocket,
                                             void *buf,
                                             size_t nbyte) {
#ifdef _WIN32
  DWORD got;
  BOOL ok = ReadFile(
    /* hFile =                */ *pxsocket,
    /* lpBuffer =             */ buf,
    /* nNumberOfBytesToRead = */ nbyte,
    /* lpNumberOfBytesRead =  */ &got,
    /* lpOverlapped =         */ NULL
  );
  if (!ok) {
    return -1;
  } else {
    return got;
  }

#else
  return read(*pxsocket, buf, nbyte);
#endif
}

PROCESSX_STATIC ssize_t processx_socket_write(processx_socket_t *pxsocket,
                                              void *buf,
                                              size_t nbyte) {
#ifdef _WIN32
  DWORD did;
  BOOL ok = WriteFile(
    /* hFile = */ *pxsocket,
    /* lpBuffer = */ buf,
    /* nNumberOfBytesToWrite = */ nbyte,
    /* lpNumberOfBytesWritten = */ &did,
    /* lpOverlapped = */ NULL
  );
  if (!ok) {
    return -1;
  } else {
    return did;
  }

#else
  return write(*pxsocket, buf, nbyte);
#endif
}

PROCESSX_STATIC int processx_socket_close(processx_socket_t *pxsocket) {
#ifdef _WIN32
  BOOL ok = CloseHandle(*pxsocket);
  if (!ok) {
    return -1;
  } else {
    return 0;
  }
#else
  return close(*pxsocket);
#endif
}

PROCESSX_STATIC const char* processx_socket_error_message(void) {
#ifdef _WIN32
#define ERRORBUF_SIZE 4096
  static char errorbuf[ERRORBUF_SIZE];
  LPVOID lpMsgBuf;
  char *failmsg = "Formatting the system message failed :(";
  char *realsysmsg = failmsg;
  DWORD errorcode = GetLastError();

  DWORD ret = FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    errorcode,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
  );

  if (ret != 0) {
    memset(errorbuf, 0, sizeof(errorbuf));
    strncpy(errorbuf, lpMsgBuf, sizeof(errorbuf) - 1);
    realsysmsg = errorbuf;
    LocalFree(lpMsgBuf);
  }

  return realsysmsg;

#else
  return strerror(errno);
#endif
}