Changeset 1281 for python/trunk/Modules/posixmodule.c
- Timestamp:
- Dec 26, 2017, 10:43:44 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk/Modules/posixmodule.c
r1254 r1281 38 38 #if defined(__KLIBC__) 39 39 #include <sys/socket.h> 40 #include <libcx/spawn2.h> 40 41 #endif 41 42 … … 8804 8805 } 8805 8806 #endif 8807 8808 #if defined(PYOS_OS2) 8809 PyDoc_STRVAR(os2_spawn2__doc__, 8810 "spawn2(mode, file, args, cwd, env, stdfds)\n\n\ 8811 Execute the program 'name' in a new process,\n\ 8812 search path to find the file.\n\ 8813 \n\ 8814 mode: mode of process creation\n\ 8815 file: executable file name\n\ 8816 args: tuple or list of strings\n\ 8817 cwd: initial working directory for the new process\n\ 8818 env: dictionary of strings mapping to strings\n\ 8819 stdfds: tuple or list of 3 file descriptors for standard I/O"); 8820 8821 static PyObject * 8822 os2_spawn2(PyObject *self, PyObject *args) 8823 { 8824 char *path, *cwd = NULL; 8825 PyObject *argv, *env, *stdfds; 8826 char **argvlist; 8827 char **envlist; 8828 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL; 8829 int mode, i, pos, argc, envc, stdfdc; 8830 Py_intptr_t spawnval; 8831 PyObject *(*argv_getitem)(PyObject *, Py_ssize_t); 8832 int lastarg = 0; 8833 PyObject *(*stdfd_getitem)(PyObject *, Py_ssize_t); 8834 int stdfdlist[3] = {0}; 8835 8836 /* Note: no need in et and Py_FileSystemDefaultEncoding for path arguments 8837 * as on OS/2 this is always the same as the default encoding. */ 8838 if (!PyArg_ParseTuple(args, "isOzOO:spawn2", &mode, 8839 &path, &argv, &cwd, &env, &stdfds)) 8840 return NULL; 8841 if (PyList_Check(argv)) { 8842 argc = PyList_Size(argv); 8843 argv_getitem = PyList_GetItem; 8844 } 8845 else if (PyTuple_Check(argv)) { 8846 argc = PyTuple_Size(argv); 8847 argv_getitem = PyTuple_GetItem; 8848 } 8849 else { 8850 PyErr_SetString(PyExc_TypeError, 8851 "spawn2() arg 3 must be a tuple or list"); 8852 goto fail_0; 8853 } 8854 8855 if (env != Py_None && !PyMapping_Check(env)) { 8856 PyErr_SetString(PyExc_TypeError, 8857 "spawn2() arg 5 must be a mapping object"); 8858 goto fail_0; 8859 } 8860 8861 if (PyList_Check(stdfds)) { 8862 stdfdc = PyList_Size(stdfds); 8863 stdfd_getitem = PyList_GetItem; 8864 } 8865 else if (PyTuple_Check(stdfds)) { 8866 stdfdc = PyTuple_Size(stdfds); 8867 stdfd_getitem = PyTuple_GetItem; 8868 } 8869 else if (stdfds == Py_None) { 8870 stdfdc = -1; 8871 } 8872 else { 8873 PyErr_SetString(PyExc_TypeError, 8874 "spawn2() arg 6 must be a tuple or list or None"); 8875 goto fail_0; 8876 } 8877 if (stdfdc != -1 && stdfdc != 3) { 8878 PyErr_SetString(PyExc_TypeError, 8879 "spawn2() arg 6 must contain 3 elements"); 8880 goto fail_0; 8881 } 8882 8883 argvlist = PyMem_NEW(char *, argc+1); 8884 if (argvlist == NULL) { 8885 PyErr_NoMemory(); 8886 goto fail_0; 8887 } 8888 8889 for (i = 0; i < argc; i++) { 8890 if (!PyArg_Parse((*argv_getitem)(argv, i), "et", 8891 Py_FileSystemDefaultEncoding, &argvlist[i])) 8892 { 8893 PyErr_SetString(PyExc_TypeError, 8894 "spawn2() arg 3 must contain only strings"); 8895 lastarg = i; 8896 goto fail_1; 8897 } 8898 } 8899 lastarg = argc; 8900 argvlist[argc] = NULL; 8901 8902 if (env == Py_None) { 8903 envlist = NULL; 8904 envc = -1; 8905 } else { 8906 i = PyMapping_Size(env); 8907 if (i < 0) 8908 goto fail_1; 8909 envlist = PyMem_NEW(char *, i + 1); 8910 if (envlist == NULL) { 8911 PyErr_NoMemory(); 8912 goto fail_1; 8913 } 8914 envc = 0; 8915 keys = PyMapping_Keys(env); 8916 vals = PyMapping_Values(env); 8917 if (!keys || !vals) 8918 goto fail_2; 8919 if (!PyList_Check(keys) || !PyList_Check(vals)) { 8920 PyErr_SetString(PyExc_TypeError, 8921 "spawn2(): env.keys() or env.values() is not a list"); 8922 goto fail_2; 8923 } 8924 8925 for (pos = 0; pos < i; pos++) { 8926 char *p, *k, *v; 8927 size_t len; 8928 8929 key = PyList_GetItem(keys, pos); 8930 val = PyList_GetItem(vals, pos); 8931 if (!key || !val) 8932 goto fail_2; 8933 8934 if (!PyArg_Parse(key, "s", &k)) { 8935 PyErr_SetString(PyExc_TypeError, 8936 "spawn2() arg 5 contains a non-string key"); 8937 goto fail_2; 8938 } 8939 if (!PyArg_Parse(val, "s", &v)) { 8940 PyErr_SetString(PyExc_TypeError, 8941 "spawn2() arg 5 contains a non-string key"); 8942 goto fail_2; 8943 } 8944 len = PyString_Size(key) + PyString_Size(val) + 2; 8945 p = PyMem_NEW(char, len); 8946 if (p == NULL) { 8947 PyErr_NoMemory(); 8948 goto fail_2; 8949 } 8950 PyOS_snprintf(p, len, "%s=%s", k, v); 8951 envlist[envc++] = p; 8952 } 8953 envlist[envc] = 0; 8954 } 8955 8956 if (stdfdc != -1) { 8957 for (i = 0; i < stdfdc; i++) { 8958 PyObject *elem = (*stdfd_getitem)(stdfds, i); 8959 if (elem == Py_None) { 8960 stdfdlist[i] = 0; 8961 } else { 8962 if (!PyArg_Parse(elem, "i", &stdfdlist[i])) { 8963 PyErr_SetString(PyExc_TypeError, 8964 "spawn2() arg 6 must contain only integers"); 8965 goto fail_2; 8966 } 8967 } 8968 } 8969 } 8970 8971 Py_BEGIN_ALLOW_THREADS 8972 8973 spawnval = spawn2(mode, path, (const char * const *)argvlist, cwd, 8974 (const char * const *)envlist, 8975 stdfdc == -1 ? NULL : stdfdlist); 8976 8977 Py_END_ALLOW_THREADS 8978 8979 if (spawnval == -1) 8980 (void) posix_error(); 8981 else 8982 res = Py_BuildValue("l", (long) spawnval); 8983 8984 fail_2: 8985 if (envlist) { 8986 while (--envc >= 0) 8987 PyMem_DEL(envlist[envc]); 8988 PyMem_DEL(envlist); 8989 } 8990 fail_1: 8991 free_string_array(argvlist, lastarg); 8992 Py_XDECREF(vals); 8993 Py_XDECREF(keys); 8994 fail_0: 8995 return res; 8996 } 8997 #endif /* PYOS_OS2 */ 8806 8998 8807 8999 static PyMethodDef posix_methods[] = { … … 9127 9319 #endif 9128 9320 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__}, 9321 #ifdef PYOS_OS2 9322 {"spawn2", os2_spawn2, METH_VARARGS, os2_spawn2__doc__}, 9323 #endif 9129 9324 {NULL, NULL} /* Sentinel */ 9130 9325 }; … … 9395 9590 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1; 9396 9591 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1; 9592 if (ins(d, "P_2_NOINHERIT", (long)P_2_NOINHERIT)) return -1; 9593 if (ins(d, "P_2_THREADSAFE", (long)P_2_THREADSAFE)) return -1; 9594 if (ins(d, "P_2_MODE_MASK", (long)P_2_MODE_MASK)) return -1; 9397 9595 #else 9398 9596 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
Note:
See TracChangeset
for help on using the changeset viewer.