diff -r d6311829da15 Modules/posixmodule.c --- a/Modules/posixmodule.c Tue Jan 28 05:00:08 2014 -0800 +++ b/Modules/posixmodule.c Wed Jan 29 06:08:44 2014 -0800 @@ -182,9 +182,10 @@ /*[clinic input] +# one of the few times we lie about this name! module os [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8cff096d1133288f]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/ #ifndef _MSC_VER @@ -679,6 +680,8 @@ + + /* * A PyArg_ParseTuple "converter" function * that handles filesystem paths in the manner @@ -774,8 +777,8 @@ PyObject *cleanup; } path_t; -#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \ - {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL} +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ + {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} static void path_cleanup(path_t *path) { @@ -1000,21 +1003,35 @@ return 0; } -/* A helper used by a number of POSIX-only functions */ -#ifndef MS_WINDOWS -static int -_parse_off_t(PyObject* arg, void* addr) -{ -#if !defined(HAVE_LARGEFILE_SUPPORT) - *((off_t*)addr) = PyLong_AsLong(arg); -#else - *((off_t*)addr) = PyLong_AsLongLong(arg); +#ifdef MS_WINDOWS + typedef PY_LONG_LONG Py_off_t; +#else + typedef off_t Py_off_t; +#endif + +static int +Py_off_t_converter(PyObject *arg, void *addr) +{ +#ifdef HAVE_LARGEFILE_SUPPORT + *((Py_off_t *)addr) = PyLong_AsLongLong(arg); +#else + *((Py_off_t *)addr) = PyLong_AsLong(arg); #endif if (PyErr_Occurred()) return 0; return 1; } -#endif + +static PyObject * +PyLong_FromPy_off_t(Py_off_t offset) +{ +#ifdef HAVE_LARGEFILE_SUPPORT + return PyLong_FromLongLong(offset); +#else + return PyLong_FromLong(offset); +#endif +} + #if defined _MSC_VER && _MSC_VER >= 1400 /* Microsoft CRT in VS2005 and higher will verify that a filehandle is @@ -1314,18 +1331,26 @@ } -/* POSIX generic methods */ - -static PyObject * -posix_fildes(PyObject *fdobj, int (*func)(int)) +static int +fildes_converter(PyObject *o, void *p) { int fd; + int *pointer = (int *)p; + fd = PyObject_AsFileDescriptor(o); + if (fd < 0) + return 0; + if (!_PyVerify_fd(fd)) { + posix_error(); + return 0; + } + *pointer = fd; + return 1; +} + +static PyObject * +posix_fildes_fd(int fd, int (*func)(int)) +{ int res; - fd = PyObject_AsFileDescriptor(fdobj); - if (fd < 0) - return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); Py_BEGIN_ALLOW_THREADS res = (*func)(fd); Py_END_ALLOW_THREADS @@ -1335,30 +1360,6 @@ return Py_None; } -static PyObject * -posix_1str(const char *func_name, PyObject *args, char *format, - int (*func)(const char*)) -{ - path_t path; - int res; - memset(&path, 0, sizeof(path)); - path.function_name = func_name; - if (!PyArg_ParseTuple(args, format, - path_converter, &path)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = (*func)(path.narrow); - Py_END_ALLOW_THREADS - if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; - } - path_cleanup(&path); - Py_INCREF(Py_None); - return Py_None; -} - #ifdef MS_WINDOWS /* This is a reimplementation of the C library's chdir function, @@ -2117,12 +2118,14 @@ static int _stat_float_times = 1; PyDoc_STRVAR(stat_float_times__doc__, -"stat_float_times([newval]) -> oldval\n\n\ +"sig=($module, value)\n\ Determine whether os.[lf]stat represents time stamps as float objects.\n\ -If newval is True, future calls to stat() return floats, if it is False,\n\ -future calls return ints. \n\ -If newval is omitted, return the current setting.\n"); - +\n\ +If value is True, future calls to stat() return floats; if it is False,\n\ +future calls return ints.\n\ +If value is omitted, return the current setting.\n"); + +/* AC 3.5: the public default value should be None, not ready for that yet */ static PyObject* stat_float_times(PyObject* self, PyObject *args) { @@ -2349,9 +2352,118 @@ } #ifdef HAVE_FSTATAT - #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable + #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FACCESSAT + #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FCHMODAT + #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FCHOWNAT + #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_LINKAT + #define LINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKDIRAT + #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_UNLINKAT + #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_SYMLINKAT + #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_OPENAT + #define OPENAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKFIFOAT + #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKNODAT + #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + + +#ifdef HAVE_FCHDIR + #define PATH_HAVE_FCHDIR 1 +#else + #define PATH_HAVE_FCHDIR 0 +#endif + +#ifdef HAVE_FCHMOD + #define PATH_HAVE_FCHMOD 1 +#else + #define PATH_HAVE_FCHMOD 0 +#endif + +#ifdef HAVE_FCHOWN + #define PATH_HAVE_FCHOWN 1 +#else + #define PATH_HAVE_FCHOWN 0 +#endif + +#ifdef HAVE_FDOPENDIR + #define PATH_HAVE_FDOPENDIR 1 +#else + #define PATH_HAVE_FDOPENDIR 0 +#endif + +#ifdef HAVE_FEXECVE + #define PATH_HAVE_FEXECVE 1 +#else + #define PATH_HAVE_FEXECVE 0 +#endif + +#ifdef HAVE_FPATHCONF + #define PATH_HAVE_FPATHCONF 1 +#else + #define PATH_HAVE_FPATHCONF 0 +#endif + +#ifdef HAVE_FSTATVFS + #define PATH_HAVE_FSTATVFS 1 +#else + #define PATH_HAVE_FSTATVFS 0 +#endif + +#ifdef HAVE_FTRUNCATE + #define PATH_HAVE_FTRUNCATE 1 +#else + #define PATH_HAVE_FTRUNCATE 0 #endif @@ -2367,18 +2479,25 @@ def converter_init(self, *, allow_fd=False, nullable=False): def strify(value): + if isinstance(value, str): + return value return str(int(bool(value))) - # right now path_t doesn't support default values. - # to support a default value, you'll need to override initialize(). - - assert self.default is unspecified + # right now the only default value path_t supports + # is None, which allows you to say that it's optional. + + if self.default == None: + if not nullable: + fail("If you give path_t a default of None, it must be nullable=True!") + elif self.default is not unspecified: + fail("The only legal default value for path_t is None!") self.nullable = nullable self.allow_fd = allow_fd - self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format( + self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format( self.function.name, + self.name, strify(nullable), strify(allow_fd), ) @@ -2389,15 +2508,78 @@ class dir_fd_converter(CConverter): type = 'int' - converter = 'OS_STAT_DIR_FD_CONVERTER' - - def converter_init(self): + + def converter_init(self, requires=None): if self.default in (unspecified, None): self.c_default = 'DEFAULT_DIR_FD' - + if isinstance(requires, str): + self.converter = requires.upper() + '_DIR_FD_CONVERTER' + else: + self.converter = 'dir_fd_converter' + +class fildes_converter(CConverter): + type = 'int' + converter = 'fildes_converter' + +class uid_t_converter(CConverter): + type = "uid_t" + converter = '_Py_Uid_Converter' + +class gid_t_converter(CConverter): + type = "gid_t" + converter = '_Py_Gid_Converter' + +class FSConverter_converter(CConverter): + type = 'PyObject *' + converter = 'PyUnicode_FSConverter' + def converter_init(self): + if self.default is not unspecified: + fail("FSConverter_converter does not support default values") + self.c_default = 'NULL' + + def cleanup(self): + return "Py_XDECREF(" + self.name + ");\n" + +class pid_t_converter(CConverter): + type = 'pid_t' + format_unit = '" _Py_PARSE_PID "' + +class idtype_t_converter(int_converter): + type = 'idtype_t' + +class id_t_converter(CConverter): + type = 'id_t' + format_unit = '" _Py_PARSE_PID "' + +class Py_intptr_t_converter(CConverter): + type = 'Py_intptr_t' + format_unit = '" _Py_PARSE_INTPTR "' + +class Py_off_t_converter(CConverter): + type = 'Py_off_t' + converter = 'Py_off_t_converter' + +class Py_off_t_return_converter(long_return_converter): + type = 'Py_off_t' + conversion_fn = 'PyLong_FromPy_off_t' + +class path_confname_converter(CConverter): + type="int" + converter="conv_path_confname" + +class confstr_confname_converter(path_confname_converter): + converter='conv_confstr_confname' + +class sysconf_confname_converter(path_confname_converter): + converter="conv_sysconf_confname" + +class sched_param_converter(CConverter): + type = 'struct sched_param' + converter = 'convert_sched_param' + impl_by_reference = True; [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=d702d58a8469cc7d]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=41b21426460b48d8]*/ /*[clinic input] @@ -2408,7 +2590,7 @@ * - dir_fd : dir_fd = None + dir_fd : dir_fd(requires='fstatat') = None If not None, it should be a file descriptor open to a directory, and path should be a relative string; path will then be relative to that directory. @@ -2462,13 +2644,13 @@ { PyObject *return_value = NULL; static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; - path_t path = PATH_T_INITIALIZE("stat", 0, 1); + path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", _keywords, - path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) goto exit; return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks); @@ -2481,47 +2663,69 @@ static PyObject * os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=33b6ee92cd1b98de input=5ae155bd475fd20a]*/ +/*[clinic end generated code: output=1056d586bde08844 input=099d356c306fa24a]*/ { return posix_do_stat("stat", path, dir_fd, follow_symlinks); } -PyDoc_STRVAR(posix_lstat__doc__, -"lstat(path, *, dir_fd=None) -> stat result\n\n\ -Like stat(), but do not follow symbolic links.\n\ -Equivalent to stat(path, follow_symlinks=False)."); - -static PyObject * -posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"path", "dir_fd", NULL}; - path_t path; +/*[clinic input] +os.lstat + + path : path_t + + * + + dir_fd : dir_fd(requires='fstatat') = None + +Perform a stat system call on the given path, without following symbolic links. + +Like stat(), but do not follow symbolic links. +Equivalent to stat(path, follow_symlinks=False). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lstat__doc__, +"sig=($module, path, *, dir_fd=None)\n" +"Perform a stat system call on the given path, without following symbolic links.\n" +"\n" +"Like stat(), but do not follow symbolic links.\n" +"Equivalent to stat(path, follow_symlinks=False)."); + +#define OS_LSTAT_METHODDEF \ + {"lstat", (PyCFunction)os_lstat, METH_VARARGS|METH_KEYWORDS, os_lstat__doc__}, + +static PyObject * +os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_lstat(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&:lstat", _keywords, + path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_lstat_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=bbcba334e313753a input=0b7474765927b925]*/ +{ int follow_symlinks = 0; - PyObject *return_value; - - memset(&path, 0, sizeof(path)); - path.function_name = "lstat"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords, - path_converter, &path, -#ifdef HAVE_FSTATAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks); - path_cleanup(&path); - return return_value; -} - - -#ifdef HAVE_FACCESSAT - #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter -#else - #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable -#endif + return posix_do_stat("lstat", path, dir_fd, follow_symlinks); +} + + /*[clinic input] os.access @@ -2534,7 +2738,7 @@ * - dir_fd : dir_fd = None + dir_fd : dir_fd(requires='faccessat') = None If not None, it should be a file descriptor open to a directory, and path should be relative; path will then be relative to that directory. @@ -2601,7 +2805,7 @@ { PyObject *return_value = NULL; static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; - path_t path = PATH_T_INITIALIZE("access", 0, 1); + path_t path = PATH_T_INITIALIZE("access", "path", 0, 1); int mode; int dir_fd = DEFAULT_DIR_FD; int effective_ids = 0; @@ -2609,7 +2813,7 @@ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", _keywords, - path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) + path_converter, &path, &mode, FACCESSAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) goto exit; return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); @@ -2622,7 +2826,7 @@ static PyObject * os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks) -/*[clinic end generated code: output=33b3fafc61e778e1 input=2e2e7594371f5b7e]*/ +/*[clinic end generated code: output=eef4b6458f063b93 input=8d9334f4c47704de]*/ { PyObject *return_value = NULL; @@ -2634,11 +2838,11 @@ #ifndef HAVE_FACCESSAT if (follow_symlinks_specified("access", follow_symlinks)) - goto exit; + return NULL; if (effective_ids) { argument_unavailable_error("access", "effective_ids"); - goto exit; + return NULL; } #endif @@ -2684,9 +2888,6 @@ return_value = PyBool_FromLong(!result); #endif -#ifndef HAVE_FACCESSAT -exit: -#endif return return_value; } @@ -2766,12 +2967,32 @@ #endif #ifdef HAVE_CTERMID -PyDoc_STRVAR(posix_ctermid__doc__, -"ctermid() -> string\n\n\ -Return the name of the controlling terminal for this process."); - -static PyObject * -posix_ctermid(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.ctermid + +Return the name of the controlling terminal for this process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_ctermid__doc__, +"sig=($module)\n" +"Return the name of the controlling terminal for this process."); + +#define OS_CTERMID_METHODDEF \ + {"ctermid", (PyCFunction)os_ctermid, METH_NOARGS, os_ctermid__doc__}, + +static PyObject * +os_ctermid_impl(PyModuleDef *module); + +static PyObject * +os_ctermid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_ctermid_impl(module); +} + +static PyObject * +os_ctermid_impl(PyModuleDef *module) +/*[clinic end generated code: output=c07754990a0dd55e input=3b87fdd52556382d]*/ { char *ret; char buffer[L_ctermid]; @@ -2785,106 +3006,232 @@ return posix_error(); return PyUnicode_DecodeFSDefault(buffer); } -#endif - -PyDoc_STRVAR(posix_chdir__doc__, -"chdir(path)\n\n\ -Change the current working directory to the specified path.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception."); - -static PyObject * -posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; +#else /* HAVE_CTERMID */ +#define OS_CTERMID_METHODDEF +#endif /* HAVE_CTERMID */ + +/*[clinic input] +os.chdir + + path: path_t(allow_fd='PATH_HAVE_FCHDIR') + +Change the current working directory to the specified path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chdir__doc__, +"sig=($module, path)\n" +"Change the current working directory to the specified path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_CHDIR_METHODDEF \ + {"chdir", (PyCFunction)os_chdir, METH_VARARGS|METH_KEYWORDS, os_chdir__doc__}, + +static PyObject * +os_chdir_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_chdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:chdir", _keywords, + path_converter, &path)) + goto exit; + return_value = os_chdir_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chdir_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=015a5f7407b24faa input=1a4a15b4d12cb15d]*/ +{ int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "chdir"; + + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + if (path->wide) + result = win32_wchdir(path->wide); + else + result = win32_chdir(path->narrow); + result = !result; /* on unix, success = 0, on windows, success = !0 */ +#else #ifdef HAVE_FCHDIR - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords, - path_converter, &path - )) - return NULL; - - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - if (path.wide) - result = win32_wchdir(path.wide); - else - result = win32_chdir(path.narrow); - result = !result; /* on unix, success = 0, on windows, success = !0 */ -#else + if (path->fd != -1) + result = fchdir(path->fd); + else +#endif + result = chdir(path->narrow); +#endif + Py_END_ALLOW_THREADS + + if (result) { + return path_error(path); + } + + Py_RETURN_NONE; +} + #ifdef HAVE_FCHDIR - if (path.fd != -1) - result = fchdir(path.fd); - else -#endif - result = chdir(path.narrow); -#endif - Py_END_ALLOW_THREADS - - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); - -exit: - path_cleanup(&path); - return return_value; -} - -#ifdef HAVE_FCHDIR -PyDoc_STRVAR(posix_fchdir__doc__, -"fchdir(fd)\n\n\ -Change to the directory of the given file descriptor. fd must be\n\ -opened on a directory, not a file. Equivalent to os.chdir(fd)."); - -static PyObject * -posix_fchdir(PyObject *self, PyObject *fdobj) -{ - return posix_fildes(fdobj, fchdir); -} + +/*[clinic input] +os.fchdir + + fd: fildes + +Change to the directory of the given file descriptor. + +fd must be opened on a directory, not a file. +Equivalent to os.chdir(fd). + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fchdir__doc__, +"sig=($module, fd)\n" +"Change to the directory of the given file descriptor.\n" +"\n" +"fd must be opened on a directory, not a file.\n" +"Equivalent to os.chdir(fd)."); + +#define OS_FCHDIR_METHODDEF \ + {"fchdir", (PyCFunction)os_fchdir, METH_VARARGS|METH_KEYWORDS, os_fchdir__doc__}, + +static PyObject * +os_fchdir_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fchdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:fchdir", _keywords, + fildes_converter, &fd)) + goto exit; + return_value = os_fchdir_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_fchdir_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=fac11823c23cd527 input=18e816479a2fa985]*/ +{ + return posix_fildes_fd(fd, fchdir); +} +#else /* HAVE_FCHDIR */ +#define OS_FCHDIR_METHODDEF #endif /* HAVE_FCHDIR */ -PyDoc_STRVAR(posix_chmod__doc__, -"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\ -Change the access permissions of a file.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception.\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, chmod will modify the symbolic link itself instead of the file the\n\ - link points to.\n\ -It is an error to use dir_fd or follow_symlinks when specifying path as\n\ - an open file descriptor.\n\ -dir_fd and follow_symlinks may not be implemented on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); - -static PyObject * -posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; + +/*[clinic input] +os.chmod + + path: path_t(allow_fd='PATH_HAVE_FCHMOD') + Path to be modified. May always be specified as a str or bytes. + On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. + + mode: int + Operating-system mode bitfield. + + * + + dir_fd : dir_fd(requires='fchmodat') = None + If not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that + directory. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + chmod will modify the symbolic link itself instead of the file + the link points to. + +Change the access permissions of a file. + +It is an error to use dir_fd or follow_symlinks when specifying path as + an open file descriptor. +dir_fd and follow_symlinks may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chmod__doc__, +"sig=($module, path, mode, *, dir_fd=None, follow_symlinks=True)\n" +"Change the access permissions of a file.\n" +"\n" +" path\n" +" Path to be modified. May always be specified as a str or bytes.\n" +" On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +" mode\n" +" Operating-system mode bitfield.\n" +" dir_fd\n" +" If not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that\n" +" directory.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" chmod will modify the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"It is an error to use dir_fd or follow_symlinks when specifying path as\n" +" an open file descriptor.\n" +"dir_fd and follow_symlinks may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_CHMOD_METHODDEF \ + {"chmod", (PyCFunction)os_chmod, METH_VARARGS|METH_KEYWORDS, os_chmod__doc__}, + +static PyObject * +os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks); + +static PyObject * +os_chmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); int mode; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&i|$O&p:chmod", _keywords, + path_converter, &path, &mode, FCHMODAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + return_value = os_chmod_impl(module, &path, mode, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=328c3396b49c35d1 input=7f1618e5e15cc196]*/ +{ int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "dir_fd", - "follow_symlinks", NULL}; #ifdef MS_WINDOWS DWORD attr; @@ -2894,33 +3241,17 @@ int fchmodat_nofollow_unsupported = 0; #endif - memset(&path, 0, sizeof(path)); - path.function_name = "chmod"; -#ifdef HAVE_FCHMOD - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords, - path_converter, &path, - &mode, -#ifdef HAVE_FCHMODAT - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks)) - return NULL; - #if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD)) if (follow_symlinks_specified("chmod", follow_symlinks)) - goto exit; -#endif - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - if (path.wide) - attr = GetFileAttributesW(path.wide); - else - attr = GetFileAttributesA(path.narrow); + return NULL; +#endif + +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + if (path->wide) + attr = GetFileAttributesW(path->wide); + else + attr = GetFileAttributesA(path->narrow); if (attr == INVALID_FILE_ATTRIBUTES) result = 0; else { @@ -2929,26 +3260,25 @@ else attr |= FILE_ATTRIBUTE_READONLY; if (path.wide) - result = SetFileAttributesW(path.wide, attr); + result = SetFileAttributesW(path->wide, attr); else - result = SetFileAttributesA(path.narrow, attr); + result = SetFileAttributesA(path->narrow, attr); } Py_END_ALLOW_THREADS if (!result) { - return_value = path_error(&path); - goto exit; + return path_error(path); } #else /* MS_WINDOWS */ Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHMOD - if (path.fd != -1) - result = fchmod(path.fd, mode); + if (path->fd != -1) + result = fchmod(path->fd, mode); else #endif #ifdef HAVE_LCHMOD if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = lchmod(path.narrow, mode); + result = lchmod(path->narrow, mode); else #endif #ifdef HAVE_FCHMODAT @@ -2963,7 +3293,7 @@ * support dir_fd and follow_symlinks=False. (Hopefully.) * Until then, we need to be careful what exception we raise. */ - result = fchmodat(dir_fd, path.narrow, mode, + result = fchmodat(dir_fd, path->narrow, mode, follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); /* * But wait! We can't throw the exception without allowing threads, @@ -2976,7 +3306,7 @@ } else #endif - result = chmod(path.narrow, mode); + result = chmod(path->narrow, mode); Py_END_ALLOW_THREADS if (result) { @@ -2990,31 +3320,62 @@ } else #endif - return_value = path_error(&path); - goto exit; - } -#endif - - Py_INCREF(Py_None); - return_value = Py_None; -exit: - path_cleanup(&path); - return return_value; + return path_error(path); + } +#endif + + Py_RETURN_NONE; } #ifdef HAVE_FCHMOD -PyDoc_STRVAR(posix_fchmod__doc__, -"fchmod(fd, mode)\n\n\ -Change the access permissions of the file given by file\n\ -descriptor fd. Equivalent to os.chmod(fd, mode)."); - -static PyObject * -posix_fchmod(PyObject *self, PyObject *args) -{ - int fd, mode, res; - if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode)) - return NULL; + +/*[clinic input] +os.fchmod + + fd: int + mode: int + +Change the access permissions of the file given by file descriptor fd. + +Equivalent to os.chmod(fd, mode). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fchmod__doc__, +"sig=($module, fd, mode)\n" +"Change the access permissions of the file given by file descriptor fd.\n" +"\n" +"Equivalent to os.chmod(fd, mode)."); + +#define OS_FCHMOD_METHODDEF \ + {"fchmod", (PyCFunction)os_fchmod, METH_VARARGS|METH_KEYWORDS, os_fchmod__doc__}, + +static PyObject * +os_fchmod_impl(PyModuleDef *module, int fd, int mode); + +static PyObject * +os_fchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "mode", NULL}; + int fd; + int mode; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "ii:fchmod", _keywords, + &fd, &mode)) + goto exit; + return_value = os_fchmod_impl(module, fd, mode); + +exit: + return return_value; +} + +static PyObject * +os_fchmod_impl(PyModuleDef *module, int fd, int mode) +/*[clinic end generated code: output=e7f7b5df88bef1b7 input=8ab11975ca01ee5b]*/ +{ + int res; Py_BEGIN_ALLOW_THREADS res = fchmod(fd, mode); Py_END_ALLOW_THREADS @@ -3022,165 +3383,369 @@ return posix_error(); Py_RETURN_NONE; } +#else /* HAVE_FCHMOD */ +#define OS_FCHMOD_METHODDEF #endif /* HAVE_FCHMOD */ #ifdef HAVE_LCHMOD PyDoc_STRVAR(posix_lchmod__doc__, -"lchmod(path, mode)\n\n\ -Change the access permissions of a file. If path is a symlink, this\n\ -affects the link itself rather than the target.\n\ -Equivalent to chmod(path, mode, follow_symlinks=False)."); - -static PyObject * -posix_lchmod(PyObject *self, PyObject *args) -{ - path_t path; - int i; + +/*[clinic input] +os.lchmod + + path: path_t + mode: int + +Change the access permissions of a file, without following symbolic links. + +If path is a symlink, this affects the link itself rather than the target. +Equivalent to chmod(path, mode, follow_symlinks=False)." +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lchmod__doc__, +"sig=($module, path, mode)\n" +"Change the access permissions of a file, without following symbolic links.\n" +"\n" +"If path is a symlink, this affects the link itself rather than the target.\n" +"Equivalent to chmod(path, mode, follow_symlinks=False).\""); + +#define OS_LCHMOD_METHODDEF \ + {"lchmod", (PyCFunction)os_lchmod, METH_VARARGS|METH_KEYWORDS, os_lchmod__doc__}, + +static PyObject * +os_lchmod_impl(PyModuleDef *module, path_t *path, int mode); + +static PyObject * +os_lchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", NULL}; + path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); + int mode; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&i:lchmod", _keywords, + path_converter, &path, &mode)) + goto exit; + return_value = os_lchmod_impl(module, &path, mode); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_lchmod_impl(PyModuleDef *module, path_t *path, int mode) +/*[clinic end generated code: output=1895413dd4a08e69 input=90c5663c7465d24f]*/ +{ int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchmod"; - if (!PyArg_ParseTuple(args, "O&i:lchmod", - path_converter, &path, &i)) - return NULL; Py_BEGIN_ALLOW_THREADS res = lchmod(path.narrow, i); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; - } - path_cleanup(&path); + path_error(path); + return NULL; + } Py_RETURN_NONE; } +#else /* HAVE_LCHMOD */ +#define OS_LCHMOD_METHODDEF #endif /* HAVE_LCHMOD */ #ifdef HAVE_CHFLAGS -PyDoc_STRVAR(posix_chflags__doc__, -"chflags(path, flags, *, follow_symlinks=True)\n\n\ -Set file flags.\n\ -\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, chflags will change flags on the symbolic link itself instead of the\n\ - file the link points to.\n\ -follow_symlinks may not be implemented on your platform. If it is\n\ -unavailable, using it will raise a NotImplementedError."); - -static PyObject * -posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; + +/*[clinic input] +os.chflags + + path: path_t + flags: unsigned_long(bitwise=True) + follow_symlinks: bool=True + +Set file flags. + +If follow_symlinks is False, and the last element of the path is a symbolic + link, chflags will change flags on the symbolic link itself instead of the + file the link points to. +follow_symlinks may not be implemented on your platform. If it is +unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chflags__doc__, +"sig=($module, path, flags, follow_symlinks=True)\n" +"Set file flags.\n" +"\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, chflags will change flags on the symbolic link itself instead of the\n" +" file the link points to.\n" +"follow_symlinks may not be implemented on your platform. If it is\n" +"unavailable, using it will raise a NotImplementedError."); + +#define OS_CHFLAGS_METHODDEF \ + {"chflags", (PyCFunction)os_chflags, METH_VARARGS|METH_KEYWORDS, os_chflags__doc__}, + +static PyObject * +os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks); + +static PyObject * +os_chflags(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); unsigned long flags; int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&k|p:chflags", _keywords, + path_converter, &path, &flags, &follow_symlinks)) + goto exit; + return_value = os_chflags_impl(module, &path, flags, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks) +/*[clinic end generated code: output=10b1e0d25980a567 input=0327e29feb876236]*/ +{ + int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "flags", "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "chflags"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords, - path_converter, &path, - &flags, &follow_symlinks)) - return NULL; #ifndef HAVE_LCHFLAGS if (follow_symlinks_specified("chflags", follow_symlinks)) - goto exit; + return NULL; #endif Py_BEGIN_ALLOW_THREADS #ifdef HAVE_LCHFLAGS if (!follow_symlinks) - result = lchflags(path.narrow, flags); - else -#endif - result = chflags(path.narrow, flags); - Py_END_ALLOW_THREADS - - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); - -exit: + result = lchflags(path->narrow, flags); + else +#endif + result = chflags(path->narrow, flags); + Py_END_ALLOW_THREADS + + if (result) + return path_error(path); + + Py_RETURN_NONE; +} +#else /* HAVE_CHFLAGS */ +#define OS_CHFLAGS_METHODDEF +#endif /* HAVE_CHFLAGS */ + +#ifdef HAVE_LCHFLAGS + +/*[clinic input] +os.lchflags + + path: path_t + flags: unsigned_long(bitwise=True) + +Set file flags. + +This function will not follow symbolic links. +Equivalent to chflags(path, flags, follow_symlinks=False). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lchflags__doc__, +"sig=($module, path, flags)\n" +"Set file flags.\n" +"\n" +"This function will not follow symbolic links.\n" +"Equivalent to chflags(path, flags, follow_symlinks=False)."); + +#define OS_LCHFLAGS_METHODDEF \ + {"lchflags", (PyCFunction)os_lchflags, METH_VARARGS|METH_KEYWORDS, os_lchflags__doc__}, + +static PyObject * +os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags); + +static PyObject * +os_lchflags(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", NULL}; + path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); + unsigned long flags; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&k:lchflags", _keywords, + path_converter, &path, &flags)) + goto exit; + return_value = os_lchflags_impl(module, &path, flags); + +exit: + /* Cleanup for path */ path_cleanup(&path); - return return_value; -} -#endif /* HAVE_CHFLAGS */ - -#ifdef HAVE_LCHFLAGS -PyDoc_STRVAR(posix_lchflags__doc__, -"lchflags(path, flags)\n\n\ -Set file flags.\n\ -This function will not follow symbolic links.\n\ -Equivalent to chflags(path, flags, follow_symlinks=False)."); - -static PyObject * -posix_lchflags(PyObject *self, PyObject *args) -{ - path_t path; - unsigned long flags; + + return return_value; +} + +static PyObject * +os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags) +/*[clinic end generated code: output=84d5bc89d22c99b8 input=f9f82ea8b585ca9d]*/ +{ int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchflags"; - if (!PyArg_ParseTuple(args, "O&k:lchflags", - path_converter, &path, &flags)) - return NULL; Py_BEGIN_ALLOW_THREADS res = lchflags(path.narrow, flags); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; - } + return path_error(path); + } + Py_RETURN_NONE; +} +#else /* HAVE_LCHFLAGS */ +#define OS_LCHFLAGS_METHODDEF +#endif /* HAVE_LCHFLAGS */ + +#ifdef HAVE_CHROOT + +/*[clinic input] +os.chroot + path: path_t + +Change root directory to path. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chroot__doc__, +"sig=($module, path)\n" +"Change root directory to path."); + +#define OS_CHROOT_METHODDEF \ + {"chroot", (PyCFunction)os_chroot, METH_VARARGS|METH_KEYWORDS, os_chroot__doc__}, + +static PyObject * +os_chroot_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_chroot(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:chroot", _keywords, + path_converter, &path)) + goto exit; + return_value = os_chroot_impl(module, &path); + +exit: + /* Cleanup for path */ path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chroot_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=2c2749adadc09b0f input=14822965652c3dc3]*/ +{ + int res; + Py_BEGIN_ALLOW_THREADS + res = chroot(path->narrow); + Py_END_ALLOW_THREADS + if (res < 0) + return path_error(path); Py_RETURN_NONE; } -#endif /* HAVE_LCHFLAGS */ - -#ifdef HAVE_CHROOT -PyDoc_STRVAR(posix_chroot__doc__, -"chroot(path)\n\n\ -Change root directory to path."); - -static PyObject * -posix_chroot(PyObject *self, PyObject *args) -{ - return posix_1str("chroot", args, "O&:chroot", chroot); -} -#endif +#else /* HAVE_CHROOT */ +#define OS_CHROOT_METHODDEF +#endif /* HAVE_CHROOT */ #ifdef HAVE_FSYNC -PyDoc_STRVAR(posix_fsync__doc__, -"fsync(fildes)\n\n\ -force write of file with filedescriptor to disk."); - -static PyObject * -posix_fsync(PyObject *self, PyObject *fdobj) -{ - return posix_fildes(fdobj, fsync); -} + +/*[clinic input] +os.fsync + + fd: fildes + +Force write of fd to disk. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fsync__doc__, +"sig=($module, fd)\n" +"Force write of fd to disk."); + +#define OS_FSYNC_METHODDEF \ + {"fsync", (PyCFunction)os_fsync, METH_VARARGS|METH_KEYWORDS, os_fsync__doc__}, + +static PyObject * +os_fsync_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fsync(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:fsync", _keywords, + fildes_converter, &fd)) + goto exit; + return_value = os_fsync_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_fsync_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=175c2435739bce17 input=21c3645c056967f2]*/ +{ + return posix_fildes_fd(fd, fsync); +} +#else /* HAVE_FSYNC */ +#define OS_FSYNC_METHODDEF #endif /* HAVE_FSYNC */ #ifdef HAVE_SYNC -PyDoc_STRVAR(posix_sync__doc__, -"sync()\n\n\ -Force write of everything to disk."); - -static PyObject * -posix_sync(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.sync + +Force write of everything to disk. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sync__doc__, +"sig=($module)\n" +"Force write of everything to disk."); + +#define OS_SYNC_METHODDEF \ + {"sync", (PyCFunction)os_sync, METH_NOARGS, os_sync__doc__}, + +static PyObject * +os_sync_impl(PyModuleDef *module); + +static PyObject * +os_sync(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_sync_impl(module); +} + +static PyObject * +os_sync_impl(PyModuleDef *module) +/*[clinic end generated code: output=9c28ad3adf769e16 input=84749fe5e9b404ff]*/ { Py_BEGIN_ALLOW_THREADS sync(); Py_END_ALLOW_THREADS Py_RETURN_NONE; } -#endif +#else /* HAVE_SYNC */ +#define OS_SYNC_METHODDEF +#endif /* HAVE_SYNC */ #ifdef HAVE_FDATASYNC @@ -3188,74 +3753,166 @@ extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ #endif -PyDoc_STRVAR(posix_fdatasync__doc__, -"fdatasync(fildes)\n\n\ -force write of file with filedescriptor to disk.\n\ - does not force update of metadata."); - -static PyObject * -posix_fdatasync(PyObject *self, PyObject *fdobj) -{ - return posix_fildes(fdobj, fdatasync); -} + +/*[clinic input] +os.fdatasync + + fd: fildes + +Force write of fd to disk without forcing update of metadata. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fdatasync__doc__, +"sig=($module, fd)\n" +"Force write of fd to disk without forcing update of metadata."); + +#define OS_FDATASYNC_METHODDEF \ + {"fdatasync", (PyCFunction)os_fdatasync, METH_VARARGS|METH_KEYWORDS, os_fdatasync__doc__}, + +static PyObject * +os_fdatasync_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fdatasync(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:fdatasync", _keywords, + fildes_converter, &fd)) + goto exit; + return_value = os_fdatasync_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_fdatasync_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=82ab3ec8d2b1be43 input=bc74791ee54dd291]*/ +{ + return posix_fildes_fd(fd, fdatasync); +} +#else /* HAVE_FDATASYNC */ +#define OS_FDATASYNC_METHODDEF #endif /* HAVE_FDATASYNC */ #ifdef HAVE_CHOWN -PyDoc_STRVAR(posix_chown__doc__, -"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\ -Change the owner and group id of path to the numeric uid and gid.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception.\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, chown will modify the symbolic link itself instead of the file the\n\ - link points to.\n\ -It is an error to use dir_fd or follow_symlinks when specifying path as\n\ - an open file descriptor.\n\ -dir_fd and follow_symlinks may not be implemented on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); - -static PyObject * -posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; + +/*[clinic input] +os.chown + + path : path_t(allow_fd='PATH_HAVE_FCHOWN') + Path to be examined; can be string, bytes, or open-file-descriptor int. + + uid: uid_t + + gid: gid_t + + * + + dir_fd : dir_fd(requires='fchownat') = None + If not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that + directory. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + stat will examine the symbolic link itself instead of the file + the link points to. + + +Change the owner and group id of path to the numeric uid and gid.\ + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, chown will modify the symbolic link itself instead of the file the + link points to. +It is an error to use dir_fd or follow_symlinks when specifying path as + an open file descriptor. +dir_fd and follow_symlinks may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chown__doc__, +"sig=($module, path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n" +"Change the owner and group id of path to the numeric uid and gid.\\\n" +"\n" +" path\n" +" Path to be examined; can be string, bytes, or open-file-descriptor int.\n" +" dir_fd\n" +" If not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that\n" +" directory.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" stat will examine the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, chown will modify the symbolic link itself instead of the file the\n" +" link points to.\n" +"It is an error to use dir_fd or follow_symlinks when specifying path as\n" +" an open file descriptor.\n" +"dir_fd and follow_symlinks may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_CHOWN_METHODDEF \ + {"chown", (PyCFunction)os_chown, METH_VARARGS|METH_KEYWORDS, os_chown__doc__}, + +static PyObject * +os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks); + +static PyObject * +os_chown(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); uid_t uid; gid_t gid; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&O&|$O&p:chown", _keywords, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid, FCHOWNAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + return_value = os_chown_impl(module, &path, uid, gid, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=a370372e80201d10 input=5623b3e0cc2b7b9a]*/ +{ int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "uid", "gid", "dir_fd", - "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "chown"; -#ifdef HAVE_FCHOWN - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords, - path_converter, &path, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid, -#ifdef HAVE_FCHOWNAT - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks)) - return NULL; #if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT)) if (follow_symlinks_specified("chown", follow_symlinks)) - goto exit; -#endif - if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) || - fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks)) - goto exit; + return NULL; +#endif + if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) || + fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks)) + return NULL; #ifdef __APPLE__ /* @@ -3266,61 +3923,89 @@ */ if ((!follow_symlinks) && (lchown == NULL)) { follow_symlinks_specified("chown", follow_symlinks); - goto exit; + return NULL; } #endif Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHOWN - if (path.fd != -1) - result = fchown(path.fd, uid, gid); + if (path->fd != -1) + result = fchown(path->fd, uid, gid); else #endif #ifdef HAVE_LCHOWN if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = lchown(path.narrow, uid, gid); + result = lchown(path->narrow, uid, gid); else #endif #ifdef HAVE_FCHOWNAT if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) - result = fchownat(dir_fd, path.narrow, uid, gid, + result = fchownat(dir_fd, path->narrow, uid, gid, follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); else #endif - result = chown(path.narrow, uid, gid); - Py_END_ALLOW_THREADS - - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); - -exit: - path_cleanup(&path); - return return_value; -} + result = chown(path->narrow, uid, gid); + Py_END_ALLOW_THREADS + + if (result) + return path_error(path); + + Py_RETURN_NONE; +} +#else /* HAVE_CHOWN */ +#define OS_CHOWN_METHODDEF #endif /* HAVE_CHOWN */ #ifdef HAVE_FCHOWN -PyDoc_STRVAR(posix_fchown__doc__, -"fchown(fd, uid, gid)\n\n\ -Change the owner and group id of the file given by file descriptor\n\ -fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid)."); - -static PyObject * -posix_fchown(PyObject *self, PyObject *args) -{ +/*[clinic input] +os.fchown + + fd: int + uid: uid_t + gid: gid_t + +Change the owner and group id of the file specified by file descriptor. + +Equivalent to os.chown(fd, uid, gid). + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fchown__doc__, +"sig=($module, fd, uid, gid)\n" +"Change the owner and group id of the file specified by file descriptor.\n" +"\n" +"Equivalent to os.chown(fd, uid, gid)."); + +#define OS_FCHOWN_METHODDEF \ + {"fchown", (PyCFunction)os_fchown, METH_VARARGS|METH_KEYWORDS, os_fchown__doc__}, + +static PyObject * +os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid); + +static PyObject * +os_fchown(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "uid", "gid", NULL}; int fd; uid_t uid; gid_t gid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "iO&O&:fchown", _keywords, + &fd, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) + goto exit; + return_value = os_fchown_impl(module, fd, uid, gid); + +exit: + return return_value; +} + +static PyObject * +os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid) +/*[clinic end generated code: output=41e1ed412d50003c input=3af544ba1b13a0d7]*/ +{ int res; - if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid)) - return NULL; Py_BEGIN_ALLOW_THREADS res = fchown(fd, uid, gid); Py_END_ALLOW_THREADS @@ -3328,41 +4013,75 @@ return posix_error(); Py_RETURN_NONE; } +#else /* HAVE_FCHOWN */ +#define OS_FCHOWN_METHODDEF #endif /* HAVE_FCHOWN */ #ifdef HAVE_LCHOWN -PyDoc_STRVAR(posix_lchown__doc__, -"lchown(path, uid, gid)\n\n\ -Change the owner and group id of path to the numeric uid and gid.\n\ -This function will not follow symbolic links.\n\ -Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); - -static PyObject * -posix_lchown(PyObject *self, PyObject *args) -{ - path_t path; + +/*[clinic input] +os.lchown + + path : path_t + uid: uid_t + gid: gid_t + +Change the owner and group id of path to the numeric uid and gid. + +This function will not follow symbolic links. +Equivalent to os.chown(path, uid, gid, follow_symlinks=False). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lchown__doc__, +"sig=($module, path, uid, gid)\n" +"Change the owner and group id of path to the numeric uid and gid.\n" +"\n" +"This function will not follow symbolic links.\n" +"Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); + +#define OS_LCHOWN_METHODDEF \ + {"lchown", (PyCFunction)os_lchown, METH_VARARGS|METH_KEYWORDS, os_lchown__doc__}, + +static PyObject * +os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid); + +static PyObject * +os_lchown(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "uid", "gid", NULL}; + path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); uid_t uid; gid_t gid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&O&:lchown", _keywords, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) + goto exit; + return_value = os_lchown_impl(module, &path, uid, gid); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid) +/*[clinic end generated code: output=f369a20d9a094b11 input=b1c6014d563a7161]*/ +{ int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchown"; - if (!PyArg_ParseTuple(args, "O&O&O&:lchown", - path_converter, &path, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = lchown(path.narrow, uid, gid); + Py_BEGIN_ALLOW_THREADS + res = lchown(path->narrow, uid, gid); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; - } - path_cleanup(&path); - Py_INCREF(Py_None); - return Py_None; -} + return path_error(path); + } + Py_RETURN_NONE; +} +#else /* HAVE_LCHOWN */ +#define OS_LCHOWN_METHODDEF #endif /* HAVE_LCHOWN */ @@ -3418,22 +4137,62 @@ return PyUnicode_DecodeFSDefault(buf); } -PyDoc_STRVAR(posix_getcwd__doc__, -"getcwd() -> path\n\n\ -Return a unicode string representing the current working directory."); - -static PyObject * -posix_getcwd_unicode(PyObject *self) + +/*[clinic input] +os.getcwd + +Return a unicode string representing the current working directory. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getcwd__doc__, +"sig=($module)\n" +"Return a unicode string representing the current working directory."); + +#define OS_GETCWD_METHODDEF \ + {"getcwd", (PyCFunction)os_getcwd, METH_NOARGS, os_getcwd__doc__}, + +static PyObject * +os_getcwd_impl(PyModuleDef *module); + +static PyObject * +os_getcwd(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getcwd_impl(module); +} + +static PyObject * +os_getcwd_impl(PyModuleDef *module) +/*[clinic end generated code: output=ee5bfe9fe6ef34ca input=f069211bb70e3d39]*/ { return posix_getcwd(0); } -PyDoc_STRVAR(posix_getcwdb__doc__, -"getcwdb() -> path\n\n\ -Return a bytes string representing the current working directory."); - -static PyObject * -posix_getcwd_bytes(PyObject *self) + +/*[clinic input] +os.getcwdb + +Return a bytes string representing the current working directory. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getcwdb__doc__, +"sig=($module)\n" +"Return a bytes string representing the current working directory."); + +#define OS_GETCWDB_METHODDEF \ + {"getcwdb", (PyCFunction)os_getcwdb, METH_NOARGS, os_getcwdb__doc__}, + +static PyObject * +os_getcwdb_impl(PyModuleDef *module); + +static PyObject * +os_getcwdb(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getcwdb_impl(module); +} + +static PyObject * +os_getcwdb_impl(PyModuleDef *module) +/*[clinic end generated code: output=f3276894e6ba255c input=f6f6a378dad3d9cb]*/ { return posix_getcwd(1); } @@ -3443,123 +4202,143 @@ #endif #ifdef HAVE_LINK -PyDoc_STRVAR(posix_link__doc__, -"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\ -Create a hard link to a file.\n\ -\n\ -If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ - descriptor open to a directory, and the respective path string (src or dst)\n\ - should be relative; the path will then be relative to that directory.\n\ -If follow_symlinks is False, and the last element of src is a symbolic\n\ - link, link will create a link to the symbolic link itself instead of the\n\ - file the link points to.\n\ -src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\ - platform. If they are unavailable, using them will raise a\n\ - NotImplementedError."); - -static PyObject * -posix_link(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t src, dst; + +/*[clinic input] + +os.link + + src : path_t + dst : path_t + + * + + src_dir_fd : dir_fd = None + dst_dir_fd : dir_fd = None + + follow_symlinks: bool = True + +Create a hard link to a file. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +If follow_symlinks is False, and the last element of src is a symbolic + link, link will create a link to the symbolic link itself instead of the + file the link points to. +src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your + platform. If they are unavailable, using them will raise a + NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_link__doc__, +"sig=($module, src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n" +"Create a hard link to a file.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of src is a symbolic\n" +" link, link will create a link to the symbolic link itself instead of the\n" +" file the link points to.\n" +"src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n" +" platform. If they are unavailable, using them will raise a\n" +" NotImplementedError."); + +#define OS_LINK_METHODDEF \ + {"link", (PyCFunction)os_link, METH_VARARGS|METH_KEYWORDS, os_link__doc__}, + +static PyObject * +os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks); + +static PyObject * +os_link(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; + path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - PyObject *return_value = NULL; - static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", - "follow_symlinks", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$O&O&p:link", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd, &follow_symlinks)) + goto exit; + return_value = os_link_impl(module, &src, &dst, src_dir_fd, dst_dir_fd, follow_symlinks); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +static PyObject * +os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks) +/*[clinic end generated code: output=a6323597681269ac input=4af89d5102b41368]*/ +{ #ifdef MS_WINDOWS BOOL result; #else int result; #endif - memset(&src, 0, sizeof(src)); - memset(&dst, 0, sizeof(dst)); - src.function_name = "link"; - dst.function_name = "link"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords, - path_converter, &src, - path_converter, &dst, - dir_fd_converter, &src_dir_fd, - dir_fd_converter, &dst_dir_fd, - &follow_symlinks)) - return NULL; - #ifndef HAVE_LINKAT if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) { argument_unavailable_error("link", "src_dir_fd and dst_dir_fd"); - goto exit; - } -#endif - - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + return NULL; + } +#endif + + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_SetString(PyExc_NotImplementedError, "link: src and dst must be the same type"); - goto exit; - } - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - if (src.wide) - result = CreateHardLinkW(dst.wide, src.wide, NULL); - else - result = CreateHardLinkA(dst.narrow, src.narrow, NULL); - Py_END_ALLOW_THREADS - - if (!result) { - return_value = path_error(&src); - goto exit; - } + return NULL; + } + +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + if (src->wide) + result = CreateHardLinkW(dst->wide, src->wide, NULL); + else + result = CreateHardLinkA(dst->narrow, src->narrow, NULL); + Py_END_ALLOW_THREADS + + if (!result) + return path_error(src); #else Py_BEGIN_ALLOW_THREADS #ifdef HAVE_LINKAT if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) - result = linkat(src_dir_fd, src.narrow, - dst_dir_fd, dst.narrow, + result = linkat(src_dir_fd, src->narrow, + dst_dir_fd, dst->narrow, follow_symlinks ? AT_SYMLINK_FOLLOW : 0); else #endif - result = link(src.narrow, dst.narrow); - Py_END_ALLOW_THREADS - - if (result) { - return_value = path_error(&src); - goto exit; - } -#endif - - return_value = Py_None; - Py_INCREF(Py_None); - -exit: - path_cleanup(&src); - path_cleanup(&dst); - return return_value; -} -#endif - - - -PyDoc_STRVAR(posix_listdir__doc__, -"listdir(path='.') -> list_of_filenames\n\n\ -Return a list containing the names of the files in the directory.\n\ -The list is in arbitrary order. It does not include the special\n\ -entries '.' and '..' even if they are present in the directory.\n\ -\n\ -path can be specified as either str or bytes. If path is bytes,\n\ - the filenames returned will also be bytes; in all other circumstances\n\ - the filenames returned will be str.\n\ -On some platforms, path may also be specified as an open file descriptor;\n\ - the file descriptor must refer to a directory.\n\ - If this functionality is unavailable, using it raises NotImplementedError."); + result = link(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + + if (result) + return path_error(src); +#endif + + Py_RETURN_NONE; +} +#else /* HAVE_LINK */ +#define OS_LINK_METHODDEF +#endif /* HAVE_LINK */ + #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) static PyObject * _listdir_windows_no_opendir(path_t *path, PyObject *list) { - static char *keywords[] = {"path", NULL}; PyObject *v; HANDLE hFindFile = INVALID_HANDLE_VALUE; BOOL result; @@ -3818,38 +4597,82 @@ } /* end of _posix_listdir */ #endif /* which OS */ -static PyObject * -posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - PyObject *list = NULL; - static char *keywords[] = {"path", NULL}; - PyObject *return_value; - - memset(&path, 0, sizeof(path)); - path.function_name = "listdir"; - path.nullable = 1; -#ifdef HAVE_FDOPENDIR - path.allow_fd = 1; - path.fd = -1; -#endif - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords, - path_converter, &path)) { - return NULL; - } - +/*[clinic input] +os.listdir + + path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None + +Return a list containing the names of the files in the directory. + +path can be specified as either str or bytes. If path is bytes, + the filenames returned will also be bytes; in all other circumstances + the filenames returned will be str. +If path is None, uses the path='.'. +On some platforms, path may also be specified as an open file descriptor;\ + the file descriptor must refer to a directory. + If this functionality is unavailable, using it raises NotImplementedError. + +The list is in arbitrary order. It does not include the special +entries '.' and '..' even if they are present in the directory. + + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_listdir__doc__, +"sig=($module, path=None)\n" +"Return a list containing the names of the files in the directory.\n" +"\n" +"path can be specified as either str or bytes. If path is bytes,\n" +" the filenames returned will also be bytes; in all other circumstances\n" +" the filenames returned will be str.\n" +"If path is None, uses the path=\'.\'.\n" +"On some platforms, path may also be specified as an open file descriptor;\\\n" +" the file descriptor must refer to a directory.\n" +" If this functionality is unavailable, using it raises NotImplementedError.\n" +"\n" +"The list is in arbitrary order. It does not include the special\n" +"entries \'.\' and \'..\' even if they are present in the directory."); + +#define OS_LISTDIR_METHODDEF \ + {"listdir", (PyCFunction)os_listdir, METH_VARARGS|METH_KEYWORDS, os_listdir__doc__}, + +static PyObject * +os_listdir_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_listdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O&:listdir", _keywords, + path_converter, &path)) + goto exit; + return_value = os_listdir_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_listdir_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=9495356126102470 input=09e300416e3cd729]*/ +{ #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) - return_value = _listdir_windows_no_opendir(&path, list); -#else - return_value = _posix_listdir(&path, list); -#endif - path_cleanup(&path); - return return_value; + return _listdir_windows_no_opendir(path, NULL); +#else + return _posix_listdir(path, NULL); +#endif } #ifdef MS_WINDOWS /* A helper function for abspath on win32 */ +/* AC 3.5: probably just convert to using path converter */ static PyObject * posix__getfullpathname(PyObject *self, PyObject *args) { @@ -3905,25 +4728,58 @@ Py_FileSystemDefaultEncoding, NULL); } return PyBytes_FromString(outbuf); -} /* end of posix__getfullpathname */ - - - -/* A helper function for samepath on windows */ -static PyObject * -posix__getfinalpathname(PyObject *self, PyObject *args) +} + + + +/*[clinic input] +os._getfinalpathname + + path: unicode + / + +A helper function for samepath on windows. +[clinic start generated code]*/ + +PyDoc_STRVAR(os__getfinalpathname__doc__, +"sig=($module, path)\n" +"A helper function for samepath on windows."); + +#define OS__GETFINALPATHNAME_METHODDEF \ + {"_getfinalpathname", (PyCFunction)os__getfinalpathname, METH_VARARGS, os__getfinalpathname__doc__}, + +static PyObject * +os__getfinalpathname_impl(PyModuleDef *module, PyObject *path); + +static PyObject * +os__getfinalpathname(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *path; + + if (!PyArg_ParseTuple(args, + "U:_getfinalpathname", + &path)) + goto exit; + return_value = os__getfinalpathname_impl(module, path); + +exit: + return return_value; +} + +static PyObject * +os__getfinalpathname_impl(PyModuleDef *module, PyObject *path) +/*[clinic end generated code: output=e45835fe01262035 input=71d5e89334891bf4]*/ { HANDLE hFile; int buf_size; wchar_t *target_path; int result_length; - PyObject *po, *result; + PyObject *result; wchar_t *path; - if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po)) - return NULL; - path = PyUnicode_AsUnicode(po); - if (path == NULL) + path_wchar = PyUnicode_AsUnicode(path); + if (path_wchar == NULL) return NULL; if(!check_GetFinalPathNameByHandle()) { @@ -3934,7 +4790,7 @@ } hFile = CreateFileW( - path, + path_wchar, 0, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ @@ -3944,14 +4800,14 @@ NULL); if(hFile == INVALID_HANDLE_VALUE) - return win32_error_object("CreateFileW", po); + return win32_error_object("CreateFileW", path); /* We have a good handle to the target, use it to determine the target path name. */ buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT); if(!buf_size) - return win32_error_object("GetFinalPathNameByHandle", po); + return win32_error_object("GetFinalPathNameByHandle", path); target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t)); if(!target_path) @@ -3960,21 +4816,22 @@ result_length = Py_GetFinalPathNameByHandleW(hFile, target_path, buf_size, VOLUME_NAME_DOS); if(!result_length) - return win32_error_object("GetFinalPathNamyByHandle", po); + return win32_error_object("GetFinalPathNamyByHandle", path); if(!CloseHandle(hFile)) - return win32_error_object("CloseHandle", po); + return win32_error_object("CloseHandle", path); target_path[result_length] = 0; result = PyUnicode_FromWideChar(target_path, result_length); PyMem_Free(target_path); return result; - -} /* end of posix__getfinalpathname */ +} PyDoc_STRVAR(posix__isdir__doc__, -"Return true if the pathname refers to an existing directory."); - +"sig=($module, path)\n" +"Return True if path refers to an existing directory."); + +/* AC 3.t: convert using path converter */ static PyObject * posix__isdir(PyObject *self, PyObject *args) { @@ -4014,19 +4871,52 @@ PyDoc_STRVAR(posix__getvolumepathname__doc__, "Return volume mount point of the specified path."); -/* A helper function for ismount on windows */ -static PyObject * -posix__getvolumepathname(PyObject *self, PyObject *args) -{ - PyObject *po, *result; - wchar_t *path, *mountpath=NULL; +/*[clinic input] +os._getvolumepathname + + path: unicode + +A helper function for ismount on Win32. +[clinic start generated code]*/ + +PyDoc_STRVAR(os__getvolumepathname__doc__, +"sig=($module, path)\n" +"A helper function for ismount on Win32."); + +#define OS__GETVOLUMEPATHNAME_METHODDEF \ + {"_getvolumepathname", (PyCFunction)os__getvolumepathname, METH_VARARGS|METH_KEYWORDS, os__getvolumepathname__doc__}, + +static PyObject * +os__getvolumepathname_impl(PyModuleDef *module, PyObject *path); + +static PyObject * +os__getvolumepathname(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + PyObject *path; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "U:_getvolumepathname", _keywords, + &path)) + goto exit; + return_value = os__getvolumepathname_impl(module, path); + +exit: + return return_value; +} + +static PyObject * +os__getvolumepathname_impl(PyModuleDef *module, PyObject *path) +/*[clinic end generated code: output=4e21cb984d4e1bc8 input=7eacadc40acbda6b]*/ +{ + PyObject *result; + wchar_t *path_wchar, *mountpath=NULL; size_t buflen; BOOL ret; - if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po)) - return NULL; - path = PyUnicode_AsUnicodeAndSize(po, &buflen); - if (path == NULL) + path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen); + if (path_wchar == NULL) return NULL; buflen += 1; @@ -4043,12 +4933,12 @@ return PyErr_NoMemory(); Py_BEGIN_ALLOW_THREADS - ret = GetVolumePathNameW(path, mountpath, + ret = GetVolumePathNameW(path_wchar, mountpath, Py_SAFE_DOWNCAST(buflen, size_t, DWORD)); Py_END_ALLOW_THREADS if (!ret) { - result = win32_error_object("_getvolumepathname", po); + result = win32_error_object("_getvolumepathname", path); goto exit; } result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); @@ -4057,78 +4947,109 @@ PyMem_Free(mountpath); return result; } -/* end of posix__getvolumepathname */ - + +#else /* MS_WINDOWS */ +#define OS__GETFINALPATHNAME_METHODDEF +#define OS__GETVOLUMEPATHNAME_METHODDEF #endif /* MS_WINDOWS */ -PyDoc_STRVAR(posix_mkdir__doc__, -"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\ -Create a directory.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError.\n\ -\n\ -The mode argument is ignored on Windows."); - -static PyObject * -posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - int mode = 0777; + +/*[clinic input] +os.mkdir + + path : path_t + + mode: int = 0o777 + + * + + dir_fd : dir_fd(requires='mkdirat') = None + +# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\ + +Create a directory. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +The mode argument is ignored on Windows. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_mkdir__doc__, +"sig=($module, path, mode=511, *, dir_fd=None)\n" +"Create a directory.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError.\n" +"\n" +"The mode argument is ignored on Windows."); + +#define OS_MKDIR_METHODDEF \ + {"mkdir", (PyCFunction)os_mkdir, METH_VARARGS|METH_KEYWORDS, os_mkdir__doc__}, + +static PyObject * +os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd); + +static PyObject * +os_mkdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); + int mode = 511; int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "mode", "dir_fd", NULL}; - PyObject *return_value = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|i$O&:mkdir", _keywords, + path_converter, &path, &mode, MKDIRAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_mkdir_impl(module, &path, mode, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd) +/*[clinic end generated code: output=9b47dc5ebb72b0c8 input=e965f68377e9b1ce]*/ +{ int result; - memset(&path, 0, sizeof(path)); - path.function_name = "mkdir"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords, - path_converter, &path, &mode, -#ifdef HAVE_MKDIRAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - if (path.wide) - result = CreateDirectoryW(path.wide, NULL); - else - result = CreateDirectoryA(path.narrow, NULL); - Py_END_ALLOW_THREADS - - if (!result) { - return_value = path_error(&path); - goto exit; - } +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + if (path->wide) + result = CreateDirectoryW(path->wide, NULL); + else + result = CreateDirectoryA(path->narrow, NULL); + Py_END_ALLOW_THREADS + + if (!result) + return path_error(path); #else Py_BEGIN_ALLOW_THREADS #if HAVE_MKDIRAT if (dir_fd != DEFAULT_DIR_FD) - result = mkdirat(dir_fd, path.narrow, mode); + result = mkdirat(dir_fd, path->narrow, mode); else #endif #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__) - result = mkdir(path.narrow); -#else - result = mkdir(path.narrow, mode); -#endif - Py_END_ALLOW_THREADS - if (result < 0) { - return_value = path_error(&path); - goto exit; - } -#endif - return_value = Py_None; - Py_INCREF(Py_None); -exit: - path_cleanup(&path); - return return_value; + result = mkdir(path->narrow); +#else + result = mkdir(path->narrow, mode); +#endif + Py_END_ALLOW_THREADS + if (result < 0) + return path_error(path); +#endif + + Py_RETURN_NONE; } @@ -4139,17 +5060,47 @@ #ifdef HAVE_NICE -PyDoc_STRVAR(posix_nice__doc__, -"nice(inc) -> new_priority\n\n\ -Decrease the priority of process by inc and return the new priority."); - -static PyObject * -posix_nice(PyObject *self, PyObject *args) -{ - int increment, value; - - if (!PyArg_ParseTuple(args, "i:nice", &increment)) - return NULL; + +/*[clinic input] +os.nice + + increment: int + / + +Add increment to the priority of process and return the new priority. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_nice__doc__, +"sig=($module, increment)\n" +"Add increment to the priority of process and return the new priority."); + +#define OS_NICE_METHODDEF \ + {"nice", (PyCFunction)os_nice, METH_VARARGS, os_nice__doc__}, + +static PyObject * +os_nice_impl(PyModuleDef *module, int increment); + +static PyObject * +os_nice(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int increment; + + if (!PyArg_ParseTuple(args, + "i:nice", + &increment)) + goto exit; + return_value = os_nice_impl(module, increment); + +exit: + return return_value; +} + +static PyObject * +os_nice_impl(PyModuleDef *module, int increment) +/*[clinic end generated code: output=f39a91e6731412c2 input=864be2d402a21da2]*/ +{ + int value; /* There are two flavours of 'nice': one that returns the new priority (as required by almost all standards out there) and the @@ -4172,62 +5123,129 @@ return posix_error(); return PyLong_FromLong((long) value); } +#else /* HAVE_NICE */ +#define OS_NICE_METHODDEF #endif /* HAVE_NICE */ #ifdef HAVE_GETPRIORITY -PyDoc_STRVAR(posix_getpriority__doc__, -"getpriority(which, who) -> current_priority\n\n\ -Get program scheduling priority."); - -static PyObject * -posix_getpriority(PyObject *self, PyObject *args) -{ - int which, who, retval; - - if (!PyArg_ParseTuple(args, "ii", &which, &who)) - return NULL; + +/*[clinic input] +os.getpriority + + which: int + who: int + +Return program scheduling priority. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getpriority__doc__, +"sig=($module, which, who)\n" +"Return program scheduling priority."); + +#define OS_GETPRIORITY_METHODDEF \ + {"getpriority", (PyCFunction)os_getpriority, METH_VARARGS|METH_KEYWORDS, os_getpriority__doc__}, + +static PyObject * +os_getpriority_impl(PyModuleDef *module, int which, int who); + +static PyObject * +os_getpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"which", "who", NULL}; + int which; + int who; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "ii:getpriority", _keywords, + &which, &who)) + goto exit; + return_value = os_getpriority_impl(module, which, who); + +exit: + return return_value; +} + +static PyObject * +os_getpriority_impl(PyModuleDef *module, int which, int who) +/*[clinic end generated code: output=13d791b82404cb3f input=9be615d40e2544ef]*/ +{ + int retval; + errno = 0; retval = getpriority(which, who); if (errno != 0) return posix_error(); return PyLong_FromLong((long)retval); } +#else /* HAVE_GETPRIORITY */ +#define OS_GETPRIORITY_METHODDEF #endif /* HAVE_GETPRIORITY */ #ifdef HAVE_SETPRIORITY -PyDoc_STRVAR(posix_setpriority__doc__, -"setpriority(which, who, prio) -> None\n\n\ -Set program scheduling priority."); - -static PyObject * -posix_setpriority(PyObject *self, PyObject *args) -{ - int which, who, prio, retval; - - if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio)) - return NULL; - retval = setpriority(which, who, prio); + +/*[clinic input] +os.setpriority + + which: int + who: int + priority: int + +Set program scheduling priority. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setpriority__doc__, +"sig=($module, which, who, priority)\n" +"Set program scheduling priority."); + +#define OS_SETPRIORITY_METHODDEF \ + {"setpriority", (PyCFunction)os_setpriority, METH_VARARGS|METH_KEYWORDS, os_setpriority__doc__}, + +static PyObject * +os_setpriority_impl(PyModuleDef *module, int which, int who, int priority); + +static PyObject * +os_setpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"which", "who", "priority", NULL}; + int which; + int who; + int priority; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "iii:setpriority", _keywords, + &which, &who, &priority)) + goto exit; + return_value = os_setpriority_impl(module, which, who, priority); + +exit: + return return_value; +} + +static PyObject * +os_setpriority_impl(PyModuleDef *module, int which, int who, int priority) +/*[clinic end generated code: output=f71638a8eaab6afb input=710ccbf65b9dc513]*/ +{ + int retval; + + retval = setpriority(which, who, priority); if (retval == -1) return posix_error(); Py_RETURN_NONE; } +#else /* HAVE_SETPRIORITY */ +#define OS_SETPRIORITY_METHODDEF #endif /* HAVE_SETPRIORITY */ static PyObject * -internal_rename(PyObject *args, PyObject *kwargs, int is_replace) +internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace) { char *function_name = is_replace ? "replace" : "rename"; - path_t src; - path_t dst; - int src_dir_fd = DEFAULT_DIR_FD; - int dst_dir_fd = DEFAULT_DIR_FD; int dir_fd_specified; - PyObject *return_value = NULL; - char format[24]; - static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; #ifdef MS_WINDOWS BOOL result; @@ -4236,210 +5254,416 @@ int result; #endif - memset(&src, 0, sizeof(src)); - memset(&dst, 0, sizeof(dst)); - src.function_name = function_name; - dst.function_name = function_name; - strcpy(format, "O&O&|$O&O&:"); - strcat(format, function_name); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, - path_converter, &src, - path_converter, &dst, - dir_fd_converter, &src_dir_fd, - dir_fd_converter, &dst_dir_fd)) - return NULL; - dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD); #ifndef HAVE_RENAMEAT if (dir_fd_specified) { argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); - goto exit; - } -#endif - - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + return NULL; + } +#endif + + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_Format(PyExc_ValueError, "%s: src and dst must be the same type", function_name); - goto exit; - } - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - if (src.wide) - result = MoveFileExW(src.wide, dst.wide, flags); - else - result = MoveFileExA(src.narrow, dst.narrow, flags); - Py_END_ALLOW_THREADS - - if (!result) { - return_value = path_error(&src); - goto exit; - } + return NULL; + } + +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + if (src->wide) + result = MoveFileExW(src->wide, dst->wide, flags); + else + result = MoveFileExA(src->narrow, dst->narrow, flags); + Py_END_ALLOW_THREADS + + if (!result) + return path_error(src); #else Py_BEGIN_ALLOW_THREADS #ifdef HAVE_RENAMEAT if (dir_fd_specified) - result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow); - else -#endif - result = rename(src.narrow, dst.narrow); - Py_END_ALLOW_THREADS - - if (result) { - return_value = path_error(&src); - goto exit; - } -#endif - - Py_INCREF(Py_None); - return_value = Py_None; -exit: + result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow); + else +#endif + result = rename(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + + if (result) + return path_error(src); +#endif + + Py_RETURN_NONE; +} + + +/*[clinic input] + +os.rename + + src : path_t + dst : path_t + + * + + src_dir_fd : dir_fd = None + dst_dir_fd : dir_fd = None + +Rename a file or directory. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +src_dir_fd and dst_dir_fd, may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_rename__doc__, +"sig=($module, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n" +"Rename a file or directory.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_RENAME_METHODDEF \ + {"rename", (PyCFunction)os_rename, METH_VARARGS|METH_KEYWORDS, os_rename__doc__}, + +static PyObject * +os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd); + +static PyObject * +os_rename(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0); + int src_dir_fd = DEFAULT_DIR_FD; + int dst_dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$O&O&:rename", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) + goto exit; + return_value = os_rename_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); + +exit: + /* Cleanup for src */ path_cleanup(&src); + /* Cleanup for dst */ path_cleanup(&dst); - return return_value; -} - -PyDoc_STRVAR(posix_rename__doc__, -"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\ -Rename a file or directory.\n\ -\n\ -If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ - descriptor open to a directory, and the respective path string (src or dst)\n\ - should be relative; the path will then be relative to that directory.\n\ -src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); - -static PyObject * -posix_rename(PyObject *self, PyObject *args, PyObject *kwargs) -{ - return internal_rename(args, kwargs, 0); -} - -PyDoc_STRVAR(posix_replace__doc__, -"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\ -Rename a file or directory, overwriting the destination.\n\ -\n\ -If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ - descriptor open to a directory, and the respective path string (src or dst)\n\ - should be relative; the path will then be relative to that directory.\n\ -src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); - -static PyObject * -posix_replace(PyObject *self, PyObject *args, PyObject *kwargs) -{ - return internal_rename(args, kwargs, 1); -} - -PyDoc_STRVAR(posix_rmdir__doc__, -"rmdir(path, *, dir_fd=None)\n\n\ -Remove a directory.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); - -static PyObject * -posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; + + return return_value; +} + +static PyObject * +os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd) +/*[clinic end generated code: output=d8cd11635cb442a9 input=4bfcdb5bc9153a4d]*/ +{ + return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0); +} + + +/*[clinic input] +os.replace = os.rename + +Rename a file or directory, overwriting the destination. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +src_dir_fd and dst_dir_fd, may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError." +[clinic start generated code]*/ + +PyDoc_STRVAR(os_replace__doc__, +"sig=($module, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n" +"Rename a file or directory, overwriting the destination.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError.\""); + +#define OS_REPLACE_METHODDEF \ + {"replace", (PyCFunction)os_replace, METH_VARARGS|METH_KEYWORDS, os_replace__doc__}, + +static PyObject * +os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd); + +static PyObject * +os_replace(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0); + int src_dir_fd = DEFAULT_DIR_FD; + int dst_dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$O&O&:replace", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) + goto exit; + return_value = os_replace_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +static PyObject * +os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd) +/*[clinic end generated code: output=88fcad52e00f5cbf input=25515dfb107c8421]*/ +{ + return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1); +} + + +/*[clinic input] +os.rmdir + + path: path_t + * + dir_fd: dir_fd(requires='unlinkat') = None + +Remove a directory. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_rmdir__doc__, +"sig=($module, path, *, dir_fd=None)\n" +"Remove a directory.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_RMDIR_METHODDEF \ + {"rmdir", (PyCFunction)os_rmdir, METH_VARARGS|METH_KEYWORDS, os_rmdir__doc__}, + +static PyObject * +os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_rmdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "dir_fd", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&:rmdir", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_rmdir_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=a6ce3131570b882d input=38c8b375ca34a7e2]*/ +{ int result; - PyObject *return_value = NULL; - - memset(&path, 0, sizeof(path)); - path.function_name = "rmdir"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords, - path_converter, &path, -#ifdef HAVE_UNLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - if (path.wide) - result = RemoveDirectoryW(path.wide); - else - result = RemoveDirectoryA(path.narrow); + + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + if (path->wide) + result = RemoveDirectoryW(path->wide); + else + result = RemoveDirectoryA(path->narrow); result = !result; /* Windows, success=1, UNIX, success=0 */ #else #ifdef HAVE_UNLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR); - else -#endif - result = rmdir(path.narrow); -#endif - Py_END_ALLOW_THREADS - - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); - -exit: - path_cleanup(&path); - return return_value; + result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR); + else +#endif + result = rmdir(path->narrow); +#endif + Py_END_ALLOW_THREADS + + if (result) + return path_error(path); + + Py_RETURN_NONE; } #ifdef HAVE_SYSTEM -PyDoc_STRVAR(posix_system__doc__, -"system(command) -> exit_status\n\n\ -Execute the command (a string) in a subshell."); - -static PyObject * -posix_system(PyObject *self, PyObject *args) -{ - long sts; -#ifdef MS_WINDOWS - wchar_t *command; - if (!PyArg_ParseTuple(args, "u:system", &command)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - sts = _wsystem(command); - Py_END_ALLOW_THREADS -#else - PyObject *command_obj; - char *command; - if (!PyArg_ParseTuple(args, "O&:system", - PyUnicode_FSConverter, &command_obj)) - return NULL; - - command = PyBytes_AsString(command_obj); - Py_BEGIN_ALLOW_THREADS - sts = system(command); - Py_END_ALLOW_THREADS - Py_DECREF(command_obj); -#endif - return PyLong_FromLong(sts); -} -#endif - - -PyDoc_STRVAR(posix_umask__doc__, -"umask(new_mask) -> old_mask\n\n\ -Set the current numeric umask and return the previous umask."); - -static PyObject * -posix_umask(PyObject *self, PyObject *args) -{ - int i; - if (!PyArg_ParseTuple(args, "i:umask", &i)) - return NULL; - i = (int)umask(i); + + +#ifdef MS_WINDOWS +/*[clinic input] +os.system -> long + + command: Py_UNICODE + +Execute the command in a subshell. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_system__doc__, +"sig=($module, command)\n" +"Execute the command in a subshell."); + +#define OS_SYSTEM_METHODDEF \ + {"system", (PyCFunction)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__}, + +static long +os_system_impl(PyModuleDef *module, Py_UNICODE *command); + +static PyObject * +os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"command", NULL}; + Py_UNICODE *command; + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "u:system", _keywords, + &command)) + goto exit; + _return_value = os_system_impl(module, command); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +static long +os_system_impl(PyModuleDef *module, Py_UNICODE *command) +/*[clinic end generated code: output=a78e7b2fdbb7245c input=303f5ce97df606b0]*/ +{ + long result; + Py_BEGIN_ALLOW_THREADS + result = _wsystem(command); + Py_END_ALLOW_THREADS + return result; +} +#else /* MS_WINDOWS */ +/*[clinic input] +os.system -> long + + command: FSConverter + +Execute the command in a subshell. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_system__doc__, +"sig=($module, command)\n" +"Execute the command in a subshell."); + +#define OS_SYSTEM_METHODDEF \ + {"system", (PyCFunction)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__}, + +static long +os_system_impl(PyModuleDef *module, PyObject *command); + +static PyObject * +os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"command", NULL}; + PyObject *command = NULL; + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:system", _keywords, + PyUnicode_FSConverter, &command)) + goto exit; + _return_value = os_system_impl(module, command); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + /* Cleanup for command */ + Py_XDECREF(command); + + return return_value; +} + +static long +os_system_impl(PyModuleDef *module, PyObject *command) +/*[clinic end generated code: output=9473b34758a2cc90 input=86a58554ba6094af]*/ +{ + long result; + char *bytes = PyBytes_AsString(command); + Py_BEGIN_ALLOW_THREADS + result = system(bytes); + Py_END_ALLOW_THREADS + return result; +} +#endif +#else /* HAVE_SYSTEM */ +#define OS_SYSTEM_METHODDEF +#endif /* HAVE_SYSTEM */ + + + +/*[clinic input] +os.umask + + mask: int + / + +Set the current numeric umask and return the previous umask. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_umask__doc__, +"sig=($module, mask)\n" +"Set the current numeric umask and return the previous umask."); + +#define OS_UMASK_METHODDEF \ + {"umask", (PyCFunction)os_umask, METH_VARARGS, os_umask__doc__}, + +static PyObject * +os_umask_impl(PyModuleDef *module, int mask); + +static PyObject * +os_umask(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int mask; + + if (!PyArg_ParseTuple(args, + "i:umask", + &mask)) + goto exit; + return_value = os_umask_impl(module, mask); + +exit: + return return_value; +} + +static PyObject * +os_umask_impl(PyModuleDef *module, int mask) +/*[clinic end generated code: output=e55afc511e96ef27 input=ab6bfd9b24d8a7e8]*/ +{ + int i = (int)umask(mask); if (i < 0) return posix_error(); return PyLong_FromLong((long)i); @@ -4481,81 +5705,142 @@ } #endif /* MS_WINDOWS */ -PyDoc_STRVAR(posix_unlink__doc__, -"unlink(path, *, dir_fd=None)\n\n\ -Remove a file (same as remove()).\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); - -PyDoc_STRVAR(posix_remove__doc__, -"remove(path, *, dir_fd=None)\n\n\ -Remove a file (same as unlink()).\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); - -static PyObject * -posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; + +/*[clinic input] +os.unlink + + path: path_t + * + dir_fd: dir_fd(requires='unlinkat')=None + +Remove a file (same as remove()). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_unlink__doc__, +"sig=($module, path, *, dir_fd=None)\n" +"Remove a file (same as remove()).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_UNLINK_METHODDEF \ + {"unlink", (PyCFunction)os_unlink, METH_VARARGS|METH_KEYWORDS, os_unlink__doc__}, + +static PyObject * +os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_unlink(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "dir_fd", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&:unlink", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_unlink_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=b758dc679d5c0e63 input=d7bcde2b1b2a2552]*/ +{ int result; - PyObject *return_value = NULL; - - memset(&path, 0, sizeof(path)); - path.function_name = "unlink"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords, - path_converter, &path, -#ifdef HAVE_UNLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - if (path.wide) - result = Py_DeleteFileW(path.wide); - else - result = DeleteFileA(path.narrow); + + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + if (path->wide) + result = Py_DeleteFileW(path->wide); + else + result = DeleteFileA(path->narrow); result = !result; /* Windows, success=1, UNIX, success=0 */ #else #ifdef HAVE_UNLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = unlinkat(dir_fd, path.narrow, 0); + result = unlinkat(dir_fd, path->narrow, 0); else #endif /* HAVE_UNLINKAT */ - result = unlink(path.narrow); -#endif - Py_END_ALLOW_THREADS - - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); - -exit: + result = unlink(path->narrow); +#endif + Py_END_ALLOW_THREADS + + if (result) + return path_error(path); + + Py_RETURN_NONE; +} + +/*[clinic input] +os.remove = os.unlink + +Remove a file (same as unlink()). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_remove__doc__, +"sig=($module, path, *, dir_fd=None)\n" +"Remove a file (same as unlink()).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_REMOVE_METHODDEF \ + {"remove", (PyCFunction)os_remove, METH_VARARGS|METH_KEYWORDS, os_remove__doc__}, + +static PyObject * +os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_remove(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&:remove", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_remove_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ path_cleanup(&path); - return return_value; -} - - -PyDoc_STRVAR(posix_uname__doc__, -"uname() -> uname_result\n\n\ -Return an object identifying the current operating system.\n\ -The object behaves like a named tuple with the following fields:\n\ - (sysname, nodename, release, version, machine)"); + + return return_value; +} + +static PyObject * +os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=1354522c85f7d4f0 input=e05c5ab55cd30983]*/ +{ + return os_unlink_impl(module, path, dir_fd); +} + static PyStructSequence_Field uname_result_fields[] = { {"sysname", "operating system name"}, @@ -4585,8 +5870,38 @@ #ifdef HAVE_UNAME -static PyObject * -posix_uname(PyObject *self, PyObject *noargs) +/*[clinic input] +os.uname + +Return an object identifying the current operating system. + +The object behaves like a named tuple with the following fields: + (sysname, nodename, release, version, machine) + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_uname__doc__, +"sig=($module)\n" +"Return an object identifying the current operating system.\n" +"\n" +"The object behaves like a named tuple with the following fields:\n" +" (sysname, nodename, release, version, machine)"); + +#define OS_UNAME_METHODDEF \ + {"uname", (PyCFunction)os_uname, METH_NOARGS, os_uname__doc__}, + +static PyObject * +os_uname_impl(PyModuleDef *module); + +static PyObject * +os_uname(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_uname_impl(module); +} + +static PyObject * +os_uname_impl(PyModuleDef *module) +/*[clinic end generated code: output=9a03d7d97d1230e0 input=e68bd246db3043ed]*/ { struct utsname u; int res; @@ -4622,34 +5937,11 @@ return value; } +#else /* HAVE_UNAME */ +#define OS_UNAME_METHODDEF #endif /* HAVE_UNAME */ -PyDoc_STRVAR(posix_utime__doc__, -"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\ -Set the access and modified time of path.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception.\n\ -\n\ -If times is not None, it must be a tuple (atime, mtime);\n\ - atime and mtime should be expressed as float seconds since the epoch.\n\ -If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\ - atime_ns and mtime_ns should be expressed as integer nanoseconds\n\ - since the epoch.\n\ -If both times and ns are None, utime uses the current time.\n\ -Specifying tuples for both times and ns is an error.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, utime will modify the symbolic link itself instead of the file the\n\ - link points to.\n\ -It is an error to use dir_fd or follow_symlinks when specifying path\n\ - as an open file descriptor.\n\ -dir_fd and follow_symlinks may not be available on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); typedef struct { int now; @@ -4735,6 +6027,10 @@ #endif } + #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable + #endif #define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)) @@ -4753,6 +6049,9 @@ #endif } + #define PATH_UTIME_HAVE_FD 1 +#else + #define PATH_UTIME_HAVE_FD 0 #endif @@ -4818,19 +6117,104 @@ return result; } -static PyObject * -posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; +/*[clinic input] +os.utime + + path: path_t(allow_fd='PATH_UTIME_HAVE_FD') + times: object = NULL + * + ns: object = NULL + dir_fd: dir_fd(requires='futimensat') = None + follow_symlinks: bool=True + +# "utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\ + +Set the access and modified time of path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. + +If times is not None, it must be a tuple (atime, mtime); + atime and mtime should be expressed as float seconds since the epoch. +If ns is not None, it must be a tuple (atime_ns, mtime_ns); + atime_ns and mtime_ns should be expressed as integer nanoseconds + since the epoch. +If both times and ns are None, utime uses the current time. +Specifying tuples for both times and ns is an error. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, utime will modify the symbolic link itself instead of the file the + link points to. +It is an error to use dir_fd or follow_symlinks when specifying path + as an open file descriptor. +dir_fd and follow_symlinks may not be available on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_utime__doc__, +"sig=($module, path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n" +"Set the access and modified time of path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +"\n" +"If times is not None, it must be a tuple (atime, mtime);\n" +" atime and mtime should be expressed as float seconds since the epoch.\n" +"If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n" +" atime_ns and mtime_ns should be expressed as integer nanoseconds\n" +" since the epoch.\n" +"If both times and ns are None, utime uses the current time.\n" +"Specifying tuples for both times and ns is an error.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, utime will modify the symbolic link itself instead of the file the\n" +" link points to.\n" +"It is an error to use dir_fd or follow_symlinks when specifying path\n" +" as an open file descriptor.\n" +"dir_fd and follow_symlinks may not be available on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_UTIME_METHODDEF \ + {"utime", (PyCFunction)os_utime, METH_VARARGS|METH_KEYWORDS, os_utime__doc__}, + +static PyObject * +os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks); + +static PyObject * +os_utime(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); PyObject *times = NULL; PyObject *ns = NULL; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - char *keywords[] = {"path", "times", "ns", "dir_fd", - "follow_symlinks", NULL}; - - utime_t utime; - + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|O$OO&p:utime", _keywords, + path_converter, &path, ×, &ns, FUTIMENSAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + return_value = os_utime_impl(module, &path, times, ns, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=117cf3b874e660fa input=1f18c17d5941aa82]*/ +{ #ifdef MS_WINDOWS HANDLE hFile; FILETIME atime, mtime; @@ -4839,25 +6223,9 @@ #endif PyObject *return_value = NULL; - - memset(&path, 0, sizeof(path)); - path.function_name = "utime"; + utime_t utime; + memset(&utime, 0, sizeof(utime_t)); -#if UTIME_HAVE_FD - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O&|O$OO&p:utime", keywords, - path_converter, &path, - ×, &ns, -#if UTIME_HAVE_DIR_FD - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks - )) - return NULL; if (times && (times != Py_None) && ns) { PyErr_SetString(PyExc_ValueError, @@ -4911,9 +6279,9 @@ goto exit; #endif - if (path_and_dir_fd_invalid("utime", &path, dir_fd) || - dir_fd_and_fd_invalid("utime", dir_fd, path.fd) || - fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks)) + if (path_and_dir_fd_invalid("utime", path, dir_fd) || + dir_fd_and_fd_invalid("utime", dir_fd, path->fd) || + fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks)) goto exit; #if !defined(HAVE_UTIMENSAT) @@ -4927,17 +6295,17 @@ #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path.wide) - hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0, + if (path->wide) + hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); else - hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0, + hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { - path_error(&path); + path_error(path); goto exit; } @@ -4962,23 +6330,23 @@ #if UTIME_HAVE_NOFOLLOW_SYMLINKS if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = utime_nofollow_symlinks(&utime, path.narrow); + result = utime_nofollow_symlinks(&utime, path->narrow); else #endif #if UTIME_HAVE_DIR_FD if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) - result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks); + result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks); else #endif #if UTIME_HAVE_FD - if (path.fd != -1) - result = utime_fd(&utime, path.fd); - else -#endif - - result = utime_default(&utime, path.narrow); + if (path->fd != -1) + result = utime_fd(&utime, path->fd); + else +#endif + + result = utime_default(&utime, path->narrow); Py_END_ALLOW_THREADS @@ -4990,11 +6358,9 @@ #endif /* MS_WINDOWS */ - Py_INCREF(Py_None); - return_value = Py_None; - -exit: - path_cleanup(&path); + Py_RETURN_NONE; + +exit: #ifdef MS_WINDOWS if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); @@ -5004,17 +6370,47 @@ /* Process operations */ -PyDoc_STRVAR(posix__exit__doc__, -"_exit(status)\n\n\ -Exit to the system with specified status, without normal exit processing."); - -static PyObject * -posix__exit(PyObject *self, PyObject *args) -{ - int sts; - if (!PyArg_ParseTuple(args, "i:_exit", &sts)) - return NULL; - _exit(sts); + +/*[clinic input] +os._exit + + status: int + +Exit to the system with specified status, without normal exit processing. +[clinic start generated code]*/ + +PyDoc_STRVAR(os__exit__doc__, +"sig=($module, status)\n" +"Exit to the system with specified status, without normal exit processing."); + +#define OS__EXIT_METHODDEF \ + {"_exit", (PyCFunction)os__exit, METH_VARARGS|METH_KEYWORDS, os__exit__doc__}, + +static PyObject * +os__exit_impl(PyModuleDef *module, int status); + +static PyObject * +os__exit(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:_exit", _keywords, + &status)) + goto exit; + return_value = os__exit_impl(module, status); + +exit: + return return_value; +} + +static PyObject * +os__exit_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=049cdc4119fcacc5 input=5e6d57556b0c4a62]*/ +{ + _exit(status); return NULL; /* Make gcc -Wall happy */ } @@ -5153,95 +6549,155 @@ #endif #ifdef HAVE_EXECV -PyDoc_STRVAR(posix_execv__doc__, -"execv(path, args)\n\n\ -Execute an executable path with arguments, replacing current process.\n\ -\n\ - path: path of executable file\n\ - args: tuple or list of strings"); - -static PyObject * -posix_execv(PyObject *self, PyObject *args) -{ - PyObject *opath; - char *path; + +/*[clinic input] +os.execv + + path: FSConverter + Path of executable file. + argv: object + Tuple or list of strings. + / + +Execute an executable path with arguments, replacing current process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_execv__doc__, +"sig=($module, path, argv)\n" +"Execute an executable path with arguments, replacing current process.\n" +"\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings."); + +#define OS_EXECV_METHODDEF \ + {"execv", (PyCFunction)os_execv, METH_VARARGS, os_execv__doc__}, + +static PyObject * +os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv); + +static PyObject * +os_execv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *path = NULL; PyObject *argv; + + if (!PyArg_ParseTuple(args, + "O&O:execv", + PyUnicode_FSConverter, &path, &argv)) + goto exit; + return_value = os_execv_impl(module, path, argv); + +exit: + /* Cleanup for path */ + Py_XDECREF(path); + + return return_value; +} + +static PyObject * +os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv) +/*[clinic end generated code: output=78fd2a6a78e49773 input=96041559925e5229]*/ +{ + char *path_char; char **argvlist; Py_ssize_t argc; /* execv has two arguments: (path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "O&O:execv", - PyUnicode_FSConverter, - &opath, &argv)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list"); - Py_DECREF(opath); return NULL; } argc = PySequence_Size(argv); if (argc < 1) { PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); - Py_DECREF(opath); return NULL; } argvlist = parse_arglist(argv, &argc); if (argvlist == NULL) { - Py_DECREF(opath); - return NULL; - } - - execv(path, argvlist); + return NULL; + } + + execv(path_char, argvlist); /* If we get here it's definitely an error */ free_string_array(argvlist, argc); - Py_DECREF(opath); return posix_error(); } -PyDoc_STRVAR(posix_execve__doc__, -"execve(path, args, env)\n\n\ -Execute a path with arguments and environment, replacing current process.\n\ -\n\ - path: path of executable file\n\ - args: tuple or list of arguments\n\ - env: dictionary of strings mapping to strings\n\ -\n\ -On some platforms, you may specify an open file descriptor for path;\n\ - execve will execute the program the file descriptor is open to.\n\ - If this functionality is unavailable, using it raises NotImplementedError."); - -static PyObject * -posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - PyObject *argv, *env; + +/*[clinic input] +os.execve + + path: path_t(allow_fd='PATH_HAVE_FEXECVE') + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. + +Execute an executable path with arguments, replacing current process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_execve__doc__, +"sig=($module, path, argv, env)\n" +"Execute an executable path with arguments, replacing current process.\n" +"\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings.\n" +" env\n" +" Dictionary of strings mapping to strings."); + +#define OS_EXECVE_METHODDEF \ + {"execve", (PyCFunction)os_execve, METH_VARARGS|METH_KEYWORDS, os_execve__doc__}, + +static PyObject * +os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env); + +static PyObject * +os_execve(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "argv", "env", NULL}; + path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); + PyObject *argv; + PyObject *env; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&OO:execve", _keywords, + path_converter, &path, &argv, &env)) + goto exit; + return_value = os_execve_impl(module, &path, argv, env); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env) +/*[clinic end generated code: output=4aece83bde877a18 input=626804fa092606d9]*/ +{ char **argvlist = NULL; char **envlist; Py_ssize_t argc, envc; - static char *keywords[] = {"path", "argv", "environment", NULL}; /* execve has three arguments: (path, argv, env), where argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - memset(&path, 0, sizeof(path)); - path.function_name = "execve"; -#ifdef HAVE_FEXECVE - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords, - path_converter, &path, - &argv, &env - )) - return NULL; - if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execve: argv must be a tuple or list"); @@ -5264,15 +6720,15 @@ goto fail; #ifdef HAVE_FEXECVE - if (path.fd > -1) - fexecve(path.fd, argvlist, envlist); - else -#endif - execve(path.narrow, argvlist, envlist); + if (path->fd > -1) + fexecve(path->fd, argvlist, envlist); + else +#endif + execve(path->narrow, argvlist, envlist); /* If we get here it's definitely an error */ - path_error(&path); + path_error(path); while (--envc >= 0) PyMem_DEL(envlist[envc]); @@ -5280,29 +6736,74 @@ fail: if (argvlist) free_string_array(argvlist, argc); - path_cleanup(&path); return NULL; } +#else /* HAVE_EXECV */ +#define OS_EXECV_METHODDEF +#define OS_EXECVE_METHODDEF #endif /* HAVE_EXECV */ #ifdef HAVE_SPAWNV -PyDoc_STRVAR(posix_spawnv__doc__, -"spawnv(mode, path, args)\n\n\ -Execute the program 'path' in a new process.\n\ -\n\ - mode: mode of process creation\n\ - path: path of executable file\n\ - args: tuple or list of strings"); - -static PyObject * -posix_spawnv(PyObject *self, PyObject *args) -{ - PyObject *opath; - char *path; +/*[clinic input] +os.spawnv + + mode: int + Mode of process creation. + path: FSConverter + Path of executable file. + argv: object + Tuple or list of strings. + / + +Execute the program specified by path in a new process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_spawnv__doc__, +"sig=($module, mode, path, argv)\n" +"Execute the program specified by path in a new process.\n" +"\n" +" mode\n" +" Mode of process creation.\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings."); + +#define OS_SPAWNV_METHODDEF \ + {"spawnv", (PyCFunction)os_spawnv, METH_VARARGS, os_spawnv__doc__}, + +static PyObject * +os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv); + +static PyObject * +os_spawnv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int mode; + PyObject *path = NULL; PyObject *argv; + + if (!PyArg_ParseTuple(args, + "iO&O:spawnv", + &mode, PyUnicode_FSConverter, &path, &argv)) + goto exit; + return_value = os_spawnv_impl(module, mode, path, argv); + +exit: + /* Cleanup for path */ + Py_XDECREF(path); + + return return_value; +} + +static PyObject * +os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv) +/*[clinic end generated code: output=17667460ac47df2e input=042c91dfc1e6debc]*/ +{ + char *path_char; char **argvlist; - int mode, i; + int i; Py_ssize_t argc; Py_intptr_t spawnval; PyObject *(*getitem)(PyObject *, Py_ssize_t); @@ -5310,11 +6811,7 @@ /* spawnv has three arguments: (mode, path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode, - PyUnicode_FSConverter, - &opath, &argv)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -5326,13 +6823,11 @@ else { PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list"); - Py_DECREF(opath); return NULL; } argvlist = PyMem_NEW(char *, argc+1); if (argvlist == NULL) { - Py_DECREF(opath); return PyErr_NoMemory(); } for (i = 0; i < argc; i++) { @@ -5342,7 +6837,6 @@ PyErr_SetString( PyExc_TypeError, "spawnv() arg 2 must contain only strings"); - Py_DECREF(opath); return NULL; } } @@ -5352,11 +6846,10 @@ mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS - spawnval = _spawnv(mode, path, argvlist); + spawnval = _spawnv(mode, path_char, argvlist); Py_END_ALLOW_THREADS free_string_array(argvlist, argc); - Py_DECREF(opath); if (spawnval == -1) return posix_error(); @@ -5365,25 +6858,71 @@ } -PyDoc_STRVAR(posix_spawnve__doc__, -"spawnve(mode, path, args, env)\n\n\ -Execute the program 'path' in a new process.\n\ -\n\ - mode: mode of process creation\n\ - path: path of executable file\n\ - args: tuple or list of arguments\n\ - env: dictionary of strings mapping to strings"); - -static PyObject * -posix_spawnve(PyObject *self, PyObject *args) -{ - PyObject *opath; - char *path; - PyObject *argv, *env; +/*[clinic input] +os.spawnv + + mode: int + Mode of process creation. + path: FSConverter + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. + / + +Execute the program specified by path in a new process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_spawnv__doc__, +"sig=($module, mode, path, argv, env)\n" +"Execute the program specified by path in a new process.\n" +"\n" +" mode\n" +" Mode of process creation.\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings.\n" +" env\n" +" Dictionary of strings mapping to strings."); + +#define OS_SPAWNV_METHODDEF \ + {"spawnv", (PyCFunction)os_spawnv, METH_VARARGS, os_spawnv__doc__}, + +static PyObject * +os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env); + +static PyObject * +os_spawnv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int mode; + PyObject *path = NULL; + PyObject *argv; + PyObject *env; + + if (!PyArg_ParseTuple(args, + "iO&OO:spawnv", + &mode, PyUnicode_FSConverter, &path, &argv, &env)) + goto exit; + return_value = os_spawnv_impl(module, mode, path, argv, env); + +exit: + /* Cleanup for path */ + Py_XDECREF(path); + + return return_value; +} + +static PyObject * +os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env) +/*[clinic end generated code: output=29e1104c698fd005 input=36eda56e8cb99852]*/ +{ + char *path_char; char **argvlist; char **envlist; PyObject *res = NULL; - int mode; Py_ssize_t argc, i, envc; Py_intptr_t spawnval; PyObject *(*getitem)(PyObject *, Py_ssize_t); @@ -5393,11 +6932,7 @@ argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode, - PyUnicode_FSConverter, - &opath, &argv, &env)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -5441,7 +6976,7 @@ mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS - spawnval = _spawnve(mode, path, argvlist, envlist); + spawnval = _spawnve(mode, path_char, argvlist, envlist); Py_END_ALLOW_THREADS if (spawnval == -1) @@ -5455,22 +6990,46 @@ fail_1: free_string_array(argvlist, lastarg); fail_0: - Py_DECREF(opath); return res; } +#else /* HAVE_SPAWNV */ +#define OS_SPAWNV_METHODDEF +#define OS_SPAWNVE_METHODDEF #endif /* HAVE_SPAWNV */ #ifdef HAVE_FORK1 -PyDoc_STRVAR(posix_fork1__doc__, -"fork1() -> pid\n\n\ -Fork a child process with a single multiplexed (i.e., not bound) thread.\n\ -\n\ -Return 0 to child process and PID of child to parent process."); - -static PyObject * -posix_fork1(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.fork1 + +Fork a child process with a single multiplexed (i.e., not bound) thread. + +Return 0 to child process and PID of child to parent process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fork1__doc__, +"sig=($module)\n" +"Fork a child process with a single multiplexed (i.e., not bound) thread.\n" +"\n" +"Return 0 to child process and PID of child to parent process."); + +#define OS_FORK1_METHODDEF \ + {"fork1", (PyCFunction)os_fork1, METH_NOARGS, os_fork1__doc__}, + +static PyObject * +os_fork1_impl(PyModuleDef *module); + +static PyObject * +os_fork1(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_fork1_impl(module); +} + +static PyObject * +os_fork1_impl(PyModuleDef *module) +/*[clinic end generated code: output=8a6a5632d4baae5b input=12db02167893926e]*/ { pid_t pid; int result = 0; @@ -5493,17 +7052,42 @@ } return PyLong_FromPid(pid); } -#endif +#else /* HAVE_FORK1 */ +#define OS_FORK1_METHODDEF +#endif /* HAVE_FORK1 */ #ifdef HAVE_FORK -PyDoc_STRVAR(posix_fork__doc__, -"fork() -> pid\n\n\ -Fork a child process.\n\ -Return 0 to child process and PID of child to parent process."); - -static PyObject * -posix_fork(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.fork + +Fork a child process. + +Return 0 to child process and PID of child to parent process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fork__doc__, +"sig=($module)\n" +"Fork a child process.\n" +"\n" +"Return 0 to child process and PID of child to parent process."); + +#define OS_FORK_METHODDEF \ + {"fork", (PyCFunction)os_fork, METH_NOARGS, os_fork__doc__}, + +static PyObject * +os_fork_impl(PyModuleDef *module); + +static PyObject * +os_fork(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_fork_impl(module); +} + +static PyObject * +os_fork_impl(PyModuleDef *module) +/*[clinic end generated code: output=e8130edacfebb967 input=13c956413110eeaa]*/ { pid_t pid; int result = 0; @@ -5526,92 +7110,216 @@ } return PyLong_FromPid(pid); } -#endif +#else /* HAVE_FORK */ +#define OS_FORK_METHODDEF +#endif /* HAVE_FORK */ #ifdef HAVE_SCHED_H #ifdef HAVE_SCHED_GET_PRIORITY_MAX -PyDoc_STRVAR(posix_sched_get_priority_max__doc__, -"sched_get_priority_max(policy)\n\n\ -Get the maximum scheduling priority for *policy*."); - -static PyObject * -posix_sched_get_priority_max(PyObject *self, PyObject *args) -{ - int policy, max; - - if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy)) - return NULL; +/*[clinic input] +os.sched_get_priority_max + + policy: int + +Get the maximum scheduling priority for policy. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_get_priority_max__doc__, +"sig=($module, policy)\n" +"Get the maximum scheduling priority for policy."); + +#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF \ + {"sched_get_priority_max", (PyCFunction)os_sched_get_priority_max, METH_VARARGS|METH_KEYWORDS, os_sched_get_priority_max__doc__}, + +static PyObject * +os_sched_get_priority_max_impl(PyModuleDef *module, int policy); + +static PyObject * +os_sched_get_priority_max(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"policy", NULL}; + int policy; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:sched_get_priority_max", _keywords, + &policy)) + goto exit; + return_value = os_sched_get_priority_max_impl(module, policy); + +exit: + return return_value; +} + +static PyObject * +os_sched_get_priority_max_impl(PyModuleDef *module, int policy) +/*[clinic end generated code: output=01bed92928f4e775 input=2097b7998eca6874]*/ +{ + int max; + max = sched_get_priority_max(policy); if (max < 0) return posix_error(); return PyLong_FromLong(max); } -PyDoc_STRVAR(posix_sched_get_priority_min__doc__, -"sched_get_priority_min(policy)\n\n\ -Get the minimum scheduling priority for *policy*."); - -static PyObject * -posix_sched_get_priority_min(PyObject *self, PyObject *args) -{ - int policy, min; - - if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy)) - return NULL; - min = sched_get_priority_min(policy); + +/*[clinic input] +os.sched_get_priority_min + + policy: int + +Get the minimum scheduling priority for policy. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_get_priority_min__doc__, +"sig=($module, policy)\n" +"Get the minimum scheduling priority for policy."); + +#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF \ + {"sched_get_priority_min", (PyCFunction)os_sched_get_priority_min, METH_VARARGS|METH_KEYWORDS, os_sched_get_priority_min__doc__}, + +static PyObject * +os_sched_get_priority_min_impl(PyModuleDef *module, int policy); + +static PyObject * +os_sched_get_priority_min(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"policy", NULL}; + int policy; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:sched_get_priority_min", _keywords, + &policy)) + goto exit; + return_value = os_sched_get_priority_min_impl(module, policy); + +exit: + return return_value; +} + +static PyObject * +os_sched_get_priority_min_impl(PyModuleDef *module, int policy) +/*[clinic end generated code: output=86d79cb183a2c806 input=21bc8fa0d70983bf]*/ +{ + int min = sched_get_priority_min(policy); if (min < 0) return posix_error(); return PyLong_FromLong(min); } - #endif /* HAVE_SCHED_GET_PRIORITY_MAX */ #ifdef HAVE_SCHED_SETSCHEDULER -PyDoc_STRVAR(posix_sched_getscheduler__doc__, -"sched_getscheduler(pid)\n\n\ -Get the scheduling policy for the process with a PID of *pid*.\n\ -Passing a PID of 0 returns the scheduling policy for the calling process."); - -static PyObject * -posix_sched_getscheduler(PyObject *self, PyObject *args) -{ +/*[clinic input] +os.sched_getscheduler + pid: pid_t + / + +Get the scheduling policy for the process identifiedy by pid. + +Passing 0 for pid returns the scheduling policy for the calling process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_getscheduler__doc__, +"sig=($module, pid)\n" +"Get the scheduling policy for the process identifiedy by pid.\n" +"\n" +"Passing 0 for pid returns the scheduling policy for the calling process."); + +#define OS_SCHED_GETSCHEDULER_METHODDEF \ + {"sched_getscheduler", (PyCFunction)os_sched_getscheduler, METH_VARARGS, os_sched_getscheduler__doc__}, + +static PyObject * +os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_getscheduler(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":sched_getscheduler", + &pid)) + goto exit; + return_value = os_sched_getscheduler_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=4376fcf0b834f36f input=5f14cfd1f189e1a0]*/ +{ int policy; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid)) - return NULL; policy = sched_getscheduler(pid); if (policy < 0) return posix_error(); return PyLong_FromLong(policy); } - -#endif +#endif /* HAVE_SCHED_SETSCHEDULER */ #if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) -static PyObject * -sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *res, *priority; - static char *kwlist[] = {"sched_priority", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority)) - return NULL; +/*[clinic input] +class os.sched_param "PyObject *" "&SchedParamType" + +@classmethod +os.sched_param.__new__ + + sched_priority: object + A scheduling parameter. + +Current has only one field: sched_priority"); +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_param__doc__, +"sig=(sched_priority)\n" +"Current has only one field: sched_priority\");\n" +"\n" +" sched_priority\n" +" A scheduling parameter."); + +static PyObject * +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority); + +static PyObject * +os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"sched_priority", NULL}; + PyObject *sched_priority; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:sched_param", _keywords, + &sched_priority)) + goto exit; + return_value = os_sched_param_impl(type, sched_priority); + +exit: + return return_value; +} + +static PyObject * +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) +/*[clinic end generated code: output=b58d1f8ce181baa5 input=73a4c22f7071fc62]*/ +{ + PyObject *res; + res = PyStructSequence_New(type); if (!res) return NULL; - Py_INCREF(priority); - PyStructSequence_SET_ITEM(res, 0, priority); + Py_INCREF(sched_priority); + PyStructSequence_SET_ITEM(res, 0, sched_priority); return res; } -PyDoc_STRVAR(sched_param__doc__, -"sched_param(sched_priority): A scheduling parameter.\n\n\ -Current has only one field: sched_priority"); static PyStructSequence_Field sched_param_fields[] = { {"sched_priority", "the scheduling priority"}, @@ -5620,7 +7328,7 @@ static PyStructSequence_Desc sched_param_desc = { "sched_param", /* name */ - sched_param__doc__, /* doc */ + os_sched_param__doc__, /* doc */ sched_param_fields, 1 }; @@ -5644,118 +7352,271 @@ res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int); return 1; } - -#endif +#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */ #ifdef HAVE_SCHED_SETSCHEDULER -PyDoc_STRVAR(posix_sched_setscheduler__doc__, -"sched_setscheduler(pid, policy, param)\n\n\ -Set the scheduling policy, *policy*, for *pid*.\n\ -If *pid* is 0, the calling process is changed.\n\ -*param* is an instance of sched_param."); - -static PyObject * -posix_sched_setscheduler(PyObject *self, PyObject *args) -{ +/*[clinic input] +os.sched_setscheduler + + pid: pid_t + policy: int + param: sched_param + / + +Set the scheduling policy for the process identified by pid. + +If pid is 0, the calling process is changed. +param is an instance of sched_param. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_setscheduler__doc__, +"sig=($module, pid, policy, param)\n" +"Set the scheduling policy for the process identified by pid.\n" +"\n" +"If pid is 0, the calling process is changed.\n" +"param is an instance of sched_param."); + +#define OS_SCHED_SETSCHEDULER_METHODDEF \ + {"sched_setscheduler", (PyCFunction)os_sched_setscheduler, METH_VARARGS, os_sched_setscheduler__doc__}, + +static PyObject * +os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param); + +static PyObject * +os_sched_setscheduler(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; int policy; struct sched_param param; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler", - &pid, &policy, &convert_sched_param, ¶m)) - return NULL; - + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "iO&:sched_setscheduler", + &pid, &policy, convert_sched_param, ¶m)) + goto exit; + return_value = os_sched_setscheduler_impl(module, pid, policy, ¶m); + +exit: + return return_value; +} + +static PyObject * +os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param) +/*[clinic end generated code: output=2c128166855fe6c2 input=c581f9469a5327dd]*/ +{ /* ** sched_setscheduler() returns 0 in Linux, but the previous ** scheduling policy under Solaris/Illumos, and others. ** On error, -1 is returned in all Operating Systems. */ - if (sched_setscheduler(pid, policy, ¶m) == -1) + if (sched_setscheduler(pid, policy, param) == -1) return posix_error(); Py_RETURN_NONE; } -#endif +#endif /* HAVE_SCHED_SETSCHEDULER*/ #ifdef HAVE_SCHED_SETPARAM -PyDoc_STRVAR(posix_sched_getparam__doc__, -"sched_getparam(pid) -> sched_param\n\n\ -Returns scheduling parameters for the process with *pid* as an instance of the\n\ -sched_param class. A PID of 0 means the calling process."); - -static PyObject * -posix_sched_getparam(PyObject *self, PyObject *args) -{ +/*[clinic input] +os.sched_getparam + pid: pid_t + / + +Returns scheduling parameters for the process identified by pid. + +If pid is 0, returns parameters for the calling process. +Return value is an instance of sched_param. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_getparam__doc__, +"sig=($module, pid)\n" +"Returns scheduling parameters for the process identified by pid.\n" +"\n" +"If pid is 0, returns parameters for the calling process.\n" +"Return value is an instance of sched_param."); + +#define OS_SCHED_GETPARAM_METHODDEF \ + {"sched_getparam", (PyCFunction)os_sched_getparam, METH_VARARGS, os_sched_getparam__doc__}, + +static PyObject * +os_sched_getparam_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_getparam(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pid; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":sched_getparam", + &pid)) + goto exit; + return_value = os_sched_getparam_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_sched_getparam_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=d49200431319d8bc input=18a1ef9c2efae296]*/ +{ + struct sched_param param; + PyObject *result; + PyObject *priority; + + if (sched_getparam(pid, ¶m)) + return posix_error(); + result = PyStructSequence_New(&SchedParamType); + if (!result) + return NULL; + priority = PyLong_FromLong(param.sched_priority); + if (!priority) { + Py_DECREF(result); + return NULL; + } + PyStructSequence_SET_ITEM(result, 0, priority); + return result; +} + + +/*[clinic input] +os.sched_setparam + pid: pid_t + param: sched_param + / + +Set scheduling parameters for the process identified by pid. + +If pid is 0, sets parameters for the calling process. +param should be an instance of sched_param. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_setparam__doc__, +"sig=($module, pid, param)\n" +"Set scheduling parameters for the process identified by pid.\n" +"\n" +"If pid is 0, sets parameters for the calling process.\n" +"param should be an instance of sched_param."); + +#define OS_SCHED_SETPARAM_METHODDEF \ + {"sched_setparam", (PyCFunction)os_sched_setparam, METH_VARARGS, os_sched_setparam__doc__}, + +static PyObject * +os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param); + +static PyObject * +os_sched_setparam(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; struct sched_param param; - PyObject *res, *priority; - - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid)) - return NULL; - if (sched_getparam(pid, ¶m)) - return posix_error(); - res = PyStructSequence_New(&SchedParamType); - if (!res) - return NULL; - priority = PyLong_FromLong(param.sched_priority); - if (!priority) { - Py_DECREF(res); - return NULL; - } - PyStructSequence_SET_ITEM(res, 0, priority); - return res; -} - -PyDoc_STRVAR(posix_sched_setparam__doc__, -"sched_setparam(pid, param)\n\n\ -Set scheduling parameters for a process with PID *pid*.\n\ -A PID of 0 means the calling process."); - -static PyObject * -posix_sched_setparam(PyObject *self, PyObject *args) -{ + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "O&:sched_setparam", + &pid, convert_sched_param, ¶m)) + goto exit; + return_value = os_sched_setparam_impl(module, pid, ¶m); + +exit: + return return_value; +} + +static PyObject * +os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param) +/*[clinic end generated code: output=a4b31ce2ea86415f input=6b8d6dfcecdc21bd]*/ +{ + if (sched_setparam(pid, param)) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SCHED_SETPARAM */ + +#ifdef HAVE_SCHED_RR_GET_INTERVAL + +/*[clinic input] +os.sched_rr_get_interval -> double + pid: pid_t + / + +Return the round-robin quantum for the process identified by pid, in seconds. + +Value returned is a float. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_rr_get_interval__doc__, +"sig=($module, pid)\n" +"Return the round-robin quantum for the process identified by pid, in seconds.\n" +"\n" +"Value returned is a float."); + +#define OS_SCHED_RR_GET_INTERVAL_METHODDEF \ + {"sched_rr_get_interval", (PyCFunction)os_sched_rr_get_interval, METH_VARARGS, os_sched_rr_get_interval__doc__}, + +static double +os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_rr_get_interval(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; - struct sched_param param; - - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam", - &pid, &convert_sched_param, ¶m)) - return NULL; - if (sched_setparam(pid, ¶m)) - return posix_error(); - Py_RETURN_NONE; -} - -#endif - -#ifdef HAVE_SCHED_RR_GET_INTERVAL - -PyDoc_STRVAR(posix_sched_rr_get_interval__doc__, -"sched_rr_get_interval(pid) -> float\n\n\ -Return the round-robin quantum for the process with PID *pid* in seconds."); - -static PyObject * -posix_sched_rr_get_interval(PyObject *self, PyObject *args) -{ - pid_t pid; + double _return_value; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":sched_rr_get_interval", + &pid)) + goto exit; + _return_value = os_sched_rr_get_interval_impl(module, pid); + if ((_return_value == -1.0) && PyErr_Occurred()) + goto exit; + return_value = PyFloat_FromDouble(_return_value); + +exit: + return return_value; +} + +static double +os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=83490f82f7a26ec8 input=2a973da15cca6fae]*/ +{ struct timespec interval; - - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid)) - return NULL; - if (sched_rr_get_interval(pid, &interval)) - return posix_error(); - return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec); -} - -#endif - -PyDoc_STRVAR(posix_sched_yield__doc__, -"sched_yield()\n\n\ -Voluntarily relinquish the CPU."); - -static PyObject * -posix_sched_yield(PyObject *self, PyObject *noargs) + if (sched_rr_get_interval(pid, &interval)) { + posix_error(); + return -1.0; + } + return (double)interval.tv_sec + 1e-9*interval.tv_nsec; +} +#endif /* HAVE_SCHED_RR_GET_INTERVAL */ + + +/*[clinic input] +os.sched_yield + +Voluntarily relinquish the CPU. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_yield__doc__, +"sig=($module)\n" +"Voluntarily relinquish the CPU."); + +#define OS_SCHED_YIELD_METHODDEF \ + {"sched_yield", (PyCFunction)os_sched_yield, METH_NOARGS, os_sched_yield__doc__}, + +static PyObject * +os_sched_yield_impl(PyModuleDef *module); + +static PyObject * +os_sched_yield(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_sched_yield_impl(module); +} + +static PyObject * +os_sched_yield_impl(PyModuleDef *module) +/*[clinic end generated code: output=62b6825b83bcbe60 input=e54d6f98189391d4]*/ { if (sched_yield()) return posix_error(); @@ -5767,35 +7628,67 @@ /* The minimum number of CPUs allocated in a cpu_set_t */ static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT; -PyDoc_STRVAR(posix_sched_setaffinity__doc__, -"sched_setaffinity(pid, cpu_set)\n\n\ -Set the affinity of the process with PID *pid* to *cpu_set*."); - -static PyObject * -posix_sched_setaffinity(PyObject *self, PyObject *args) -{ +/*[clinic input] +os.sched_setaffinity + pid: pid_t + mask : object + / + +Set the CPU affinity of the process identified by pid to mask. + +mask should be an iterable of integers identifying CPUs. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_setaffinity__doc__, +"sig=($module, pid, mask)\n" +"Set the CPU affinity of the process identified by pid to mask.\n" +"\n" +"mask should be an iterable of integers identifying CPUs."); + +#define OS_SCHED_SETAFFINITY_METHODDEF \ + {"sched_setaffinity", (PyCFunction)os_sched_setaffinity, METH_VARARGS, os_sched_setaffinity__doc__}, + +static PyObject * +os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask); + +static PyObject * +os_sched_setaffinity(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; + PyObject *mask; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "O:sched_setaffinity", + &pid, &mask)) + goto exit; + return_value = os_sched_setaffinity_impl(module, pid, mask); + +exit: + return return_value; +} + +static PyObject * +os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask) +/*[clinic end generated code: output=90304360f1be65dd input=a0791a597c7085ba]*/ +{ int ncpus; size_t setsize; - cpu_set_t *mask = NULL; - PyObject *iterable, *iterator = NULL, *item; - - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity", - &pid, &iterable)) - return NULL; - - iterator = PyObject_GetIter(iterable); + cpu_set_t *cpu_set = NULL; + PyObject *iterator = NULL, *item; + + iterator = PyObject_GetIter(mask); if (iterator == NULL) return NULL; ncpus = NCPUS_START; setsize = CPU_ALLOC_SIZE(ncpus); - mask = CPU_ALLOC(ncpus); - if (mask == NULL) { + cpu_set = CPU_ALLOC(ncpus); + if (cpu_set == NULL) { PyErr_NoMemory(); goto error; } - CPU_ZERO_S(setsize, mask); + CPU_ZERO_S(setsize, cpu_set); while ((item = PyIter_Next(iterator))) { long cpu; @@ -5836,48 +7729,78 @@ } newsetsize = CPU_ALLOC_SIZE(newncpus); CPU_ZERO_S(newsetsize, newmask); - memcpy(newmask, mask, setsize); - CPU_FREE(mask); + memcpy(newmask, cpu_set, setsize); + CPU_FREE(cpu_set); setsize = newsetsize; - mask = newmask; + cpu_set = newmask; ncpus = newncpus; } - CPU_SET_S(cpu, setsize, mask); + CPU_SET_S(cpu, setsize, cpu_set); } Py_CLEAR(iterator); - if (sched_setaffinity(pid, setsize, mask)) { + if (sched_setaffinity(pid, setsize, cpu_set)) { posix_error(); goto error; } - CPU_FREE(mask); + CPU_FREE(cpu_set); Py_RETURN_NONE; error: - if (mask) - CPU_FREE(mask); + if (cpu_set) + CPU_FREE(cpu_set); Py_XDECREF(iterator); return NULL; } -PyDoc_STRVAR(posix_sched_getaffinity__doc__, -"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\ -Return the affinity of the process with PID *pid*.\n\ -The returned cpu_set will be of size *ncpus*."); - -static PyObject * -posix_sched_getaffinity(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.sched_getaffinity + pid: pid_t + / + +Return the affinity of the process identified by pid. + +The affinity is returned as a set of CPU identifiers. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_getaffinity__doc__, +"sig=($module, pid)\n" +"Return the affinity of the process identified by pid.\n" +"\n" +"The affinity is returned as a set of CPU identifiers."); + +#define OS_SCHED_GETAFFINITY_METHODDEF \ + {"sched_getaffinity", (PyCFunction)os_sched_getaffinity, METH_VARARGS, os_sched_getaffinity__doc__}, + +static PyObject * +os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_getaffinity(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":sched_getaffinity", + &pid)) + goto exit; + return_value = os_sched_getaffinity_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=b683a34ba1d48c05 input=eaf161936874b8a1]*/ +{ int cpu, ncpus, count; size_t setsize; cpu_set_t *mask = NULL; PyObject *res = NULL; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity", - &pid)) - return NULL; - ncpus = NCPUS_START; while (1) { setsize = CPU_ALLOC_SIZE(ncpus); @@ -5927,6 +7850,47 @@ #endif /* HAVE_SCHED_H */ +#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF +#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF +#endif /* OS_SCHED_GET_PRIORITY_MAX_METHODDEF */ + +#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF +#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF +#endif /* OS_SCHED_GET_PRIORITY_MIN_METHODDEF */ + +#ifndef OS_SCHED_GETSCHEDULER_METHODDEF +#define OS_SCHED_GETSCHEDULER_METHODDEF +#endif /* OS_SCHED_GETSCHEDULER_METHODDEF */ + +#ifndef OS_SCHED_SETSCHEDULER_METHODDEF +#define OS_SCHED_SETSCHEDULER_METHODDEF +#endif /* OS_SCHED_SETSCHEDULER_METHODDEF */ + +#ifndef OS_SCHED_GETPARAM_METHODDEF +#define OS_SCHED_GETPARAM_METHODDEF +#endif /* OS_SCHED_GETPARAM_METHODDEF */ + +#ifndef OS_SCHED_SETPARAM_METHODDEF +#define OS_SCHED_SETPARAM_METHODDEF +#endif /* OS_SCHED_SETPARAM_METHODDEF */ + +#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF +#define OS_SCHED_RR_GET_INTERVAL_METHODDEF +#endif /* OS_SCHED_RR_GET_INTERVAL_METHODDEF */ + +#ifndef OS_SCHED_YIELD_METHODDEF +#define OS_SCHED_YIELD_METHODDEF +#endif /* OS_SCHED_YIELD_METHODDEF */ + +#ifndef OS_SCHED_SETAFFINITY_METHODDEF +#define OS_SCHED_SETAFFINITY_METHODDEF +#endif /* OS_SCHED_SETAFFINITY_METHODDEF */ + +#ifndef OS_SCHED_GETAFFINITY_METHODDEF +#define OS_SCHED_GETAFFINITY_METHODDEF +#endif /* OS_SCHED_GETAFFINITY_METHODDEF */ + + /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) @@ -5954,12 +7918,38 @@ #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) -PyDoc_STRVAR(posix_openpty__doc__, -"openpty() -> (master_fd, slave_fd)\n\n\ -Open a pseudo-terminal, returning open fd's for both master and slave end.\n"); - -static PyObject * -posix_openpty(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.openpty + +Open a pseudo-terminal. + +Return a tuple of (master_fd, slave_fd) containing open file descriptors +for both the master and slave ends. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_openpty__doc__, +"sig=($module)\n" +"Open a pseudo-terminal.\n" +"\n" +"Return a tuple of (master_fd, slave_fd) containing open file descriptors\n" +"for both the master and slave ends."); + +#define OS_OPENPTY_METHODDEF \ + {"openpty", (PyCFunction)os_openpty, METH_NOARGS, os_openpty__doc__}, + +static PyObject * +os_openpty_impl(PyModuleDef *module); + +static PyObject * +os_openpty(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_openpty_impl(module); +} + +static PyObject * +os_openpty_impl(PyModuleDef *module) +/*[clinic end generated code: output=e7292ddf9f125a68 input=f3d99fd99e762907]*/ { int master_fd = -1, slave_fd = -1; #ifndef HAVE_OPENPTY @@ -6046,17 +8036,47 @@ close(slave_fd); return NULL; } +#else /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ +#define OS_OPENPTY_METHODDEF #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ #ifdef HAVE_FORKPTY -PyDoc_STRVAR(posix_forkpty__doc__, -"forkpty() -> (pid, master_fd)\n\n\ -Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ -Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ -To both, return fd of newly opened pseudo-terminal.\n"); - -static PyObject * -posix_forkpty(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.forkpty + +Fork a new process with a new pseudo-terminal as controlling tty. + +Returns a tuple of (pid, master_fd). +Like fork(), return pid of 0 to the child process, +and pid of child to the parent process. +To both, return fd of newly opened pseudo-terminal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_forkpty__doc__, +"sig=($module)\n" +"Fork a new process with a new pseudo-terminal as controlling tty.\n" +"\n" +"Returns a tuple of (pid, master_fd).\n" +"Like fork(), return pid of 0 to the child process,\n" +"and pid of child to the parent process.\n" +"To both, return fd of newly opened pseudo-terminal."); + +#define OS_FORKPTY_METHODDEF \ + {"forkpty", (PyCFunction)os_forkpty, METH_NOARGS, os_forkpty__doc__}, + +static PyObject * +os_forkpty_impl(PyModuleDef *module); + +static PyObject * +os_forkpty(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_forkpty_impl(module); +} + +static PyObject * +os_forkpty_impl(PyModuleDef *module) +/*[clinic end generated code: output=c4f36c192c40c441 input=f1f7f4bae3966010]*/ { int master_fd = -1, result = 0; pid_t pid; @@ -6080,64 +8100,156 @@ } return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); } -#endif +#else /* HAVE_FORKPTY */ +#define OS_FORKPTY_METHODDEF +#endif /* HAVE_FORKPTY */ #ifdef HAVE_GETEGID -PyDoc_STRVAR(posix_getegid__doc__, -"getegid() -> egid\n\n\ -Return the current process's effective group id."); - -static PyObject * -posix_getegid(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.getegid + +Return the current process's effective group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getegid__doc__, +"sig=($module)\n" +"Return the current process\'s effective group id."); + +#define OS_GETEGID_METHODDEF \ + {"getegid", (PyCFunction)os_getegid, METH_NOARGS, os_getegid__doc__}, + +static PyObject * +os_getegid_impl(PyModuleDef *module); + +static PyObject * +os_getegid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getegid_impl(module); +} + +static PyObject * +os_getegid_impl(PyModuleDef *module) +/*[clinic end generated code: output=a5e64c209cd39684 input=1596f79ad1107d5d]*/ { return _PyLong_FromGid(getegid()); } -#endif +#else /* HAVE_GETEGID */ +#define OS_GETEGID_METHODDEF +#endif /* HAVE_GETEGID */ #ifdef HAVE_GETEUID -PyDoc_STRVAR(posix_geteuid__doc__, -"geteuid() -> euid\n\n\ -Return the current process's effective user id."); - -static PyObject * -posix_geteuid(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.geteuid + +Return the current process's effective user id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_geteuid__doc__, +"sig=($module)\n" +"Return the current process\'s effective user id."); + +#define OS_GETEUID_METHODDEF \ + {"geteuid", (PyCFunction)os_geteuid, METH_NOARGS, os_geteuid__doc__}, + +static PyObject * +os_geteuid_impl(PyModuleDef *module); + +static PyObject * +os_geteuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_geteuid_impl(module); +} + +static PyObject * +os_geteuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=9f463fd30ac4e33b input=4644c662d3bd9f19]*/ { return _PyLong_FromUid(geteuid()); } -#endif +#else /* HAVE_GETEUID */ +#define OS_GETEUID_METHODDEF +#endif /* HAVE_GETEUID */ #ifdef HAVE_GETGID -PyDoc_STRVAR(posix_getgid__doc__, -"getgid() -> gid\n\n\ -Return the current process's group id."); - -static PyObject * -posix_getgid(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.getgid + +Return the current process's group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getgid__doc__, +"sig=($module)\n" +"Return the current process\'s group id."); + +#define OS_GETGID_METHODDEF \ + {"getgid", (PyCFunction)os_getgid, METH_NOARGS, os_getgid__doc__}, + +static PyObject * +os_getgid_impl(PyModuleDef *module); + +static PyObject * +os_getgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getgid_impl(module); +} + +static PyObject * +os_getgid_impl(PyModuleDef *module) +/*[clinic end generated code: output=e85a12f8d0f59f7d input=58796344cd87c0f6]*/ { return _PyLong_FromGid(getgid()); } -#endif - - -PyDoc_STRVAR(posix_getpid__doc__, -"getpid() -> pid\n\n\ -Return the current process id"); - -static PyObject * -posix_getpid(PyObject *self, PyObject *noargs) +#else /* HAVE_GETGID */ +#define OS_GETGID_METHODDEF +#endif /* HAVE_GETGID */ + + + +/*[clinic input] +os.getpid + +Return the current process id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getpid__doc__, +"sig=($module)\n" +"Return the current process id."); + +#define OS_GETPID_METHODDEF \ + {"getpid", (PyCFunction)os_getpid, METH_NOARGS, os_getpid__doc__}, + +static PyObject * +os_getpid_impl(PyModuleDef *module); + +static PyObject * +os_getpid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getpid_impl(module); +} + +static PyObject * +os_getpid_impl(PyModuleDef *module) +/*[clinic end generated code: output=68633cfbc3230949 input=5a9a00f0ab68aa00]*/ { return PyLong_FromPid(getpid()); } #ifdef HAVE_GETGROUPLIST + +/* AC 3.5: funny apple logic below */ PyDoc_STRVAR(posix_getgrouplist__doc__, -"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\ -Returns a list of groups to which a user belongs.\n\n\ - user: username to lookup\n\ - group: base group id of the user"); +"sig=($module, user, group)\n\ +\n\ +Returns a list of groups to which a user belongs.\n\ +\n\ +user is the name of the user, as a str.\n\ +group is the base group id of the user."); static PyObject * posix_getgrouplist(PyObject *self, PyObject *args) @@ -6205,15 +8317,36 @@ return list; } -#endif +#else /* HAVE_GETGROUPLIST */ +#endif /* HAVE_GETGROUPLIST */ #ifdef HAVE_GETGROUPS -PyDoc_STRVAR(posix_getgroups__doc__, -"getgroups() -> list of group IDs\n\n\ -Return list of supplemental group IDs for the process."); - -static PyObject * -posix_getgroups(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.getgroups + +Return list of supplemental group IDs for the process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getgroups__doc__, +"sig=($module)\n" +"Return list of supplemental group IDs for the process."); + +#define OS_GETGROUPS_METHODDEF \ + {"getgroups", (PyCFunction)os_getgroups, METH_NOARGS, os_getgroups__doc__}, + +static PyObject * +os_getgroups_impl(PyModuleDef *module); + +static PyObject * +os_getgroups(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getgroups_impl(module); +} + +static PyObject * +os_getgroups_impl(PyModuleDef *module) +/*[clinic end generated code: output=16540f88c893e0f4 input=d3f109412e6a155c]*/ { PyObject *result = NULL; @@ -6312,7 +8445,8 @@ return result; } -#endif +#else /* HAVE_GETGROUPS */ +#endif /* HAVE_GETGROUPS */ #ifdef HAVE_INITGROUPS PyDoc_STRVAR(posix_initgroups__doc__, @@ -6321,6 +8455,7 @@ the groups of which the specified username is a member, plus the specified\n\ group id."); +/* AC 3.5: funny apple logic */ static PyObject * posix_initgroups(PyObject *self, PyObject *args) { @@ -6353,34 +8488,87 @@ Py_INCREF(Py_None); return Py_None; } -#endif +#else /* HAVE_INITGROUPS */ +#endif /* HAVE_INITGROUPS */ #ifdef HAVE_GETPGID -PyDoc_STRVAR(posix_getpgid__doc__, -"getpgid(pid) -> pgid\n\n\ -Call the system call getpgid()."); - -static PyObject * -posix_getpgid(PyObject *self, PyObject *args) -{ - pid_t pid, pgid; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid)) - return NULL; - pgid = getpgid(pid); + +/*[clinic input] +os.getpgid + + pid: pid_t + +Call the system call getpgid(), and return the result. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getpgid__doc__, +"sig=($module, pid)\n" +"Call the system call getpgid(), and return the result."); + +#define OS_GETPGID_METHODDEF \ + {"getpgid", (PyCFunction)os_getpgid, METH_VARARGS|METH_KEYWORDS, os_getpgid__doc__}, + +static PyObject * +os_getpgid_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_getpgid(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"pid", NULL}; + pid_t pid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "" _Py_PARSE_PID ":getpgid", _keywords, + &pid)) + goto exit; + return_value = os_getpgid_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_getpgid_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=260dec5ebc689061 input=39d710ae3baaf1c7]*/ +{ + pid_t pgid = getpgid(pid); if (pgid < 0) return posix_error(); return PyLong_FromPid(pgid); } +#else /* HAVE_GETPGID */ +#define OS_GETPGID_METHODDEF #endif /* HAVE_GETPGID */ #ifdef HAVE_GETPGRP -PyDoc_STRVAR(posix_getpgrp__doc__, -"getpgrp() -> pgrp\n\n\ -Return the current process group id."); - -static PyObject * -posix_getpgrp(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.getpgrp + +Return the current process group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getpgrp__doc__, +"sig=($module)\n" +"Return the current process group id."); + +#define OS_GETPGRP_METHODDEF \ + {"getpgrp", (PyCFunction)os_getpgrp, METH_NOARGS, os_getpgrp__doc__}, + +static PyObject * +os_getpgrp_impl(PyModuleDef *module); + +static PyObject * +os_getpgrp(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getpgrp_impl(module); +} + +static PyObject * +os_getpgrp_impl(PyModuleDef *module) +/*[clinic end generated code: output=39a25296b949c601 input=6846fb2bb9a3705e]*/ { #ifdef GETPGRP_HAVE_ARG return PyLong_FromPid(getpgrp(0)); @@ -6388,16 +8576,38 @@ return PyLong_FromPid(getpgrp()); #endif /* GETPGRP_HAVE_ARG */ } +#else /* HAVE_GETPGRP */ +#define OS_GETPGRP_METHODDEF #endif /* HAVE_GETPGRP */ #ifdef HAVE_SETPGRP -PyDoc_STRVAR(posix_setpgrp__doc__, -"setpgrp()\n\n\ -Make this process the process group leader."); - -static PyObject * -posix_setpgrp(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.setpgrp + +Make the current process the leader of its process group. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setpgrp__doc__, +"sig=($module)\n" +"Make the current process the leader of its process group."); + +#define OS_SETPGRP_METHODDEF \ + {"setpgrp", (PyCFunction)os_setpgrp, METH_NOARGS, os_setpgrp__doc__}, + +static PyObject * +os_setpgrp_impl(PyModuleDef *module); + +static PyObject * +os_setpgrp(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_setpgrp_impl(module); +} + +static PyObject * +os_setpgrp_impl(PyModuleDef *module) +/*[clinic end generated code: output=6ae0d22df72cb58a input=1f0619fcb5731e7e]*/ { #ifdef SETPGRP_HAVE_ARG if (setpgrp(0, 0) < 0) @@ -6408,7 +8618,8 @@ Py_INCREF(Py_None); return Py_None; } - +#else /* HAVE_SETPGRP */ +#define OS_SETPGRP_METHODDEF #endif /* HAVE_SETPGRP */ #ifdef HAVE_GETPPID @@ -6455,14 +8666,37 @@ } #endif /*MS_WINDOWS*/ -PyDoc_STRVAR(posix_getppid__doc__, -"getppid() -> ppid\n\n\ -Return the parent's process id. If the parent process has already exited,\n\ -Windows machines will still return its id; others systems will return the id\n\ -of the 'init' process (1)."); - -static PyObject * -posix_getppid(PyObject *self, PyObject *noargs) +/*[clinic input] +os.getppid + +Return the parent's process id. + +If the parent process has already exited, Windows machines will still +return its id; others systems will return the id of the 'init' process (1). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getppid__doc__, +"sig=($module)\n" +"Return the parent\'s process id.\n" +"\n" +"If the parent process has already exited, Windows machines will still\n" +"return its id; others systems will return the id of the \'init\' process (1)."); + +#define OS_GETPPID_METHODDEF \ + {"getppid", (PyCFunction)os_getppid, METH_NOARGS, os_getppid__doc__}, + +static PyObject * +os_getppid_impl(PyModuleDef *module); + +static PyObject * +os_getppid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getppid_impl(module); +} + +static PyObject * +os_getppid_impl(PyModuleDef *module) +/*[clinic end generated code: output=b575fffcdb99cb45 input=e637cb87539c030e]*/ { #ifdef MS_WINDOWS return win32_getppid(); @@ -6470,16 +8704,38 @@ return PyLong_FromPid(getppid()); #endif } +#else /* HAVE_GETPPID */ +#define OS_GETPPID_METHODDEF #endif /* HAVE_GETPPID */ #ifdef HAVE_GETLOGIN -PyDoc_STRVAR(posix_getlogin__doc__, -"getlogin() -> string\n\n\ -Return the actual login name."); - -static PyObject * -posix_getlogin(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.getlogin + +Return the actual login name. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getlogin__doc__, +"sig=($module)\n" +"Return the actual login name."); + +#define OS_GETLOGIN_METHODDEF \ + {"getlogin", (PyCFunction)os_getlogin, METH_NOARGS, os_getlogin__doc__}, + +static PyObject * +os_getlogin_impl(PyModuleDef *module); + +static PyObject * +os_getlogin(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getlogin_impl(module); +} + +static PyObject * +os_getlogin_impl(PyModuleDef *module) +/*[clinic end generated code: output=edb8495b31ab706c input=2a21ab1e917163df]*/ { PyObject *result = NULL; #ifdef MS_WINDOWS @@ -6510,79 +8766,104 @@ #endif return result; } +#else /* HAVE_GETLOGIN */ +#define OS_GETLOGIN_METHODDEF #endif /* HAVE_GETLOGIN */ #ifdef HAVE_GETUID -PyDoc_STRVAR(posix_getuid__doc__, -"getuid() -> uid\n\n\ -Return the current process's user id."); - -static PyObject * -posix_getuid(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.getuid + +Return the current process's user id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getuid__doc__, +"sig=($module)\n" +"Return the current process\'s user id."); + +#define OS_GETUID_METHODDEF \ + {"getuid", (PyCFunction)os_getuid, METH_NOARGS, os_getuid__doc__}, + +static PyObject * +os_getuid_impl(PyModuleDef *module); + +static PyObject * +os_getuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getuid_impl(module); +} + +static PyObject * +os_getuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=3bfa40f1a29378c4 input=b53c8b35f110a516]*/ { return _PyLong_FromUid(getuid()); } -#endif +#else /* HAVE_GETUID */ +#define OS_GETUID_METHODDEF +#endif /* HAVE_GETUID */ + +#ifdef MS_WINDOWS +#define HAVE_KILL +#endif /* MS_WINDOWS */ #ifdef HAVE_KILL -PyDoc_STRVAR(posix_kill__doc__, -"kill(pid, sig)\n\n\ -Kill a process with a signal."); - -static PyObject * -posix_kill(PyObject *self, PyObject *args) -{ +/*[clinic input] +os.kill + + pid: pid_t + signal: Py_ssize_t + / + +Kill a process with a signal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_kill__doc__, +"sig=($module, pid, signal)\n" +"Kill a process with a signal."); + +#define OS_KILL_METHODDEF \ + {"kill", (PyCFunction)os_kill, METH_VARARGS, os_kill__doc__}, + +static PyObject * +os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal); + +static PyObject * +os_kill(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; - int sig; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig)) - return NULL; - if (kill(pid, sig) == -1) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} -#endif - -#ifdef HAVE_KILLPG -PyDoc_STRVAR(posix_killpg__doc__, -"killpg(pgid, sig)\n\n\ -Kill a process group with a signal."); - -static PyObject * -posix_killpg(PyObject *self, PyObject *args) -{ - int sig; - pid_t pgid; - /* XXX some man pages make the `pgid` parameter an int, others - a pid_t. Since getpgrp() returns a pid_t, we assume killpg should - take the same type. Moreover, pid_t is always at least as wide as - int (else compilation of this module fails), which is safe. */ - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig)) - return NULL; - if (killpg(pgid, sig) == -1) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} -#endif - -#ifdef MS_WINDOWS -PyDoc_STRVAR(win32_kill__doc__, -"kill(pid, sig)\n\n\ -Kill a process with a signal."); - -static PyObject * -win32_kill(PyObject *self, PyObject *args) + Py_ssize_t signal; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "n:kill", + &pid, &signal)) + goto exit; + return_value = os_kill_impl(module, pid, signal); + +exit: + return return_value; +} + +static PyObject * +os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal) +/*[clinic end generated code: output=725625c738809d8e input=61a36b86ca275ab9]*/ +#ifndef MS_WINDOWS +{ + if (kill(pid, (int)signal) == -1) + return posix_error(); + Py_RETURN_NONE; +} +#else /* !MS_WINDOWS */ { PyObject *result; pid_t pid; - DWORD sig, err; + DWORD sig = (DWORD)signal; + DWORD err; HANDLE handle; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig)) - return NULL; - /* Console processes which share a common console can be sent CTRL+C or CTRL+BREAK events, provided they handle said events. */ if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { @@ -6613,7 +8894,66 @@ CloseHandle(handle); return result; } -#endif /* MS_WINDOWS */ +#endif /* !MS_WINDOWS */ + +#else /* HAVE_KILL */ +#define OS_KILL_METHODDEF +#endif /* HAVE_KILL */ + +#ifdef HAVE_KILLPG + +/*[clinic input] +os.killpg + + pgid: pid_t + signal: int + / + +Kill a process group with a signal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_killpg__doc__, +"sig=($module, pgid, signal)\n" +"Kill a process group with a signal."); + +#define OS_KILLPG_METHODDEF \ + {"killpg", (PyCFunction)os_killpg, METH_VARARGS, os_killpg__doc__}, + +static PyObject * +os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal); + +static PyObject * +os_killpg(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pgid; + int signal; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "i:killpg", + &pgid, &signal)) + goto exit; + return_value = os_killpg_impl(module, pgid, signal); + +exit: + return return_value; +} + +static PyObject * +os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal) +/*[clinic end generated code: output=47bb6f34440348b9 input=38b5449eb8faec19]*/ +{ + /* XXX some man pages make the `pgid` parameter an int, others + a pid_t. Since getpgrp() returns a pid_t, we assume killpg should + take the same type. Moreover, pid_t is always at least as wide as + int (else compilation of this module fails), which is safe. */ + if (killpg(pgid, signal) == -1) + return posix_error(); + Py_RETURN_NONE; +} +#else /* HAVE_KILLPG */ +#define OS_KILLPG_METHODDEF +#endif /* HAVE_KILLPG */ #ifdef HAVE_PLOCK @@ -6621,151 +8961,375 @@ #include #endif -PyDoc_STRVAR(posix_plock__doc__, -"plock(op)\n\n\ + +/*[clinic input] +os.plock + op: int + / + Lock program segments into memory."); - -static PyObject * -posix_plock(PyObject *self, PyObject *args) -{ +[clinic start generated code]*/ + +PyDoc_STRVAR(os_plock__doc__, +"sig=($module, op)\n" +"Lock program segments into memory.\");"); + +#define OS_PLOCK_METHODDEF \ + {"plock", (PyCFunction)os_plock, METH_VARARGS, os_plock__doc__}, + +static PyObject * +os_plock_impl(PyModuleDef *module, int op); + +static PyObject * +os_plock(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int op; - if (!PyArg_ParseTuple(args, "i:plock", &op)) - return NULL; + + if (!PyArg_ParseTuple(args, + "i:plock", + &op)) + goto exit; + return_value = os_plock_impl(module, op); + +exit: + return return_value; +} + +static PyObject * +os_plock_impl(PyModuleDef *module, int op) +/*[clinic end generated code: output=a218d8c6e3637916 input=e6e5e348e1525f60]*/ +{ if (plock(op) == -1) return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} -#endif + Py_RETURN_NONE; +} +#else /* HAVE_PLOCK */ +#define OS_PLOCK_METHODDEF +#endif /* HAVE_PLOCK */ #ifdef HAVE_SETUID -PyDoc_STRVAR(posix_setuid__doc__, -"setuid(uid)\n\n\ -Set the current process's user id."); - -static PyObject * -posix_setuid(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.setuid + + uid: uid_t + / + +Set the current process's user id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setuid__doc__, +"sig=($module, uid)\n" +"Set the current process\'s user id."); + +#define OS_SETUID_METHODDEF \ + {"setuid", (PyCFunction)os_setuid, METH_VARARGS, os_setuid__doc__}, + +static PyObject * +os_setuid_impl(PyModuleDef *module, uid_t uid); + +static PyObject * +os_setuid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; uid_t uid; - if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid)) - return NULL; + + if (!PyArg_ParseTuple(args, + "O&:setuid", + _Py_Uid_Converter, &uid)) + goto exit; + return_value = os_setuid_impl(module, uid); + +exit: + return return_value; +} + +static PyObject * +os_setuid_impl(PyModuleDef *module, uid_t uid) +/*[clinic end generated code: output=01ccf56bb5d91bea input=c921a3285aa22256]*/ +{ if (setuid(uid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} + Py_RETURN_NONE; +} +#else /* HAVE_SETUID */ +#define OS_SETUID_METHODDEF #endif /* HAVE_SETUID */ #ifdef HAVE_SETEUID -PyDoc_STRVAR(posix_seteuid__doc__, -"seteuid(uid)\n\n\ -Set the current process's effective user id."); - -static PyObject * -posix_seteuid (PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.seteuid + + euid: uid_t + / + +Set the current process's effective user id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_seteuid__doc__, +"sig=($module, euid)\n" +"Set the current process\'s effective user id."); + +#define OS_SETEUID_METHODDEF \ + {"seteuid", (PyCFunction)os_seteuid, METH_VARARGS, os_seteuid__doc__}, + +static PyObject * +os_seteuid_impl(PyModuleDef *module, uid_t euid); + +static PyObject * +os_seteuid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; uid_t euid; - if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid)) - return NULL; - if (seteuid(euid) < 0) { + + if (!PyArg_ParseTuple(args, + "O&:seteuid", + _Py_Uid_Converter, &euid)) + goto exit; + return_value = os_seteuid_impl(module, euid); + +exit: + return return_value; +} + +static PyObject * +os_seteuid_impl(PyModuleDef *module, uid_t euid) +/*[clinic end generated code: output=1ac091a1c5feca78 input=ba93d927e4781aa9]*/ +{ + if (seteuid(euid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#else /* HAVE_SETEUID */ +#define OS_SETEUID_METHODDEF +#endif /* HAVE_SETEUID */ + +#ifdef HAVE_SETEGID + +/*[clinic input] +os.setegid + + egid: gid_t + / + +Set the current process's effective group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setegid__doc__, +"sig=($module, egid)\n" +"Set the current process\'s effective group id."); + +#define OS_SETEGID_METHODDEF \ + {"setegid", (PyCFunction)os_setegid, METH_VARARGS, os_setegid__doc__}, + +static PyObject * +os_setegid_impl(PyModuleDef *module, gid_t egid); + +static PyObject * +os_setegid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + gid_t egid; + + if (!PyArg_ParseTuple(args, + "O&:setegid", + _Py_Gid_Converter, &egid)) + goto exit; + return_value = os_setegid_impl(module, egid); + +exit: + return return_value; +} + +static PyObject * +os_setegid_impl(PyModuleDef *module, gid_t egid) +/*[clinic end generated code: output=5962529480ca4e4e input=4080526d0ccd6ce3]*/ +{ + if (setegid(egid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#else /* HAVE_SETEGID */ +#define OS_SETEGID_METHODDEF +#endif /* HAVE_SETEGID */ + +#ifdef HAVE_SETREUID + +/*[clinic input] +os.setreuid + + ruid: uid_t + euid: uid_t + / + +Set the current process's real and effective user ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setreuid__doc__, +"sig=($module, ruid, euid)\n" +"Set the current process\'s real and effective user ids."); + +#define OS_SETREUID_METHODDEF \ + {"setreuid", (PyCFunction)os_setreuid, METH_VARARGS, os_setreuid__doc__}, + +static PyObject * +os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid); + +static PyObject * +os_setreuid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + uid_t ruid; + uid_t euid; + + if (!PyArg_ParseTuple(args, + "O&O&:setreuid", + _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid)) + goto exit; + return_value = os_setreuid_impl(module, ruid, euid); + +exit: + return return_value; +} + +static PyObject * +os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid) +/*[clinic end generated code: output=da6cf62a6471752d input=0ca8978de663880c]*/ +{ + if (setreuid(ruid, euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); return Py_None; } } -#endif /* HAVE_SETEUID */ - -#ifdef HAVE_SETEGID -PyDoc_STRVAR(posix_setegid__doc__, -"setegid(gid)\n\n\ -Set the current process's effective group id."); - -static PyObject * -posix_setegid (PyObject *self, PyObject *args) -{ +#else /* HAVE_SETREUID */ +#define OS_SETREUID_METHODDEF +#endif /* HAVE_SETREUID */ + +#ifdef HAVE_SETREGID + +/*[clinic input] +os.setregid + + rgid: gid_t + egid: gid_t + / + +Set the current process's real and effective group ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setregid__doc__, +"sig=($module, rgid, egid)\n" +"Set the current process\'s real and effective group ids."); + +#define OS_SETREGID_METHODDEF \ + {"setregid", (PyCFunction)os_setregid, METH_VARARGS, os_setregid__doc__}, + +static PyObject * +os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid); + +static PyObject * +os_setregid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + gid_t rgid; gid_t egid; - if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid)) - return NULL; - if (setegid(egid) < 0) { - return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } -} -#endif /* HAVE_SETEGID */ - -#ifdef HAVE_SETREUID -PyDoc_STRVAR(posix_setreuid__doc__, -"setreuid(ruid, euid)\n\n\ -Set the current process's real and effective user ids."); - -static PyObject * -posix_setreuid (PyObject *self, PyObject *args) -{ - uid_t ruid, euid; - if (!PyArg_ParseTuple(args, "O&O&:setreuid", - _Py_Uid_Converter, &ruid, - _Py_Uid_Converter, &euid)) - return NULL; - if (setreuid(ruid, euid) < 0) { - return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } -} -#endif /* HAVE_SETREUID */ - -#ifdef HAVE_SETREGID -PyDoc_STRVAR(posix_setregid__doc__, -"setregid(rgid, egid)\n\n\ -Set the current process's real and effective group ids."); - -static PyObject * -posix_setregid (PyObject *self, PyObject *args) -{ - gid_t rgid, egid; - if (!PyArg_ParseTuple(args, "O&O&:setregid", - _Py_Gid_Converter, &rgid, - _Py_Gid_Converter, &egid)) - return NULL; - if (setregid(rgid, egid) < 0) { - return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } -} + + if (!PyArg_ParseTuple(args, + "O&O&:setregid", + _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid)) + goto exit; + return_value = os_setregid_impl(module, rgid, egid); + +exit: + return return_value; +} + +static PyObject * +os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid) +/*[clinic end generated code: output=71f35e3bd8e7e718 input=c59499f72846db78]*/ +{ + if (setregid(rgid, egid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#else /* HAVE_SETREGID */ +#define OS_SETREGID_METHODDEF #endif /* HAVE_SETREGID */ #ifdef HAVE_SETGID -PyDoc_STRVAR(posix_setgid__doc__, -"setgid(gid)\n\n\ -Set the current process's group id."); - -static PyObject * -posix_setgid(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.setgid + gid: gid_t + / + +Set the current process's group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setgid__doc__, +"sig=($module, gid)\n" +"Set the current process\'s group id."); + +#define OS_SETGID_METHODDEF \ + {"setgid", (PyCFunction)os_setgid, METH_VARARGS, os_setgid__doc__}, + +static PyObject * +os_setgid_impl(PyModuleDef *module, gid_t gid); + +static PyObject * +os_setgid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; gid_t gid; - if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid)) - return NULL; + + if (!PyArg_ParseTuple(args, + "O&:setgid", + _Py_Gid_Converter, &gid)) + goto exit; + return_value = os_setgid_impl(module, gid); + +exit: + return return_value; +} + +static PyObject * +os_setgid_impl(PyModuleDef *module, gid_t gid) +/*[clinic end generated code: output=aab9c157677a7916 input=27d30c4059045dc6]*/ +{ if (setgid(gid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} + Py_RETURN_NONE; +} +#else /* HAVE_SETGID */ +#define OS_SETGID_METHODDEF #endif /* HAVE_SETGID */ #ifdef HAVE_SETGROUPS -PyDoc_STRVAR(posix_setgroups__doc__, -"setgroups(list)\n\n\ -Set the groups of the current process to list."); - -static PyObject * -posix_setgroups(PyObject *self, PyObject *groups) + +/*[clinic input] +os.setgroups + + groups: object + / + +Set the groups of the current process to list. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setgroups__doc__, +"sig=($module, groups)\n" +"Set the groups of the current process to list."); + +#define OS_SETGROUPS_METHODDEF \ + {"setgroups", (PyCFunction)os_setgroups, METH_O, os_setgroups__doc__}, + +static PyObject * +os_setgroups(PyModuleDef *module, PyObject *groups) +/*[clinic end generated code: output=09ea2a543ef470c9 input=fa742ca3daf85a7e]*/ { int i, len; gid_t grouplist[MAX_GROUPS]; @@ -6803,6 +9367,8 @@ Py_INCREF(Py_None); return Py_None; } +#else /* HAVE_SETGROUPS */ +#define OS_SETGROUPS_METHODDEF #endif /* HAVE_SETGROUPS */ #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) @@ -6867,77 +9433,198 @@ #endif /* HAVE_WAIT3 || HAVE_WAIT4 */ #ifdef HAVE_WAIT3 -PyDoc_STRVAR(posix_wait3__doc__, -"wait3(options) -> (pid, status, rusage)\n\n\ -Wait for completion of a child process."); - -static PyObject * -posix_wait3(PyObject *self, PyObject *args) + +/*[clinic input] +os.wait3 + + options: int +Wait for completion of a child process. + +Returns a tuple of information about the child process: + (pid, status, rusage) +[clinic start generated code]*/ + +PyDoc_STRVAR(os_wait3__doc__, +"sig=($module, options)\n" +"Wait for completion of a child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status, rusage)"); + +#define OS_WAIT3_METHODDEF \ + {"wait3", (PyCFunction)os_wait3, METH_VARARGS|METH_KEYWORDS, os_wait3__doc__}, + +static PyObject * +os_wait3_impl(PyModuleDef *module, int options); + +static PyObject * +os_wait3(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"options", NULL}; + int options; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:wait3", _keywords, + &options)) + goto exit; + return_value = os_wait3_impl(module, options); + +exit: + return return_value; +} + +static PyObject * +os_wait3_impl(PyModuleDef *module, int options) +/*[clinic end generated code: output=f6312d27d69ee70a input=8ac4c56956b61710]*/ { pid_t pid; - int options; struct rusage ru; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, "i:wait3", &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS pid = wait3(&status, options, &ru); Py_END_ALLOW_THREADS return wait_helper(pid, WAIT_STATUS_INT(status), &ru); } +#else /* HAVE_WAIT3 */ +#define OS_WAIT3_METHODDEF #endif /* HAVE_WAIT3 */ #ifdef HAVE_WAIT4 -PyDoc_STRVAR(posix_wait4__doc__, -"wait4(pid, options) -> (pid, status, rusage)\n\n\ -Wait for completion of a given child process."); - -static PyObject * -posix_wait4(PyObject *self, PyObject *args) -{ + +/*[clinic input] + +os.wait4 + + pid: pid_t + options: int + +Wait for completion of a specific child process. + +Returns a tuple of information about the child process: + (pid, status, rusage) +[clinic start generated code]*/ + +PyDoc_STRVAR(os_wait4__doc__, +"sig=($module, pid, options)\n" +"Wait for completion of a specific child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status, rusage)"); + +#define OS_WAIT4_METHODDEF \ + {"wait4", (PyCFunction)os_wait4, METH_VARARGS|METH_KEYWORDS, os_wait4__doc__}, + +static PyObject * +os_wait4_impl(PyModuleDef *module, pid_t pid, int options); + +static PyObject * +os_wait4(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"pid", "options", NULL}; pid_t pid; int options; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "" _Py_PARSE_PID "i:wait4", _keywords, + &pid, &options)) + goto exit; + return_value = os_wait4_impl(module, pid, options); + +exit: + return return_value; +} + +static PyObject * +os_wait4_impl(PyModuleDef *module, pid_t pid, int options) +/*[clinic end generated code: output=0eaf2cd6c773219f input=d11deed0750600ba]*/ +{ struct rusage ru; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS pid = wait4(pid, &status, options, &ru); Py_END_ALLOW_THREADS return wait_helper(pid, WAIT_STATUS_INT(status), &ru); } +#else /* HAVE_WAIT4 */ +#define OS_WAIT4_METHODDEF #endif /* HAVE_WAIT4 */ #if defined(HAVE_WAITID) && !defined(__APPLE__) -PyDoc_STRVAR(posix_waitid__doc__, -"waitid(idtype, id, options) -> waitid_result\n\n\ -Wait for the completion of one or more child processes.\n\n\ -idtype can be P_PID, P_PGID or P_ALL.\n\ -id specifies the pid to wait on.\n\ -options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\ -or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\ -Returns either waitid_result or None if WNOHANG is specified and there are\n\ -no children in a waitable state."); - -static PyObject * -posix_waitid(PyObject *self, PyObject *args) -{ - PyObject *result; + +/*[clinic input] +os.waitid + + idtype: idtype_t + Must be one of be P_PID, P_PGID or P_ALL. + id: id_t + The id to wait on. + options: int + Constructed from the ORing of one or more of WEXITED, WSTOPPED + or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT. + / + +Returns the result of waiting for a process or processes. + +Returns either waitid_result or None if WNOHANG is specified and there are +no children in a waitable state. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_waitid__doc__, +"sig=($module, idtype, id, options)\n" +"Returns the result of waiting for a process or processes.\n" +"\n" +" idtype\n" +" Must be one of be P_PID, P_PGID or P_ALL.\n" +" id\n" +" The id to wait on.\n" +" options\n" +" Constructed from the ORing of one or more of WEXITED, WSTOPPED\n" +" or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n" +"\n" +"Returns either waitid_result or None if WNOHANG is specified and there are\n" +"no children in a waitable state."); + +#define OS_WAITID_METHODDEF \ + {"waitid", (PyCFunction)os_waitid, METH_VARARGS, os_waitid__doc__}, + +static PyObject * +os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options); + +static PyObject * +os_waitid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; idtype_t idtype; id_t id; - int options, res; + int options; + + if (!PyArg_ParseTuple(args, + "i" _Py_PARSE_PID "i:waitid", + &idtype, &id, &options)) + goto exit; + return_value = os_waitid_impl(module, idtype, id, options); + +exit: + return return_value; +} + +static PyObject * +os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options) +/*[clinic end generated code: output=a33b1c52626f6415 input=d8e7f76e052b7920]*/ +{ + PyObject *result; + int res; siginfo_t si; si.si_pid = 0; - if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options)) - return NULL; + Py_BEGIN_ALLOW_THREADS res = waitid(idtype, id, &si, options); Py_END_ALLOW_THREADS @@ -6963,23 +9650,65 @@ return result; } -#endif - -#ifdef HAVE_WAITPID -PyDoc_STRVAR(posix_waitpid__doc__, -"waitpid(pid, options) -> (pid, status)\n\n\ -Wait for completion of a given child process."); - -static PyObject * -posix_waitpid(PyObject *self, PyObject *args) -{ +#else /* defined(HAVE_WAITID) && !defined(__APPLE__) */ +#define OS_WAITID_METHODDEF +#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */ + +#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) + +/*[clinic input] +os.waitpid + pid: pid_t + options: int + / + +Wait for completion of a given child process. + +Returns a tuple of information regarding the child process: + (pid, status) + +The options argument is ignored on Windows. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_waitpid__doc__, +"sig=($module, pid, options)\n" +"Wait for completion of a given child process.\n" +"\n" +"Returns a tuple of information regarding the child process:\n" +" (pid, status)\n" +"\n" +"The options argument is ignored on Windows."); + +#define OS_WAITPID_METHODDEF \ + {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__}, + +static PyObject * +os_waitpid_impl(PyModuleDef *module, pid_t pid, int options); + +static PyObject * +os_waitpid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; int options; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "i:waitpid", + &pid, &options)) + goto exit; + return_value = os_waitpid_impl(module, pid, options); + +exit: + return return_value; +} + +static PyObject * +os_waitpid_impl(PyModuleDef *module, pid_t pid, int options) +/*[clinic end generated code: output=7cfe5b7d527b7bea input=0bf1666b8758fda3]*/ +{ WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options)) - return NULL; Py_BEGIN_ALLOW_THREADS pid = waitpid(pid, &status, options); Py_END_ALLOW_THREADS @@ -6992,18 +9721,59 @@ #elif defined(HAVE_CWAIT) /* MS C has a variant of waitpid() that's usable for most purposes. */ -PyDoc_STRVAR(posix_waitpid__doc__, -"waitpid(pid, options) -> (pid, status << 8)\n\n" -"Wait for completion of a given process. options is ignored on Windows."); - -static PyObject * -posix_waitpid(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.waitpid + pid: Py_intptr_t + options: int + / + +Wait for completion of a given process. + +Returns a tuple of information regarding the process: + (pid, status << 8) + +The options argument is ignored on Windows. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_waitpid__doc__, +"sig=($module, pid, options)\n" +"Wait for completion of a given process.\n" +"\n" +"Returns a tuple of information regarding the process:\n" +" (pid, status << 8)\n" +"\n" +"The options argument is ignored on Windows."); + +#define OS_WAITPID_METHODDEF \ + {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__}, + +static PyObject * +os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options); + +static PyObject * +os_waitpid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; Py_intptr_t pid; - int status, options; - - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options)) - return NULL; + int options; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_INTPTR "i:waitpid", + &pid, &options)) + goto exit; + return_value = os_waitpid_impl(module, pid, options); + +exit: + return return_value; +} + +static PyObject * +os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options) +/*[clinic end generated code: output=1bcc867cdd09bdf9 input=444c8f51cca5b862]*/ +{ + int status; + Py_BEGIN_ALLOW_THREADS pid = _cwait(&status, pid, options); Py_END_ALLOW_THREADS @@ -7013,15 +9783,43 @@ /* shift the status left a byte so this is more like the POSIX waitpid */ return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8); } -#endif /* HAVE_WAITPID || HAVE_CWAIT */ +#else /* defined(HAVE_WAITPID) || defined(HAVE_CWAIT) */ +#define OS_WAITPID_METHODDEF +#endif /* defined(HAVE_WAITPID) || defined(HAVE_CWAIT) */ #ifdef HAVE_WAIT -PyDoc_STRVAR(posix_wait__doc__, -"wait() -> (pid, status)\n\n\ -Wait for completion of a child process."); - -static PyObject * -posix_wait(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.wait + +Wait for completion of a child process. + +Returns a tuple of information about the child process: + (pid, status) +[clinic start generated code]*/ + +PyDoc_STRVAR(os_wait__doc__, +"sig=($module)\n" +"Wait for completion of a child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status)"); + +#define OS_WAIT_METHODDEF \ + {"wait", (PyCFunction)os_wait, METH_NOARGS, os_wait__doc__}, + +static PyObject * +os_wait_impl(PyModuleDef *module); + +static PyObject * +os_wait(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_wait_impl(module); +} + +static PyObject * +os_wait_impl(PyModuleDef *module) +/*[clinic end generated code: output=b84ec20994718ca5 input=03b0182d4a4700ce]*/ { pid_t pid; WAIT_TYPE status; @@ -7035,12 +9833,14 @@ return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); } -#endif +#else /* HAVE_WAIT */ +#define OS_WAIT_METHODDEF +#endif /* HAVE_WAIT */ #if defined(HAVE_READLINK) || defined(MS_WINDOWS) PyDoc_STRVAR(readlink__doc__, -"readlink(path, *, dir_fd=None) -> path\n\n\ +"sig=($module, path, *, dir_fd=None)\n\n\ Return a string representing the path to which the symbolic link points.\n\ \n\ If dir_fd is not None, it should be a file descriptor open to a directory,\n\ @@ -7051,6 +9851,7 @@ #ifdef HAVE_READLINK +/* AC 3.5: merge win32 and not together */ static PyObject * posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -7099,20 +9900,84 @@ #endif /* HAVE_READLINK */ +#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) + +static PyObject * +win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) +{ + wchar_t *path; + DWORD n_bytes_returned; + DWORD io_result; + PyObject *po, *result; + int dir_fd; + HANDLE reparse_point_handle; + + char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; + wchar_t *print_name; + + static char *keywords[] = {"path", "dir_fd", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords, + &po, + dir_fd_unavailable, &dir_fd + )) + return NULL; + + path = PyUnicode_AsUnicode(po); + if (path == NULL) + return NULL; + + /* First get a handle to the reparse point */ + Py_BEGIN_ALLOW_THREADS + reparse_point_handle = CreateFileW( + path, + 0, + 0, + 0, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, + 0); + Py_END_ALLOW_THREADS + + if (reparse_point_handle==INVALID_HANDLE_VALUE) + return win32_error_object("readlink", po); + + Py_BEGIN_ALLOW_THREADS + /* New call DeviceIoControl to read the reparse point */ + io_result = DeviceIoControl( + reparse_point_handle, + FSCTL_GET_REPARSE_POINT, + 0, 0, /* in buffer */ + target_buffer, sizeof(target_buffer), + &n_bytes_returned, + 0 /* we're not using OVERLAPPED_IO */ + ); + CloseHandle(reparse_point_handle); + Py_END_ALLOW_THREADS + + if (io_result==0) + return win32_error_object("readlink", po); + + if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) + { + PyErr_SetString(PyExc_ValueError, + "not a symbolic link"); + return NULL; + } + print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + + rdb->SymbolicLinkReparseBuffer.PrintNameOffset; + + result = PyUnicode_FromWideChar(print_name, + rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); + return result; +} + +#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ + + #ifdef HAVE_SYMLINK -PyDoc_STRVAR(posix_symlink__doc__, -"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\ -Create a symbolic link pointing to src named dst.\n\n\ -target_is_directory is required on Windows if the target is to be\n\ - interpreted as a directory. (On Windows, symlink requires\n\ - Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\ - target_is_directory is ignored on non-Windows platforms.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); #if defined(MS_WINDOWS) @@ -7261,186 +10126,144 @@ #endif -static PyObject * -posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t src; - path_t dst; +/*[clinic input] +os.symlink + src: path_t + dst: path_t + target_is_directory: bool = False + * + dir_fd: dir_fd(requires='symlinkat')=None + +# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\ + +Create a symbolic link pointing to src named dst. + +target_is_directory is required on Windows if the target is to be + interpreted as a directory. (On Windows, symlink requires + Windows 6.0 or greater, and raises a NotImplementedError otherwise.) + target_is_directory is ignored on non-Windows platforms. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_symlink__doc__, +"sig=($module, src, dst, target_is_directory=False, *, dir_fd=None)\n" +"Create a symbolic link pointing to src named dst.\n" +"\n" +"target_is_directory is required on Windows if the target is to be\n" +" interpreted as a directory. (On Windows, symlink requires\n" +" Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n" +" target_is_directory is ignored on non-Windows platforms.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_SYMLINK_METHODDEF \ + {"symlink", (PyCFunction)os_symlink, METH_VARARGS|METH_KEYWORDS, os_symlink__doc__}, + +static PyObject * +os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd); + +static PyObject * +os_symlink(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; + path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0); + int target_is_directory = 0; int dir_fd = DEFAULT_DIR_FD; - int target_is_directory = 0; - static char *keywords[] = {"src", "dst", "target_is_directory", - "dir_fd", NULL}; - PyObject *return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|p$O&:symlink", _keywords, + path_converter, &src, path_converter, &dst, &target_is_directory, SYMLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_symlink_impl(module, &src, &dst, target_is_directory, dir_fd); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +static PyObject * +os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd) +/*[clinic end generated code: output=9256aeae06602d97 input=e820ec4472547bc3]*/ +{ #ifdef MS_WINDOWS DWORD result; #else int result; #endif - memset(&src, 0, sizeof(src)); - src.function_name = "symlink"; - src.argument_name = "src"; - memset(&dst, 0, sizeof(dst)); - dst.function_name = "symlink"; - dst.argument_name = "dst"; - #ifdef MS_WINDOWS if (!check_CreateSymbolicLink()) { PyErr_SetString(PyExc_NotImplementedError, "CreateSymbolicLink functions not found"); - return NULL; + return NULL; } if (!win32_can_symlink) { PyErr_SetString(PyExc_OSError, "symbolic link privilege not held"); - return NULL; - } -#endif - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink", - keywords, - path_converter, &src, - path_converter, &dst, - &target_is_directory, -#ifdef HAVE_SYMLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + return NULL; + } +#endif + + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_SetString(PyExc_ValueError, "symlink: src and dst must be the same type"); - return_value = NULL; - goto exit; - } - -#ifdef MS_WINDOWS - - Py_BEGIN_ALLOW_THREADS - if (dst.wide) { + return NULL; + } + +#ifdef MS_WINDOWS + + Py_BEGIN_ALLOW_THREADS + if (dst->wide) { /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirW(src.wide, dst.wide); - result = Py_CreateSymbolicLinkW(dst.wide, src.wide, + target_is_directory |= _check_dirW(src->wide, dst->wide); + result = Py_CreateSymbolicLinkW(dst->wide, src->wide, target_is_directory); } else { /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirA(src.narrow, dst.narrow); - result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow, + target_is_directory |= _check_dirA(src->narrow, dst->narrow); + result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow, target_is_directory); } Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&src); - goto exit; - } + if (!result) + return path_error(src); #else Py_BEGIN_ALLOW_THREADS #if HAVE_SYMLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = symlinkat(src.narrow, dir_fd, dst.narrow); - else -#endif - result = symlink(src.narrow, dst.narrow); - Py_END_ALLOW_THREADS - - if (result) { - return_value = path_error(&src); - goto exit; - } -#endif - - return_value = Py_None; - Py_INCREF(Py_None); - goto exit; /* silence "unused label" warning */ -exit: - path_cleanup(&src); - path_cleanup(&dst); - return return_value; -} - + result = symlinkat(src->narrow, dir_fd, dst->narrow); + else +#endif + result = symlink(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + + if (result) + return path_error(src); +#endif + + Py_RETURN_NONE; +} +#else /* HAVE_SYMLINK */ #endif /* HAVE_SYMLINK */ -#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) - -static PyObject * -win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) -{ - wchar_t *path; - DWORD n_bytes_returned; - DWORD io_result; - PyObject *po, *result; - int dir_fd; - HANDLE reparse_point_handle; - - char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; - wchar_t *print_name; - - static char *keywords[] = {"path", "dir_fd", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords, - &po, - dir_fd_unavailable, &dir_fd - )) - return NULL; - - path = PyUnicode_AsUnicode(po); - if (path == NULL) - return NULL; - - /* First get a handle to the reparse point */ - Py_BEGIN_ALLOW_THREADS - reparse_point_handle = CreateFileW( - path, - 0, - 0, - 0, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, - 0); - Py_END_ALLOW_THREADS - - if (reparse_point_handle==INVALID_HANDLE_VALUE) - return win32_error_object("readlink", po); - - Py_BEGIN_ALLOW_THREADS - /* New call DeviceIoControl to read the reparse point */ - io_result = DeviceIoControl( - reparse_point_handle, - FSCTL_GET_REPARSE_POINT, - 0, 0, /* in buffer */ - target_buffer, sizeof(target_buffer), - &n_bytes_returned, - 0 /* we're not using OVERLAPPED_IO */ - ); - CloseHandle(reparse_point_handle); - Py_END_ALLOW_THREADS - - if (io_result==0) - return win32_error_object("readlink", po); - - if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) - { - PyErr_SetString(PyExc_ValueError, - "not a symbolic link"); - return NULL; - } - print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.PrintNameOffset; - - result = PyUnicode_FromWideChar(print_name, - rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); - return result; -} - -#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ static PyStructSequence_Field times_result_fields[] = { @@ -7506,15 +10329,46 @@ return value; } -PyDoc_STRVAR(posix_times__doc__, -"times() -> times_result\n\n\ -Return an object containing floating point numbers indicating process\n\ -times. The object behaves like a named tuple with these fields:\n\ - (utime, stime, cutime, cstime, elapsed_time)"); - -#if defined(MS_WINDOWS) -static PyObject * -posix_times(PyObject *self, PyObject *noargs) + +#ifndef MS_WINDOWS +#define NEED_TICKS_PER_SECOND +static long ticks_per_second = -1; +#endif /* MS_WINDOWS */ + +/*[clinic input] +os.times + +Return a collection containing process timing information. + +The object returned behaves like a named tuple with these fields: + (utime, stime, cutime, cstime, elapsed_time) +All fields are floating point numbers. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_times__doc__, +"sig=($module)\n" +"Return a collection containing process timing information.\n" +"\n" +"The object returned behaves like a named tuple with these fields:\n" +" (utime, stime, cutime, cstime, elapsed_time)\n" +"All fields are floating point numbers."); + +#define OS_TIMES_METHODDEF \ + {"times", (PyCFunction)os_times, METH_NOARGS, os_times__doc__}, + +static PyObject * +os_times_impl(PyModuleDef *module); + +static PyObject * +os_times(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_times_impl(module); +} + +static PyObject * +os_times_impl(PyModuleDef *module) +/*[clinic end generated code: output=b224ae988b58ea28 input=2bf9df3d6ab2e48b]*/ +#ifdef MS_WINDOWS { FILETIME create, exit, kernel, user; HANDLE hProc; @@ -7534,12 +10388,10 @@ (double)0, (double)0); } -#else /* Not Windows */ -#define NEED_TICKS_PER_SECOND -static long ticks_per_second = -1; -static PyObject * -posix_times(PyObject *self, PyObject *noargs) -{ +#else /* MS_WINDOWS */ +{ + + struct tms t; clock_t c; errno = 0; @@ -7553,103 +10405,252 @@ (double)t.tms_cstime / ticks_per_second, (double)c / ticks_per_second); } -#endif - +#endif /* MS_WINDOWS */ +#else /* HAVE_TIMES */ +#define TIMES_METHODDEF #endif /* HAVE_TIMES */ #ifdef HAVE_GETSID -PyDoc_STRVAR(posix_getsid__doc__, -"getsid(pid) -> sid\n\n\ -Call the system call getsid()."); - -static PyObject * -posix_getsid(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.getsid + + pid: pid_t + / + +Call the system call getsid(pid) and return the result. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getsid__doc__, +"sig=($module, pid)\n" +"Call the system call getsid(pid) and return the result."); + +#define OS_GETSID_METHODDEF \ + {"getsid", (PyCFunction)os_getsid, METH_VARARGS, os_getsid__doc__}, + +static PyObject * +os_getsid_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_getsid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":getsid", + &pid)) + goto exit; + return_value = os_getsid_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_getsid_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=8fa1d37b57042026 input=eeb2b923a30ce04e]*/ +{ int sid; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid)) - return NULL; sid = getsid(pid); if (sid < 0) return posix_error(); return PyLong_FromLong((long)sid); } +#else /* HAVE_GETSID */ +#define OS_GETSID_METHODDEF #endif /* HAVE_GETSID */ #ifdef HAVE_SETSID -PyDoc_STRVAR(posix_setsid__doc__, -"setsid()\n\n\ -Call the system call setsid()."); - -static PyObject * -posix_setsid(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.setsid + +Call the system call setsid(). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setsid__doc__, +"sig=($module)\n" +"Call the system call setsid()."); + +#define OS_SETSID_METHODDEF \ + {"setsid", (PyCFunction)os_setsid, METH_NOARGS, os_setsid__doc__}, + +static PyObject * +os_setsid_impl(PyModuleDef *module); + +static PyObject * +os_setsid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_setsid_impl(module); +} + +static PyObject * +os_setsid_impl(PyModuleDef *module) +/*[clinic end generated code: output=d01888b98bea33c6 input=5fff45858e2f0776]*/ { if (setsid() < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} + Py_RETURN_NONE; +} +#else /* HAVE_SETSID */ +#define OS_SETSID_METHODDEF #endif /* HAVE_SETSID */ #ifdef HAVE_SETPGID -PyDoc_STRVAR(posix_setpgid__doc__, -"setpgid(pid, pgrp)\n\n\ -Call the system call setpgid()."); - -static PyObject * -posix_setpgid(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.setpgid + + pid: pid_t + pgrp: pid_t + / + +Call the system call setpgid(pid, pgrp). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setpgid__doc__, +"sig=($module, pid, pgrp)\n" +"Call the system call setpgid(pid, pgrp)."); + +#define OS_SETPGID_METHODDEF \ + {"setpgid", (PyCFunction)os_setpgid, METH_VARARGS, os_setpgid__doc__}, + +static PyObject * +os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp); + +static PyObject * +os_setpgid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; pid_t pid; - int pgrp; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp)) - return NULL; + pid_t pgrp; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "" _Py_PARSE_PID ":setpgid", + &pid, &pgrp)) + goto exit; + return_value = os_setpgid_impl(module, pid, pgrp); + +exit: + return return_value; +} + +static PyObject * +os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp) +/*[clinic end generated code: output=3d7c4d1da34f3555 input=fceb395eca572e1a]*/ +{ if (setpgid(pid, pgrp) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} + Py_RETURN_NONE; +} +#else /* HAVE_SETPGID */ +#define OS_SETPGID_METHODDEF #endif /* HAVE_SETPGID */ #ifdef HAVE_TCGETPGRP -PyDoc_STRVAR(posix_tcgetpgrp__doc__, -"tcgetpgrp(fd) -> pgid\n\n\ -Return the process group associated with the terminal given by a fd."); - -static PyObject * -posix_tcgetpgrp(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.tcgetpgrp + + fd: int + / + +Return the process group associated with the terminal specified by fd. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_tcgetpgrp__doc__, +"sig=($module, fd)\n" +"Return the process group associated with the terminal specified by fd."); + +#define OS_TCGETPGRP_METHODDEF \ + {"tcgetpgrp", (PyCFunction)os_tcgetpgrp, METH_VARARGS, os_tcgetpgrp__doc__}, + +static PyObject * +os_tcgetpgrp_impl(PyModuleDef *module, int fd); + +static PyObject * +os_tcgetpgrp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_ParseTuple(args, + "i:tcgetpgrp", + &fd)) + goto exit; + return_value = os_tcgetpgrp_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_tcgetpgrp_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=9b69754090a1871c input=7f6c18eac10ada86]*/ +{ + pid_t pgid = tcgetpgrp(fd); + if (pgid < 0) + return posix_error(); + return PyLong_FromPid(pgid); +} +#else /* HAVE_TCGETPGRP */ +#define OS_TCGETPGRP_METHODDEF +#endif /* HAVE_TCGETPGRP */ + + +#ifdef HAVE_TCSETPGRP + +/*[clinic input] +os.tcsetpgrp + + fd: int + pgid: pid_t + / + +Set the process group associated with the terminal specified by fd. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_tcsetpgrp__doc__, +"sig=($module, fd, pgid)\n" +"Set the process group associated with the terminal specified by fd."); + +#define OS_TCSETPGRP_METHODDEF \ + {"tcsetpgrp", (PyCFunction)os_tcsetpgrp, METH_VARARGS, os_tcsetpgrp__doc__}, + +static PyObject * +os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid); + +static PyObject * +os_tcsetpgrp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int fd; pid_t pgid; - if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) - return NULL; - pgid = tcgetpgrp(fd); - if (pgid < 0) - return posix_error(); - return PyLong_FromPid(pgid); -} -#endif /* HAVE_TCGETPGRP */ - - -#ifdef HAVE_TCSETPGRP -PyDoc_STRVAR(posix_tcsetpgrp__doc__, -"tcsetpgrp(fd, pgid)\n\n\ -Set the process group associated with the terminal given by a fd."); - -static PyObject * -posix_tcsetpgrp(PyObject *self, PyObject *args) -{ - int fd; - pid_t pgid; - if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid)) - return NULL; + + if (!PyArg_ParseTuple(args, + "i" _Py_PARSE_PID ":tcsetpgrp", + &fd, &pgid)) + goto exit; + return_value = os_tcsetpgrp_impl(module, fd, pgid); + +exit: + return return_value; +} + +static PyObject * +os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid) +/*[clinic end generated code: output=f2823a60d9c71652 input=5bdc997c6a619020]*/ +{ if (tcsetpgrp(fd, pgid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} + Py_RETURN_NONE; +} +#else /* HAVE_TCSETPGRP */ +#define OS_TCSETPGRP_METHODDEF #endif /* HAVE_TCSETPGRP */ /* Functions acting on file descriptors */ @@ -7658,44 +10659,79 @@ extern int _Py_open_cloexec_works; #endif -PyDoc_STRVAR(posix_open__doc__, -"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ -Open a file for low level IO. Returns a file handle (integer).\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); - -static PyObject * -posix_open(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; + +/*[clinic input] +os.open -> int + path: path_t + flags: int + mode: int = 0o777 + * + dir_fd: dir_fd(requires='openat') = None + +# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ + +Open a file for low level IO. Returns a file descriptor (integer). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_open__doc__, +"sig=($module, path, flags, mode=511, *, dir_fd=None)\n" +"Open a file for low level IO. Returns a file descriptor (integer).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_OPEN_METHODDEF \ + {"open", (PyCFunction)os_open, METH_VARARGS|METH_KEYWORDS, os_open__doc__}, + +static int +os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd); + +static PyObject * +os_open(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); int flags; - int mode = 0777; + int mode = 511; int dir_fd = DEFAULT_DIR_FD; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&i|i$O&:open", _keywords, + path_converter, &path, &flags, &mode, OPENAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + _return_value = os_open_impl(module, &path, flags, mode, dir_fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static int +os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd) +/*[clinic end generated code: output=8855eed0257e614b input=ad8623b29acd2934]*/ +{ int fd; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + #ifdef O_CLOEXEC int *atomic_flag_works = &_Py_open_cloexec_works; #elif !defined(MS_WINDOWS) int *atomic_flag_works = NULL; #endif - memset(&path, 0, sizeof(path)); - path.function_name = "open"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords, - path_converter, &path, - &flags, &mode, -#ifdef HAVE_OPENAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - #ifdef MS_WINDOWS flags |= O_NOINHERIT; #elif defined(O_CLOEXEC) @@ -7705,46 +10741,73 @@ Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS if (path.wide) - fd = _wopen(path.wide, flags, mode); + fd = _wopen(path->wide, flags, mode); else #endif #ifdef HAVE_OPENAT if (dir_fd != DEFAULT_DIR_FD) - fd = openat(dir_fd, path.narrow, flags, mode); - else -#endif - fd = open(path.narrow, flags, mode); + fd = openat(dir_fd, path->narrow, flags, mode); + else +#endif + fd = open(path->narrow, flags, mode); Py_END_ALLOW_THREADS if (fd == -1) { - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object); - goto exit; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); + return -1; } #ifndef MS_WINDOWS if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { close(fd); - goto exit; - } -#endif - - return_value = PyLong_FromLong((long)fd); - -exit: - path_cleanup(&path); - return return_value; -} - -PyDoc_STRVAR(posix_close__doc__, -"close(fd)\n\n\ -Close a file descriptor (for low level IO)."); - -static PyObject * -posix_close(PyObject *self, PyObject *args) -{ - int fd, res; - if (!PyArg_ParseTuple(args, "i:close", &fd)) - return NULL; + return -1; + } +#endif + + return fd; +} + + +/*[clinic input] +os.close + + fd: int + +Close a file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_close__doc__, +"sig=($module, fd)\n" +"Close a file descriptor."); + +#define OS_CLOSE_METHODDEF \ + {"close", (PyCFunction)os_close, METH_VARARGS|METH_KEYWORDS, os_close__doc__}, + +static PyObject * +os_close_impl(PyModuleDef *module, int fd); + +static PyObject * +os_close(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:close", _keywords, + &fd)) + goto exit; + return_value = os_close_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_close_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=d85a25f144aa040a input=2bc42451ca5c3223]*/ +{ + int res; if (!_PyVerify_fd(fd)) return posix_error(); Py_BEGIN_ALLOW_THREADS @@ -7752,23 +10815,54 @@ Py_END_ALLOW_THREADS if (res < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} - - -PyDoc_STRVAR(posix_closerange__doc__, -"closerange(fd_low, fd_high)\n\n\ -Closes all file descriptors in [fd_low, fd_high), ignoring errors."); - -static PyObject * -posix_closerange(PyObject *self, PyObject *args) -{ - int fd_from, fd_to, i; - if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) - return NULL; - Py_BEGIN_ALLOW_THREADS - for (i = fd_from; i < fd_to; i++) + Py_RETURN_NONE; +} + + +/*[clinic input] +os.closerange + + fd_low: int + fd_high: int + / + +Closes all file descriptors in [fd_low, fd_high), ignoring errors. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_closerange__doc__, +"sig=($module, fd_low, fd_high)\n" +"Closes all file descriptors in [fd_low, fd_high), ignoring errors."); + +#define OS_CLOSERANGE_METHODDEF \ + {"closerange", (PyCFunction)os_closerange, METH_VARARGS, os_closerange__doc__}, + +static PyObject * +os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high); + +static PyObject * +os_closerange(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd_low; + int fd_high; + + if (!PyArg_ParseTuple(args, + "ii:closerange", + &fd_low, &fd_high)) + goto exit; + return_value = os_closerange_impl(module, fd_low, fd_high); + +exit: + return return_value; +} + +static PyObject * +os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high) +/*[clinic end generated code: output=0b76a1967b703e15 input=5855a3d053ebd4ec]*/ +{ + int i; + Py_BEGIN_ALLOW_THREADS + for (i = fd_low; i < fd_high; i++) if (_PyVerify_fd(i)) close(i); Py_END_ALLOW_THREADS @@ -7776,36 +10870,96 @@ } -PyDoc_STRVAR(posix_dup__doc__, -"dup(fd) -> fd2\n\n\ -Return a duplicate of a file descriptor."); - -static PyObject * -posix_dup(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.dup -> int + + fd: int + / + +Return a duplicate of a file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_dup__doc__, +"sig=($module, fd)\n" +"Return a duplicate of a file descriptor."); + +#define OS_DUP_METHODDEF \ + {"dup", (PyCFunction)os_dup, METH_VARARGS, os_dup__doc__}, + +static int +os_dup_impl(PyModuleDef *module, int fd); + +static PyObject * +os_dup(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int fd; - - if (!PyArg_ParseTuple(args, "i:dup", &fd)) - return NULL; - - fd = _Py_dup(fd); - if (fd == -1) - return NULL; - - return PyLong_FromLong((long)fd); -} - - -PyDoc_STRVAR(posix_dup2__doc__, -"dup2(old_fd, new_fd)\n\n\ -Duplicate file descriptor."); - -static PyObject * -posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"fd", "fd2", "inheritable", NULL}; - int fd, fd2; + int _return_value; + + if (!PyArg_ParseTuple(args, + "i:dup", + &fd)) + goto exit; + _return_value = os_dup_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_dup_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=658f85df60421f21 input=6f10f7ea97f7852a]*/ +{ + return _Py_dup(fd); +} + + +/*[clinic input] +os.dup2 + fd: int + fd2: int + inheritable: bool=True + +Duplicate file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_dup2__doc__, +"sig=($module, fd, fd2, inheritable=True)\n" +"Duplicate file descriptor."); + +#define OS_DUP2_METHODDEF \ + {"dup2", (PyCFunction)os_dup2, METH_VARARGS|METH_KEYWORDS, os_dup2__doc__}, + +static PyObject * +os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable); + +static PyObject * +os_dup2(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "fd2", "inheritable", NULL}; + int fd; + int fd2; int inheritable = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "ii|p:dup2", _keywords, + &fd, &fd2, &inheritable)) + goto exit; + return_value = os_dup2_impl(module, fd, fd2, inheritable); + +exit: + return return_value; +} + +static PyObject * +os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable) +/*[clinic end generated code: output=41e3b02454df6ac2 input=76e96f511be0352f]*/ +{ int res; #if defined(HAVE_DUP3) && \ !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)) @@ -7813,10 +10967,6 @@ int dup3_works = -1; #endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords, - &fd, &fd2, &inheritable)) - return NULL; - if (!_PyVerify_fd_dup2(fd, fd2)) return posix_error(); @@ -7877,30 +11027,69 @@ #endif - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #ifdef HAVE_LOCKF -PyDoc_STRVAR(posix_lockf__doc__, -"lockf(fd, cmd, len)\n\n\ -Apply, test or remove a POSIX lock on an open file descriptor.\n\n\ -fd is an open file descriptor.\n\ -cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\ -F_TEST.\n\ -len specifies the section of the file to lock."); - -static PyObject * -posix_lockf(PyObject *self, PyObject *args) -{ - int fd, cmd, res; - off_t len; - if (!PyArg_ParseTuple(args, "iiO&:lockf", - &fd, &cmd, _parse_off_t, &len)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - res = lockf(fd, cmd, len); + +/*[clinic input] +os.lockf + + fd: int + An open file descriptor. + command: int + One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST. + length: Py_off_t + The number of bytes to lock, starting at the current position. + / + +Apply, test or remove a POSIX lock on an open file descriptor. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lockf__doc__, +"sig=($module, fd, command, length)\n" +"Apply, test or remove a POSIX lock on an open file descriptor.\n" +"\n" +" fd\n" +" An open file descriptor.\n" +" command\n" +" One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.\n" +" length\n" +" The number of bytes to lock, starting at the current position."); + +#define OS_LOCKF_METHODDEF \ + {"lockf", (PyCFunction)os_lockf, METH_VARARGS, os_lockf__doc__}, + +static PyObject * +os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length); + +static PyObject * +os_lockf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int command; + Py_off_t length; + + if (!PyArg_ParseTuple(args, + "iiO&:lockf", + &fd, &command, Py_off_t_converter, &length)) + goto exit; + return_value = os_lockf_impl(module, fd, command, length); + +exit: + return return_value; +} + +static PyObject * +os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length) +/*[clinic end generated code: output=383cc6aa6faaad3b input=65da41d2106e9b79]*/ +{ + int res; + + Py_BEGIN_ALLOW_THREADS + res = lockf(fd, command, length); Py_END_ALLOW_THREADS if (res < 0) @@ -7908,95 +11097,161 @@ Py_RETURN_NONE; } -#endif - - -PyDoc_STRVAR(posix_lseek__doc__, -"lseek(fd, pos, how) -> newpos\n\n\ -Set the current position of a file descriptor.\n\ -Return the new cursor position in bytes, starting from the beginning."); - -static PyObject * -posix_lseek(PyObject *self, PyObject *args) -{ - int fd, how; -#ifdef MS_WINDOWS - PY_LONG_LONG pos, res; -#else - off_t pos, res; -#endif - PyObject *posobj; - if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) - return NULL; +#else /* HAVE_LOCKF */ +#define OS_LOCKF_METHODDEF +#endif /* HAVE_LOCKF */ + + + +/*[clinic input] +os.lseek -> Py_off_t + + fd: int + position: Py_off_t + how: int + / + +Set the position of a file descriptor. Return the new position. + +Return the new cursor position in number of bytes +relative to the beginning of the file. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lseek__doc__, +"sig=($module, fd, position, how)\n" +"Set the position of a file descriptor. Return the new position.\n" +"\n" +"Return the new cursor position in number of bytes\n" +"relative to the beginning of the file."); + +#define OS_LSEEK_METHODDEF \ + {"lseek", (PyCFunction)os_lseek, METH_VARARGS, os_lseek__doc__}, + +static Py_off_t +os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how); + +static PyObject * +os_lseek(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t position; + int how; + Py_off_t _return_value; + + if (!PyArg_ParseTuple(args, + "iO&i:lseek", + &fd, Py_off_t_converter, &position, &how)) + goto exit; + _return_value = os_lseek_impl(module, fd, position, how); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromPy_off_t(_return_value); + +exit: + return return_value; +} + +static Py_off_t +os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how) +/*[clinic end generated code: output=a9beaa676ab5d249 input=902654ad3f96a6d3]*/ +{ + Py_off_t result; + + if (!_PyVerify_fd(fd)) { + posix_error(); + return -1; + } #ifdef SEEK_SET /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ switch (how) { - case 0: how = SEEK_SET; break; - case 1: how = SEEK_CUR; break; - case 2: how = SEEK_END; break; + case 0: how = SEEK_SET; break; + case 1: how = SEEK_CUR; break; + case 2: how = SEEK_END; break; } #endif /* SEEK_END */ -#if !defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLong(posobj); -#else - pos = PyLong_AsLongLong(posobj); -#endif - if (PyErr_Occurred()) - return NULL; - - if (!_PyVerify_fd(fd)) - return posix_error(); - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - res = _lseeki64(fd, pos, how); -#else - res = lseek(fd, pos, how); -#endif - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - -#if !defined(HAVE_LARGEFILE_SUPPORT) - return PyLong_FromLong(res); -#else - return PyLong_FromLongLong(res); -#endif -} - - -PyDoc_STRVAR(posix_read__doc__, -"read(fd, buffersize) -> bytes\n\n\ -Read a file descriptor."); - -static PyObject * -posix_read(PyObject *self, PyObject *args) -{ - int fd, size; + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + result = _lseeki64(fd, position, how); +#else + result = lseek(fd, position, how); +#endif + Py_END_ALLOW_THREADS + + if (result < 0) + posix_error(); + + return result; +} + + + +/*[clinic input] +os.read + fd: int + length: int + / + +Read a file descriptor. Returns a bytes object. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_read__doc__, +"sig=($module, fd, length)\n" +"Read a file descriptor. Returns a bytes object."); + +#define OS_READ_METHODDEF \ + {"read", (PyCFunction)os_read, METH_VARARGS, os_read__doc__}, + +static PyObject * +os_read_impl(PyModuleDef *module, int fd, int length); + +static PyObject * +os_read(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int length; + + if (!PyArg_ParseTuple(args, + "ii:read", + &fd, &length)) + goto exit; + return_value = os_read_impl(module, fd, length); + +exit: + return return_value; +} + +static PyObject * +os_read_impl(PyModuleDef *module, int fd, int length) +/*[clinic end generated code: output=eb2fde1c7c69ea11 input=0b6250f9217aa019]*/ +{ Py_ssize_t n; PyObject *buffer; - if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) - return NULL; - if (size < 0) { + + if (length < 0) { errno = EINVAL; return posix_error(); } - buffer = PyBytes_FromStringAndSize((char *)NULL, size); + if (!_PyVerify_fd(fd)) + return posix_error(); + + buffer = PyBytes_FromStringAndSize((char *)NULL, length); if (buffer == NULL) return NULL; - if (!_PyVerify_fd(fd)) { - Py_DECREF(buffer); - return posix_error(); - } - Py_BEGIN_ALLOW_THREADS - n = read(fd, PyBytes_AS_STRING(buffer), size); - Py_END_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + n = read(fd, PyBytes_AS_STRING(buffer), length); + Py_END_ALLOW_THREADS + if (n < 0) { Py_DECREF(buffer); return posix_error(); } - if (n != size) + + if (n != length) _PyBytes_Resize(&buffer, n); + return buffer; } @@ -8059,69 +11314,160 @@ #endif #ifdef HAVE_READV -PyDoc_STRVAR(posix_readv__doc__, -"readv(fd, buffers) -> bytesread\n\n\ -Read from a file descriptor fd into a number of mutable, bytes-like\n\ -objects (\"buffers\"). readv will transfer data into each buffer\n\ -until it is full and then move on to the next buffer in the sequence\n\ -to hold the rest of the data.\n\n\ -readv returns the total number of bytes read (which may be less than\n\ -the total capacity of all the buffers."); - -static PyObject * -posix_readv(PyObject *self, PyObject *args) -{ - int fd, cnt; + +/*[clinic input] +os.readv -> Py_ssize_t + + fd: int + buffers: object + / + +Read from a file descriptor fd into an iterable of buffers. + +The buffers should be mutable buffers accepting bytes. +readv will transfer data into each buffer until it is full +and then move on to the next buffer in the sequence to hold +the rest of the data. + +readv returns the total number of bytes read, +which may be less than the total capacity of all the buffers. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_readv__doc__, +"sig=($module, fd, buffers)\n" +"Read from a file descriptor fd into an iterable of buffers.\n" +"\n" +"The buffers should be mutable buffers accepting bytes.\n" +"readv will transfer data into each buffer until it is full\n" +"and then move on to the next buffer in the sequence to hold\n" +"the rest of the data.\n" +"\n" +"readv returns the total number of bytes read,\n" +"which may be less than the total capacity of all the buffers."); + +#define OS_READV_METHODDEF \ + {"readv", (PyCFunction)os_readv, METH_VARARGS, os_readv__doc__}, + +static Py_ssize_t +os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers); + +static PyObject * +os_readv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, + "iO:readv", + &fd, &buffers)) + goto exit; + _return_value = os_readv_impl(module, fd, buffers); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +static Py_ssize_t +os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers) +/*[clinic end generated code: output=054a1b7a0706a6c0 input=e679eb5dbfa0357d]*/ +{ + int cnt; Py_ssize_t n; - PyObject *seq; struct iovec *iov; Py_buffer *buf; - if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq)) - return NULL; - if (!PySequence_Check(seq)) { + if (!PySequence_Check(buffers)) { PyErr_SetString(PyExc_TypeError, "readv() arg 2 must be a sequence"); - return NULL; - } - cnt = PySequence_Size(seq); - - if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0) - return NULL; + return -1; + } + + cnt = PySequence_Size(buffers); + + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) + return -1; Py_BEGIN_ALLOW_THREADS n = readv(fd, iov, cnt); Py_END_ALLOW_THREADS iov_cleanup(iov, buf, cnt); - if (n < 0) - return posix_error(); - - return PyLong_FromSsize_t(n); -} -#endif + if (n < 0) { + posix_error(); + return -1; + } + + return n; +} +#else /* HAVE_READV */ +#define OS_READV_METHODDEF +#endif /* HAVE_READV */ #ifdef HAVE_PREAD -PyDoc_STRVAR(posix_pread__doc__, -"pread(fd, buffersize, offset) -> string\n\n\ -Read from a file descriptor, fd, at a position of offset. It will read up\n\ -to buffersize number of bytes. The file offset remains unchanged."); - -static PyObject * -posix_pread(PyObject *self, PyObject *args) -{ - int fd, size; - off_t offset; + +/*[clinic input] +# TODO length should be size_t! but Python doesn't support parsing size_t yet. +os.pread + + fd: int + length: int + offset: Py_off_t + / + +Read a number of bytes from a file descriptor starting at a particular offset. + +Read length bytes from file descriptor fd, starting at offset bytes from +the beginning of the file. The file offset remains unchanged. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pread__doc__, +"sig=($module, fd, length, offset)\n" +"Read a number of bytes from a file descriptor starting at a particular offset.\n" +"\n" +"Read length bytes from file descriptor fd, starting at offset bytes from\n" +"the beginning of the file. The file offset remains unchanged."); + +#define OS_PREAD_METHODDEF \ + {"pread", (PyCFunction)os_pread, METH_VARARGS, os_pread__doc__}, + +static PyObject * +os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset); + +static PyObject * +os_pread(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int length; + Py_off_t offset; + + if (!PyArg_ParseTuple(args, + "iiO&:pread", + &fd, &length, Py_off_t_converter, &offset)) + goto exit; + return_value = os_pread_impl(module, fd, length, offset); + +exit: + return return_value; +} + +static PyObject * +os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset) +/*[clinic end generated code: output=e14455d7c233006d input=084948dcbaa35d4c]*/ +{ Py_ssize_t n; PyObject *buffer; - if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset)) - return NULL; - - if (size < 0) { + + if (length < 0) { errno = EINVAL; return posix_error(); } - buffer = PyBytes_FromStringAndSize((char *)NULL, size); + buffer = PyBytes_FromStringAndSize((char *)NULL, length); if (buffer == NULL) return NULL; if (!_PyVerify_fd(fd)) { @@ -8129,49 +11475,92 @@ return posix_error(); } Py_BEGIN_ALLOW_THREADS - n = pread(fd, PyBytes_AS_STRING(buffer), size, offset); + n = pread(fd, PyBytes_AS_STRING(buffer), length, offset); Py_END_ALLOW_THREADS if (n < 0) { Py_DECREF(buffer); return posix_error(); } - if (n != size) + if (n != length) _PyBytes_Resize(&buffer, n); return buffer; } -#endif - -PyDoc_STRVAR(posix_write__doc__, -"write(fd, data) -> byteswritten\n\n\ -Write bytes to a file descriptor."); - -static PyObject * -posix_write(PyObject *self, PyObject *args) -{ - Py_buffer pbuf; +#else /* HAVE_PREAD */ +#define OS_PREAD_METHODDEF +#endif /* HAVE_PREAD */ + + +/*[clinic input] +os.write -> Py_ssize_t + + fd: int + data: Py_buffer + / + +Write a bytes object to a file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_write__doc__, +"sig=($module, fd, data)\n" +"Write a bytes object to a file descriptor."); + +#define OS_WRITE_METHODDEF \ + {"write", (PyCFunction)os_write, METH_VARARGS, os_write__doc__}, + +static Py_ssize_t +os_write_impl(PyModuleDef *module, int fd, Py_buffer *data); + +static PyObject * +os_write(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int fd; - Py_ssize_t size, len; - - if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf)) - return NULL; + Py_buffer data = {NULL, NULL}; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, + "iy*:write", + &fd, &data)) + goto exit; + _return_value = os_write_impl(module, fd, &data); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +static Py_ssize_t +os_write_impl(PyModuleDef *module, int fd, Py_buffer *data) +/*[clinic end generated code: output=dfeca3b408cbc849 input=3207e28963234f3c]*/ +{ + Py_ssize_t size; + Py_ssize_t len = data->len; + if (!_PyVerify_fd(fd)) { - PyBuffer_Release(&pbuf); - return posix_error(); - } - len = pbuf.len; + posix_error(); + return -1; + } + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS if (len > INT_MAX) len = INT_MAX; - size = write(fd, pbuf.buf, (int)len); -#else - size = write(fd, pbuf.buf, len); -#endif - Py_END_ALLOW_THREADS - PyBuffer_Release(&pbuf); - if (size < 0) - return posix_error(); - return PyLong_FromSsize_t(size); + size = write(fd, data->buf, (int)len); +#else + size = write(fd, data->buf, len); +#endif + Py_END_ALLOW_THREADS + if (size < 0) { + posix_error(); + return -1; + } + return size; } #ifdef HAVE_SENDFILE @@ -8181,6 +11570,7 @@ -> byteswritten\n\ Copy nbytes bytes from file descriptor in to file descriptor out."); +/* AC 3.5: don't bother converting, has optional group*/ static PyObject * posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) { @@ -8206,10 +11596,10 @@ #ifdef __APPLE__ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile", - keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes, + keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes, #else if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile", - keywords, &out, &in, _parse_off_t, &offset, &len, + keywords, &out, &in, Py_off_t_converter, &offset, &len, #endif &headers, &trailers, &flags)) return NULL; @@ -8302,7 +11692,7 @@ return Py_BuildValue("n", ret); } #endif - if (!_parse_off_t(offobj, &offset)) + if (!Py_off_t_converter(offobj, &offset)) return NULL; Py_BEGIN_ALLOW_THREADS ret = sendfile(out, in, &offset, count); @@ -8312,21 +11702,58 @@ return Py_BuildValue("n", ret); #endif } -#endif - -PyDoc_STRVAR(posix_fstat__doc__, -"fstat(fd) -> stat result\n\n\ -Like stat(), but for an open file descriptor.\n\ -Equivalent to stat(fd=fd)."); - -static PyObject * -posix_fstat(PyObject *self, PyObject *args) -{ +#else /* HAVE_SENDFILE */ +#endif /* HAVE_SENDFILE */ + + +/*[clinic input] +os.fstat + + fd : int + +Perform a stat system call on the given file descriptor. + +Like stat(), but for an open file descriptor. +Equivalent to os.stat(fd). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fstat__doc__, +"sig=($module, fd)\n" +"Perform a stat system call on the given file descriptor.\n" +"\n" +"Like stat(), but for an open file descriptor.\n" +"Equivalent to os.stat(fd)."); + +#define OS_FSTAT_METHODDEF \ + {"fstat", (PyCFunction)os_fstat, METH_VARARGS|METH_KEYWORDS, os_fstat__doc__}, + +static PyObject * +os_fstat_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fstat(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:fstat", _keywords, + &fd)) + goto exit; + return_value = os_fstat_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_fstat_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=fc645f5d8fa41065 input=27e0e0ebbe5600c9]*/ +{ STRUCT_STAT st; int res; - if (!PyArg_ParseTuple(args, "i:fstat", &fd)) - return NULL; + Py_BEGIN_ALLOW_THREADS res = FSTAT(fd, &st); Py_END_ALLOW_THREADS @@ -8341,29 +11768,93 @@ return _pystat_fromstructstat(&st); } -PyDoc_STRVAR(posix_isatty__doc__, -"isatty(fd) -> bool\n\n\ -Return True if the file descriptor 'fd' is an open file descriptor\n\ -connected to the slave end of a terminal."); - -static PyObject * -posix_isatty(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.isatty -> bool + fd: int + / + +Return True if the fd is connected to a terminal. + +Return True if the file descriptor is an open file descriptor +connected to the slave end of a terminal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_isatty__doc__, +"sig=($module, fd)\n" +"Return True if the fd is connected to a terminal.\n" +"\n" +"Return True if the file descriptor is an open file descriptor\n" +"connected to the slave end of a terminal."); + +#define OS_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)os_isatty, METH_VARARGS, os_isatty__doc__}, + +static int +os_isatty_impl(PyModuleDef *module, int fd); + +static PyObject * +os_isatty(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int fd; - if (!PyArg_ParseTuple(args, "i:isatty", &fd)) - return NULL; + int _return_value; + + if (!PyArg_ParseTuple(args, + "i:isatty", + &fd)) + goto exit; + _return_value = os_isatty_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_isatty_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=1f1f27be9f1e2a40 input=08ce94aa1eaf7b5e]*/ +{ if (!_PyVerify_fd(fd)) - return PyBool_FromLong(0); - return PyBool_FromLong(isatty(fd)); + return 0; + return isatty(fd); } #ifdef HAVE_PIPE -PyDoc_STRVAR(posix_pipe__doc__, -"pipe() -> (read_end, write_end)\n\n\ -Create a pipe."); - -static PyObject * -posix_pipe(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.pipe + +Create a pipe. + +Returns a tuple of two file descriptors: + (read_fd, write_fd) +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pipe__doc__, +"sig=($module)\n" +"Create a pipe.\n" +"\n" +"Returns a tuple of two file descriptors:\n" +" (read_fd, write_fd)"); + +#define OS_PIPE_METHODDEF \ + {"pipe", (PyCFunction)os_pipe, METH_NOARGS, os_pipe__doc__}, + +static PyObject * +os_pipe_impl(PyModuleDef *module); + +static PyObject * +os_pipe(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_pipe_impl(module); +} + +static PyObject * +os_pipe_impl(PyModuleDef *module) +/*[clinic end generated code: output=50b4384247e6a8de input=02535e8c8fa6c4d4]*/ { int fds[2]; #ifdef MS_WINDOWS @@ -8429,515 +11920,1048 @@ #endif /* !MS_WINDOWS */ return Py_BuildValue("(ii)", fds[0], fds[1]); } +#else /* HAVE_PIPE */ +#define OS_PIPE_METHODDEF #endif /* HAVE_PIPE */ #ifdef HAVE_PIPE2 -PyDoc_STRVAR(posix_pipe2__doc__, -"pipe2(flags) -> (read_end, write_end)\n\n\ -Create a pipe with flags set atomically.\n\ -flags can be constructed by ORing together one or more of these values:\n\ -O_NONBLOCK, O_CLOEXEC.\n\ -"); - -static PyObject * -posix_pipe2(PyObject *self, PyObject *arg) -{ + +/*[clinic input] +os.pipe2 + + flags: int + / + +Create a pipe with flags set atomically. + +Returns a tuple of two file descriptors: + (read_fd, write_fd) + +flags can be constructed by ORing together one or more of these values: +O_NONBLOCK, O_CLOEXEC. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pipe2__doc__, +"sig=($module, flags)\n" +"Create a pipe with flags set atomically.\n" +"\n" +"Returns a tuple of two file descriptors:\n" +" (read_fd, write_fd)\n" +"\n" +"flags can be constructed by ORing together one or more of these values:\n" +"O_NONBLOCK, O_CLOEXEC."); + +#define OS_PIPE2_METHODDEF \ + {"pipe2", (PyCFunction)os_pipe2, METH_VARARGS, os_pipe2__doc__}, + +static PyObject * +os_pipe2_impl(PyModuleDef *module, int flags); + +static PyObject * +os_pipe2(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int flags; + + if (!PyArg_ParseTuple(args, + "i:pipe2", + &flags)) + goto exit; + return_value = os_pipe2_impl(module, flags); + +exit: + return return_value; +} + +static PyObject * +os_pipe2_impl(PyModuleDef *module, int flags) +/*[clinic end generated code: output=ed9ae7b75102749c input=f261b6e7e63c6817]*/ +{ int fds[2]; int res; - flags = _PyLong_AsInt(arg); - if (flags == -1 && PyErr_Occurred()) - return NULL; - res = pipe2(fds, flags); if (res != 0) return posix_error(); return Py_BuildValue("(ii)", fds[0], fds[1]); } +#else /* HAVE_PIPE2 */ +#define OS_PIPE2_METHODDEF #endif /* HAVE_PIPE2 */ #ifdef HAVE_WRITEV -PyDoc_STRVAR(posix_writev__doc__, -"writev(fd, buffers) -> byteswritten\n\n\ -Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\ -must be a sequence of bytes-like objects.\n\n\ -writev writes the contents of each object to the file descriptor\n\ -and returns the total number of bytes written."); - -static PyObject * -posix_writev(PyObject *self, PyObject *args) -{ - int fd, cnt; - Py_ssize_t res; - PyObject *seq; + +/*[clinic input] +os.writev -> Py_ssize_t + fd: int + buffers: object + / + +Iterate over buffers, and write the contents of each to a file descriptor. + +Returns the total number of bytes written. +buffers must be a sequence of bytes-like objects. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_writev__doc__, +"sig=($module, fd, buffers)\n" +"Iterate over buffers, and write the contents of each to a file descriptor.\n" +"\n" +"Returns the total number of bytes written.\n" +"buffers must be a sequence of bytes-like objects."); + +#define OS_WRITEV_METHODDEF \ + {"writev", (PyCFunction)os_writev, METH_VARARGS, os_writev__doc__}, + +static Py_ssize_t +os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers); + +static PyObject * +os_writev(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, + "iO:writev", + &fd, &buffers)) + goto exit; + _return_value = os_writev_impl(module, fd, buffers); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +static Py_ssize_t +os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers) +/*[clinic end generated code: output=1cc267420ec2b46d input=5b8d17fe4189d2fe]*/ +{ + int cnt; + Py_ssize_t result; struct iovec *iov; Py_buffer *buf; - if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq)) - return NULL; - if (!PySequence_Check(seq)) { + + if (!PySequence_Check(buffers)) { PyErr_SetString(PyExc_TypeError, "writev() arg 2 must be a sequence"); - return NULL; - } - cnt = PySequence_Size(seq); - - if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - res = writev(fd, iov, cnt); + return -1; + } + cnt = PySequence_Size(buffers); + + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { + return -1; + } + + Py_BEGIN_ALLOW_THREADS + result = writev(fd, iov, cnt); Py_END_ALLOW_THREADS iov_cleanup(iov, buf, cnt); - if (res < 0) - return posix_error(); - - return PyLong_FromSsize_t(res); -} -#endif + if (result < 0) + posix_error(); + + return result; +} +#else /* HAVE_WRITEV */ +#define OS_WRITEV_METHODDEF +#endif /* HAVE_WRITEV */ #ifdef HAVE_PWRITE -PyDoc_STRVAR(posix_pwrite__doc__, -"pwrite(fd, string, offset) -> byteswritten\n\n\ -Write string to a file descriptor, fd, from offset, leaving the file\n\ -offset unchanged."); - -static PyObject * -posix_pwrite(PyObject *self, PyObject *args) -{ - Py_buffer pbuf; + +/*[clinic input] +os.pwrite -> Py_ssize_t + + fd: int + buffer: Py_buffer + offset: Py_off_t + / + +Write bytes to a file descriptor starting at a particular offset. + +Write buffer to fd, starting at offset bytes from the beginning of +the file. Returns the number of bytes writte. Does not change the +current file offset. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pwrite__doc__, +"sig=($module, fd, buffer, offset)\n" +"Write bytes to a file descriptor starting at a particular offset.\n" +"\n" +"Write buffer to fd, starting at offset bytes from the beginning of\n" +"the file. Returns the number of bytes writte. Does not change the\n" +"current file offset."); + +#define OS_PWRITE_METHODDEF \ + {"pwrite", (PyCFunction)os_pwrite, METH_VARARGS, os_pwrite__doc__}, + +static Py_ssize_t +os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset); + +static PyObject * +os_pwrite(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int fd; - off_t offset; + Py_buffer buffer = {NULL, NULL}; + Py_off_t offset; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, + "iy*O&:pwrite", + &fd, &buffer, Py_off_t_converter, &offset)) + goto exit; + _return_value = os_pwrite_impl(module, fd, &buffer, offset); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) + PyBuffer_Release(&buffer); + + return return_value; +} + +static Py_ssize_t +os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset) +/*[clinic end generated code: output=ca9006b58aea2971 input=19903f1b3dd26377]*/ +{ Py_ssize_t size; - if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset)) - return NULL; - if (!_PyVerify_fd(fd)) { - PyBuffer_Release(&pbuf); - return posix_error(); - } - Py_BEGIN_ALLOW_THREADS - size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset); - Py_END_ALLOW_THREADS - PyBuffer_Release(&pbuf); + posix_error(); + return -1; + } + + Py_BEGIN_ALLOW_THREADS + size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset); + Py_END_ALLOW_THREADS + if (size < 0) - return posix_error(); - return PyLong_FromSsize_t(size); -} -#endif + posix_error(); + return size; +} +#else /* HAVE_PWRITE */ +#define OS_PWRITE_METHODDEF +#endif /* HAVE_PWRITE */ #ifdef HAVE_MKFIFO -PyDoc_STRVAR(posix_mkfifo__doc__, -"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\ -Create a FIFO (a POSIX named pipe).\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); - -static PyObject * -posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - int mode = 0666; + +/*[clinic input] +os.mkfifo + + path: path_t + mode: int=0o666 + * + dir_fd: dir_fd(requires='mkfifoat')=None + +Create a "fifo" (a POSIX named pipe). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_mkfifo__doc__, +"sig=($module, path, mode=438, *, dir_fd=None)\n" +"Create a \"fifo\" (a POSIX named pipe).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_MKFIFO_METHODDEF \ + {"mkfifo", (PyCFunction)os_mkfifo, METH_VARARGS|METH_KEYWORDS, os_mkfifo__doc__}, + +static PyObject * +os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd); + +static PyObject * +os_mkfifo(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); + int mode = 438; int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|i$O&:mkfifo", _keywords, + path_converter, &path, &mode, MKFIFOAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_mkfifo_impl(module, &path, mode, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd) +/*[clinic end generated code: output=da691430e85f1eef input=73032e98a36e0e19]*/ +{ int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "dir_fd", NULL}; - - memset(&path, 0, sizeof(path)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords, - path_converter, &path, - &mode, -#ifdef HAVE_MKFIFOAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKFIFOAT if (dir_fd != DEFAULT_DIR_FD) - result = mkfifoat(dir_fd, path.narrow, mode); - else -#endif - result = mkfifo(path.narrow, mode); - Py_END_ALLOW_THREADS - - if (result < 0) { - return_value = posix_error(); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); - -exit: - path_cleanup(&path); - return return_value; -} -#endif + result = mkfifoat(dir_fd, path->narrow, mode); + else +#endif + result = mkfifo(path->narrow, mode); + Py_END_ALLOW_THREADS + + if (result < 0) + return posix_error(); + + Py_RETURN_NONE; +} +#else /* HAVE_MKFIFO */ +#define OS_MKFIFO_METHODDEF +#endif /* HAVE_MKFIFO */ #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) -PyDoc_STRVAR(posix_mknod__doc__, -"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\ -Create a filesystem node (file, device special file or named pipe)\n\ -named filename. mode specifies both the permissions to use and the\n\ -type of node to be created, being combined (bitwise OR) with one of\n\ -S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\ -device defines the newly created device special file (probably using\n\ -os.makedev()), otherwise it is ignored.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); - - -static PyObject * -posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - int mode = 0666; + +/*[clinic input] +os.mknod + + path: path_t + mode: int=0o600 + device: int=0 + * + dir_fd: dir_fd(requires='mknodat')=None + +Create a node in the file system. + +Create a node in the file system (file, device special file or named pipe) +at path. mode specifies both the permissions to use and the +type of node to be created, being combined (bitwise OR) with one of +S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode, +device defines the newly created device special file (probably using +os.makedev()). Otherwise device is ignored. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_mknod__doc__, +"sig=($module, path, mode=384, device=0, *, dir_fd=None)\n" +"Create a node in the file system.\n" +"\n" +"Create a node in the file system (file, device special file or named pipe)\n" +"at path. mode specifies both the permissions to use and the\n" +"type of node to be created, being combined (bitwise OR) with one of\n" +"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,\n" +"device defines the newly created device special file (probably using\n" +"os.makedev()). Otherwise device is ignored.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_MKNOD_METHODDEF \ + {"mknod", (PyCFunction)os_mknod, METH_VARARGS|METH_KEYWORDS, os_mknod__doc__}, + +static PyObject * +os_mknod_impl(PyModuleDef *module, path_t *path, int mode, int device, int dir_fd); + +static PyObject * +os_mknod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "device", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); + int mode = 384; int device = 0; int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|ii$O&:mknod", _keywords, + path_converter, &path, &mode, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_mknod_impl(module, &path, mode, device, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_mknod_impl(PyModuleDef *module, path_t *path, int mode, int device, int dir_fd) +/*[clinic end generated code: output=4f67ac801d51691d input=30e02126aba9732e]*/ +{ int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL}; - - memset(&path, 0, sizeof(path)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords, - path_converter, &path, - &mode, &device, -#ifdef HAVE_MKNODAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKNODAT if (dir_fd != DEFAULT_DIR_FD) - result = mknodat(dir_fd, path.narrow, mode, device); - else -#endif - result = mknod(path.narrow, mode, device); - Py_END_ALLOW_THREADS - - if (result < 0) { - return_value = posix_error(); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); - -exit: + result = mknodat(dir_fd, path->narrow, mode, device); + else +#endif + result = mknod(path->narrow, mode, device); + Py_END_ALLOW_THREADS + + if (result < 0) + return posix_error(); + + Py_RETURN_NONE; +} +#else /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */ +#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */ + +#ifdef HAVE_DEVICE_MACROS + +/*[clinic input] +os.major -> unsigned_int + + device: int + / + +Extracts a device major number from a raw device number. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_major__doc__, +"sig=($module, device)\n" +"Extracts a device major number from a raw device number."); + +#define OS_MAJOR_METHODDEF \ + {"major", (PyCFunction)os_major, METH_VARARGS, os_major__doc__}, + +static unsigned int +os_major_impl(PyModuleDef *module, int device); + +static PyObject * +os_major(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int device; + unsigned int _return_value; + + if (!PyArg_ParseTuple(args, + "i:major", + &device)) + goto exit; + _return_value = os_major_impl(module, device); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); + +exit: + return return_value; +} + +static unsigned int +os_major_impl(PyModuleDef *module, int device) +/*[clinic end generated code: output=2350ca31c5b7002d input=ea48820b7e10d310]*/ +{ + return major(device); +} + +/*[clinic input] +os.minor -> unsigned_int + + device: int + / + +Extracts a device minor number from a raw device number. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_minor__doc__, +"sig=($module, device)\n" +"Extracts a device minor number from a raw device number."); + +#define OS_MINOR_METHODDEF \ + {"minor", (PyCFunction)os_minor, METH_VARARGS, os_minor__doc__}, + +static unsigned int +os_minor_impl(PyModuleDef *module, int device); + +static PyObject * +os_minor(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int device; + unsigned int _return_value; + + if (!PyArg_ParseTuple(args, + "i:minor", + &device)) + goto exit; + _return_value = os_minor_impl(module, device); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); + +exit: + return return_value; +} + +static unsigned int +os_minor_impl(PyModuleDef *module, int device) +/*[clinic end generated code: output=79647ba9f58f6a7d input=089733ebbf9754e8]*/ +{ + return minor(device); +} + + +/*[clinic input] +os.makedev -> unsigned_int + + major: int + minor: int + / + +Composes a raw device number from the major and minor device numbers. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_makedev__doc__, +"sig=($module, major, minor)\n" +"Composes a raw device number from the major and minor device numbers."); + +#define OS_MAKEDEV_METHODDEF \ + {"makedev", (PyCFunction)os_makedev, METH_VARARGS, os_makedev__doc__}, + +static unsigned int +os_makedev_impl(PyModuleDef *module, int major, int minor); + +static PyObject * +os_makedev(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int major; + int minor; + unsigned int _return_value; + + if (!PyArg_ParseTuple(args, + "ii:makedev", + &major, &minor)) + goto exit; + _return_value = os_makedev_impl(module, major, minor); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); + +exit: + return return_value; +} + +static unsigned int +os_makedev_impl(PyModuleDef *module, int major, int minor) +/*[clinic end generated code: output=ab3051d09c076701 input=f55bf7cffb028a08]*/ +{ + return makedev(major, minor); +} +#else /* HAVE_DEVICE_MACROS */ +#define OS_MAJOR_METHODDEF +#define OS_MINOR_METHODDEF +#define OS_MAKEDEV_METHODDEF +#endif /* HAVE_DEVICE_MACROS */ + + +#ifdef HAVE_FTRUNCATE + +/*[clinic input] +os.ftruncate + + fd: int + length: Py_off_t + / + +Truncate a file, specified by file descriptor, to a specific length. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_ftruncate__doc__, +"sig=($module, fd, length)\n" +"Truncate a file, specified by file descriptor, to a specific length."); + +#define OS_FTRUNCATE_METHODDEF \ + {"ftruncate", (PyCFunction)os_ftruncate, METH_VARARGS, os_ftruncate__doc__}, + +static PyObject * +os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length); + +static PyObject * +os_ftruncate(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t length; + + if (!PyArg_ParseTuple(args, + "iO&:ftruncate", + &fd, Py_off_t_converter, &length)) + goto exit; + return_value = os_ftruncate_impl(module, fd, length); + +exit: + return return_value; +} + +static PyObject * +os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length) +/*[clinic end generated code: output=dbba97a874c153a5 input=63b43641e52818f2]*/ +{ + int result; + + Py_BEGIN_ALLOW_THREADS + result = ftruncate(fd, length); + Py_END_ALLOW_THREADS + if (result < 0) + return posix_error(); + Py_RETURN_NONE; +} +#else /* HAVE_FTRUNCATE */ +#define OS_FTRUNCATE_METHODDEF +#endif /* HAVE_FTRUNCATE */ + +#ifdef HAVE_TRUNCATE + +/*[clinic input] +os.truncate + path: path_t(allow_fd='PATH_HAVE_FTRUNCATE') + length: Py_off_t + +Truncate a file, specified by path, to a specific length. + +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_truncate__doc__, +"sig=($module, path, length)\n" +"Truncate a file, specified by path, to a specific length.\n" +"\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_TRUNCATE_METHODDEF \ + {"truncate", (PyCFunction)os_truncate, METH_VARARGS|METH_KEYWORDS, os_truncate__doc__}, + +static PyObject * +os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length); + +static PyObject * +os_truncate(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "length", NULL}; + path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); + Py_off_t length; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&:truncate", _keywords, + path_converter, &path, Py_off_t_converter, &length)) + goto exit; + return_value = os_truncate_impl(module, &path, length); + +exit: + /* Cleanup for path */ path_cleanup(&path); - return return_value; -} -#endif - -#ifdef HAVE_DEVICE_MACROS -PyDoc_STRVAR(posix_major__doc__, -"major(device) -> major number\n\ -Extracts a device major number from a raw device number."); - -static PyObject * -posix_major(PyObject *self, PyObject *args) -{ - int device; - if (!PyArg_ParseTuple(args, "i:major", &device)) - return NULL; - return PyLong_FromLong((long)major(device)); -} - -PyDoc_STRVAR(posix_minor__doc__, -"minor(device) -> minor number\n\ -Extracts a device minor number from a raw device number."); - -static PyObject * -posix_minor(PyObject *self, PyObject *args) -{ - int device; - if (!PyArg_ParseTuple(args, "i:minor", &device)) - return NULL; - return PyLong_FromLong((long)minor(device)); -} - -PyDoc_STRVAR(posix_makedev__doc__, -"makedev(major, minor) -> device number\n\ -Composes a raw device number from the major and minor device numbers."); - -static PyObject * -posix_makedev(PyObject *self, PyObject *args) -{ - int major, minor; - if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) - return NULL; - return PyLong_FromLong((long)makedev(major, minor)); -} -#endif /* device macros */ - - + + return return_value; +} + +static PyObject * +os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length) +/*[clinic end generated code: output=04bc79b4ddfe4ea4 input=77229cf0b50a9b77]*/ +{ + int result; + + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FTRUNCATE -PyDoc_STRVAR(posix_ftruncate__doc__, -"ftruncate(fd, length)\n\n\ -Truncate a file to a specified length."); - -static PyObject * -posix_ftruncate(PyObject *self, PyObject *args) -{ + if (path->fd != -1) + result = ftruncate(path->fd, length); + else +#endif + result = truncate(path->narrow, length); + Py_END_ALLOW_THREADS + if (result < 0) + return path_error(path); + + Py_RETURN_NONE; +} +#else /* HAVE_TRUNCATE */ +#define OS_TRUNCATE_METHODDEF +#endif /* HAVE_TRUNCATE */ + +#ifdef HAVE_POSIX_FALLOCATE + +/*[clinic input] +os.posix_fallocate + + fd: int + offset: Py_off_t + length: Py_off_t + / + +Ensure a file has allocated at least a particular number of bytes on disk. + +Ensure that the file specified by fd encompasses a range of bytes +starting at offset bytes from the beginning and continuing for length bytes. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_posix_fallocate__doc__, +"sig=($module, fd, offset, length)\n" +"Ensure a file has allocated at least a particular number of bytes on disk.\n" +"\n" +"Ensure that the file specified by fd encompasses a range of bytes\n" +"starting at offset bytes from the beginning and continuing for length bytes."); + +#define OS_POSIX_FALLOCATE_METHODDEF \ + {"posix_fallocate", (PyCFunction)os_posix_fallocate, METH_VARARGS, os_posix_fallocate__doc__}, + +static PyObject * +os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length); + +static PyObject * +os_posix_fallocate(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int fd; - off_t length; - int res; - - if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - res = ftruncate(fd, length); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} -#endif - -#ifdef HAVE_TRUNCATE -PyDoc_STRVAR(posix_truncate__doc__, -"truncate(path, length)\n\n\ -Truncate the file given by path to length bytes.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception."); - -static PyObject * -posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - off_t length; - int res; - PyObject *result = NULL; - static char *keywords[] = {"path", "length", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "truncate"; -#ifdef HAVE_FTRUNCATE - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords, - path_converter, &path, - _parse_off_t, &length)) - return NULL; - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FTRUNCATE - if (path.fd != -1) - res = ftruncate(path.fd, length); - else -#endif - res = truncate(path.narrow, length); - Py_END_ALLOW_THREADS - if (res < 0) - result = path_error(&path); - else { - Py_INCREF(Py_None); - result = Py_None; - } - path_cleanup(&path); - return result; -} -#endif - -#ifdef HAVE_POSIX_FALLOCATE -PyDoc_STRVAR(posix_posix_fallocate__doc__, -"posix_fallocate(fd, offset, len)\n\n\ -Ensures that enough disk space is allocated for the file specified by fd\n\ -starting from offset and continuing for len bytes."); - -static PyObject * -posix_posix_fallocate(PyObject *self, PyObject *args) -{ - off_t len, offset; - int res, fd; - - if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate", - &fd, _parse_off_t, &offset, _parse_off_t, &len)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - res = posix_fallocate(fd, offset, len); - Py_END_ALLOW_THREADS - if (res != 0) { - errno = res; + Py_off_t offset; + Py_off_t length; + + if (!PyArg_ParseTuple(args, + "iO&O&:posix_fallocate", + &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length)) + goto exit; + return_value = os_posix_fallocate_impl(module, fd, offset, length); + +exit: + return return_value; +} + +static PyObject * +os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length) +/*[clinic end generated code: output=6a226369d51c7946 input=d7a2ef0ab2ca52fb]*/ +{ + int result; + + Py_BEGIN_ALLOW_THREADS + result = posix_fallocate(fd, offset, length); + Py_END_ALLOW_THREADS + if (result != 0) { + errno = result; return posix_error(); } Py_RETURN_NONE; } -#endif +#else /* HAVE_POSIX_FALLOCATE */ +#define OS_POSIX_FALLOCATE_METHODDEF +#endif /* HAVE_POSIX_FALLOCATE */ #ifdef HAVE_POSIX_FADVISE -PyDoc_STRVAR(posix_posix_fadvise__doc__, -"posix_fadvise(fd, offset, len, advice)\n\n\ -Announces an intention to access data in a specific pattern thus allowing\n\ -the kernel to make optimizations.\n\ -The advice applies to the region of the file specified by fd starting at\n\ -offset and continuing for len bytes.\n\ -advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\ -POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\ -POSIX_FADV_DONTNEED."); - -static PyObject * -posix_posix_fadvise(PyObject *self, PyObject *args) -{ - off_t len, offset; - int res, fd, advice; - - if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise", - &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - res = posix_fadvise(fd, offset, len, advice); - Py_END_ALLOW_THREADS - if (res != 0) { - errno = res; + +/*[clinic input] +os.posix_fadvise + + fd: int + offset: Py_off_t + length: Py_off_t + advice: int + / + +Announce an intention to access data in a specific pattern. + +Announce an intention to access data in a specific pattern, thus allowing +the kernel to make optimizations. +The advice applies to the region of the file specified by fd starting at +offset and continuing for length bytes. +advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL, +POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or +POSIX_FADV_DONTNEED. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_posix_fadvise__doc__, +"sig=($module, fd, offset, length, advice)\n" +"Announce an intention to access data in a specific pattern.\n" +"\n" +"Announce an intention to access data in a specific pattern, thus allowing\n" +"the kernel to make optimizations.\n" +"The advice applies to the region of the file specified by fd starting at\n" +"offset and continuing for length bytes.\n" +"advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n" +"POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or\n" +"POSIX_FADV_DONTNEED."); + +#define OS_POSIX_FADVISE_METHODDEF \ + {"posix_fadvise", (PyCFunction)os_posix_fadvise, METH_VARARGS, os_posix_fadvise__doc__}, + +static PyObject * +os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice); + +static PyObject * +os_posix_fadvise(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t offset; + Py_off_t length; + int advice; + + if (!PyArg_ParseTuple(args, + "iO&O&i:posix_fadvise", + &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length, &advice)) + goto exit; + return_value = os_posix_fadvise_impl(module, fd, offset, length, advice); + +exit: + return return_value; +} + +static PyObject * +os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice) +/*[clinic end generated code: output=85f9c720750c74fa input=0fbe554edc2f04b5]*/ +{ + int result; + + Py_BEGIN_ALLOW_THREADS + result = posix_fadvise(fd, offset, length, advice); + Py_END_ALLOW_THREADS + if (result != 0) { + errno = result; return posix_error(); } Py_RETURN_NONE; } -#endif +#else /* HAVE_POSIX_FADVISE */ +#define OS_POSIX_FADVISE_METHODDEF +#endif /* HAVE_POSIX_FADVISE */ #ifdef HAVE_PUTENV -PyDoc_STRVAR(posix_putenv__doc__, -"putenv(key, value)\n\n\ -Change or add an environment variable."); /* Save putenv() parameters as values here, so we can collect them when they * get re-set with another call for the same key. */ static PyObject *posix_putenv_garbage; -static PyObject * -posix_putenv(PyObject *self, PyObject *args) -{ - PyObject *newstr = NULL; -#ifdef MS_WINDOWS - PyObject *os1, *os2; - wchar_t *newenv; - - if (!PyArg_ParseTuple(args, - "UU:putenv", - &os1, &os2)) - return NULL; - - newstr = PyUnicode_FromFormat("%U=%U", os1, os2); - if (newstr == NULL) { +static void +posix_putenv_garbage_setitem(PyObject *name, PyObject *value) +{ + /* Install the first arg and newstr in posix_putenv_garbage; + * this will cause previous value to be collected. This has to + * happen after the real putenv() call because the old value + * was still accessible until then. */ + if (PyDict_SetItem(posix_putenv_garbage, name, value)) + /* really not much we can do; just leak */ + PyErr_Clear(); + else + Py_DECREF(value); +} + + +#ifdef MS_WINDOWS +/*[clinic input] +os.putenv + + name: unicode + value: unicode + / + +Change or add an environment variable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_putenv__doc__, +"sig=($module, name, value)\n" +"Change or add an environment variable."); + +#define OS_PUTENV_METHODDEF \ + {"putenv", (PyCFunction)os_putenv, METH_VARARGS, os_putenv__doc__}, + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value); + +static PyObject * +os_putenv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + PyObject *value; + + if (!PyArg_ParseTuple(args, + "UU:putenv", + &name, &value)) + goto exit; + return_value = os_putenv_impl(module, name, value); + +exit: + return return_value; +} + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value) +/*[clinic end generated code: output=0fdcda8183dcb4f5 input=ba586581c2e6105f]*/ +{ + wchar_t *env; + + PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value); + if (unicode == NULL) { PyErr_NoMemory(); - goto error; - } - if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) { + return NULL; + } + if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) { PyErr_Format(PyExc_ValueError, "the environment variable is longer than %u characters", _MAX_ENV); goto error; } - newenv = PyUnicode_AsUnicode(newstr); - if (newenv == NULL) + env = PyUnicode_AsUnicode(unicode); + if (env == NULL) goto error; - if (_wputenv(newenv)) { + if (_wputenv(env)) { posix_error(); goto error; } -#else - PyObject *os1, *os2; - char *s1, *s2; - char *newenv; - - if (!PyArg_ParseTuple(args, - "O&O&:putenv", - PyUnicode_FSConverter, &os1, - PyUnicode_FSConverter, &os2)) - return NULL; - s1 = PyBytes_AsString(os1); - s2 = PyBytes_AsString(os2); - - newstr = PyBytes_FromFormat("%s=%s", s1, s2); - if (newstr == NULL) { + + posix_putenv_garbage_setitem(name, unicode); + Py_RETURN_NONE; + +error: + Py_DECREF(unicode); + return NULL; +} + +#else /* MS_WINDOWS */ + +/*[clinic input] +os.putenv + + name: FSConverter + value: FSConverter + / + +Change or add an environment variable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_putenv__doc__, +"sig=($module, name, value)\n" +"Change or add an environment variable."); + +#define OS_PUTENV_METHODDEF \ + {"putenv", (PyCFunction)os_putenv, METH_VARARGS, os_putenv__doc__}, + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value); + +static PyObject * +os_putenv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name = NULL; + PyObject *value = NULL; + + if (!PyArg_ParseTuple(args, + "O&O&:putenv", + PyUnicode_FSConverter, &name, PyUnicode_FSConverter, &value)) + goto exit; + return_value = os_putenv_impl(module, name, value); + +exit: + /* Cleanup for name */ + Py_XDECREF(name); + /* Cleanup for value */ + Py_XDECREF(value); + + return return_value; +} + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value) +/*[clinic end generated code: output=ad949b3893172fcb input=a97bc6152f688d31]*/ +{ + PyObject *bytes = NULL; + char *env; + char *name_string = PyBytes_AsString(name); + char *value_string = PyBytes_AsString(value); + + bytes = PyBytes_FromFormat("%s=%s", name_string, value_string); + if (bytes == NULL) { PyErr_NoMemory(); - goto error; - } - - newenv = PyBytes_AS_STRING(newstr); - if (putenv(newenv)) { - posix_error(); - goto error; - } -#endif - - /* Install the first arg and newstr in posix_putenv_garbage; - * this will cause previous value to be collected. This has to - * happen after the real putenv() call because the old value - * was still accessible until then. */ - if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) { - /* really not much we can do; just leak */ - PyErr_Clear(); - } - else { - Py_DECREF(newstr); - } - -#ifndef MS_WINDOWS - Py_DECREF(os1); - Py_DECREF(os2); -#endif + return NULL; + } + + env = PyBytes_AS_STRING(bytes); + if (putenv(env)) { + Py_DECREF(bytes); + return posix_error(); + } + + posix_putenv_garbage_setitem(name, bytes); Py_RETURN_NONE; - -error: -#ifndef MS_WINDOWS - Py_DECREF(os1); - Py_DECREF(os2); -#endif - Py_XDECREF(newstr); - return NULL; -} -#endif /* putenv */ +} +#endif /* MS_WINDOWS */ +#else /* HAVE_PUTENV */ +#define OS_PUTENV_METHODDEF +#endif /* HAVE_PUTENV */ #ifdef HAVE_UNSETENV -PyDoc_STRVAR(posix_unsetenv__doc__, -"unsetenv(key)\n\n\ -Delete an environment variable."); - -static PyObject * -posix_unsetenv(PyObject *self, PyObject *args) -{ - PyObject *name; + +/*[clinic input] +os.unsetenv + name: FSConverter + / + +Delete an environment variable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_unsetenv__doc__, +"sig=($module, name)\n" +"Delete an environment variable."); + +#define OS_UNSETENV_METHODDEF \ + {"unsetenv", (PyCFunction)os_unsetenv, METH_VARARGS, os_unsetenv__doc__}, + +static PyObject * +os_unsetenv_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +os_unsetenv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name = NULL; + + if (!PyArg_ParseTuple(args, + "O&:unsetenv", + PyUnicode_FSConverter, &name)) + goto exit; + return_value = os_unsetenv_impl(module, name); + +exit: + /* Cleanup for name */ + Py_XDECREF(name); + + return return_value; +} + +static PyObject * +os_unsetenv_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=8a2fcb274ffa7cb0 input=2bb5288a599c7107]*/ +{ #ifndef HAVE_BROKEN_UNSETENV int err; #endif - if (!PyArg_ParseTuple(args, "O&:unsetenv", - - PyUnicode_FSConverter, &name)) - return NULL; - #ifdef HAVE_BROKEN_UNSETENV unsetenv(PyBytes_AS_STRING(name)); #else err = unsetenv(PyBytes_AS_STRING(name)); - if (err) { - Py_DECREF(name); - return posix_error(); - } + if (err) + return posix_error(); #endif /* Remove the key from posix_putenv_garbage; @@ -8949,23 +12973,53 @@ /* really not much we can do; just leak */ PyErr_Clear(); } - Py_DECREF(name); Py_RETURN_NONE; } -#endif /* unsetenv */ - -PyDoc_STRVAR(posix_strerror__doc__, -"strerror(code) -> string\n\n\ -Translate an error code to a message string."); - -static PyObject * -posix_strerror(PyObject *self, PyObject *args) -{ +#else /* HAVE_UNSETENV */ +#define OS_UNSETENV_METHODDEF +#endif /* HAVE_UNSETENV */ + + +/*[clinic input] +os.strerror + + code: int + / + +Translate an error code to a message string. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_strerror__doc__, +"sig=($module, code)\n" +"Translate an error code to a message string."); + +#define OS_STRERROR_METHODDEF \ + {"strerror", (PyCFunction)os_strerror, METH_VARARGS, os_strerror__doc__}, + +static PyObject * +os_strerror_impl(PyModuleDef *module, int code); + +static PyObject * +os_strerror(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int code; - char *message; - if (!PyArg_ParseTuple(args, "i:strerror", &code)) - return NULL; - message = strerror(code); + + if (!PyArg_ParseTuple(args, + "i:strerror", + &code)) + goto exit; + return_value = os_strerror_impl(module, code); + +exit: + return return_value; +} + +static PyObject * +os_strerror_impl(PyModuleDef *module, int code) +/*[clinic end generated code: output=5e5d65255d807362 input=75a8673d97915a91]*/ +{ + char *message = strerror(code); if (message == NULL) { PyErr_SetString(PyExc_ValueError, "strerror() argument out of range"); @@ -8978,155 +13032,454 @@ #ifdef HAVE_SYS_WAIT_H #ifdef WCOREDUMP -PyDoc_STRVAR(posix_WCOREDUMP__doc__, -"WCOREDUMP(status) -> bool\n\n\ -Return True if the process returning 'status' was dumped to a core file."); - -static PyObject * -posix_WCOREDUMP(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status))) - return NULL; - - return PyBool_FromLong(WCOREDUMP(status)); + +/*[clinic input] +os.WCOREDUMP -> bool + + status: int + / + +Return True if the process returning status was dumped to a core file. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WCOREDUMP__doc__, +"sig=($module, status)\n" +"Return True if the process returning status was dumped to a core file."); + +#define OS_WCOREDUMP_METHODDEF \ + {"WCOREDUMP", (PyCFunction)os_WCOREDUMP, METH_VARARGS, os_WCOREDUMP__doc__}, + +static int +os_WCOREDUMP_impl(PyModuleDef *module, int status); + +static PyObject * +os_WCOREDUMP(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int status; + int _return_value; + + if (!PyArg_ParseTuple(args, + "i:WCOREDUMP", + &status)) + goto exit; + _return_value = os_WCOREDUMP_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WCOREDUMP_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=42d842f1a6234cbf input=8b05e7ab38528d04]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WCOREDUMP(wait_status); } #endif /* WCOREDUMP */ #ifdef WIFCONTINUED -PyDoc_STRVAR(posix_WIFCONTINUED__doc__, -"WIFCONTINUED(status) -> bool\n\n\ -Return True if the process returning 'status' was continued from a\n\ -job control stop."); - -static PyObject * -posix_WIFCONTINUED(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status))) - return NULL; - - return PyBool_FromLong(WIFCONTINUED(status)); + +/*[clinic input] +os.WIFCONTINUED -> bool + + status: int + +Return True if a particular process was continued from a job control stop. + +Return True if the process returning status was continued from a +job control stop. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WIFCONTINUED__doc__, +"sig=($module, status)\n" +"Return True if a particular process was continued from a job control stop.\n" +"\n" +"Return True if the process returning status was continued from a\n" +"job control stop."); + +#define OS_WIFCONTINUED_METHODDEF \ + {"WIFCONTINUED", (PyCFunction)os_WIFCONTINUED, METH_VARARGS|METH_KEYWORDS, os_WIFCONTINUED__doc__}, + +static int +os_WIFCONTINUED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFCONTINUED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WIFCONTINUED", _keywords, + &status)) + goto exit; + _return_value = os_WIFCONTINUED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WIFCONTINUED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=d57cead340fd145f input=e777e7d38eb25bd9]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFCONTINUED(wait_status); } #endif /* WIFCONTINUED */ #ifdef WIFSTOPPED -PyDoc_STRVAR(posix_WIFSTOPPED__doc__, -"WIFSTOPPED(status) -> bool\n\n\ -Return True if the process returning 'status' was stopped."); - -static PyObject * -posix_WIFSTOPPED(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status))) - return NULL; - - return PyBool_FromLong(WIFSTOPPED(status)); + +/*[clinic input] +os.WIFSTOPPED -> bool + + status: int + +Return True if the process returning status was stopped. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WIFSTOPPED__doc__, +"sig=($module, status)\n" +"Return True if the process returning status was stopped."); + +#define OS_WIFSTOPPED_METHODDEF \ + {"WIFSTOPPED", (PyCFunction)os_WIFSTOPPED, METH_VARARGS|METH_KEYWORDS, os_WIFSTOPPED__doc__}, + +static int +os_WIFSTOPPED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFSTOPPED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WIFSTOPPED", _keywords, + &status)) + goto exit; + _return_value = os_WIFSTOPPED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WIFSTOPPED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=3a8124c714df7eed input=043cb7f1289ef904]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFSTOPPED(wait_status); } #endif /* WIFSTOPPED */ #ifdef WIFSIGNALED -PyDoc_STRVAR(posix_WIFSIGNALED__doc__, -"WIFSIGNALED(status) -> bool\n\n\ -Return True if the process returning 'status' was terminated by a signal."); - -static PyObject * -posix_WIFSIGNALED(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status))) - return NULL; - - return PyBool_FromLong(WIFSIGNALED(status)); + +/*[clinic input] +os.WIFSIGNALED -> bool + + status: int + +Return True if the process returning status was terminated by a signal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WIFSIGNALED__doc__, +"sig=($module, status)\n" +"Return True if the process returning status was terminated by a signal."); + +#define OS_WIFSIGNALED_METHODDEF \ + {"WIFSIGNALED", (PyCFunction)os_WIFSIGNALED, METH_VARARGS|METH_KEYWORDS, os_WIFSIGNALED__doc__}, + +static int +os_WIFSIGNALED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFSIGNALED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WIFSIGNALED", _keywords, + &status)) + goto exit; + _return_value = os_WIFSIGNALED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WIFSIGNALED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=74eb4e2289baf43d input=d55ba7cc9ce5dc43]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFSIGNALED(wait_status); } #endif /* WIFSIGNALED */ #ifdef WIFEXITED -PyDoc_STRVAR(posix_WIFEXITED__doc__, -"WIFEXITED(status) -> bool\n\n\ -Return true if the process returning 'status' exited using the exit()\n\ -system call."); - -static PyObject * -posix_WIFEXITED(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status))) - return NULL; - - return PyBool_FromLong(WIFEXITED(status)); + +/*[clinic input] +os.WIFEXITED -> bool + + status: int + +Return True if the process returning status exited via the exit() system call. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WIFEXITED__doc__, +"sig=($module, status)\n" +"Return True if the process returning status exited via the exit() system call."); + +#define OS_WIFEXITED_METHODDEF \ + {"WIFEXITED", (PyCFunction)os_WIFEXITED, METH_VARARGS|METH_KEYWORDS, os_WIFEXITED__doc__}, + +static int +os_WIFEXITED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFEXITED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WIFEXITED", _keywords, + &status)) + goto exit; + _return_value = os_WIFEXITED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WIFEXITED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=a90364e63cb04d14 input=d63775a6791586c0]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFEXITED(wait_status); } #endif /* WIFEXITED */ #ifdef WEXITSTATUS -PyDoc_STRVAR(posix_WEXITSTATUS__doc__, -"WEXITSTATUS(status) -> integer\n\n\ -Return the process return code from 'status'."); - -static PyObject * -posix_WEXITSTATUS(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status))) - return NULL; - - return Py_BuildValue("i", WEXITSTATUS(status)); + +/*[clinic input] +os.WEXITSTATUS -> int + + status: int + +Return the process return code from status. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WEXITSTATUS__doc__, +"sig=($module, status)\n" +"Return the process return code from status."); + +#define OS_WEXITSTATUS_METHODDEF \ + {"WEXITSTATUS", (PyCFunction)os_WEXITSTATUS, METH_VARARGS|METH_KEYWORDS, os_WEXITSTATUS__doc__}, + +static int +os_WEXITSTATUS_impl(PyModuleDef *module, int status); + +static PyObject * +os_WEXITSTATUS(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WEXITSTATUS", _keywords, + &status)) + goto exit; + _return_value = os_WEXITSTATUS_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WEXITSTATUS_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=ee096f9563b496c2 input=e1fb4944e377585b]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WEXITSTATUS(wait_status); } #endif /* WEXITSTATUS */ #ifdef WTERMSIG -PyDoc_STRVAR(posix_WTERMSIG__doc__, -"WTERMSIG(status) -> integer\n\n\ -Return the signal that terminated the process that provided the 'status'\n\ -value."); - -static PyObject * -posix_WTERMSIG(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status))) - return NULL; - - return Py_BuildValue("i", WTERMSIG(status)); + +/*[clinic input] +os.WTERMSIG -> int + + status: int + +Return the signal that terminated the process that provided the status value. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WTERMSIG__doc__, +"sig=($module, status)\n" +"Return the signal that terminated the process that provided the status value."); + +#define OS_WTERMSIG_METHODDEF \ + {"WTERMSIG", (PyCFunction)os_WTERMSIG, METH_VARARGS|METH_KEYWORDS, os_WTERMSIG__doc__}, + +static int +os_WTERMSIG_impl(PyModuleDef *module, int status); + +static PyObject * +os_WTERMSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WTERMSIG", _keywords, + &status)) + goto exit; + _return_value = os_WTERMSIG_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WTERMSIG_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=c2e0019e093c80c0 input=727fd7f84ec3f243]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WTERMSIG(wait_status); } #endif /* WTERMSIG */ #ifdef WSTOPSIG -PyDoc_STRVAR(posix_WSTOPSIG__doc__, -"WSTOPSIG(status) -> integer\n\n\ -Return the signal that stopped the process that provided\n\ -the 'status' value."); - -static PyObject * -posix_WSTOPSIG(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status))) - return NULL; - - return Py_BuildValue("i", WSTOPSIG(status)); + +/*[clinic input] +os.WSTOPSIG -> int + + status: int + +Return the signal that stopped the process that provided the status value. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WSTOPSIG__doc__, +"sig=($module, status)\n" +"Return the signal that stopped the process that provided the status value."); + +#define OS_WSTOPSIG_METHODDEF \ + {"WSTOPSIG", (PyCFunction)os_WSTOPSIG, METH_VARARGS|METH_KEYWORDS, os_WSTOPSIG__doc__}, + +static int +os_WSTOPSIG_impl(PyModuleDef *module, int status); + +static PyObject * +os_WSTOPSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WSTOPSIG", _keywords, + &status)) + goto exit; + _return_value = os_WSTOPSIG_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WSTOPSIG_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=cf9dd613d9c02a2c input=46ebf1d1b293c5c1]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WSTOPSIG(wait_status); } #endif /* WSTOPSIG */ #endif /* HAVE_SYS_WAIT_H */ +#ifndef OS_WCOREDUMP_METHODDEF +#define OS_WCOREDUMP_METHODDEF +#endif /* OS_WCOREDUMP_METHODDEF */ + +#ifndef OS_WIFCONTINUED_METHODDEF +#define OS_WIFCONTINUED_METHODDEF +#endif /* OS_WIFCONTINUED_METHODDEF */ + +#ifndef OS_WIFSTOPPED_METHODDEF +#define OS_WIFSTOPPED_METHODDEF +#endif /* OS_WIFSTOPPED_METHODDEF */ + +#ifndef OS_WIFSIGNALED_METHODDEF +#define OS_WIFSIGNALED_METHODDEF +#endif /* OS_WIFSIGNALED_METHODDEF */ + +#ifndef OS_WIFEXITED_METHODDEF +#define OS_WIFEXITED_METHODDEF +#endif /* OS_WIFEXITED_METHODDEF */ + +#ifndef OS_WEXITSTATUS_METHODDEF +#define OS_WEXITSTATUS_METHODDEF +#endif /* OS_WEXITSTATUS_METHODDEF */ + +#ifndef OS_WTERMSIG_METHODDEF +#define OS_WTERMSIG_METHODDEF +#endif /* OS_WTERMSIG_METHODDEF */ + +#ifndef OS_WSTOPSIG_METHODDEF +#define OS_WSTOPSIG_METHODDEF +#endif /* OS_WSTOPSIG_METHODDEF */ + + #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) #ifdef _SCO_DS @@ -9179,104 +13532,195 @@ return v; } -PyDoc_STRVAR(posix_fstatvfs__doc__, -"fstatvfs(fd) -> statvfs result\n\n\ -Perform an fstatvfs system call on the given fd.\n\ -Equivalent to statvfs(fd)."); - -static PyObject * -posix_fstatvfs(PyObject *self, PyObject *args) -{ - int fd, res; + +/*[clinic input] +os.fstatvfs + fd: int + / + +Perform an fstatvfs system call on the given fd. + +Equivalent to statvfs(fd). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fstatvfs__doc__, +"sig=($module, fd)\n" +"Perform an fstatvfs system call on the given fd.\n" +"\n" +"Equivalent to statvfs(fd)."); + +#define OS_FSTATVFS_METHODDEF \ + {"fstatvfs", (PyCFunction)os_fstatvfs, METH_VARARGS, os_fstatvfs__doc__}, + +static PyObject * +os_fstatvfs_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fstatvfs(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_ParseTuple(args, + "i:fstatvfs", + &fd)) + goto exit; + return_value = os_fstatvfs_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_fstatvfs_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=f20712815929d41f input=d8122243ac50975e]*/ +{ + int result; struct statvfs st; - if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = fstatvfs(fd, &st); - Py_END_ALLOW_THREADS - if (res != 0) + Py_BEGIN_ALLOW_THREADS + result = fstatvfs(fd, &st); + Py_END_ALLOW_THREADS + if (result != 0) return posix_error(); return _pystatvfs_fromstructstatvfs(st); } -#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */ +#else /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */ +#define OS_FSTATVFS_METHODDEF +#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */ #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) #include -PyDoc_STRVAR(posix_statvfs__doc__, -"statvfs(path)\n\n\ -Perform a statvfs system call on the given path.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception."); - -static PyObject * -posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"path", NULL}; - path_t path; + +/*[clinic input] +os.statvfs + + path: path_t(allow_fd='PATH_HAVE_FSTATVFS') + +Perform a statvfs system call on the given path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_statvfs__doc__, +"sig=($module, path)\n" +"Perform a statvfs system call on the given path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_STATVFS_METHODDEF \ + {"statvfs", (PyCFunction)os_statvfs, METH_VARARGS|METH_KEYWORDS, os_statvfs__doc__}, + +static PyObject * +os_statvfs_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_statvfs(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:statvfs", _keywords, + path_converter, &path)) + goto exit; + return_value = os_statvfs_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_statvfs_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=483972f5cb806c8e input=3f5c35791c669bd9]*/ +{ int result; - PyObject *return_value = NULL; struct statvfs st; - memset(&path, 0, sizeof(path)); - path.function_name = "statvfs"; + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FSTATVFS - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords, - path_converter, &path - )) - return NULL; - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FSTATVFS - if (path.fd != -1) { + if (path->fd != -1) { #ifdef __APPLE__ /* handle weak-linking on Mac OS X 10.3 */ if (fstatvfs == NULL) { - fd_specified("statvfs", path.fd); - goto exit; - } -#endif - result = fstatvfs(path.fd, &st); - } - else -#endif - result = statvfs(path.narrow, &st); + fd_specified("statvfs", path->fd); + return NULL; + } +#endif + result = fstatvfs(path->fd, &st); + } + else +#endif + result = statvfs(path->narrow, &st); Py_END_ALLOW_THREADS if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = _pystatvfs_fromstructstatvfs(st); - -exit: - path_cleanup(&path); - return return_value; -} -#endif /* HAVE_STATVFS */ + return path_error(path); + } + + return _pystatvfs_fromstructstatvfs(st); +} +#else /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */ +#define OS_STATVFS_METHODDEF +#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */ #ifdef MS_WINDOWS PyDoc_STRVAR(win32__getdiskusage__doc__, -"_getdiskusage(path) -> (total, free)\n\n\ -Return disk usage statistics about the given path as (total, free) tuple."); - + +/*[clinic input] +os._getdiskusage + + path: Py_UNICODE + +Return disk usage statistics about the given path as a (total, free) tuple. +[clinic start generated code]*/ + +PyDoc_STRVAR(os__getdiskusage__doc__, +"sig=($module, path)\n" +"Return disk usage statistics about the given path as a (total, free) tuple."); + +#define OS__GETDISKUSAGE_METHODDEF \ + {"_getdiskusage", (PyCFunction)os__getdiskusage, METH_VARARGS|METH_KEYWORDS, os__getdiskusage__doc__}, + +static PyObject * +os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path); + +static PyObject * +os__getdiskusage(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + Py_UNICODE *path; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "u:_getdiskusage", _keywords, + &path)) + goto exit; + return_value = os__getdiskusage_impl(module, path); + +exit: + return return_value; +} + +static PyObject * +os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path) +/*[clinic end generated code: output=4cdb23e2eb75c4d6 input=6458133aed893c78]*/ static PyObject * win32__getdiskusage(PyObject *self, PyObject *args) { BOOL retval; ULARGE_INTEGER _, total, free; - const wchar_t *path; - - if (! PyArg_ParseTuple(args, "u", &path)) - return NULL; Py_BEGIN_ALLOW_THREADS retval = GetDiskFreeSpaceExW(path, &_, &total, &free); @@ -9286,7 +13730,9 @@ return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart); } -#endif +#else /* MS_WINDOWS */ +#define OS__GETDISKUSAGE_METHODDEF +#endif /* MS_WINDOWS */ /* This is used for fpathconf(), pathconf(), confstr() and sysconf(). @@ -9444,80 +13890,149 @@ #endif #ifdef HAVE_FPATHCONF -PyDoc_STRVAR(posix_fpathconf__doc__, -"fpathconf(fd, name) -> integer\n\n\ -Return the configuration limit name for the file descriptor fd.\n\ -If there is no limit, return -1."); - -static PyObject * -posix_fpathconf(PyObject *self, PyObject *args) -{ - PyObject *result = NULL; - int name, fd; - - if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, - conv_path_confname, &name)) { - long limit; - - errno = 0; - limit = fpathconf(fd, name); - if (limit == -1 && errno != 0) - posix_error(); - else - result = PyLong_FromLong(limit); - } - return result; -} -#endif + +/*[clinic input] +os.fpathconf -> long + + fd: int + name: path_confname + / + +Return the configuration limit name for the file descriptor fd. + +If there is no limit, return -1. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fpathconf__doc__, +"sig=($module, fd, name)\n" +"Return the configuration limit name for the file descriptor fd.\n" +"\n" +"If there is no limit, return -1."); + +#define OS_FPATHCONF_METHODDEF \ + {"fpathconf", (PyCFunction)os_fpathconf, METH_VARARGS, os_fpathconf__doc__}, + +static long +os_fpathconf_impl(PyModuleDef *module, int fd, int name); + +static PyObject * +os_fpathconf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int name; + long _return_value; + + if (!PyArg_ParseTuple(args, + "iO&:fpathconf", + &fd, conv_path_confname, &name)) + goto exit; + _return_value = os_fpathconf_impl(module, fd, name); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +static long +os_fpathconf_impl(PyModuleDef *module, int fd, int name) +/*[clinic end generated code: output=be274d233ecdcca4 input=5942a024d3777810]*/ +{ + long limit; + + errno = 0; + limit = fpathconf(fd, name); + if (limit == -1 && errno != 0) + posix_error(); + + return limit; +} +#else /* HAVE_FPATHCONF */ +#define OS_FPATHCONF_METHODDEF +#endif /* HAVE_FPATHCONF */ #ifdef HAVE_PATHCONF -PyDoc_STRVAR(posix_pathconf__doc__, -"pathconf(path, name) -> integer\n\n\ -Return the configuration limit name for the file or directory path.\n\ -If there is no limit, return -1.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception."); - -static PyObject * -posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - PyObject *result = NULL; + +/*[clinic input] +os.pathconf -> long + path: path_t(allow_fd='PATH_HAVE_FPATHCONF') + name: path_confname + +Return the configuration limit name for the file or directory path. + +If there is no limit, return -1. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pathconf__doc__, +"sig=($module, path, name)\n" +"Return the configuration limit name for the file or directory path.\n" +"\n" +"If there is no limit, return -1.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_PATHCONF_METHODDEF \ + {"pathconf", (PyCFunction)os_pathconf, METH_VARARGS|METH_KEYWORDS, os_pathconf__doc__}, + +static long +os_pathconf_impl(PyModuleDef *module, path_t *path, int name); + +static PyObject * +os_pathconf(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "name", NULL}; + path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); int name; - static char *keywords[] = {"path", "name", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "pathconf"; -#ifdef HAVE_FPATHCONF - path.allow_fd = 1; -#endif - if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords, - path_converter, &path, - conv_path_confname, &name)) { + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&:pathconf", _keywords, + path_converter, &path, conv_path_confname, &name)) + goto exit; + _return_value = os_pathconf_impl(module, &path, name); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static long +os_pathconf_impl(PyModuleDef *module, path_t *path, int name) +/*[clinic end generated code: output=a2f855148e746b43 input=bc3e2a985af27e5e]*/ +{ long limit; errno = 0; #ifdef HAVE_FPATHCONF - if (path.fd != -1) - limit = fpathconf(path.fd, name); - else -#endif - limit = pathconf(path.narrow, name); + if (path->fd != -1) + limit = fpathconf(path->fd, name); + else +#endif + limit = pathconf(path->narrow, name); if (limit == -1 && errno != 0) { if (errno == EINVAL) /* could be a path or name problem */ posix_error(); else - result = path_error(&path); - } - else - result = PyLong_FromLong(limit); - } - path_cleanup(&path); - return result; -} -#endif + path_error(path); + } + + return limit; +} +#else /* HAVE_PATHCONF */ +#define OS_PATHCONF_METHODDEF +#endif /* HAVE_PATHCONF */ #ifdef HAVE_CONFSTR static struct constdef posix_constants_confstr[] = { @@ -9681,21 +14196,49 @@ / sizeof(struct constdef)); } -PyDoc_STRVAR(posix_confstr__doc__, -"confstr(name) -> string\n\n\ -Return a string-valued system configuration variable."); - -static PyObject * -posix_confstr(PyObject *self, PyObject *args) +/*[clinic input] +os.confstr + + name: confstr_confname + / + +Return a string-valued system configuration variable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_confstr__doc__, +"sig=($module, name)\n" +"Return a string-valued system configuration variable."); + +#define OS_CONFSTR_METHODDEF \ + {"confstr", (PyCFunction)os_confstr, METH_VARARGS, os_confstr__doc__}, + +static PyObject * +os_confstr_impl(PyModuleDef *module, int name); + +static PyObject * +os_confstr(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int name; + + if (!PyArg_ParseTuple(args, + "O&:confstr", + conv_confstr_confname, &name)) + goto exit; + return_value = os_confstr_impl(module, name); + +exit: + return return_value; +} + +static PyObject * +os_confstr_impl(PyModuleDef *module, int name) +/*[clinic end generated code: output=4e59b78b6e5dce52 input=18fb4d0567242e65]*/ { PyObject *result = NULL; - int name; char buffer[255]; size_t len; - if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) - return NULL; - errno = 0; len = confstr(name, buffer, sizeof(buffer)); if (len == 0) { @@ -9720,7 +14263,9 @@ result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); return result; } -#endif +#else /* HAVE_CONFSTR */ +#define OS_CONFSTR_METHODDEF +#endif /* HAVE_CONFSTR */ #ifdef HAVE_SYSCONF @@ -10227,29 +14772,60 @@ / sizeof(struct constdef)); } -PyDoc_STRVAR(posix_sysconf__doc__, -"sysconf(name) -> integer\n\n\ -Return an integer-valued system configuration variable."); - -static PyObject * -posix_sysconf(PyObject *self, PyObject *args) -{ - PyObject *result = NULL; + +/*[clinic input] +os.sysconf -> long + name: sysconf_confname + / + +Return an integer-valued system configuration variable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sysconf__doc__, +"sig=($module, name)\n" +"Return an integer-valued system configuration variable."); + +#define OS_SYSCONF_METHODDEF \ + {"sysconf", (PyCFunction)os_sysconf, METH_VARARGS, os_sysconf__doc__}, + +static long +os_sysconf_impl(PyModuleDef *module, int name); + +static PyObject * +os_sysconf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int name; - - if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { - long value; - - errno = 0; - value = sysconf(name); - if (value == -1 && errno != 0) - posix_error(); - else - result = PyLong_FromLong(value); - } - return result; -} -#endif + long _return_value; + + if (!PyArg_ParseTuple(args, + "O&:sysconf", + conv_sysconf_confname, &name)) + goto exit; + _return_value = os_sysconf_impl(module, name); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +static long +os_sysconf_impl(PyModuleDef *module, int name) +/*[clinic end generated code: output=529bace530ef1ee6 input=279e3430a33f29e4]*/ +{ + long value; + + errno = 0; + value = sysconf(name); + if (value == -1 && errno != 0) + posix_error(); + return value; +} +#else /* HAVE_SYSCONF */ +#define OS_SYSCONF_METHODDEF +#endif /* HAVE_SYSCONF */ /* This code is used to ensure that the tables of configuration value names @@ -10326,13 +14902,38 @@ } -PyDoc_STRVAR(posix_abort__doc__, -"abort() -> does not return!\n\n\ -Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ -in the hardest way possible on the hosting operating system."); - -static PyObject * -posix_abort(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.abort + +Abort the interpreter immediately. + +This function 'dumps core' or otherwise fails in the hardest way possible +on the hosting operating system. This function never returns. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_abort__doc__, +"sig=($module)\n" +"Abort the interpreter immediately.\n" +"\n" +"This function \'dumps core\' or otherwise fails in the hardest way possible\n" +"on the hosting operating system. This function never returns."); + +#define OS_ABORT_METHODDEF \ + {"abort", (PyCFunction)os_abort, METH_NOARGS, os_abort__doc__}, + +static PyObject * +os_abort_impl(PyModuleDef *module); + +static PyObject * +os_abort(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_abort_impl(module); +} + +static PyObject * +os_abort_impl(PyModuleDef *module) +/*[clinic end generated code: output=0bf96a823c03dab2 input=cf2c7d98bc504047]*/ { abort(); /*NOTREACHED*/ @@ -10341,9 +14942,10 @@ } #ifdef MS_WINDOWS +/* AC 3.5: change to path_t? but that might change exceptions */ PyDoc_STRVAR(win32_startfile__doc__, -"startfile(filepath [, operation]) - Start a file with its associated\n\ -application.\n\ +"sig=($module, path, operation='open')\n\ +Start a file with its associated application.\n\ \n\ When \"operation\" is not specified or \"open\", this acts like\n\ double-clicking the file in Explorer, or giving the file name as an\n\ @@ -10433,17 +15035,43 @@ Py_INCREF(Py_None); return Py_None; } -#endif +#endif /* MS_WINDOWS */ #ifdef HAVE_GETLOADAVG -PyDoc_STRVAR(posix_getloadavg__doc__, -"getloadavg() -> (float, float, float)\n\n\ -Return the number of processes in the system run queue averaged over\n\ -the last 1, 5, and 15 minutes or raises OSError if the load average\n\ -was unobtainable"); - -static PyObject * -posix_getloadavg(PyObject *self, PyObject *noargs) + +/*[clinic input] +os.getloadavg + +Return average recent system load information. + +Return the number of processes in the system run queue averaged over +the last 1, 5, and 15 minutes as a tuple of three floats. +Raises OSError if the load average was unobtainable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getloadavg__doc__, +"sig=($module)\n" +"Return average recent system load information.\n" +"\n" +"Return the number of processes in the system run queue averaged over\n" +"the last 1, 5, and 15 minutes as a tuple of three floats.\n" +"Raises OSError if the load average was unobtainable."); + +#define OS_GETLOADAVG_METHODDEF \ + {"getloadavg", (PyCFunction)os_getloadavg, METH_NOARGS, os_getloadavg__doc__}, + +static PyObject * +os_getloadavg_impl(PyModuleDef *module); + +static PyObject * +os_getloadavg(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getloadavg_impl(module); +} + +static PyObject * +os_getloadavg_impl(PyModuleDef *module) +/*[clinic end generated code: output=53fa3a6249efd944 input=3d6d826b76d8a34e]*/ { double loadavg[3]; if (getloadavg(loadavg, 3)!=3) { @@ -10452,72 +15080,191 @@ } else return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); } -#endif - -PyDoc_STRVAR(device_encoding__doc__, -"device_encoding(fd) -> str\n\n\ -Return a string describing the encoding of the device\n\ -if the output is a terminal; else return None."); - -static PyObject * -device_encoding(PyObject *self, PyObject *args) -{ +#else /* HAVE_GETLOADAVG */ +#define OS_GETLOADAVG_METHODDEF +#endif /* HAVE_GETLOADAVG */ + + +/*[clinic input] +os.device_encoding + fd: int + +Return a string describing the encoding of a terminal's file descriptor. + +The file descriptor must be attached to a terminal. +If the device is not a terminal, return None. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_device_encoding__doc__, +"sig=($module, fd)\n" +"Return a string describing the encoding of a terminal\'s file descriptor.\n" +"\n" +"The file descriptor must be attached to a terminal.\n" +"If the device is not a terminal, return None."); + +#define OS_DEVICE_ENCODING_METHODDEF \ + {"device_encoding", (PyCFunction)os_device_encoding, METH_VARARGS|METH_KEYWORDS, os_device_encoding__doc__}, + +static PyObject * +os_device_encoding_impl(PyModuleDef *module, int fd); + +static PyObject * +os_device_encoding(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; int fd; - if (!PyArg_ParseTuple(args, "i:device_encoding", &fd)) - return NULL; - + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:device_encoding", _keywords, + &fd)) + goto exit; + return_value = os_device_encoding_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_device_encoding_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=d73b063fa15ad290 input=9e1d4a42b66df312]*/ +{ return _Py_device_encoding(fd); } #ifdef HAVE_SETRESUID -PyDoc_STRVAR(posix_setresuid__doc__, -"setresuid(ruid, euid, suid)\n\n\ -Set the current process's real, effective, and saved user ids."); - -static PyObject* -posix_setresuid (PyObject *self, PyObject *args) -{ - /* We assume uid_t is no larger than a long. */ - uid_t ruid, euid, suid; - if (!PyArg_ParseTuple(args, "O&O&O&:setresuid", - _Py_Uid_Converter, &ruid, - _Py_Uid_Converter, &euid, - _Py_Uid_Converter, &suid)) - return NULL; + +/*[clinic input] +os.setresuid + + ruid: uid_t + euid: uid_t + suid: uid_t + / + +Set the current process's real, effective, and saved user ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setresuid__doc__, +"sig=($module, ruid, euid, suid)\n" +"Set the current process\'s real, effective, and saved user ids."); + +#define OS_SETRESUID_METHODDEF \ + {"setresuid", (PyCFunction)os_setresuid, METH_VARARGS, os_setresuid__doc__}, + +static PyObject * +os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid); + +static PyObject * +os_setresuid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + uid_t ruid; + uid_t euid; + uid_t suid; + + if (!PyArg_ParseTuple(args, + "O&O&O&:setresuid", + _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid, _Py_Uid_Converter, &suid)) + goto exit; + return_value = os_setresuid_impl(module, ruid, euid, suid); + +exit: + return return_value; +} + +static PyObject * +os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid) +/*[clinic end generated code: output=ef0d6e83632e2904 input=9e33cb79a82792f3]*/ +{ if (setresuid(ruid, euid, suid) < 0) return posix_error(); Py_RETURN_NONE; } -#endif +#else /* HAVE_SETRESUID */ +#define OS_SETRESUID_METHODDEF +#endif /* HAVE_SETRESUID */ #ifdef HAVE_SETRESGID -PyDoc_STRVAR(posix_setresgid__doc__, -"setresgid(rgid, egid, sgid)\n\n\ -Set the current process's real, effective, and saved group ids."); - -static PyObject* -posix_setresgid (PyObject *self, PyObject *args) -{ - gid_t rgid, egid, sgid; - if (!PyArg_ParseTuple(args, "O&O&O&:setresgid", - _Py_Gid_Converter, &rgid, - _Py_Gid_Converter, &egid, - _Py_Gid_Converter, &sgid)) - return NULL; + +/*[clinic input] +os.setresgid + + rgid: gid_t + egid: gid_t + sgid: gid_t + / + +Set the current process's real, effective, and saved group ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setresgid__doc__, +"sig=($module, rgid, egid, sgid)\n" +"Set the current process\'s real, effective, and saved group ids."); + +#define OS_SETRESGID_METHODDEF \ + {"setresgid", (PyCFunction)os_setresgid, METH_VARARGS, os_setresgid__doc__}, + +static PyObject * +os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid); + +static PyObject * +os_setresgid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + gid_t rgid; + gid_t egid; + gid_t sgid; + + if (!PyArg_ParseTuple(args, + "O&O&O&:setresgid", + _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid, _Py_Gid_Converter, &sgid)) + goto exit; + return_value = os_setresgid_impl(module, rgid, egid, sgid); + +exit: + return return_value; +} + +static PyObject * +os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid) +/*[clinic end generated code: output=82e536bf4300f250 input=33e9e0785ef426b1]*/ +{ if (setresgid(rgid, egid, sgid) < 0) return posix_error(); Py_RETURN_NONE; } -#endif +#else /* HAVE_SETRESGID */ +#define OS_SETRESGID_METHODDEF +#endif /* HAVE_SETRESGID */ #ifdef HAVE_GETRESUID -PyDoc_STRVAR(posix_getresuid__doc__, -"getresuid() -> (ruid, euid, suid)\n\n\ -Get tuple of the current process's real, effective, and saved user ids."); - -static PyObject* -posix_getresuid (PyObject *self, PyObject *noargs) + +/*[clinic input] +os.getresuid + +Return a tuple of the current process's real, effective, and saved user ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getresuid__doc__, +"sig=($module)\n" +"Return a tuple of the current process\'s real, effective, and saved user ids."); + +#define OS_GETRESUID_METHODDEF \ + {"getresuid", (PyCFunction)os_getresuid, METH_NOARGS, os_getresuid__doc__}, + +static PyObject * +os_getresuid_impl(PyModuleDef *module); + +static PyObject * +os_getresuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getresuid_impl(module); +} + +static PyObject * +os_getresuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=d8a0be72f5095a09 input=41ccfa8e1f6517ad]*/ { uid_t ruid, euid, suid; if (getresuid(&ruid, &euid, &suid) < 0) @@ -10526,59 +15273,116 @@ _PyLong_FromUid(euid), _PyLong_FromUid(suid)); } -#endif +#else /* HAVE_GETRESUID */ +#define OS_GETRESUID_METHODDEF +#endif /* HAVE_GETRESUID */ #ifdef HAVE_GETRESGID -PyDoc_STRVAR(posix_getresgid__doc__, -"getresgid() -> (rgid, egid, sgid)\n\n\ -Get tuple of the current process's real, effective, and saved group ids."); - -static PyObject* -posix_getresgid (PyObject *self, PyObject *noargs) -{ - uid_t rgid, egid, sgid; + +/*[clinic input] +os.getresgid + +Return a tuple of the current process's real, effective, and saved group ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getresgid__doc__, +"sig=($module)\n" +"Return a tuple of the current process\'s real, effective, and saved group ids."); + +#define OS_GETRESGID_METHODDEF \ + {"getresgid", (PyCFunction)os_getresgid, METH_NOARGS, os_getresgid__doc__}, + +static PyObject * +os_getresgid_impl(PyModuleDef *module); + +static PyObject * +os_getresgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getresgid_impl(module); +} + +static PyObject * +os_getresgid_impl(PyModuleDef *module) +/*[clinic end generated code: output=9fc2b1e88ae57913 input=517e68db9ca32df6]*/ +{ + gid_t rgid, egid, sgid; if (getresgid(&rgid, &egid, &sgid) < 0) return posix_error(); return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid), _PyLong_FromGid(egid), _PyLong_FromGid(sgid)); } -#endif +#else /* HAVE_GETRESGID */ +#define OS_GETRESGID_METHODDEF +#endif /* HAVE_GETRESGID */ #ifdef USE_XATTRS -PyDoc_STRVAR(posix_getxattr__doc__, -"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\ -Return the value of extended attribute attribute on path.\n\ -\n\ -path may be either a string or an open file descriptor.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, getxattr will examine the symbolic link itself instead of the file\n\ - the link points to."); - -static PyObject * -posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - path_t attribute; +/*[clinic input] +os.getxattr + + path: path_t(allow_fd=True) + attribute: path_t + * + follow_symlinks: bool = True + +Return the value of extended attribute attribute on path. + +path may be either a string or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, getxattr will examine the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getxattr__doc__, +"sig=($module, path, attribute, *, follow_symlinks=True)\n" +"Return the value of extended attribute attribute on path.\n" +"\n" +"path may be either a string or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, getxattr will examine the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_GETXATTR_METHODDEF \ + {"getxattr", (PyCFunction)os_getxattr, METH_VARARGS|METH_KEYWORDS, os_getxattr__doc__}, + +static PyObject * +os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks); + +static PyObject * +os_getxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0); int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$p:getxattr", _keywords, + path_converter, &path, path_converter, &attribute, &follow_symlinks)) + goto exit; + return_value = os_getxattr_impl(module, &path, &attribute, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + /* Cleanup for attribute */ + path_cleanup(&attribute); + + return return_value; +} + +static PyObject * +os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks) +/*[clinic end generated code: output=c26878ad5f5ddb21 input=8c8ea3bab78d89c2]*/ +{ + Py_ssize_t i; PyObject *buffer = NULL; - int i; - static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - memset(&attribute, 0, sizeof(attribute)); - path.function_name = "getxattr"; - attribute.function_name = "getxattr"; - path.allow_fd = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords, - path_converter, &path, - path_converter, &attribute, - &follow_symlinks)) - return NULL; - - if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks)) - goto exit; + + if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) + return NULL; for (i = 0; ; i++) { void *ptr; @@ -10586,30 +15390,29 @@ static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; Py_ssize_t buffer_size = buffer_sizes[i]; if (!buffer_size) { - path_error(&path); - goto exit; + path_error(path); + return NULL; } buffer = PyBytes_FromStringAndSize(NULL, buffer_size); if (!buffer) - goto exit; + return NULL; ptr = PyBytes_AS_STRING(buffer); Py_BEGIN_ALLOW_THREADS; - if (path.fd >= 0) - result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size); + if (path->fd >= 0) + result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size); else if (follow_symlinks) - result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size); + result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size); else - result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size); + result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size); Py_END_ALLOW_THREADS; if (result < 0) { Py_DECREF(buffer); - buffer = NULL; if (errno == ERANGE) continue; - path_error(&path); - goto exit; + path_error(path); + return NULL; } if (result != buffer_size) { @@ -10619,168 +15422,252 @@ break; } -exit: - path_cleanup(&path); - path_cleanup(&attribute); return buffer; } -PyDoc_STRVAR(posix_setxattr__doc__, -"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\ -Set extended attribute attribute on path to value.\n\ -path may be either a string or an open file descriptor.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, setxattr will modify the symbolic link itself instead of the file\n\ - the link points to."); - -static PyObject * -posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - path_t attribute; - Py_buffer value; + +/*[clinic input] +os.setxattr + + path: path_t(allow_fd=True) + attribute: path_t + value: Py_buffer + flags: int = 0 + * + follow_symlinks: bool = True + +Set extended attribute attribute on path to value. + +path may be either a string or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, setxattr will modify the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setxattr__doc__, +"sig=($module, path, attribute, value, flags=0, *, follow_symlinks=True)\n" +"Set extended attribute attribute on path to value.\n" +"\n" +"path may be either a string or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, setxattr will modify the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_SETXATTR_METHODDEF \ + {"setxattr", (PyCFunction)os_setxattr, METH_VARARGS|METH_KEYWORDS, os_setxattr__doc__}, + +static PyObject * +os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks); + +static PyObject * +os_setxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0); + Py_buffer value = {NULL, NULL}; int flags = 0; int follow_symlinks = 1; - int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "attribute", "value", - "flags", "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "setxattr"; - path.allow_fd = 1; - memset(&attribute, 0, sizeof(attribute)); - memset(&value, 0, sizeof(value)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr", - keywords, - path_converter, &path, - path_converter, &attribute, - &value, &flags, - &follow_symlinks)) - return NULL; - - if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks)) - goto exit; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&y*|i$p:setxattr", _keywords, + path_converter, &path, path_converter, &attribute, &value, &flags, &follow_symlinks)) + goto exit; + return_value = os_setxattr_impl(module, &path, &attribute, &value, flags, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + /* Cleanup for attribute */ + path_cleanup(&attribute); + /* Cleanup for value */ + if (value.obj) + PyBuffer_Release(&value); + + return return_value; +} + +static PyObject * +os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks) +/*[clinic end generated code: output=bcc261be7f90900a input=f0d26833992015c2]*/ +{ + ssize_t result; + + if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) + return NULL; Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - result = fsetxattr(path.fd, attribute.narrow, - value.buf, value.len, flags); + if (path->fd > -1) + result = fsetxattr(path->fd, attribute->narrow, + value->buf, value->len, flags); else if (follow_symlinks) - result = setxattr(path.narrow, attribute.narrow, - value.buf, value.len, flags); - else - result = lsetxattr(path.narrow, attribute.narrow, - value.buf, value.len, flags); + result = setxattr(path->narrow, attribute->narrow, + value->buf, value->len, flags); + else + result = lsetxattr(path->narrow, attribute->narrow, + value->buf, value->len, flags); Py_END_ALLOW_THREADS; if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(return_value); - -exit: + path_error(path); + return NULL; + } + + Py_RETURN_NONE; +} + + +/*[clinic input] +os.removexattr + + path: path_t(allow_fd=True) + attribute: path_t + * + follow_symlinks: bool = True + +Remove extended attribute attribute on path. + +path may be either a string or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, removexattr will modify the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_removexattr__doc__, +"sig=($module, path, attribute, *, follow_symlinks=True)\n" +"Remove extended attribute attribute on path.\n" +"\n" +"path may be either a string or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, removexattr will modify the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_REMOVEXATTR_METHODDEF \ + {"removexattr", (PyCFunction)os_removexattr, METH_VARARGS|METH_KEYWORDS, os_removexattr__doc__}, + +static PyObject * +os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks); + +static PyObject * +os_removexattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0); + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$p:removexattr", _keywords, + path_converter, &path, path_converter, &attribute, &follow_symlinks)) + goto exit; + return_value = os_removexattr_impl(module, &path, &attribute, follow_symlinks); + +exit: + /* Cleanup for path */ path_cleanup(&path); + /* Cleanup for attribute */ path_cleanup(&attribute); - PyBuffer_Release(&value); - - return return_value; -} - -PyDoc_STRVAR(posix_removexattr__doc__, -"removexattr(path, attribute, *, follow_symlinks=True)\n\n\ -Remove extended attribute attribute on path.\n\ -path may be either a string or an open file descriptor.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, removexattr will modify the symbolic link itself instead of the file\n\ - the link points to."); - -static PyObject * -posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - path_t attribute; + + return return_value; +} + +static PyObject * +os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks) +/*[clinic end generated code: output=a94b0a6736b91624 input=cdb54834161e3329]*/ +{ + ssize_t result; + + if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + if (path->fd > -1) + result = fremovexattr(path->fd, attribute->narrow); + else if (follow_symlinks) + result = removexattr(path->narrow, attribute->narrow); + else + result = lremovexattr(path->narrow, attribute->narrow); + Py_END_ALLOW_THREADS; + + if (result) { + return path_error(path); + } + + Py_RETURN_NONE; +} + + +/*[clinic input] +os.listxattr + + path: path_t(allow_fd=True, nullable=True) = None + * + follow_symlinks: bool = True + +Return a list of extended attributes on path. + +path may be either None, a string, or an open file descriptor. +if path is None, listxattr will examine the current directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, listxattr will examine the symbolic link itself instead of the file + the link points to. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_listxattr__doc__, +"sig=($module, path=None, *, follow_symlinks=True)\n" +"Return a list of extended attributes on path.\n" +"\n" +"path may be either None, a string, or an open file descriptor.\n" +"if path is None, listxattr will examine the current directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, listxattr will examine the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_LISTXATTR_METHODDEF \ + {"listxattr", (PyCFunction)os_listxattr, METH_VARARGS|METH_KEYWORDS, os_listxattr__doc__}, + +static PyObject * +os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks); + +static PyObject * +os_listxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); int follow_symlinks = 1; - int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "removexattr"; - memset(&attribute, 0, sizeof(attribute)); - attribute.function_name = "removexattr"; - path.allow_fd = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr", - keywords, - path_converter, &path, - path_converter, &attribute, - &follow_symlinks)) - return NULL; - - if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks)) - goto exit; - - Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - result = fremovexattr(path.fd, attribute.narrow); - else if (follow_symlinks) - result = removexattr(path.narrow, attribute.narrow); - else - result = lremovexattr(path.narrow, attribute.narrow); - Py_END_ALLOW_THREADS; - - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(return_value); - -exit: + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O&$p:listxattr", _keywords, + path_converter, &path, &follow_symlinks)) + goto exit; + return_value = os_listxattr_impl(module, &path, follow_symlinks); + +exit: + /* Cleanup for path */ path_cleanup(&path); - path_cleanup(&attribute); - - return return_value; -} - -PyDoc_STRVAR(posix_listxattr__doc__, -"listxattr(path='.', *, follow_symlinks=True)\n\n\ -Return a list of extended attributes on path.\n\ -\n\ -path may be either None, a string, or an open file descriptor.\n\ -if path is None, listxattr will examine the current directory.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, listxattr will examine the symbolic link itself instead of the file\n\ - the link points to."); - -static PyObject * -posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - int follow_symlinks = 1; + + return return_value; +} + +static PyObject * +os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks) +/*[clinic end generated code: output=c5da9198f46c935b input=08cca53ac0b07c13]*/ +{ Py_ssize_t i; PyObject *result = NULL; + const char *name; char *buffer = NULL; - char *name; - static char *keywords[] = {"path", "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "listxattr"; - path.allow_fd = 1; - path.fd = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords, - path_converter, &path, - &follow_symlinks)) - return NULL; - - if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks)) - goto exit; - - name = path.narrow ? path.narrow : "."; + + if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) + goto exit; + + name = path->narrow ? path->narrow : "."; + for (i = 0; ; i++) { char *start, *trace, *end; ssize_t length; @@ -10788,7 +15675,7 @@ Py_ssize_t buffer_size = buffer_sizes[i]; if (!buffer_size) { /* ERANGE */ - path_error(&path); + path_error(path); break; } buffer = PyMem_MALLOC(buffer_size); @@ -10798,8 +15685,8 @@ } Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - length = flistxattr(path.fd, buffer, buffer_size); + if (path->fd > -1) + length = flistxattr(path->fd, buffer, buffer_size); else if (follow_symlinks) length = listxattr(name, buffer, buffer_size); else @@ -10812,7 +15699,7 @@ buffer = NULL; continue; } - path_error(&path); + path_error(path); break; } @@ -10845,43 +15732,76 @@ break; } exit: - path_cleanup(&path); if (buffer) PyMem_FREE(buffer); return result; } +#else /* USE_XATTRS */ +#define OS_GETXATTR_METHODDEF +#define OS_SETXATTR_METHODDEF +#define OS_REMOVEXATTR_METHODDEF +#define OS_LISTXATTR_METHODDEF #endif /* USE_XATTRS */ -PyDoc_STRVAR(posix_urandom__doc__, -"urandom(n) -> str\n\n\ -Return n random bytes suitable for cryptographic use."); - -static PyObject * -posix_urandom(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.urandom + + size: Py_ssize_t + / + +Return a bytes object containing random bytes suitable for cryptographic use. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_urandom__doc__, +"sig=($module, size)\n" +"Return a bytes object containing random bytes suitable for cryptographic use."); + +#define OS_URANDOM_METHODDEF \ + {"urandom", (PyCFunction)os_urandom, METH_VARARGS, os_urandom__doc__}, + +static PyObject * +os_urandom_impl(PyModuleDef *module, Py_ssize_t size); + +static PyObject * +os_urandom(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; Py_ssize_t size; - PyObject *result; - int ret; - - /* Read arguments */ - if (!PyArg_ParseTuple(args, "n:urandom", &size)) - return NULL; + + if (!PyArg_ParseTuple(args, + "n:urandom", + &size)) + goto exit; + return_value = os_urandom_impl(module, size); + +exit: + return return_value; +} + +static PyObject * +os_urandom_impl(PyModuleDef *module, Py_ssize_t size) +/*[clinic end generated code: output=7e3c27800e165fbd input=4067cdb1b6776c29]*/ +{ + PyObject *bytes; + int result; + if (size < 0) return PyErr_Format(PyExc_ValueError, "negative argument not allowed"); - result = PyBytes_FromStringAndSize(NULL, size); - if (result == NULL) - return NULL; - - ret = _PyOS_URandom(PyBytes_AS_STRING(result), - PyBytes_GET_SIZE(result)); - if (ret == -1) { - Py_DECREF(result); - return NULL; - } - return result; + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) + return NULL; + + result = _PyOS_URandom(PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes)); + if (result == -1) { + Py_DECREF(bytes); + return NULL; + } + return bytes; } /* Terminal size querying */ @@ -10905,6 +15825,7 @@ }; #if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) +/* AC 3.5: fd should accept None */ PyDoc_STRVAR(termsize__doc__, "Return the size of the terminal window as (columns, lines).\n" \ "\n" \ @@ -10988,15 +15909,35 @@ } return termsize; } +#else /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ #endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ -PyDoc_STRVAR(posix_cpu_count__doc__, -"cpu_count() -> integer\n\n\ -Return the number of CPUs in the system, or None if this value cannot be\n\ -established."); - -static PyObject * -posix_cpu_count(PyObject *self) + +/*[clinic input] +os.cpu_count + +Return the number of CPUs in the system; return None if indeterminable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_cpu_count__doc__, +"sig=($module)\n" +"Return the number of CPUs in the system; return None if indeterminable."); + +#define OS_CPU_COUNT_METHODDEF \ + {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__}, + +static PyObject * +os_cpu_count_impl(PyModuleDef *module); + +static PyObject * +os_cpu_count(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_cpu_count_impl(module); +} + +static PyObject * +os_cpu_count_impl(PyModuleDef *module) +/*[clinic end generated code: output=8c364c20468fefa6 input=d55e2f8f3823a628]*/ { int ncpu = 0; #ifdef MS_WINDOWS @@ -11025,45 +15966,102 @@ Py_RETURN_NONE; } -PyDoc_STRVAR(get_inheritable__doc__, - "get_inheritable(fd) -> bool\n" \ - "\n" \ - "Get the close-on-exe flag of the specified file descriptor."); - -static PyObject* -posix_get_inheritable(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.get_inheritable -> bool + + fd: int + / + +Get the close-on-exe flag of the specified file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_get_inheritable__doc__, +"sig=($module, fd)\n" +"Get the close-on-exe flag of the specified file descriptor."); + +#define OS_GET_INHERITABLE_METHODDEF \ + {"get_inheritable", (PyCFunction)os_get_inheritable, METH_VARARGS, os_get_inheritable__doc__}, + +static int +os_get_inheritable_impl(PyModuleDef *module, int fd); + +static PyObject * +os_get_inheritable(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int _return_value; + + if (!PyArg_ParseTuple(args, + "i:get_inheritable", + &fd)) + goto exit; + _return_value = os_get_inheritable_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_get_inheritable_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=aaefc796a6e99ff3 input=89ac008dc9ab6b95]*/ +{ + if (!_PyVerify_fd(fd)){ + posix_error(); + return -1; + } + + return _Py_get_inheritable(fd); +} + + +/*[clinic input] +os.set_inheritable + fd: int + inheritable: int + / + +Set the inheritable flag of the specified file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_set_inheritable__doc__, +"sig=($module, fd, inheritable)\n" +"Set the inheritable flag of the specified file descriptor."); + +#define OS_SET_INHERITABLE_METHODDEF \ + {"set_inheritable", (PyCFunction)os_set_inheritable, METH_VARARGS, os_set_inheritable__doc__}, + +static PyObject * +os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable); + +static PyObject * +os_set_inheritable(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; int fd; int inheritable; - if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd)) - return NULL; - + if (!PyArg_ParseTuple(args, + "ii:set_inheritable", + &fd, &inheritable)) + goto exit; + return_value = os_set_inheritable_impl(module, fd, inheritable); + +exit: + return return_value; +} + +static PyObject * +os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable) +/*[clinic end generated code: output=195b9837d7fbb9e2 input=9ceaead87a1e2402]*/ +{ if (!_PyVerify_fd(fd)) return posix_error(); - inheritable = _Py_get_inheritable(fd); - if (inheritable < 0) - return NULL; - return PyBool_FromLong(inheritable); -} - -PyDoc_STRVAR(set_inheritable__doc__, - "set_inheritable(fd, inheritable)\n" \ - "\n" \ - "Set the inheritable flag of the specified file descriptor."); - -static PyObject* -posix_set_inheritable(PyObject *self, PyObject *args) -{ - int fd, inheritable; - - if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable)) - return NULL; - - if (!_PyVerify_fd(fd)) - return posix_error(); - if (_Py_set_inheritable(fd, inheritable, NULL) < 0) return NULL; Py_RETURN_NONE; @@ -11071,55 +16069,112 @@ #ifdef MS_WINDOWS -PyDoc_STRVAR(get_handle_inheritable__doc__, - "get_handle_inheritable(fd) -> bool\n" \ - "\n" \ - "Get the close-on-exe flag of the specified file descriptor."); - -static PyObject* -posix_get_handle_inheritable(PyObject *self, PyObject *args) -{ + +/*[clinic input] +os.get_handle_inheritable -> bool + handle: Py_intptr_t + / + +Get the close-on-exe flag of the specified file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_get_handle_inheritable__doc__, +"sig=($module, handle)\n" +"Get the close-on-exe flag of the specified file descriptor."); + +#define OS_GET_HANDLE_INHERITABLE_METHODDEF \ + {"get_handle_inheritable", (PyCFunction)os_get_handle_inheritable, METH_VARARGS, os_get_handle_inheritable__doc__}, + +static int +os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle); + +static PyObject * +os_get_handle_inheritable(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; Py_intptr_t handle; + int _return_value; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_INTPTR ":get_handle_inheritable", + &handle)) + goto exit; + _return_value = os_get_handle_inheritable_impl(module, handle); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle) +/*[clinic end generated code: output=8249f5945858cb51 input=5f7759443aae3dc5]*/ +{ DWORD flags; - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) - return NULL; - if (!GetHandleInformation((HANDLE)handle, &flags)) { PyErr_SetFromWindowsErr(0); return NULL; } - return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT); -} - -PyDoc_STRVAR(set_handle_inheritable__doc__, - "set_handle_inheritable(fd, inheritable)\n" \ - "\n" \ - "Set the inheritable flag of the specified handle."); - + return flags & HANDLE_FLAG_INHERIT; +} + +/*[clinic input] +os.set_handle_inheritable + handle: Py_intptr_t + inheritable: bool + / + +Set the inheritable flag of the specified handle. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_set_handle_inheritable__doc__, +"sig=($module, handle, inheritable)\n" +"Set the inheritable flag of the specified handle."); + +#define OS_SET_HANDLE_INHERITABLE_METHODDEF \ + {"set_handle_inheritable", (PyCFunction)os_set_handle_inheritable, METH_VARARGS, os_set_handle_inheritable__doc__}, + +static PyObject * +os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable); + +static PyObject * +os_set_handle_inheritable(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_intptr_t handle; + int inheritable; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_INTPTR "p:set_handle_inheritable", + &handle, &inheritable)) + goto exit; + return_value = os_set_handle_inheritable_impl(module, handle, inheritable); + +exit: + return return_value; +} + +static PyObject * +os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable) +/*[clinic end generated code: output=91f58ae296ebdbcb input=e64b2b2730469def]*/ static PyObject* posix_set_handle_inheritable(PyObject *self, PyObject *args) { - int inheritable = 1; - Py_intptr_t handle; - DWORD flags; - - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable", - &handle, &inheritable)) - return NULL; - - if (inheritable) - flags = HANDLE_FLAG_INHERIT; - else - flags = 0; + DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0; if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { PyErr_SetFromWindowsErr(0); return NULL; } Py_RETURN_NONE; } -#endif /* MS_WINDOWS */ +#else /* MS_WINDOWS */ +#define OS_GET_HANDLE_INHERITABLE_METHODDEF +#define OS_SET_HANDLE_INHERITABLE_METHODDEF +#endif /* MS_WINDOWS */ @@ -11128,71 +16183,26 @@ OS_STAT_METHODDEF OS_ACCESS_METHODDEF OS_TTYNAME_METHODDEF - - {"chdir", (PyCFunction)posix_chdir, - METH_VARARGS | METH_KEYWORDS, - posix_chdir__doc__}, -#ifdef HAVE_CHFLAGS - {"chflags", (PyCFunction)posix_chflags, - METH_VARARGS | METH_KEYWORDS, - posix_chflags__doc__}, -#endif /* HAVE_CHFLAGS */ - {"chmod", (PyCFunction)posix_chmod, - METH_VARARGS | METH_KEYWORDS, - posix_chmod__doc__}, -#ifdef HAVE_FCHMOD - {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__}, -#endif /* HAVE_FCHMOD */ -#ifdef HAVE_CHOWN - {"chown", (PyCFunction)posix_chown, - METH_VARARGS | METH_KEYWORDS, - posix_chown__doc__}, -#endif /* HAVE_CHOWN */ -#ifdef HAVE_LCHMOD - {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__}, -#endif /* HAVE_LCHMOD */ -#ifdef HAVE_FCHOWN - {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__}, -#endif /* HAVE_FCHOWN */ -#ifdef HAVE_LCHFLAGS - {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__}, -#endif /* HAVE_LCHFLAGS */ -#ifdef HAVE_LCHOWN - {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__}, -#endif /* HAVE_LCHOWN */ -#ifdef HAVE_CHROOT - {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__}, -#endif -#ifdef HAVE_CTERMID - {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__}, -#endif - {"getcwd", (PyCFunction)posix_getcwd_unicode, - METH_NOARGS, posix_getcwd__doc__}, - {"getcwdb", (PyCFunction)posix_getcwd_bytes, - METH_NOARGS, posix_getcwdb__doc__}, -#if defined(HAVE_LINK) || defined(MS_WINDOWS) - {"link", (PyCFunction)posix_link, - METH_VARARGS | METH_KEYWORDS, - posix_link__doc__}, -#endif /* HAVE_LINK */ - {"listdir", (PyCFunction)posix_listdir, - METH_VARARGS | METH_KEYWORDS, - posix_listdir__doc__}, - {"lstat", (PyCFunction)posix_lstat, - METH_VARARGS | METH_KEYWORDS, - posix_lstat__doc__}, - {"mkdir", (PyCFunction)posix_mkdir, - METH_VARARGS | METH_KEYWORDS, - posix_mkdir__doc__}, -#ifdef HAVE_NICE - {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, -#endif /* HAVE_NICE */ -#ifdef HAVE_GETPRIORITY - {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__}, -#endif /* HAVE_GETPRIORITY */ -#ifdef HAVE_SETPRIORITY - {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__}, -#endif /* HAVE_SETPRIORITY */ + OS_CHDIR_METHODDEF + OS_CHFLAGS_METHODDEF + OS_CHMOD_METHODDEF + OS_FCHMOD_METHODDEF + OS_LCHMOD_METHODDEF + OS_CHOWN_METHODDEF + OS_FCHOWN_METHODDEF + OS_LCHOWN_METHODDEF + OS_LCHFLAGS_METHODDEF + OS_CHROOT_METHODDEF + OS_CTERMID_METHODDEF + OS_GETCWD_METHODDEF + OS_GETCWDB_METHODDEF + OS_LINK_METHODDEF + OS_LISTDIR_METHODDEF + OS_LSTAT_METHODDEF + OS_MKDIR_METHODDEF + OS_NICE_METHODDEF + OS_GETPRIORITY_METHODDEF + OS_SETPRIORITY_METHODDEF #ifdef HAVE_READLINK {"readlink", (PyCFunction)posix_readlink, METH_VARARGS | METH_KEYWORDS, @@ -11203,376 +16213,157 @@ METH_VARARGS | METH_KEYWORDS, readlink__doc__}, #endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ - {"rename", (PyCFunction)posix_rename, - METH_VARARGS | METH_KEYWORDS, - posix_rename__doc__}, - {"replace", (PyCFunction)posix_replace, - METH_VARARGS | METH_KEYWORDS, - posix_replace__doc__}, - {"rmdir", (PyCFunction)posix_rmdir, - METH_VARARGS | METH_KEYWORDS, - posix_rmdir__doc__}, + OS_RENAME_METHODDEF + OS_REPLACE_METHODDEF + OS_RMDIR_METHODDEF {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, -#if defined(HAVE_SYMLINK) - {"symlink", (PyCFunction)posix_symlink, - METH_VARARGS | METH_KEYWORDS, - posix_symlink__doc__}, -#endif /* HAVE_SYMLINK */ -#ifdef HAVE_SYSTEM - {"system", posix_system, METH_VARARGS, posix_system__doc__}, -#endif - {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, -#ifdef HAVE_UNAME - {"uname", posix_uname, METH_NOARGS, posix_uname__doc__}, -#endif /* HAVE_UNAME */ - {"unlink", (PyCFunction)posix_unlink, - METH_VARARGS | METH_KEYWORDS, - posix_unlink__doc__}, - {"remove", (PyCFunction)posix_unlink, - METH_VARARGS | METH_KEYWORDS, - posix_remove__doc__}, - {"utime", (PyCFunction)posix_utime, - METH_VARARGS | METH_KEYWORDS, posix_utime__doc__}, -#ifdef HAVE_TIMES - {"times", posix_times, METH_NOARGS, posix_times__doc__}, -#endif /* HAVE_TIMES */ - {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, -#ifdef HAVE_EXECV - {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, - {"execve", (PyCFunction)posix_execve, - METH_VARARGS | METH_KEYWORDS, - posix_execve__doc__}, -#endif /* HAVE_EXECV */ -#ifdef HAVE_SPAWNV - {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, - {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, -#endif /* HAVE_SPAWNV */ -#ifdef HAVE_FORK1 - {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__}, -#endif /* HAVE_FORK1 */ -#ifdef HAVE_FORK - {"fork", posix_fork, METH_NOARGS, posix_fork__doc__}, -#endif /* HAVE_FORK */ -#ifdef HAVE_SCHED_H -#ifdef HAVE_SCHED_GET_PRIORITY_MAX - {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__}, - {"sched_get_priority_min", posix_sched_get_priority_min, METH_VARARGS, posix_sched_get_priority_min__doc__}, -#endif -#ifdef HAVE_SCHED_SETPARAM - {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__}, -#endif -#ifdef HAVE_SCHED_SETSCHEDULER - {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__}, -#endif -#ifdef HAVE_SCHED_RR_GET_INTERVAL - {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__}, -#endif -#ifdef HAVE_SCHED_SETPARAM - {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__}, -#endif -#ifdef HAVE_SCHED_SETSCHEDULER - {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__}, -#endif - {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__}, -#ifdef HAVE_SCHED_SETAFFINITY - {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__}, - {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__}, -#endif -#endif /* HAVE_SCHED_H */ -#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) - {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__}, -#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */ -#ifdef HAVE_FORKPTY - {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__}, -#endif /* HAVE_FORKPTY */ -#ifdef HAVE_GETEGID - {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__}, -#endif /* HAVE_GETEGID */ -#ifdef HAVE_GETEUID - {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__}, -#endif /* HAVE_GETEUID */ -#ifdef HAVE_GETGID - {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__}, -#endif /* HAVE_GETGID */ + OS_SYMLINK_METHODDEF + OS_SYSTEM_METHODDEF + OS_UMASK_METHODDEF + OS_UNAME_METHODDEF + OS_UNLINK_METHODDEF + OS_REMOVE_METHODDEF + OS_UTIME_METHODDEF + OS_TIMES_METHODDEF + OS__EXIT_METHODDEF + OS_EXECV_METHODDEF + OS_EXECVE_METHODDEF + OS_SPAWNV_METHODDEF + OS_SPAWNVE_METHODDEF + OS_FORK1_METHODDEF + OS_FORK_METHODDEF + OS_SCHED_GET_PRIORITY_MAX_METHODDEF + OS_SCHED_GET_PRIORITY_MIN_METHODDEF + OS_SCHED_GETPARAM_METHODDEF + OS_SCHED_GETSCHEDULER_METHODDEF + OS_SCHED_RR_GET_INTERVAL_METHODDEF + OS_SCHED_SETPARAM_METHODDEF + OS_SCHED_SETSCHEDULER_METHODDEF + OS_SCHED_YIELD_METHODDEF + OS_SCHED_SETAFFINITY_METHODDEF + OS_SCHED_GETAFFINITY_METHODDEF + OS_OPENPTY_METHODDEF + OS_FORKPTY_METHODDEF + OS_GETEGID_METHODDEF + OS_GETEUID_METHODDEF + OS_GETGID_METHODDEF #ifdef HAVE_GETGROUPLIST {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__}, #endif -#ifdef HAVE_GETGROUPS - {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__}, -#endif - {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__}, -#ifdef HAVE_GETPGRP - {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__}, -#endif /* HAVE_GETPGRP */ -#ifdef HAVE_GETPPID - {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__}, -#endif /* HAVE_GETPPID */ -#ifdef HAVE_GETUID - {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__}, -#endif /* HAVE_GETUID */ -#ifdef HAVE_GETLOGIN - {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__}, -#endif -#ifdef HAVE_KILL - {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, -#endif /* HAVE_KILL */ -#ifdef HAVE_KILLPG - {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__}, -#endif /* HAVE_KILLPG */ -#ifdef HAVE_PLOCK - {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, -#endif /* HAVE_PLOCK */ + OS_GETGROUPS_METHODDEF + OS_GETPID_METHODDEF + OS_GETPGRP_METHODDEF + OS_GETPPID_METHODDEF + OS_GETUID_METHODDEF + OS_GETLOGIN_METHODDEF + OS_KILL_METHODDEF + OS_KILLPG_METHODDEF + OS_PLOCK_METHODDEF #ifdef MS_WINDOWS {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, - {"kill", win32_kill, METH_VARARGS, win32_kill__doc__}, -#endif -#ifdef HAVE_SETUID - {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, -#endif /* HAVE_SETUID */ -#ifdef HAVE_SETEUID - {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, -#endif /* HAVE_SETEUID */ -#ifdef HAVE_SETEGID - {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, -#endif /* HAVE_SETEGID */ -#ifdef HAVE_SETREUID - {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, -#endif /* HAVE_SETREUID */ -#ifdef HAVE_SETREGID - {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, -#endif /* HAVE_SETREGID */ -#ifdef HAVE_SETGID - {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, -#endif /* HAVE_SETGID */ -#ifdef HAVE_SETGROUPS - {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, -#endif /* HAVE_SETGROUPS */ +#endif + OS_SETUID_METHODDEF + OS_SETEUID_METHODDEF + OS_SETREUID_METHODDEF + OS_SETGID_METHODDEF + OS_SETEGID_METHODDEF + OS_SETREGID_METHODDEF + OS_SETGROUPS_METHODDEF #ifdef HAVE_INITGROUPS {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, #endif /* HAVE_INITGROUPS */ -#ifdef HAVE_GETPGID - {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, -#endif /* HAVE_GETPGID */ -#ifdef HAVE_SETPGRP - {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__}, -#endif /* HAVE_SETPGRP */ -#ifdef HAVE_WAIT - {"wait", posix_wait, METH_NOARGS, posix_wait__doc__}, -#endif /* HAVE_WAIT */ -#ifdef HAVE_WAIT3 - {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__}, -#endif /* HAVE_WAIT3 */ -#ifdef HAVE_WAIT4 - {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__}, -#endif /* HAVE_WAIT4 */ -#if defined(HAVE_WAITID) && !defined(__APPLE__) - {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__}, -#endif -#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) - {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, -#endif /* HAVE_WAITPID */ -#ifdef HAVE_GETSID - {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__}, -#endif /* HAVE_GETSID */ -#ifdef HAVE_SETSID - {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__}, -#endif /* HAVE_SETSID */ -#ifdef HAVE_SETPGID - {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, -#endif /* HAVE_SETPGID */ -#ifdef HAVE_TCGETPGRP - {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, -#endif /* HAVE_TCGETPGRP */ -#ifdef HAVE_TCSETPGRP - {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, -#endif /* HAVE_TCSETPGRP */ - {"open", (PyCFunction)posix_open,\ - METH_VARARGS | METH_KEYWORDS, - posix_open__doc__}, - {"close", posix_close, METH_VARARGS, posix_close__doc__}, - {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, - {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, - {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, - {"dup2", (PyCFunction)posix_dup2, - METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__}, -#ifdef HAVE_LOCKF - {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__}, -#endif - {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, - {"read", posix_read, METH_VARARGS, posix_read__doc__}, -#ifdef HAVE_READV - {"readv", posix_readv, METH_VARARGS, posix_readv__doc__}, -#endif -#ifdef HAVE_PREAD - {"pread", posix_pread, METH_VARARGS, posix_pread__doc__}, -#endif - {"write", posix_write, METH_VARARGS, posix_write__doc__}, -#ifdef HAVE_WRITEV - {"writev", posix_writev, METH_VARARGS, posix_writev__doc__}, -#endif -#ifdef HAVE_PWRITE - {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__}, -#endif + OS_GETPGID_METHODDEF + OS_SETPGRP_METHODDEF + OS_WAIT_METHODDEF + OS_WAIT3_METHODDEF + OS_WAIT4_METHODDEF + OS_WAITID_METHODDEF + OS_WAITPID_METHODDEF + OS_GETSID_METHODDEF + OS_SETSID_METHODDEF + OS_SETPGID_METHODDEF + OS_TCGETPGRP_METHODDEF + OS_TCSETPGRP_METHODDEF + OS_OPEN_METHODDEF + OS_CLOSE_METHODDEF + OS_CLOSERANGE_METHODDEF + OS_DEVICE_ENCODING_METHODDEF + OS_DUP_METHODDEF + OS_DUP2_METHODDEF + OS_LOCKF_METHODDEF + OS_LSEEK_METHODDEF + OS_READ_METHODDEF + OS_READV_METHODDEF + OS_PREAD_METHODDEF + OS_WRITE_METHODDEF + OS_WRITEV_METHODDEF + OS_PWRITE_METHODDEF #ifdef HAVE_SENDFILE {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS, posix_sendfile__doc__}, #endif - {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, - {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, -#ifdef HAVE_PIPE - {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, -#endif -#ifdef HAVE_PIPE2 - {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__}, -#endif -#ifdef HAVE_MKFIFO - {"mkfifo", (PyCFunction)posix_mkfifo, - METH_VARARGS | METH_KEYWORDS, - posix_mkfifo__doc__}, -#endif -#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) - {"mknod", (PyCFunction)posix_mknod, - METH_VARARGS | METH_KEYWORDS, - posix_mknod__doc__}, -#endif -#ifdef HAVE_DEVICE_MACROS - {"major", posix_major, METH_VARARGS, posix_major__doc__}, - {"minor", posix_minor, METH_VARARGS, posix_minor__doc__}, - {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__}, -#endif -#ifdef HAVE_FTRUNCATE - {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, -#endif -#ifdef HAVE_TRUNCATE - {"truncate", (PyCFunction)posix_truncate, - METH_VARARGS | METH_KEYWORDS, - posix_truncate__doc__}, -#endif -#ifdef HAVE_POSIX_FALLOCATE - {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__}, -#endif -#ifdef HAVE_POSIX_FADVISE - {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__}, -#endif -#ifdef HAVE_PUTENV - {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, -#endif -#ifdef HAVE_UNSETENV - {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__}, -#endif - {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, -#ifdef HAVE_FCHDIR - {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__}, -#endif -#ifdef HAVE_FSYNC - {"fsync", posix_fsync, METH_O, posix_fsync__doc__}, -#endif -#ifdef HAVE_SYNC - {"sync", posix_sync, METH_NOARGS, posix_sync__doc__}, -#endif -#ifdef HAVE_FDATASYNC - {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__}, -#endif -#ifdef HAVE_SYS_WAIT_H -#ifdef WCOREDUMP - {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__}, -#endif /* WCOREDUMP */ -#ifdef WIFCONTINUED - {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__}, -#endif /* WIFCONTINUED */ -#ifdef WIFSTOPPED - {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, -#endif /* WIFSTOPPED */ -#ifdef WIFSIGNALED - {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, -#endif /* WIFSIGNALED */ -#ifdef WIFEXITED - {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, -#endif /* WIFEXITED */ -#ifdef WEXITSTATUS - {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, -#endif /* WEXITSTATUS */ -#ifdef WTERMSIG - {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, -#endif /* WTERMSIG */ -#ifdef WSTOPSIG - {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, -#endif /* WSTOPSIG */ -#endif /* HAVE_SYS_WAIT_H */ -#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) - {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, -#endif -#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) - {"statvfs", (PyCFunction)posix_statvfs, - METH_VARARGS | METH_KEYWORDS, - posix_statvfs__doc__}, -#endif -#ifdef HAVE_CONFSTR - {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, -#endif -#ifdef HAVE_SYSCONF - {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, -#endif -#ifdef HAVE_FPATHCONF - {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, -#endif -#ifdef HAVE_PATHCONF - {"pathconf", (PyCFunction)posix_pathconf, - METH_VARARGS | METH_KEYWORDS, - posix_pathconf__doc__}, -#endif - {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, + OS_FSTAT_METHODDEF + OS_ISATTY_METHODDEF + OS_PIPE_METHODDEF + OS_PIPE2_METHODDEF + OS_MKFIFO_METHODDEF + OS_MKNOD_METHODDEF + OS_MAJOR_METHODDEF + OS_MINOR_METHODDEF + OS_MAKEDEV_METHODDEF + OS_FTRUNCATE_METHODDEF + OS_TRUNCATE_METHODDEF + OS_POSIX_FALLOCATE_METHODDEF + OS_POSIX_FADVISE_METHODDEF + OS_PUTENV_METHODDEF + OS_UNSETENV_METHODDEF + OS_STRERROR_METHODDEF + OS_FCHDIR_METHODDEF + OS_FSYNC_METHODDEF + OS_SYNC_METHODDEF + OS_FDATASYNC_METHODDEF + OS_WCOREDUMP_METHODDEF + OS_WIFCONTINUED_METHODDEF + OS_WIFSTOPPED_METHODDEF + OS_WIFSIGNALED_METHODDEF + OS_WIFEXITED_METHODDEF + OS_WEXITSTATUS_METHODDEF + OS_WTERMSIG_METHODDEF + OS_WSTOPSIG_METHODDEF + OS_FSTATVFS_METHODDEF + OS_STATVFS_METHODDEF + OS_CONFSTR_METHODDEF + OS_SYSCONF_METHODDEF + OS_FPATHCONF_METHODDEF + OS_PATHCONF_METHODDEF + OS_ABORT_METHODDEF #ifdef MS_WINDOWS {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, - {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, - {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__}, - {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__}, -#endif -#ifdef HAVE_GETLOADAVG - {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -#endif - {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__}, -#ifdef HAVE_SETRESUID - {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__}, -#endif -#ifdef HAVE_SETRESGID - {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__}, -#endif -#ifdef HAVE_GETRESUID - {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__}, -#endif -#ifdef HAVE_GETRESGID - {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__}, -#endif - -#ifdef USE_XATTRS - {"setxattr", (PyCFunction)posix_setxattr, - METH_VARARGS | METH_KEYWORDS, - posix_setxattr__doc__}, - {"getxattr", (PyCFunction)posix_getxattr, - METH_VARARGS | METH_KEYWORDS, - posix_getxattr__doc__}, - {"removexattr", (PyCFunction)posix_removexattr, - METH_VARARGS | METH_KEYWORDS, - posix_removexattr__doc__}, - {"listxattr", (PyCFunction)posix_listxattr, - METH_VARARGS | METH_KEYWORDS, - posix_listxattr__doc__}, -#endif +#endif + OS__GETDISKUSAGE_METHODDEF + OS__GETFINALPATHNAME_METHODDEF + OS__GETVOLUMEPATHNAME_METHODDEF + OS_GETLOADAVG_METHODDEF + OS_URANDOM_METHODDEF + OS_SETRESUID_METHODDEF + OS_SETRESGID_METHODDEF + OS_GETRESUID_METHODDEF + OS_GETRESGID_METHODDEF + + OS_GETXATTR_METHODDEF + OS_SETXATTR_METHODDEF + OS_REMOVEXATTR_METHODDEF + OS_LISTXATTR_METHODDEF + #if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__}, #endif - {"cpu_count", (PyCFunction)posix_cpu_count, - METH_NOARGS, posix_cpu_count__doc__}, - {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__}, - {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__}, -#ifdef MS_WINDOWS - {"get_handle_inheritable", posix_get_handle_inheritable, - METH_VARARGS, get_handle_inheritable__doc__}, - {"set_handle_inheritable", posix_set_handle_inheritable, - METH_VARARGS, set_handle_inheritable__doc__}, -#endif + OS_CPU_COUNT_METHODDEF + OS_GET_INHERITABLE_METHODDEF + OS_SET_INHERITABLE_METHODDEF + OS_GET_HANDLE_INHERITABLE_METHODDEF + OS_SET_HANDLE_INHERITABLE_METHODDEF {NULL, NULL} /* Sentinel */ }; @@ -12237,7 +17028,7 @@ sched_param_desc.name = MODNAME ".sched_param"; if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0) return NULL; - SchedParamType.tp_new = sched_param_new; + SchedParamType.tp_new = os_sched_param; #endif /* initialize TerminalSize_info */ diff -r d6311829da15 Tools/clinic/clinic.py --- a/Tools/clinic/clinic.py Tue Jan 28 05:00:08 2014 -0800 +++ b/Tools/clinic/clinic.py Wed Jan 29 06:08:44 2014 -0800 @@ -1515,6 +1515,7 @@ # The callable should not call builtins.print. return_converters = {} +clinic = None class Clinic: presets_text = """ @@ -1993,7 +1994,8 @@ # set, in case you subclass) if ((cls.format_unit != 'O&') and (cls.format_unit not in legacy_converters)): - legacy_converters[cls.format_unit] = cls + if cls.format_unit: + legacy_converters[cls.format_unit] = cls return cls def add_legacy_c_converter(format_unit, **kwargs): @@ -2005,7 +2007,8 @@ added_f = f else: added_f = functools.partial(f, **kwargs) - legacy_converters[format_unit] = added_f + if format_unit: + legacy_converters[format_unit] = added_f return f return closure @@ -3053,7 +3056,7 @@ return if field not in fd: - fail("Invalid field " + repr(field) + ", must be one of:\n " + ", ".join(valid_fields)) + fail("Invalid field " + repr(field) + ", must be one of:\n preset push pop print everything " + " ".join(fd)) fd[field] = d def directive_dump(self, name): @@ -3132,6 +3135,18 @@ # self.block = self.ClinicOutputBlock(self) if self.ignore_line(line): return + + # is it a directive? + fields = shlex.split(line) + directive_name = fields[0] + directive = self.directives.get(directive_name, None) + if directive: + try: + directive(*fields[1:]) + except TypeError as e: + fail(str(e)) + return + self.next(self.state_modulename_name, line) def state_modulename_name(self, line): @@ -3156,17 +3171,6 @@ self.indent.infer(line) - # is it a directive? - fields = shlex.split(line) - directive_name = fields[0] - directive = self.directives.get(directive_name, None) - if directive: - try: - directive(*fields[1:]) - except TypeError as e: - fail(str(e)) - return - # are we cloning? before, equals, existing = line.rpartition('=') if equals: @@ -3974,6 +3978,7 @@ print("Legacy converters:") legacy = sorted(legacy_converters) + print("LEGACY", legacy) print(' ' + ' '.join(c for c in legacy if c[0].isupper())) print(' ' + ' '.join(c for c in legacy if c[0].islower())) print()