示例#1
0
        public unsafe static PosixResult Pipe(out PipeEnd readEnd, out PipeEnd writeEnd, bool blocking)
        {
            int *fds   = stackalloc int[2];
            int  flags = O_CLOEXEC;

            if (!blocking)
            {
                flags |= O_NONBLOCK;
            }

            readEnd  = new PipeEnd();
            writeEnd = new PipeEnd();

            int res = pipe2(fds, flags);

            if (res == 0)
            {
                readEnd.SetHandle(fds[0]);
                writeEnd.SetHandle(fds[1]);
            }
            else
            {
                readEnd  = null;
                writeEnd = null;
            }

            return(PosixResult.FromReturnValue(res));
        }
        public static unsafe PosixResult SocketPair(int domain, int type, int protocol, bool blocking, out int socket1, out int socket2)
        {
            int *sv = stackalloc int[2];

            type |= SOCK_CLOEXEC;

            if (!blocking)
            {
                type |= SOCK_NONBLOCK;
            }

            int rv = socketpair(domain, type, protocol, sv);

            if (rv == 0)
            {
                socket1 = sv[0];
                socket2 = sv[1];
            }
            else
            {
                socket1 = -1;
                socket2 = -1;
            }

            return(PosixResult.FromReturnValue(rv));
        }
        public static unsafe PosixResult GetAvailableBytes(int socket)
        {
            int availableBytes;
            int rv = ioctl(socket, FIONREAD, &availableBytes);

            return(PosixResult.FromReturnValue(rv == -1 ? rv : availableBytes));
        }
        public static unsafe PosixResult GetSockName(int socket, sockaddr_storage *addr)
        {
            socklen_t sockLen = SizeOf.sockaddr_storage;
            int       rv      = getsockname(socket, (sockaddr *)addr, &sockLen);

            return(PosixResult.FromReturnValue(rv));
        }
        public static unsafe PosixResult Read(SafeHandle handle, byte *buf, int count)
        {
            bool addedRef = false;

            try
            {
                handle.DangerousAddRef(ref addedRef);

                int     fd = handle.DangerousGetHandle().ToInt32();
                ssize_t rv;
                do
                {
                    rv = read(fd, buf, count);
                } while (rv < 0 && errno == EINTR);

                return(PosixResult.FromReturnValue(rv));
            }
            finally
            {
                if (addedRef)
                {
                    handle.DangerousRelease();
                }
            }
        }
        public unsafe PosixResult TryBind(string unixPath)
        {
            sockaddr_un addr;

            GetSockaddrUn(unixPath, out addr);
            int rv = bind(DangerousGetHandle().ToInt32(), (sockaddr *)&addr, SizeOf.sockaddr_un);

            return(PosixResult.FromReturnValue(rv));
        }
        public unsafe PosixResult TryBind(IPEndPointStruct endpoint)
        {
            sockaddr_storage addr;

            GetSockaddrInet(endpoint, &addr, out int length);

            int rv = bind(DangerousGetHandle().ToInt32(), (sockaddr *)&addr, length);

            return(PosixResult.FromReturnValue(rv));
        }
示例#8
0
        public static unsafe PosixResult EPollControl(int epoll, int operation, int fd, int events, int data)
        {
            epoll_event ev = default(epoll_event);

            ev.events  = events;
            ev.data.fd = data;

            int rv = epoll_ctl(epoll, operation, fd, &ev);

            return(PosixResult.FromReturnValue(rv));
        }
        public unsafe static PosixResult SetCurrentThreadAffinity(int cpuId)
        {
            cpu_set_t cpu_set;

            CPU_ZERO(&cpu_set);
            CPU_SET(cpuId, &cpu_set);

            int rv = sched_setaffinity(0, SizeOf.cpu_set_t, &cpu_set);

            return(PosixResult.FromReturnValue(rv));
        }
        public unsafe static PosixResult ReceiveSocket(int fromSocket, out int socket, bool blocking)
        {
            socket = -1;
            byte  dummyBuffer = 0;
            iovec iov         = default(iovec);

            iov.iov_base = &dummyBuffer;
            iov.iov_len  = 1;

            int   controlLength = CMSG_SPACE(sizeof(int));
            byte *control       = stackalloc byte[controlLength];

            msghdr header = default(msghdr);

            header.msg_iov        = &iov;
            header.msg_iovlen     = 1;
            header.msg_control    = control;
            header.msg_controllen = controlLength;

            int flags = MSG_NOSIGNAL | MSG_CMSG_CLOEXEC;

            ssize_t rv;

            do
            {
                rv = recvmsg(fromSocket, &header, flags);
            } while (rv < 0 && errno == EINTR);

            if (rv != -1)
            {
                for (cmsghdr *cmsg = CMSG_FIRSTHDR(&header); cmsg != null; cmsg = CMSG_NXTHDR(&header, cmsg))
                {
                    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
                    {
                        int *fdptr = (int *)CMSG_DATA(cmsg);
                        socket = *fdptr;

                        flags = fcntl(socket, F_GETFL, 0);
                        if (blocking)
                        {
                            flags &= ~O_NONBLOCK;
                        }
                        else
                        {
                            flags |= O_NONBLOCK;
                        }
                        fcntl(socket, F_SETFL, flags);
                        break;
                    }
                }
            }

            return(PosixResult.FromReturnValue(rv));
        }
示例#11
0
        public static unsafe PosixResult EPollWait(int epoll, epoll_event *events, int maxEvents, int timeout)
        {
            int rv;

            do
            {
                rv = epoll_wait(epoll, events, maxEvents, timeout);
            } while (rv < 0 && errno == EINTR);

            return(PosixResult.FromReturnValue(rv));
        }
        public static unsafe PosixResult Socket(int domain, int type, int protocol, bool blocking, out int s)
        {
            type |= SOCK_CLOEXEC;
            if (!blocking)
            {
                type |= SOCK_NONBLOCK;
            }

            s = socket(domain, type, protocol);

            return(PosixResult.FromReturnValue(s));
        }
        public unsafe static PosixResult GetAvailableCpusForProcess()
        {
            cpu_set_t set;

            int rv = sched_getaffinity(getpid(), SizeOf.cpu_set_t, &set);

            if (rv == 0)
            {
                rv = CPU_COUNT(&set);
            }

            return(PosixResult.FromReturnValue(rv));
        }
        public unsafe static PosixResult ClearCurrentThreadAffinity()
        {
            cpu_set_t cpu_set;

            CPU_ZERO(&cpu_set);
            for (int cpuId = 0; cpuId < CPU_SETSIZE; cpuId++)
            {
                CPU_SET(cpuId, &cpu_set);
            }

            int rv = sched_setaffinity(0, SizeOf.cpu_set_t, &cpu_set);

            return(PosixResult.FromReturnValue(rv));
        }
        public unsafe PosixResult TryConnect(string unixPath)
        {
            sockaddr_un addr;

            GetSockaddrUn(unixPath, out addr);
            int rv;

            do
            {
                rv = connect(DangerousGetHandle().ToInt32(), (sockaddr *)&addr, SizeOf.sockaddr_un);
            } while (rv < 0 && errno == EINTR);

            return(PosixResult.FromReturnValue(rv));
        }
        public unsafe PosixResult TryConnect(IPEndPointStruct endpoint)
        {
            sockaddr_storage addr;

            GetSockaddrInet(endpoint, &addr, out int length);
            int rv;

            do
            {
                rv = connect(DangerousGetHandle().ToInt32(), (sockaddr *)&addr, length);
            } while (rv < 0 && errno == EINTR);

            return(PosixResult.FromReturnValue(rv));
        }
        public static unsafe PosixResult Disconnect(int socket)
        {
            sockaddr addr = default(sockaddr);

            addr.sa_family = AF_UNSPEC;

            int rv;

            do
            {
                rv = connect(socket, &addr, SizeOf.sockaddr);
            } while (rv < 0 && errno == EINTR);

            return(PosixResult.FromReturnValue(rv));
        }
示例#18
0
        public static PosixResult EPollCreate(out EPoll epoll)
        {
            epoll = new EPoll();

            int rv = epoll_create1(EPOLL_CLOEXEC);

            if (rv == -1)
            {
                epoll = null;
            }
            else
            {
                epoll.SetHandle(rv);
            }

            return(PosixResult.FromReturnValue(rv));
        }
        public unsafe static PosixResult AcceptAndSendHandleTo(Socket fromSocket, int toSocket)
        {
            int     acceptFd = fromSocket.DangerousGetHandle().ToInt32();
            ssize_t rv;

            do
            {
                rv = accept4(acceptFd, null, null, SOCK_CLOEXEC);
            } while (rv < 0 && errno == EINTR);

            if (rv != -1)
            {
                int acceptedFd = (int)rv;

                byte  dummyBuffer = 0;
                iovec iov         = default(iovec);
                iov.iov_base = &dummyBuffer;
                iov.iov_len  = 1;

                int   controlLength = CMSG_SPACE(sizeof(int));
                byte *control       = stackalloc byte[controlLength];

                msghdr header = default(msghdr);
                header.msg_iov        = &iov;
                header.msg_iovlen     = 1;
                header.msg_control    = control;
                header.msg_controllen = controlLength;

                cmsghdr *cmsg = CMSG_FIRSTHDR(&header);
                cmsg->cmsg_level = SOL_SOCKET;
                cmsg->cmsg_type  = SCM_RIGHTS;
                cmsg->cmsg_len   = CMSG_LEN(sizeof(int));
                int *fdptr = (int *)CMSG_DATA(cmsg);
                *    fdptr = acceptedFd;

                do
                {
                    rv = sendmsg(toSocket, &header, MSG_NOSIGNAL);
                } while (rv < 0 && errno == EINTR);

                IOInterop.Close(acceptedFd);
            }

            return(PosixResult.FromReturnValue(rv));
        }
        public static unsafe PosixResult Receive(int socket, iovec *ioVectors, int ioVectorLen)
        {
            msghdr hdr = default(msghdr);

            hdr.msg_iov    = ioVectors;
            hdr.msg_iovlen = ioVectorLen;

            int flags = MSG_NOSIGNAL;

            ssize_t rv;

            do
            {
                rv = recvmsg(socket, &hdr, flags);
            } while (rv < 0 && errno == EINTR);

            return(PosixResult.FromReturnValue(rv));
        }
        public unsafe static PosixResult CompleteZeroCopy(int socket)
        {
            msghdr msg           = default(msghdr);
            int    controlLength = 100;
            byte * control       = stackalloc byte[controlLength];

            do
            {
                msg.msg_control    = control;
                msg.msg_controllen = controlLength;

                ssize_t rv;
                do
                {
                    rv = recvmsg(socket, &msg, MSG_NOSIGNAL | MSG_ERRQUEUE);
                } while (rv < 0 && errno == EINTR);

                if (rv == -1)
                {
                    return(PosixResult.FromReturnValue(rv));
                }
                cmsghdr *cm = CMSG_FIRSTHDR(&msg);
                if (cm == null)
                {
                    continue;
                }

                if (!((cm->cmsg_level == SOL_IP && cm->cmsg_type == IP_RECVERR) ||
                      (cm->cmsg_level == SOL_IPV6 && cm->cmsg_type == IPV6_RECVERR)))
                {
                    continue;
                }

                sock_extended_err *serr = (sock_extended_err *)CMSG_DATA(cm);
                if ((serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) ||
                    (serr->ee_errno != 0))
                {
                    continue;
                }

                return(new PosixResult(((serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED) != 0) ?
                                       ZeroCopyCopied : ZeroCopySuccess));
            } while (true);
        }
        public static unsafe PosixResult Accept(int socket, bool blocking, out int clientSocket)
        {
            int flags = SOCK_CLOEXEC;

            if (!blocking)
            {
                flags |= SOCK_NONBLOCK;
            }
            int rv;

            do
            {
                rv = accept4(socket, null, null, flags);
            } while (rv < 0 && errno == EINTR);

            clientSocket = rv;

            return(PosixResult.FromReturnValue(rv));
        }
示例#23
0
        public unsafe static PosixResult IoGetEvents(aio_context_t ctx, int min_nr, int nr, io_event *events, int timeoutMs)
        {
            timespec timeout    = default(timespec);
            bool     hasTimeout = timeoutMs >= 0;

            if (hasTimeout)
            {
                timeout.tv_sec  = timeoutMs / 1000;
                timeout.tv_nsec = 1000 * (timeoutMs % 1000);
            }
            int rv;

            do
            {
                rv = io_getevents(ctx, min_nr, nr, events, hasTimeout ? &timeout : null);
            } while (rv < 0 && errno == EINTR);

            return(PosixResult.FromReturnValue(rv));
        }
        public static unsafe PosixResult GetSockOpt(SafeHandle socket, int level, int optname, void *optval, socklen_t *optlen)
        {
            int rv = getsockopt(socket.DangerousGetHandle().ToInt32(), level, optname, optval, optlen);

            return(PosixResult.FromReturnValue(rv));
        }
示例#25
0
        public unsafe static PosixResult IoSetup(int nr, aio_context_t *ctx)
        {
            int rv = io_setup((uint)nr, ctx);

            return(PosixResult.FromReturnValue(rv));
        }
        public static PosixResult Shutdown(int socket, int how)
        {
            int rv = shutdown(socket, how);

            return(PosixResult.FromReturnValue(rv));
        }
        public PosixResult TryListen(int backlog)
        {
            int rv = listen(DangerousGetHandle().ToInt32(), backlog);

            return(PosixResult.FromReturnValue(rv));
        }
        public static unsafe PosixResult SetSockOpt(int socket, int level, int optname, void *optval, socklen_t optlen)
        {
            int rv = setsockopt(socket, level, optname, optval, optlen);

            return(PosixResult.FromReturnValue(rv));
        }
示例#29
0
        public unsafe static PosixResult IoDestroy(aio_context_t ctx)
        {
            int rv = io_destroy(ctx);

            return(PosixResult.FromReturnValue(rv));
        }
示例#30
0
        public unsafe static PosixResult IoSubmit(aio_context_t ctx, int nr, iocb **iocbpp)
        {
            int rv = io_submit(ctx, nr, iocbpp);

            return(PosixResult.FromReturnValue(rv));
        }