Show More
@@ -11,6 +11,7 b'' | |||||
11 | #include <Python.h> |
|
11 | #include <Python.h> | |
12 | #include <fcntl.h> |
|
12 | #include <fcntl.h> | |
13 | #include <stdio.h> |
|
13 | #include <stdio.h> | |
|
14 | #include <stdlib.h> | |||
14 | #include <string.h> |
|
15 | #include <string.h> | |
15 | #include <errno.h> |
|
16 | #include <errno.h> | |
16 |
|
17 | |||
@@ -19,6 +20,7 b'' | |||||
19 | #include <io.h> |
|
20 | #include <io.h> | |
20 | #else |
|
21 | #else | |
21 | #include <dirent.h> |
|
22 | #include <dirent.h> | |
|
23 | #include <sys/socket.h> | |||
22 | #include <sys/stat.h> |
|
24 | #include <sys/stat.h> | |
23 | #include <sys/types.h> |
|
25 | #include <sys/types.h> | |
24 | #include <unistd.h> |
|
26 | #include <unistd.h> | |
@@ -648,6 +650,69 b' bail:' | |||||
648 | return NULL; |
|
650 | return NULL; | |
649 | } |
|
651 | } | |
650 |
|
652 | |||
|
653 | /* | |||
|
654 | * recvfds() simply does not release GIL during blocking io operation because | |||
|
655 | * command server is known to be single-threaded. | |||
|
656 | */ | |||
|
657 | ||||
|
658 | static ssize_t recvfdstobuf(int sockfd, int **rfds, void *cbuf, size_t cbufsize) | |||
|
659 | { | |||
|
660 | char dummy[1]; | |||
|
661 | struct iovec iov = {dummy, sizeof(dummy)}; | |||
|
662 | struct msghdr msgh = {0}; | |||
|
663 | struct cmsghdr *cmsg; | |||
|
664 | ||||
|
665 | msgh.msg_iov = &iov; | |||
|
666 | msgh.msg_iovlen = 1; | |||
|
667 | msgh.msg_control = cbuf; | |||
|
668 | msgh.msg_controllen = (socklen_t)cbufsize; | |||
|
669 | if (recvmsg(sockfd, &msgh, 0) < 0) | |||
|
670 | return -1; | |||
|
671 | ||||
|
672 | for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg; | |||
|
673 | cmsg = CMSG_NXTHDR(&msgh, cmsg)) { | |||
|
674 | if (cmsg->cmsg_level != SOL_SOCKET || | |||
|
675 | cmsg->cmsg_type != SCM_RIGHTS) | |||
|
676 | continue; | |||
|
677 | *rfds = (int *)CMSG_DATA(cmsg); | |||
|
678 | return (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); | |||
|
679 | } | |||
|
680 | ||||
|
681 | *rfds = cbuf; | |||
|
682 | return 0; | |||
|
683 | } | |||
|
684 | ||||
|
685 | static PyObject *recvfds(PyObject *self, PyObject *args) | |||
|
686 | { | |||
|
687 | int sockfd; | |||
|
688 | int *rfds = NULL; | |||
|
689 | ssize_t rfdscount, i; | |||
|
690 | char cbuf[256]; | |||
|
691 | PyObject *rfdslist = NULL; | |||
|
692 | ||||
|
693 | if (!PyArg_ParseTuple(args, "i", &sockfd)) | |||
|
694 | return NULL; | |||
|
695 | ||||
|
696 | rfdscount = recvfdstobuf(sockfd, &rfds, cbuf, sizeof(cbuf)); | |||
|
697 | if (rfdscount < 0) | |||
|
698 | return PyErr_SetFromErrno(PyExc_OSError); | |||
|
699 | ||||
|
700 | rfdslist = PyList_New(rfdscount); | |||
|
701 | if (!rfdslist) | |||
|
702 | goto bail; | |||
|
703 | for (i = 0; i < rfdscount; i++) { | |||
|
704 | PyObject *obj = PyInt_FromLong(rfds[i]); | |||
|
705 | if (!obj) | |||
|
706 | goto bail; | |||
|
707 | PyList_SET_ITEM(rfdslist, i, obj); | |||
|
708 | } | |||
|
709 | return rfdslist; | |||
|
710 | ||||
|
711 | bail: | |||
|
712 | Py_XDECREF(rfdslist); | |||
|
713 | return NULL; | |||
|
714 | } | |||
|
715 | ||||
651 | #endif /* ndef _WIN32 */ |
|
716 | #endif /* ndef _WIN32 */ | |
652 |
|
717 | |||
653 | static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs) |
|
718 | static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs) | |
@@ -816,6 +881,8 b' static PyMethodDef methods[] = {' | |||||
816 | {"statfiles", (PyCFunction)statfiles, METH_VARARGS | METH_KEYWORDS, |
|
881 | {"statfiles", (PyCFunction)statfiles, METH_VARARGS | METH_KEYWORDS, | |
817 | "stat a series of files or symlinks\n" |
|
882 | "stat a series of files or symlinks\n" | |
818 | "Returns None for non-existent entries and entries of other types.\n"}, |
|
883 | "Returns None for non-existent entries and entries of other types.\n"}, | |
|
884 | {"recvfds", (PyCFunction)recvfds, METH_VARARGS, | |||
|
885 | "receive list of file descriptors via socket\n"}, | |||
819 | #endif |
|
886 | #endif | |
820 | #ifdef __APPLE__ |
|
887 | #ifdef __APPLE__ | |
821 | { |
|
888 | { |
General Comments 0
You need to be logged in to leave comments.
Login now