mercurial/cext/osutil.c
changeset 49275 c6a3243567b6
parent 48841 2ef3b7d30cc1
child 51738 b619ba39d10a
equal deleted inserted replaced
49273:34020d1f1635 49275:c6a3243567b6
   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)