Skip to content

Commit bb3d093

Browse files
dmabuptbnoordhuis
authored andcommitted
ibmi: add support for new platform
Support the IBM i platform. - add a new file src/unix/ibmi.c - extract the common functions from /src/unix/aix.c into aix-common.c - update uv.gyp and include/uv-unix.h to enable the new file ibmi.c PR-URL: libuv#1601 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Gireesh Punathil <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent 5070620 commit bb3d093

File tree

7 files changed

+449
-243
lines changed

7 files changed

+449
-243
lines changed

Makefile.am

+1-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ libuv_la_CFLAGS += -D_ALL_SOURCE \
329329
-D_THREAD_SAFE \
330330
-DHAVE_SYS_AHAFS_EVPRODS_H
331331
include_HEADERS += include/uv-aix.h
332-
libuv_la_SOURCES += src/unix/aix.c
332+
libuv_la_SOURCES += src/unix/aix.c src/unix/aix-common.c
333333
endif
334334

335335
if ANDROID

checksparse.sh

+10
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,18 @@ case `uname -s` in
177177
AIX)
178178
SPARSE_FLAGS="$SPARSE_FLAGS -D_AIX=1"
179179
SOURCES="$SOURCES
180+
src/unix/aix-common.c
180181
src/unix/aix.c"
181182
;;
183+
OS400)
184+
SPARSE_FLAGS="$SPARSE_FLAGS -D_PASE=1"
185+
SOURCES="$SOURCES
186+
src/unix/aix-common.c
187+
src/unix/ibmi.c
188+
src/unix/posix-poll.c
189+
src/unix/no-fsevents.c
190+
src/unix/no-proctitle.c"
191+
;;
182192
Darwin)
183193
SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1"
184194
SOURCES="$SOURCES

include/uv-unix.h

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
# include "uv-linux.h"
4949
#elif defined (__MVS__)
5050
# include "uv-os390.h"
51+
#elif defined(_PASE)
52+
# include "uv-posix.h"
5153
#elif defined(_AIX)
5254
# include "uv-aix.h"
5355
#elif defined(__sun)

src/unix/aix-common.c

+292
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
/* Copyright libuv project contributors. All rights reserved.
2+
*
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to
5+
* deal in the Software without restriction, including without limitation the
6+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7+
* sell copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19+
* IN THE SOFTWARE.
20+
*/
21+
22+
#include "uv.h"
23+
#include "internal.h"
24+
25+
#include <stdio.h>
26+
#include <stdint.h>
27+
#include <stdlib.h>
28+
#include <string.h>
29+
#include <assert.h>
30+
#include <errno.h>
31+
32+
#include <sys/types.h>
33+
#include <sys/socket.h>
34+
#include <sys/ioctl.h>
35+
#include <net/if.h>
36+
#include <netinet/in.h>
37+
#include <arpa/inet.h>
38+
39+
#include <sys/time.h>
40+
#include <unistd.h>
41+
#include <fcntl.h>
42+
#include <utmp.h>
43+
#include <libgen.h>
44+
45+
#include <sys/protosw.h>
46+
#include <procinfo.h>
47+
#include <sys/proc.h>
48+
#include <sys/procfs.h>
49+
50+
#include <sys/poll.h>
51+
52+
#include <sys/pollset.h>
53+
#include <ctype.h>
54+
55+
#include <sys/mntctl.h>
56+
#include <sys/vmount.h>
57+
#include <limits.h>
58+
#include <strings.h>
59+
#include <sys/vnode.h>
60+
61+
uint64_t uv__hrtime(uv_clocktype_t type) {
62+
uint64_t G = 1000000000;
63+
timebasestruct_t t;
64+
read_wall_time(&t, TIMEBASE_SZ);
65+
time_base_to_time(&t, TIMEBASE_SZ);
66+
return (uint64_t) t.tb_high * G + t.tb_low;
67+
}
68+
69+
70+
/*
71+
* We could use a static buffer for the path manipulations that we need outside
72+
* of the function, but this function could be called by multiple consumers and
73+
* we don't want to potentially create a race condition in the use of snprintf.
74+
* There is no direct way of getting the exe path in AIX - either through /procfs
75+
* or through some libc APIs. The below approach is to parse the argv[0]'s pattern
76+
* and use it in conjunction with PATH environment variable to craft one.
77+
*/
78+
int uv_exepath(char* buffer, size_t* size) {
79+
int res;
80+
char args[PATH_MAX];
81+
char abspath[PATH_MAX];
82+
size_t abspath_size;
83+
struct procsinfo pi;
84+
85+
if (buffer == NULL || size == NULL || *size == 0)
86+
return -EINVAL;
87+
88+
pi.pi_pid = getpid();
89+
res = getargs(&pi, sizeof(pi), args, sizeof(args));
90+
if (res < 0)
91+
return -EINVAL;
92+
93+
/*
94+
* Possibilities for args:
95+
* i) an absolute path such as: /home/user/myprojects/nodejs/node
96+
* ii) a relative path such as: ./node or ../myprojects/nodejs/node
97+
* iii) a bare filename such as "node", after exporting PATH variable
98+
* to its location.
99+
*/
100+
101+
/* Case i) and ii) absolute or relative paths */
102+
if (strchr(args, '/') != NULL) {
103+
if (realpath(args, abspath) != abspath)
104+
return -errno;
105+
106+
abspath_size = strlen(abspath);
107+
108+
*size -= 1;
109+
if (*size > abspath_size)
110+
*size = abspath_size;
111+
112+
memcpy(buffer, abspath, *size);
113+
buffer[*size] = '\0';
114+
115+
return 0;
116+
} else {
117+
/* Case iii). Search PATH environment variable */
118+
char trypath[PATH_MAX];
119+
char *clonedpath = NULL;
120+
char *token = NULL;
121+
char *path = getenv("PATH");
122+
123+
if (path == NULL)
124+
return -EINVAL;
125+
126+
clonedpath = uv__strdup(path);
127+
if (clonedpath == NULL)
128+
return -ENOMEM;
129+
130+
token = strtok(clonedpath, ":");
131+
while (token != NULL) {
132+
snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, args);
133+
if (realpath(trypath, abspath) == abspath) {
134+
/* Check the match is executable */
135+
if (access(abspath, X_OK) == 0) {
136+
abspath_size = strlen(abspath);
137+
138+
*size -= 1;
139+
if (*size > abspath_size)
140+
*size = abspath_size;
141+
142+
memcpy(buffer, abspath, *size);
143+
buffer[*size] = '\0';
144+
145+
uv__free(clonedpath);
146+
return 0;
147+
}
148+
}
149+
token = strtok(NULL, ":");
150+
}
151+
uv__free(clonedpath);
152+
153+
/* Out of tokens (path entries), and no match found */
154+
return -EINVAL;
155+
}
156+
}
157+
158+
void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
159+
int i;
160+
161+
for (i = 0; i < count; ++i) {
162+
uv__free(cpu_infos[i].model);
163+
}
164+
165+
uv__free(cpu_infos);
166+
}
167+
168+
169+
int uv_interface_addresses(uv_interface_address_t** addresses,
170+
int* count) {
171+
uv_interface_address_t* address;
172+
int sockfd, inet6, size = 1;
173+
struct ifconf ifc;
174+
struct ifreq *ifr, *p, flg;
175+
struct sockaddr_dl* sa_addr;
176+
177+
*count = 0;
178+
179+
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
180+
return -errno;
181+
}
182+
183+
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
184+
uv__close(sockfd);
185+
return -errno;
186+
}
187+
188+
ifc.ifc_req = (struct ifreq*)uv__malloc(size);
189+
ifc.ifc_len = size;
190+
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
191+
uv__close(sockfd);
192+
return -errno;
193+
}
194+
195+
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
196+
197+
/* Count all up and running ipv4/ipv6 addresses */
198+
ifr = ifc.ifc_req;
199+
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
200+
p = ifr;
201+
ifr = (struct ifreq*)
202+
((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
203+
204+
if (!(p->ifr_addr.sa_family == AF_INET6 ||
205+
p->ifr_addr.sa_family == AF_INET))
206+
continue;
207+
208+
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
209+
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
210+
uv__close(sockfd);
211+
return -errno;
212+
}
213+
214+
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
215+
continue;
216+
217+
(*count)++;
218+
}
219+
220+
/* Alloc the return interface structs */
221+
*addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
222+
if (!(*addresses)) {
223+
uv__close(sockfd);
224+
return -ENOMEM;
225+
}
226+
address = *addresses;
227+
228+
ifr = ifc.ifc_req;
229+
while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
230+
p = ifr;
231+
ifr = (struct ifreq*)
232+
((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
233+
234+
if (!(p->ifr_addr.sa_family == AF_INET6 ||
235+
p->ifr_addr.sa_family == AF_INET))
236+
continue;
237+
238+
inet6 = (p->ifr_addr.sa_family == AF_INET6);
239+
240+
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
241+
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
242+
uv__close(sockfd);
243+
return -ENOSYS;
244+
}
245+
246+
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
247+
continue;
248+
249+
/* All conditions above must match count loop */
250+
251+
address->name = uv__strdup(p->ifr_name);
252+
253+
if (inet6)
254+
address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
255+
else
256+
address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
257+
258+
sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
259+
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
260+
261+
if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) {
262+
uv__close(sockfd);
263+
return -ENOSYS;
264+
}
265+
266+
if (inet6)
267+
address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr);
268+
else
269+
address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
270+
271+
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
272+
273+
address++;
274+
}
275+
276+
#undef ADDR_SIZE
277+
278+
uv__close(sockfd);
279+
return 0;
280+
}
281+
282+
283+
void uv_free_interface_addresses(uv_interface_address_t* addresses,
284+
int count) {
285+
int i;
286+
287+
for (i = 0; i < count; ++i) {
288+
uv__free(addresses[i].name);
289+
}
290+
291+
uv__free(addresses);
292+
}

0 commit comments

Comments
 (0)