gint system_pipe2(gint pipefds[2], gint flags) { /* we only support non-blocking sockets, and require * SOCK_NONBLOCK to be set immediately */ gboolean isBlocking = TRUE; /* clear non-blocking flags if set to get true type */ if(flags & O_NONBLOCK) { flags = flags & ~O_NONBLOCK; isBlocking = FALSE; } if(flags & O_CLOEXEC) { flags = flags & ~O_CLOEXEC; isBlocking = FALSE; } /* check inputs for what we support */ if(isBlocking) { warning("we only support non-blocking pipes: please bitwise OR 'O_NONBLOCK' with flags"); errno = EINVAL; return -1; } Node* node = _system_switchInShadowContext(); gint handle = node_createDescriptor(node, DT_PIPE); Channel* channel = (Channel*) node_lookupDescriptor(node, handle); gint linkedHandle = channel_getLinkedHandle(channel); _system_switchOutShadowContext(node); pipefds[0] = handle; /* reader */ pipefds[1] = linkedHandle; /* writer */ return 0; }
gint system_socketPair(gint domain, gint type, gint protocol, gint fds[2]) { /* create a pair of connected sockets, i.e. a bi-directional pipe */ if(domain != AF_UNIX) { errno = EAFNOSUPPORT; return -1; } /* only support non-blocking sockets */ gboolean isBlocking = FALSE; /* clear non-blocking flags if set to get true type */ gint realType = type; if(realType & SOCK_NONBLOCK) { realType = realType & ~SOCK_NONBLOCK; isBlocking = FALSE; } if(realType & SOCK_CLOEXEC) { realType = realType & ~SOCK_CLOEXEC; isBlocking = FALSE; } if(realType != SOCK_STREAM) { errno = EPROTONOSUPPORT; return -1; } gint result = 0; Host* node = _system_switchInShadowContext(); if(isBlocking) { warning("we only support non-blocking sockets: please bitwise OR 'SOCK_NONBLOCK' with type flags"); errno = EPROTONOSUPPORT; result = -1; } if(result == 0) { gint handle = host_createDescriptor(node, DT_SOCKETPAIR); Channel* channel = (Channel*) host_lookupDescriptor(node, handle); gint linkedHandle = channel_getLinkedHandle(channel); fds[0] = handle; fds[1] = linkedHandle; } _system_switchOutShadowContext(node); return result; }