Issue #10812: Add some extra posix functions to the os module.

This commit is contained in:
Ross Lagerwall 2011-03-17 20:20:30 +02:00
parent eb8cee8383
commit 7807c3545d
7 changed files with 1258 additions and 167 deletions

View File

@ -743,6 +743,17 @@ as internal buffering of data.
.. versionadded:: 3.3
.. function:: fexecve(fd, args, env)
Execute the program specified by a file descriptor *fd* with arguments given
by *args* and environment given by *env*, replacing the current process.
*args* and *env* are given as in :func:`execve`.
Availability: Unix.
.. versionadded:: 3.3
.. function:: fpathconf(fd, name)
Return system configuration information relevant to an open file. *name*
@ -819,6 +830,45 @@ as internal buffering of data.
.. versionadded:: 3.3
.. function:: futimens(fd, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec))
futimens(fd, None, None)
Updates the timestamps of a file specified by the file descriptor *fd*, with
nanosecond precision.
The second form sets *atime* and *mtime* to the current time.
If *atime_nsec* or *mtime_nsec* is specified as :data:`UTIME_NOW`, the corresponding
timestamp is updated to the current time.
If *atime_nsec* or *mtime_nsec* is specified as :data:`UTIME_OMIT`, the corresponding
timestamp is not updated.
Availability: Unix.
.. versionadded:: 3.3
.. data:: UTIME_NOW
UTIME_OMIT
Flags used with :func:`futimens` to specify that the timestamp must be
updated either to the current time or not updated at all.
Availability: Unix.
.. versionadded:: 3.3
.. function:: futimes(fd, (atime, mtime))
futimes(fd, None)
Set the access and modified time of the file specified by the file
descriptor *fd* to the given values. If the second form is used, set the
access and modified times to the current time.
Availability: Unix.
.. versionadded:: 3.3
.. function:: isatty(fd)
Return ``True`` if the file descriptor *fd* is open and connected to a
@ -841,6 +891,30 @@ as internal buffering of data.
.. versionadded:: 3.3
.. function:: lockf(fd, cmd, len)
Apply, test or remove a POSIX lock on an open file descriptor.
*fd* is an open file descriptor.
*cmd* specifies the command to use - one of :data:`F_LOCK`, :data:`F_TLOCK`,
:data:`F_ULOCK` or :data:`F_TEST`.
*len* specifies the section of the file to lock.
Availability: Unix.
.. versionadded:: 3.3
.. data:: F_LOCK
F_TLOCK
F_ULOCK
F_TEST
Flags that specify what action :func:`lockf` will take.
Availability: Unix.
.. versionadded:: 3.3
.. function:: lseek(fd, pos, how)
Set the current position of file descriptor *fd* to position *pos*, modified
@ -945,6 +1019,66 @@ as internal buffering of data.
Availability: Unix, Windows.
.. function:: posix_fallocate(fd, offset, len)
Ensures that enough disk space is allocated for the file specified by *fd*
starting from *offset* and continuing for *len* bytes.
Availability: Unix.
.. versionadded:: 3.3
.. function:: posix_fadvise(fd, offset, len, advice)
Announces 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 *len* bytes.
*advice* is one of :data:`POSIX_FADV_NORMAL`, :data:`POSIX_FADV_SEQUENTIAL`,
:data:`POSIX_FADV_RANDOM`, :data:`POSIX_FADV_NOREUSE`,
:data:`POSIX_FADV_WILLNEED` or :data:`POSIX_FADV_DONTNEED`.
Availability: Unix.
.. versionadded:: 3.3
.. data:: POSIX_FADV_NORMAL
POSIX_FADV_SEQUENTIAL
POSIX_FADV_RANDOM
POSIX_FADV_NOREUSE
POSIX_FADV_WILLNEED
POSIX_FADV_DONTNEED
Flags that can be used in *advice* in :func:`posix_fadvise` that specify
the access pattern that is likely to be used.
Availability: Unix.
.. versionadded:: 3.3
.. function:: pread(fd, buffersize, offset)
Read from a file descriptor, *fd*, at a position of *offset*. It will read up
to *buffersize* number of bytes. The file offset remains unchanged.
Availability: Unix.
.. versionadded:: 3.3
.. function:: pwrite(fd, string, offset)
Write *string* to a file descriptor, *fd*, from *offset*, leaving the file
offset unchanged.
Availability: Unix.
.. versionadded:: 3.3
.. function:: read(fd, n)
Read at most *n* bytes from file descriptor *fd*. Return a bytestring containing the
@ -1038,6 +1172,17 @@ as internal buffering of data.
.. versionadded:: 3.3
.. function:: readv(fd, buffers)
Read from a file descriptor into a number of writable buffers. *buffers* is
an arbitrary sequence of writable buffers. Returns the total number of bytes
read.
Availability: Unix.
.. versionadded:: 3.3
.. function:: tcgetpgrp(fd)
Return the process group associated with the terminal given by *fd* (an open
@ -1111,6 +1256,17 @@ as internal buffering of data.
:meth:`~file.write` method.
.. function:: writev(fd, buffers)
Write the the contents of *buffers* to file descriptor *fd*, where *buffers*
is an arbitrary sequence of buffers.
Returns the total number of bytes written.
Availability: Unix.
.. versionadded:: 3.3
.. _open-constants:
``open()`` flag constants
@ -1384,6 +1540,17 @@ Files and Directories
Added support for Windows 6.0 (Vista) symbolic links.
.. function:: lutimes(path, (atime, mtime))
lutimes(path, None)
Like :func:`utime`, but if *path* is a symbolic link, it is not
dereferenced.
Availability: Unix.
.. versionadded:: 3.3
.. function:: mkfifo(path[, mode])
Create a FIFO (a named pipe) named *path* with numeric mode *mode*. The
@ -1727,6 +1894,25 @@ Files and Directories
Added support for Windows 6.0 (Vista) symbolic links.
.. function:: sync()
Force write of everything to disk.
Availability: Unix.
.. versionadded:: 3.3
.. function:: truncate(path, length)
Truncate the file corresponding to *path*, so that it is at most
*length* bytes in size.
Availability: Unix.
.. versionadded:: 3.3
.. function:: unlink(path)
Remove (delete) the file *path*. This is the same function as
@ -2306,6 +2492,58 @@ written in Python, such as a mail server's external command delivery program.
Availability: Unix.
.. function:: waitid(idtype, id, options)
Wait for the completion of one or more child processes.
*idtype* can be :data:`P_PID`, :data:`P_PGID` or :data:`P_ALL`.
*id* specifies the pid to wait on.
*options* is constructed from the ORing of one or more of :data:`WEXITED`,
:data:`WSTOPPED` or :data:`WCONTINUED` and additionally may be ORed with
:data:`WNOHANG` or :data:`WNOWAIT`. The return value is an object
representing the data contained in the :c:type:`siginfo_t` structure, namely:
:attr:`si_pid`, :attr:`si_uid`, :attr:`si_signo`, :attr:`si_status`,
:attr:`si_code` or ``None`` if :data:`WNOHANG` is specified and there are no
children in a waitable state.
Availability: Unix.
.. versionadded:: 3.3
.. data:: P_PID
P_PGID
P_ALL
These are the possible values for *idtype* in :func:`waitid`. They affect
how *id* is interpreted.
Availability: Unix.
.. versionadded:: 3.3
.. data:: WEXITED
WSTOPPED
WNOWAIT
Flags that can be used in *options* in :func:`waitid` that specify what
child signal to wait for.
Availability: Unix.
.. versionadded:: 3.3
.. data:: CLD_EXITED
CLD_DUMPED
CLD_TRAPPED
CLD_CONTINUED
These are the possible values for :attr:`si_code` in the result returned by
:func:`waitid`.
Availability: Unix.
.. versionadded:: 3.3
.. function:: waitpid(pid, options)

View File

@ -37,7 +37,7 @@ class PosixTester(unittest.TestCase):
NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
"times", "getloadavg",
"getegid", "geteuid", "getgid", "getgroups",
"getpid", "getpgrp", "getppid", "getuid",
"getpid", "getpgrp", "getppid", "getuid", "sync",
]
for name in NO_ARG_FUNCTIONS:
@ -132,6 +132,156 @@ class PosixTester(unittest.TestCase):
finally:
fp.close()
@unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
def test_truncate(self):
with open(support.TESTFN, 'w') as fp:
fp.write('test')
fp.flush()
posix.truncate(support.TESTFN, 0)
@unittest.skipUnless(hasattr(posix, 'fexecve'), "test needs posix.fexecve()")
@unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
@unittest.skipUnless(hasattr(os, 'wait'), "test needs os.wait()")
def test_fexecve(self):
fp = os.open(sys.executable, os.O_RDONLY)
try:
pid = os.fork()
if pid == 0:
os.chdir(os.path.split(sys.executable)[0])
posix.fexecve(fp, [sys.executable, '-c', 'pass'], os.environ)
else:
self.assertEqual(os.wait(), (pid, 0))
finally:
os.close(fp)
@unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
@unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
def test_waitid(self):
pid = os.fork()
if pid == 0:
os.chdir(os.path.split(sys.executable)[0])
posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
else:
res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
self.assertEqual(pid, res.si_pid)
@unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
def test_lockf(self):
fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
try:
os.write(fd, b'test')
os.lseek(fd, 0, os.SEEK_SET)
posix.lockf(fd, posix.F_LOCK, 4)
# section is locked
posix.lockf(fd, posix.F_ULOCK, 4)
finally:
os.close(fd)
@unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
def test_pread(self):
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
try:
os.write(fd, b'test')
os.lseek(fd, 0, os.SEEK_SET)
self.assertEqual(b'es', posix.pread(fd, 2, 1))
# the first pread() shoudn't disturb the file offset
self.assertEqual(b'te', posix.read(fd, 2))
finally:
os.close(fd)
@unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
def test_pwrite(self):
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
try:
os.write(fd, b'test')
os.lseek(fd, 0, os.SEEK_SET)
posix.pwrite(fd, b'xx', 1)
self.assertEqual(b'txxt', posix.read(fd, 4))
finally:
os.close(fd)
@unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
"test needs posix.posix_fallocate()")
def test_posix_fallocate(self):
fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
try:
posix.posix_fallocate(fd, 0, 10)
except OSError as inst:
# issue10812, ZFS doesn't appear to support posix_fallocate,
# so skip Solaris-based since they are likely to have ZFS.
if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
raise
finally:
os.close(fd)
@unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
"test needs posix.posix_fadvise()")
def test_posix_fadvise(self):
fd = os.open(support.TESTFN, os.O_RDONLY)
try:
posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
finally:
os.close(fd)
@unittest.skipUnless(hasattr(posix, 'futimes'), "test needs posix.futimes()")
def test_futimes(self):
now = time.time()
fd = os.open(support.TESTFN, os.O_RDONLY)
try:
posix.futimes(fd, None)
self.assertRaises(TypeError, posix.futimes, fd, (None, None))
self.assertRaises(TypeError, posix.futimes, fd, (now, None))
self.assertRaises(TypeError, posix.futimes, fd, (None, now))
posix.futimes(fd, (int(now), int(now)))
posix.futimes(fd, (now, now))
finally:
os.close(fd)
@unittest.skipUnless(hasattr(posix, 'lutimes'), "test needs posix.lutimes()")
def test_lutimes(self):
now = time.time()
posix.lutimes(support.TESTFN, None)
self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, None))
self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (now, None))
self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, now))
posix.lutimes(support.TESTFN, (int(now), int(now)))
posix.lutimes(support.TESTFN, (now, now))
@unittest.skipUnless(hasattr(posix, 'futimens'), "test needs posix.futimens()")
def test_futimens(self):
now = time.time()
fd = os.open(support.TESTFN, os.O_RDONLY)
try:
self.assertRaises(TypeError, posix.futimens, fd, (None, None), (None, None))
self.assertRaises(TypeError, posix.futimens, fd, (now, 0), None)
self.assertRaises(TypeError, posix.futimens, fd, None, (now, 0))
posix.futimens(fd, (int(now), int((now - int(now)) * 1e9)),
(int(now), int((now - int(now)) * 1e9)))
finally:
os.close(fd)
@unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
def test_writev(self):
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
try:
os.writev(fd, (b'test1', b'tt2', b't3'))
os.lseek(fd, 0, os.SEEK_SET)
self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
finally:
os.close(fd)
@unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
def test_readv(self):
fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
try:
os.write(fd, b'test1tt2t3')
os.lseek(fd, 0, os.SEEK_SET)
buf = [bytearray(i) for i in [5, 3, 2]]
self.assertEqual(posix.readv(fd, buf), 10)
self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
finally:
os.close(fd)
def test_dup(self):
if hasattr(posix, 'dup'):
fp = open(support.TESTFN)

View File

@ -72,6 +72,7 @@ Core and Builtins
Library
-------
- Issue #10812: Add some extra posix functions to the os module.
- Issue #10979: unittest stdout buffering now works with class and module
setup and teardown.

File diff suppressed because it is too large Load Diff

17
configure vendored
View File

@ -776,8 +776,7 @@ CFLAGS
LDFLAGS
LIBS
CPPFLAGS
CPP
CPPFLAGS'
CPP'
# Initialize some variables set by options.
@ -9251,19 +9250,21 @@ $as_echo "MACHDEP_OBJS" >&6; }
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \
fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes \
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
initgroups kill killpg lchmod lchown linkat lstat mbrtowc mkdirat mkfifo \
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
pthread_init putenv readlink readlinkat realpath renameat \
posix_fallocate posix_fadvise pread \
pthread_init putenv pwrite readlink readlinkat readv realpath renameat \
select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
setgid sethostname \
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat \
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat sync \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
truncate uname unlinkat unsetenv utimensat utimes waitpid wait3 wait4 \
wcscoll wcsftime wcsxfrm _getpty
truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
wcscoll wcsftime wcsxfrm writev _getpty
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -2496,19 +2496,21 @@ AC_MSG_RESULT(MACHDEP_OBJS)
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \
fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes \
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
initgroups kill killpg lchmod lchown linkat lstat mbrtowc mkdirat mkfifo \
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
pthread_init putenv readlink readlinkat realpath renameat \
posix_fallocate posix_fadvise pread \
pthread_init putenv pwrite readlink readlinkat readv realpath renameat \
select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
setgid sethostname \
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat \
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat sync \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
truncate uname unlinkat unsetenv utimensat utimes waitpid wait3 wait4 \
wcscoll wcsftime wcsxfrm _getpty)
truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
wcscoll wcsftime wcsxfrm writev _getpty)
# For some functions, having a definition is not sufficient, since
# we want to take their address.

View File

@ -232,6 +232,9 @@
/* Define to 1 if you have the `fdopendir' function. */
#undef HAVE_FDOPENDIR
/* Define to 1 if you have the `fexecve' function. */
#undef HAVE_FEXECVE
/* Define to 1 if you have the `finite' function. */
#undef HAVE_FINITE
@ -274,6 +277,12 @@
/* Define to 1 if you have the `ftruncate' function. */
#undef HAVE_FTRUNCATE
/* Define to 1 if you have the `futimens' function. */
#undef HAVE_FUTIMENS
/* Define to 1 if you have the `futimes' function. */
#undef HAVE_FUTIMES
/* Define to 1 if you have the `futimesat' function. */
#undef HAVE_FUTIMESAT
@ -461,6 +470,9 @@
/* Define to 1 if you have the <linux/tipc.h> header file. */
#undef HAVE_LINUX_TIPC_H
/* Define to 1 if you have the `lockf' function. */
#undef HAVE_LOCKF
/* Define to 1 if you have the `log1p' function. */
#undef HAVE_LOG1P
@ -473,6 +485,9 @@
/* Define to 1 if you have the `lstat' function. */
#undef HAVE_LSTAT
/* Define to 1 if you have the `lutimes' function. */
#undef HAVE_LUTIMES
/* Define this if you have the makedev macro. */
#undef HAVE_MAKEDEV
@ -545,6 +560,15 @@
/* Define to 1 if you have the <poll.h> header file. */
#undef HAVE_POLL_H
/* Define to 1 if you have the `posix_fadvise' function. */
#undef HAVE_POSIX_FADVISE
/* Define to 1 if you have the `posix_fallocate' function. */
#undef HAVE_POSIX_FALLOCATE
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
/* Define to 1 if you have the <process.h> header file. */
#undef HAVE_PROCESS_H
@ -569,12 +593,18 @@
/* Define to 1 if you have the `putenv' function. */
#undef HAVE_PUTENV
/* Define to 1 if you have the `pwrite' function. */
#undef HAVE_PWRITE
/* Define to 1 if you have the `readlink' function. */
#undef HAVE_READLINK
/* Define to 1 if you have the `readlinkat' function. */
#undef HAVE_READLINKAT
/* Define to 1 if you have the `readv' function. */
#undef HAVE_READV
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
@ -775,6 +805,9 @@
/* Define to 1 if you have the `symlinkat' function. */
#undef HAVE_SYMLINKAT
/* Define to 1 if you have the `sync' function. */
#undef HAVE_SYNC
/* Define to 1 if you have the `sysconf' function. */
#undef HAVE_SYSCONF
@ -952,6 +985,9 @@
/* Define to 1 if you have the `wait4' function. */
#undef HAVE_WAIT4
/* Define to 1 if you have the `waitid' function. */
#undef HAVE_WAITID
/* Define to 1 if you have the `waitpid' function. */
#undef HAVE_WAITPID
@ -971,6 +1007,9 @@
*/
#undef HAVE_WORKING_TZSET
/* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV
/* Define if the zlib library has inflateCopy */
#undef HAVE_ZLIB_COPY