diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b3b5572e1cf..6dfe73017ab 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7,6 +7,8 @@ of the compiler used. Different compilers define their own feature test macro, e.g. '_MSC_VER'. */ +// --- Python includes ------------------------------------------------------ + #include "Python.h" #ifdef __VXWORKS__ @@ -26,40 +28,392 @@ #include "pycore_time.h" // _PyLong_FromTime_t() #include "pycore_typeobject.h" // _PyType_AddMethod() +#ifndef MS_WINDOWS +# include "posixmodule.h" // _PyLong_FromUid() +#else +# include "pycore_fileutils_windows.h" // _Py_GetFileInformationByName() +# include "osdefs.h" // SEP +# include "winreparse.h" // _Py_REPARSE_DATA_BUFFER +#endif + + +// --- System includes ------------------------------------------------------ + +#include // ctermid() +#include // system() + #ifdef HAVE_UNISTD_H # include // symlink() #endif +#ifdef __APPLE__ + /* Needed for the implementation of os.statvfs */ +# include +# include +#endif + +#ifdef HAVE_SYS_TIME_H +# include // futimes() +#endif + +#ifdef HAVE_SYS_PIDFD_H +# include // PIDFD_NONBLOCK +#endif + +#ifdef __EMSCRIPTEN__ +# include "emscripten.h" // emscripten_debugger() +#endif + +#ifdef HAVE_SYS_UIO_H +# include +#endif + +#ifdef HAVE_SYS_TYPES_H + /* Should be included before on HP-UX v3 */ +# include +#endif +#ifdef HAVE_SYS_SYSMACROS_H + /* GNU C Library: major(), minor(), makedev() */ +# include +#endif + +#ifdef HAVE_SYS_STAT_H +# include +#endif + +#ifdef HAVE_SYS_WAIT_H +# include // WNOHANG +#endif + +#ifdef HAVE_LINUX_WAIT_H +# include // P_PIDFD +#endif + +#ifdef HAVE_SIGNAL_H +# include +#endif + +#ifdef HAVE_FCNTL_H +# include // fcntl() +#endif + +#ifdef HAVE_GRP_H +# include // setgroups() +#endif + +#ifdef HAVE_SYSEXITS_H +# include // EX_OK +#endif + +#ifdef HAVE_SYS_LOADAVG_H +# include // getloadavg() +#endif + +#ifdef HAVE_SYS_SENDFILE_H +# include // sendfile() +#endif + +#if defined(__APPLE__) +# include // fcopyfile() +#endif + +#ifdef HAVE_SCHED_H +# include // sched_setscheduler() +#endif +#ifdef HAVE_LINUX_SCHED_H +# include // SCHED_IDLE, SCHED_RR +#endif + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) +# ifdef HAVE_SYS_SOCKET_H +# include +# endif +#endif + +#ifdef HAVE_DLFCN_H +# include +#endif + +#ifdef __hpux +# include +#endif + +#if defined(__DragonFly__) || \ + defined(__OpenBSD__) || \ + defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__APPLE__) +# include +#endif + +#ifdef HAVE_LINUX_RANDOM_H +# include // GRND_RANDOM +#endif +#ifdef HAVE_GETRANDOM_SYSCALL +# include // syscall() +#endif + +#ifdef HAVE_POSIX_SPAWN +# include // posix_spawn() +#endif + +#ifdef HAVE_UTIME_H +# include // utime() +#endif + +#ifdef HAVE_SYS_UTIME_H +# include +# define HAVE_UTIME_H /* pretend we do for the rest of this file */ +#endif + +#ifdef HAVE_SYS_TIMES_H +# include // times() +#endif + +#ifdef HAVE_SYS_PARAM_H +# include +#endif + +#ifdef HAVE_SYS_UTSNAME_H +# include // uname() +#endif + +/* memfd_create is either defined in sys/mman.h or sys/memfd.h + * linux/memfd.h defines additional flags + */ +#ifdef HAVE_SYS_MMAN_H +# include // memfd_create() +#endif +#ifdef HAVE_SYS_MEMFD_H +# include // memfd_create() +#endif +#ifdef HAVE_LINUX_MEMFD_H +# include // memfd_create(), MFD_CLOEXEC +#endif + +#ifdef HAVE_SYS_EVENTFD_H +# include // eventfd() +#endif + +#ifdef HAVE_SYS_TIMERFD_H +# include // timerfd_create() +#endif + +#ifdef _Py_MEMORY_SANITIZER +# include // __msan_unpoison() +#endif + + +// --- More complex system includes ----------------------------------------- + #ifdef MS_WINDOWS # include # if !defined(MS_WINDOWS_GAMES) || defined(MS_WINDOWS_DESKTOP) -# include +# include // PathCchSkipRoot() # endif -# include -# include // UNLEN -# include "osdefs.h" // SEP # include // SetEntriesInAcl +# include // UNLEN # include // SDDL_REVISION_1 +# include // FSCTL_GET_REPARSE_POINT # if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) # define HAVE_SYMLINK # endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */ #endif -#ifndef MS_WINDOWS -# include "posixmodule.h" -#else -# include "pycore_fileutils_windows.h" -# include "winreparse.h" + +#ifdef _MSC_VER +# ifdef HAVE_DIRECT_H +# include +# endif +# ifdef HAVE_IO_H +# include +# endif +# ifdef HAVE_PROCESS_H +# include // getpid(), _cwait() +# endif +# include +#endif /* _MSC_VER */ + + +#ifdef HAVE__GETPTY +# include // mode_t + // SGI apparently needs this forward declaration + extern char * _getpty(int *, int, mode_t, int); #endif + +#if defined(HAVE_SYS_XATTR_H) +# if defined(HAVE_LINUX_LIMITS_H) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) +# define USE_XATTRS +# include // Needed for XATTR_SIZE_MAX on musl libc. +# endif +# if defined(__CYGWIN__) +# define USE_XATTRS +# include // Needed for XATTR_SIZE_MAX and XATTR_LIST_MAX. +# endif +#endif +#ifdef USE_XATTRS +# include // fgetxattr() +#endif + + +#ifdef HAVE_WINDOWS_CONSOLE_IO +# define TERMSIZE_USE_CONIO +#elif defined(HAVE_SYS_IOCTL_H) +# include // ioctl(), TIOCGWINSZ +# if defined(HAVE_TERMIOS_H) +# include +# endif +# if defined(TIOCGWINSZ) +# define TERMSIZE_USE_IOCTL +# endif +#endif + + +/* Various compilers have only certain posix functions */ +/* XXX Gosh I wish these were all moved into pyconfig.h */ +#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ +# define HAVE_OPENDIR 1 +# define HAVE_SYSTEM 1 +# include +#elif defined( _MSC_VER) + /* Microsoft compiler */ +# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) +# define HAVE_GETPPID 1 +# endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_APP | MS_WINDOWS_SYSTEM */ +# if defined(MS_WINDOWS_DESKTOP) +# define HAVE_GETLOGIN 1 +# endif /* MS_WINDOWS_DESKTOP */ +# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) +# define HAVE_SPAWNV 1 +# define HAVE_EXECV 1 +# define HAVE_WSPAWNV 1 +# define HAVE_WEXECV 1 +# define HAVE_SYSTEM 1 +# define HAVE_CWAIT 1 +# endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */ +# define HAVE_PIPE 1 +# define HAVE_FSYNC 1 +# define fsync _commit +#endif + + +#if !defined(_MSC_VER) && defined(__sgi) && _COMPILER_VERSION>=700 +/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode + (default) */ +extern char *ctermid_r(char *); +#endif + + +#if defined(__VXWORKS__) +# include +# include +# include +# include +# ifndef _P_WAIT +# define _P_WAIT 0 +# define _P_NOWAIT 1 +# define _P_NOWAITO 1 +# endif +#endif /* __VXWORKS__ */ + + +#ifdef HAVE_DIRENT_H +# include // opendir() +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# if defined(__WATCOMC__) && !defined(__QNX__) +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +# else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# endif +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +#endif + + +#if defined(MAJOR_IN_MKDEV) +# include +#else +# if defined(MAJOR_IN_SYSMACROS) +# include +# endif +# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) +# include +# endif +#endif + + +// --- Macros --------------------------------------------------------------- + +#ifndef MAXPATHLEN +# if defined(PATH_MAX) && PATH_MAX > 1024 +# define MAXPATHLEN PATH_MAX +# else +# define MAXPATHLEN 1024 +# endif +#endif /* MAXPATHLEN */ + + +#ifdef UNION_WAIT + /* Emulate some macros on systems that have a union instead of macros */ +# ifndef WIFEXITED +# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) +# endif +# ifndef WEXITSTATUS +# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) +# endif +# ifndef WTERMSIG +# define WTERMSIG(u_wait) ((u_wait).w_termsig) +# endif +# define WAIT_TYPE union wait +# define WAIT_STATUS_INT(s) (s.w_status) +#else + /* !UNION_WAIT */ +# define WAIT_TYPE int +# define WAIT_STATUS_INT(s) (s) +#endif /* UNION_WAIT */ + + +/* Don't use the "_r" form if we don't need it (also, won't have a + prototype for it, at least on Solaris -- maybe others as well?). */ +#if defined(HAVE_CTERMID_R) +# define USE_CTERMID_R +#endif + + +/* choose the appropriate stat and fstat functions and return structs */ +#undef STAT +#undef FSTAT +#undef STRUCT_STAT +#ifdef MS_WINDOWS +# define STAT win32_stat +# define LSTAT win32_lstat +# define FSTAT _Py_fstat_noraise +# define STRUCT_STAT struct _Py_stat_struct +#else +# define STAT stat +# define LSTAT lstat +# define FSTAT fstat +# define STRUCT_STAT struct stat +#endif + + #if !defined(EX_OK) && defined(EXIT_SUCCESS) # define EX_OK EXIT_SUCCESS #endif -#ifdef __APPLE__ - /* Needed for the implementation of os.statvfs */ -# include -# include +#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) +# undef HAVE_SCHED_SETAFFINITY #endif /* On android API level 21, 'AT_EACCESS' is not declared although @@ -68,25 +422,13 @@ # undef HAVE_FACCESSAT #endif -#include // ctermid() -#include // system() -#ifdef HAVE_SYS_TIME_H -# include // futimes() -#endif -#ifdef HAVE_SYS_PIDFD_H -# include // PIDFD_NONBLOCK +#if defined(__sun) +/* Something to implement in autoconf, not present in autoconf 2.69 */ +# define HAVE_STRUCT_STAT_ST_FSTYPE 1 #endif -// SGI apparently needs this forward declaration -#ifdef HAVE__GETPTY -# include // mode_t - extern char * _getpty(int *, int, mode_t, int); -#endif - -#ifdef __EMSCRIPTEN__ -#include "emscripten.h" // emscripten_debugger() -#endif +// --- Apple __builtin_available() macros ----------------------------------- /* * A number of APIs are available on macOS from a certain macOS version. @@ -247,308 +589,7 @@ #endif -PyDoc_STRVAR(posix__doc__, -"This module provides access to operating system functionality that is\n\ -standardized by the C Standard and the POSIX standard (a thinly\n\ -disguised Unix interface). Refer to the library manual and\n\ -corresponding Unix manual entries for more information on calls."); - - -#ifdef HAVE_SYS_UIO_H -# include -#endif - -#ifdef HAVE_SYS_TYPES_H -/* Should be included before on HP-UX v3 */ -# include -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_SYS_SYSMACROS_H -/* GNU C Library: major(), minor(), makedev() */ -# include -#endif - -#ifdef HAVE_SYS_STAT_H -# include -#endif /* HAVE_SYS_STAT_H */ - -#ifdef HAVE_SYS_WAIT_H -# include // WNOHANG -#endif -#ifdef HAVE_LINUX_WAIT_H -# include // P_PIDFD -#endif - -#ifdef HAVE_SIGNAL_H -# include -#endif - -#ifdef HAVE_FCNTL_H -# include -#endif - -#ifdef HAVE_GRP_H -# include -#endif - -#ifdef HAVE_SYSEXITS_H -# include -#endif - -#ifdef HAVE_SYS_LOADAVG_H -# include -#endif - -#ifdef HAVE_SYS_SENDFILE_H -# include -#endif - -#if defined(__APPLE__) -# include -#endif - -#ifdef HAVE_SCHED_H -# include -#endif - -#ifdef HAVE_LINUX_SCHED_H -# include -#endif - -#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) -# undef HAVE_SCHED_SETAFFINITY -#endif - -#if defined(HAVE_SYS_XATTR_H) -# if defined(HAVE_LINUX_LIMITS_H) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) -# define USE_XATTRS -# include // Needed for XATTR_SIZE_MAX on musl libc. -# endif -# if defined(__CYGWIN__) -# define USE_XATTRS -# include // Needed for XATTR_SIZE_MAX and XATTR_LIST_MAX. -# endif -#endif - -#ifdef USE_XATTRS -# include -#endif - -#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) -# ifdef HAVE_SYS_SOCKET_H -# include -# endif -#endif - -#ifdef HAVE_DLFCN_H -# include -#endif - -#ifdef __hpux -# include -#endif - -#if defined(__DragonFly__) || \ - defined(__OpenBSD__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__APPLE__) -# include -#endif - -#ifdef HAVE_LINUX_RANDOM_H -# include -#endif -#ifdef HAVE_GETRANDOM_SYSCALL -# include -#endif - -#ifdef HAVE_WINDOWS_CONSOLE_IO -# define TERMSIZE_USE_CONIO -#elif defined(HAVE_SYS_IOCTL_H) -# include -# if defined(HAVE_TERMIOS_H) -# include -# endif -# if defined(TIOCGWINSZ) -# define TERMSIZE_USE_IOCTL -# endif -#endif /* HAVE_WINDOWS_CONSOLE_IO */ - -/* Various compilers have only certain posix functions */ -/* XXX Gosh I wish these were all moved into pyconfig.h */ -#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ -# define HAVE_OPENDIR 1 -# define HAVE_SYSTEM 1 -# include -#elif defined( _MSC_VER) - /* Microsoft compiler */ -# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) -# define HAVE_GETPPID 1 -# endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_APP | MS_WINDOWS_SYSTEM */ -# if defined(MS_WINDOWS_DESKTOP) -# define HAVE_GETLOGIN 1 -# endif /* MS_WINDOWS_DESKTOP */ -# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) -# define HAVE_SPAWNV 1 -# define HAVE_EXECV 1 -# define HAVE_WSPAWNV 1 -# define HAVE_WEXECV 1 -# define HAVE_SYSTEM 1 -# define HAVE_CWAIT 1 -# endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */ -# define HAVE_PIPE 1 -# define HAVE_FSYNC 1 -# define fsync _commit -#endif /* ! __WATCOMC__ || __QNX__ */ - -/*[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=94a0f0f978acae17]*/ - -#ifndef _MSC_VER - -#if defined(__sgi)&&_COMPILER_VERSION>=700 -/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode - (default) */ -extern char *ctermid_r(char *); -#endif - -#endif /* !_MSC_VER */ - -#if defined(__VXWORKS__) -# include -# include -# include -# include -# ifndef _P_WAIT -# define _P_WAIT 0 -# define _P_NOWAIT 1 -# define _P_NOWAITO 1 -# endif -#endif /* __VXWORKS__ */ - -#ifdef HAVE_POSIX_SPAWN -# include -#endif - -#ifdef HAVE_UTIME_H -# include -#endif /* HAVE_UTIME_H */ - -#ifdef HAVE_SYS_UTIME_H -# include -# define HAVE_UTIME_H /* pretend we do for the rest of this file */ -#endif /* HAVE_SYS_UTIME_H */ - -#ifdef HAVE_SYS_TIMES_H -# include -#endif /* HAVE_SYS_TIMES_H */ - -#ifdef HAVE_SYS_PARAM_H -# include -#endif /* HAVE_SYS_PARAM_H */ - -#ifdef HAVE_SYS_UTSNAME_H -# include -#endif /* HAVE_SYS_UTSNAME_H */ - -#ifdef HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# if defined(__WATCOMC__) && !defined(__QNX__) -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -# else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# endif -# ifdef HAVE_SYS_NDIR_H -# include -# endif -# ifdef HAVE_SYS_DIR_H -# include -# endif -# ifdef HAVE_NDIR_H -# include -# endif -#endif - -#ifdef _MSC_VER -# ifdef HAVE_DIRECT_H -# include -# endif -# ifdef HAVE_IO_H -# include -# endif -# ifdef HAVE_PROCESS_H -# include -# endif -# include -#endif /* _MSC_VER */ - -#ifndef MAXPATHLEN -# if defined(PATH_MAX) && PATH_MAX > 1024 -# define MAXPATHLEN PATH_MAX -# else -# define MAXPATHLEN 1024 -# endif -#endif /* MAXPATHLEN */ - -#ifdef UNION_WAIT - /* Emulate some macros on systems that have a union instead of macros */ -# ifndef WIFEXITED -# define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) -# endif -# ifndef WEXITSTATUS -# define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) -# endif -# ifndef WTERMSIG -# define WTERMSIG(u_wait) ((u_wait).w_termsig) -# endif -# define WAIT_TYPE union wait -# define WAIT_STATUS_INT(s) (s.w_status) -#else - /* !UNION_WAIT */ -# define WAIT_TYPE int -# define WAIT_STATUS_INT(s) (s) -#endif /* UNION_WAIT */ - -/* Don't use the "_r" form if we don't need it (also, won't have a - prototype for it, at least on Solaris -- maybe others as well?). */ -#if defined(HAVE_CTERMID_R) -# define USE_CTERMID_R -#endif - -/* choose the appropriate stat and fstat functions and return structs */ -#undef STAT -#undef FSTAT -#undef STRUCT_STAT -#ifdef MS_WINDOWS -# define STAT win32_stat -# define LSTAT win32_lstat -# define FSTAT _Py_fstat_noraise -# define STRUCT_STAT struct _Py_stat_struct -#else -# define STAT stat -# define LSTAT lstat -# define FSTAT fstat -# define STRUCT_STAT struct stat -#endif - -#if defined(MAJOR_IN_MKDEV) -# include -#else -# if defined(MAJOR_IN_SYSMACROS) -# include -# endif -# if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) -# include -# endif -#endif +// --- os module ------------------------------------------------------------ #ifdef MS_WINDOWS # define INITFUNC PyInit_nt @@ -560,37 +601,20 @@ extern char *ctermid_r(char *); # define MODNAME_OBJ &_Py_ID(posix) #endif -#if defined(__sun) -/* Something to implement in autoconf, not present in autoconf 2.69 */ -# define HAVE_STRUCT_STAT_ST_FSTYPE 1 -#endif +/*[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=94a0f0f978acae17]*/ -/* memfd_create is either defined in sys/mman.h or sys/memfd.h - * linux/memfd.h defines additional flags - */ -#ifdef HAVE_SYS_MMAN_H -# include -#endif -#ifdef HAVE_SYS_MEMFD_H -# include -#endif -#ifdef HAVE_LINUX_MEMFD_H -# include -#endif +PyDoc_STRVAR(posix__doc__, +"This module provides access to operating system functionality that is\n\ +standardized by the C Standard and the POSIX standard (a thinly\n\ +disguised Unix interface). Refer to the library manual and\n\ +corresponding Unix manual entries for more information on calls."); -/* eventfd() */ -#ifdef HAVE_SYS_EVENTFD_H -# include -#endif -/* timerfd_create() */ -#ifdef HAVE_SYS_TIMERFD_H -# include -#endif - -#ifdef _Py_MEMORY_SANITIZER -# include -#endif +// --- Functions ------------------------------------------------------------ #ifdef HAVE_FORK static void