683 bail: |
683 bail: |
684 Py_DECREF(stats); |
684 Py_DECREF(stats); |
685 return NULL; |
685 return NULL; |
686 } |
686 } |
687 |
687 |
688 /* |
|
689 * recvfds() simply does not release GIL during blocking io operation because |
|
690 * command server is known to be single-threaded. |
|
691 * |
|
692 * Old systems such as Solaris don't provide CMSG_LEN, msg_control, etc. |
|
693 * Currently, recvfds() is not supported on these platforms. |
|
694 */ |
|
695 #ifdef CMSG_LEN |
|
696 |
|
697 static ssize_t recvfdstobuf(int sockfd, int **rfds, void *cbuf, size_t cbufsize) |
|
698 { |
|
699 char dummy[1]; |
|
700 struct iovec iov = {dummy, sizeof(dummy)}; |
|
701 struct msghdr msgh = {0}; |
|
702 struct cmsghdr *cmsg; |
|
703 |
|
704 msgh.msg_iov = &iov; |
|
705 msgh.msg_iovlen = 1; |
|
706 msgh.msg_control = cbuf; |
|
707 msgh.msg_controllen = (socklen_t)cbufsize; |
|
708 if (recvmsg(sockfd, &msgh, 0) < 0) |
|
709 return -1; |
|
710 |
|
711 for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg; |
|
712 cmsg = CMSG_NXTHDR(&msgh, cmsg)) { |
|
713 if (cmsg->cmsg_level != SOL_SOCKET || |
|
714 cmsg->cmsg_type != SCM_RIGHTS) |
|
715 continue; |
|
716 *rfds = (int *)CMSG_DATA(cmsg); |
|
717 return (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); |
|
718 } |
|
719 |
|
720 *rfds = cbuf; |
|
721 return 0; |
|
722 } |
|
723 |
|
724 static PyObject *recvfds(PyObject *self, PyObject *args) |
|
725 { |
|
726 int sockfd; |
|
727 int *rfds = NULL; |
|
728 ssize_t rfdscount, i; |
|
729 char cbuf[256]; |
|
730 PyObject *rfdslist = NULL; |
|
731 |
|
732 if (!PyArg_ParseTuple(args, "i", &sockfd)) |
|
733 return NULL; |
|
734 |
|
735 rfdscount = recvfdstobuf(sockfd, &rfds, cbuf, sizeof(cbuf)); |
|
736 if (rfdscount < 0) |
|
737 return PyErr_SetFromErrno(PyExc_OSError); |
|
738 |
|
739 rfdslist = PyList_New(rfdscount); |
|
740 if (!rfdslist) |
|
741 goto bail; |
|
742 for (i = 0; i < rfdscount; i++) { |
|
743 PyObject *obj = PyLong_FromLong(rfds[i]); |
|
744 if (!obj) |
|
745 goto bail; |
|
746 PyList_SET_ITEM(rfdslist, i, obj); |
|
747 } |
|
748 return rfdslist; |
|
749 |
|
750 bail: |
|
751 Py_XDECREF(rfdslist); |
|
752 return NULL; |
|
753 } |
|
754 |
|
755 #endif /* CMSG_LEN */ |
|
756 |
|
757 /* allow disabling setprocname via compiler flags */ |
688 /* allow disabling setprocname via compiler flags */ |
758 #ifndef SETPROCNAME_USE_NONE |
689 #ifndef SETPROCNAME_USE_NONE |
759 #if defined(HAVE_SETPROCTITLE) |
690 #if defined(HAVE_SETPROCTITLE) |
760 /* setproctitle is the first choice - available in FreeBSD */ |
691 /* setproctitle is the first choice - available in FreeBSD */ |
761 #define SETPROCNAME_USE_SETPROCTITLE |
692 #define SETPROCNAME_USE_SETPROCTITLE |
1283 "On error, this function may raise either a WindowsError or an IOError."}, |
1214 "On error, this function may raise either a WindowsError or an IOError."}, |
1284 #else |
1215 #else |
1285 {"statfiles", (PyCFunction)statfiles, METH_VARARGS | METH_KEYWORDS, |
1216 {"statfiles", (PyCFunction)statfiles, METH_VARARGS | METH_KEYWORDS, |
1286 "stat a series of files or symlinks\n" |
1217 "stat a series of files or symlinks\n" |
1287 "Returns None for non-existent entries and entries of other types.\n"}, |
1218 "Returns None for non-existent entries and entries of other types.\n"}, |
1288 #ifdef CMSG_LEN |
|
1289 {"recvfds", (PyCFunction)recvfds, METH_VARARGS, |
|
1290 "receive list of file descriptors via socket\n"}, |
|
1291 #endif |
|
1292 #ifndef SETPROCNAME_USE_NONE |
1219 #ifndef SETPROCNAME_USE_NONE |
1293 {"setprocname", (PyCFunction)setprocname, METH_VARARGS, |
1220 {"setprocname", (PyCFunction)setprocname, METH_VARARGS, |
1294 "set process title (best-effort)\n"}, |
1221 "set process title (best-effort)\n"}, |
1295 #endif |
1222 #endif |
1296 #if defined(HAVE_BSD_STATFS) || defined(HAVE_LINUX_STATFS) |
1223 #if defined(HAVE_BSD_STATFS) || defined(HAVE_LINUX_STATFS) |