Index: configure
===================================================================
--- configure (revision 87540)
+++ configure (working copy)
@@ -5999,7 +5999,7 @@
sys/lock.h sys/mkdev.h sys/modem.h \
sys/param.h sys/poll.h sys/select.h sys/socket.h sys/statvfs.h sys/stat.h \
sys/termio.h sys/time.h \
-sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
+sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
bluetooth/bluetooth.h linux/tipc.h spawn.h util.h
do :
@@ -9240,19 +9240,20 @@
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \
- gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
+ clock confstr ctermid execv fchmod fchown fexecve fork fpathconf ftime \
+ ftruncate futimens futimes \
+ gai_strerror getgroups gethostid getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
- initgroups kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \
- mremap nice pathconf pause plock poll pthread_init \
- putenv readlink realpath \
+ initgroups kill killpg lchmod lchown lockf lstat lutimes mbrtowc mkfifo mknod \
+ mktime mremap nice pathconf pause plock poll posix_fallocate posix_fadvise pread \
+ pthread_init putenv pwrite readlink readv realpath \
select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \
- setgid \
+ setgid sethostid sethostname \
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \
- sigaction siginterrupt sigrelse snprintf strftime strlcpy \
+ sigaction siginterrupt sigrelse snprintf strftime strlcpy sync \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
- truncate uname unsetenv utimes waitpid wait3 wait4 \
- wcscoll wcsftime wcsxfrm _getpty
+ truncate uname unsetenv 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"
Index: configure.in
===================================================================
--- configure.in (revision 87540)
+++ configure.in (working copy)
@@ -1283,7 +1283,7 @@
sys/lock.h sys/mkdev.h sys/modem.h \
sys/param.h sys/poll.h sys/select.h sys/socket.h sys/statvfs.h sys/stat.h \
sys/termio.h sys/time.h \
-sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
+sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
bluetooth/bluetooth.h linux/tipc.h spawn.h util.h)
AC_HEADER_DIRENT
@@ -2525,19 +2525,20 @@
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \
- gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
+ clock confstr ctermid execv fchmod fchown fexecve fork fpathconf ftime \
+ ftruncate futimens futimes \
+ gai_strerror getgroups gethostid getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
- initgroups kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \
- mremap nice pathconf pause plock poll pthread_init \
- putenv readlink realpath \
+ initgroups kill killpg lchmod lchown lockf lstat lutimes mbrtowc mkfifo mknod \
+ mktime mremap nice pathconf pause plock poll posix_fallocate posix_fadvise pread \
+ pthread_init putenv pwrite readlink readv realpath \
select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \
- setgid \
+ setgid sethostid sethostname \
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \
- sigaction siginterrupt sigrelse snprintf strftime strlcpy \
+ sigaction siginterrupt sigrelse snprintf strftime strlcpy sync \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
- truncate uname unsetenv utimes waitpid wait3 wait4 \
- wcscoll wcsftime wcsxfrm _getpty)
+ truncate uname unsetenv 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.
Index: Misc/NEWS
===================================================================
--- Misc/NEWS (revision 87540)
+++ Misc/NEWS (working copy)
@@ -2,6 +2,9 @@
Python News
+++++++++++
+- Issue #XXXXX: Add some missing functions to the posix module. Patch by
+ Ross Lagerwall.
+
What's New in Python 3.2 Release Candidate 1
============================================
Index: Doc/library/os.rst
===================================================================
--- Doc/library/os.rst (revision 87540)
+++ Doc/library/os.rst (working copy)
@@ -637,6 +637,17 @@
This function is not available on MacOS.
+.. 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*
@@ -690,6 +701,45 @@
Availability: Unix.
+.. 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
@@ -698,6 +748,30 @@
Availability: Unix.
+.. 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
@@ -758,6 +832,66 @@
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
@@ -775,6 +909,18 @@
:meth:`~file.readline` methods.
+.. function:: readv(fd, (size1, size2, ...))
+
+ Read from a file descriptor into multiple strings, specified by a tuple
+ of sizes, returning a tuple of bytestrings. It may read fewer bytes than
+ the sum of the sizes and may return fewer bytestrings than the number of
+ sizes given.
+
+ Availability: Unix.
+
+ .. versionadded:: 3.3
+
+
.. function:: tcgetpgrp(fd)
Return the process group associated with the terminal given by *fd* (an open
@@ -816,6 +962,16 @@
:meth:`~file.write` method.
+.. function:: writev(fd, (bytes1, bytes2, ...))
+
+ Write the bytestring in *bytes1*, *bytes2*, etc, to file descriptor *fd*.
+ Returns the total number of bytes written.
+
+ Availability: Unix.
+
+ .. versionadded:: 3.3
+
+
.. _open-constants:
``open()`` flag constants
@@ -1087,6 +1243,17 @@
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
@@ -1408,6 +1575,25 @@
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
@@ -1987,7 +2173,43 @@
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 result is a tuple containing the
+ same data as *siginfo_t* in the POSIX specification.
+
+ 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
+
+
.. function:: waitpid(pid, options)
The details of this function differ on Unix and Windows.
@@ -2164,6 +2386,15 @@
Availability: Unix.
+.. function:: gethostid()
+
+ Returns the host id, a unique 32-bit identifier for the current machine.
+
+ Availability: Unix.
+
+ .. versionadded:: 3.3
+
+
.. function:: getloadavg()
Return the number of processes in the system run queue averaged over the last
@@ -2173,6 +2404,15 @@
Availability: Unix.
+.. function:: sethostname(name)
+
+ Sets the machine's hostname to *name*.
+
+ Availability: Unix.
+
+ .. versionadded:: 3.3
+
+
.. function:: sysconf(name)
Return integer-valued system configuration values. If the configuration value
Index: Lib/test/test_posix.py
===================================================================
--- Lib/test/test_posix.py (revision 87540)
+++ Lib/test/test_posix.py (working copy)
@@ -132,6 +132,176 @@
finally:
fp.close()
+ @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
+ def test_truncate(self):
+ fp = open(support.TESTFN, 'w+')
+ try:
+ # we need to have some data to truncate
+ fp.write('test')
+ fp.flush()
+ posix.truncate(support.TESTFN, 0)
+ finally:
+ fp.close()
+
+ @unittest.skipUnless(hasattr(posix, 'sync'), "test needs posix.sync()")
+ def test_sync(self):
+ posix.sync()
+
+ @unittest.skipUnless(hasattr(posix, 'fexecve'), "test needs posix.fexecve()")
+ @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
+ @unittest.skipUnless(hasattr(os, 'chdir'), "test needs os.chdir()")
+ @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
+ 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:
+ os.waitpid(pid, 0)
+ finally:
+ os.close(fp)
+
+ @unittest.skipUnless(hasattr(posix, 'gethostid'), "test needs posix.gethostid()")
+ def test_gethostid(self):
+ self.assertTrue(isinstance(posix.gethostid(), int))
+
+ @unittest.skipUnless(hasattr(posix, 'sethostname'), "test needs posix.sethostname()")
+ def test_sethostname(self):
+ import socket
+ oldhn = socket.gethostname()
+ try:
+ posix.sethostname('new')
+ except OSError as inst:
+ # requires root permission
+ self.assertEqual(inst.errno, 1)
+ else:
+ # running test as root!
+ self.assertEqual(socket.gethostname(), 'new')
+ posix.sethostname(oldhn)
+
+ @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
+ @unittest.skipUnless(hasattr(os, 'chdir'), "test needs os.chdir()")
+ @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[3])
+
+ @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)
+ 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)
+
+ 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)
+ self.assertEqual((b'test1', b'tt2', b't3'), posix.readv(fd, (5, 3, 2)))
+ finally:
+ os.close(fd)
+
def test_dup(self):
if hasattr(posix, 'dup'):
fp = open(support.TESTFN)
Index: Modules/posixmodule.c
===================================================================
--- Modules/posixmodule.c (revision 87540)
+++ Modules/posixmodule.c (working copy)
@@ -59,6 +59,10 @@
#include "osdefs.h"
#endif
+#ifdef HAVE_SYS_UIO_H
+#include
+#endif
+
#ifdef HAVE_SYS_TYPES_H
#include
#endif /* HAVE_SYS_TYPES_H */
@@ -2074,6 +2078,21 @@
}
#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)
+{
+ Py_BEGIN_ALLOW_THREADS
+ sync();
+ Py_END_ALLOW_THREADS
+ Py_RETURN_NONE;
+}
+#endif
+
#ifdef HAVE_FDATASYNC
#ifdef __hpux
@@ -3333,7 +3352,164 @@
#endif /* MS_WINDOWS */
}
+#ifdef HAVE_FUTIMES
+PyDoc_STRVAR(posix_futimes__doc__,
+"futimes(fd, (atime, mtime))\n\
+futimes(fd, None)\n\n\
+Set the access and modified time of the file specified by the file\n\
+descriptor fd to the given values. If the second form is used, set the\n\
+access and modified times to the current time.");
+static PyObject *
+posix_futimes(PyObject *self, PyObject *args)
+{
+ int res, fd;
+ PyObject* arg;
+
+ struct timeval buf[2];
+
+ if (!PyArg_ParseTuple(args, "iO:futimes", &fd, &arg))
+ return NULL;
+
+ if (arg == Py_None) {
+ /* optional time values not given */
+ Py_BEGIN_ALLOW_THREADS
+ res = futimes(fd, NULL);
+ Py_END_ALLOW_THREADS
+ }
+ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "futimes() arg 2 must be a tuple (atime, mtime)");
+ return NULL;
+ }
+ else {
+ if (extract_time(PyTuple_GET_ITEM(arg, 0),
+ &(buf[0].tv_sec), &(buf[0].tv_usec)) == -1) {
+ return NULL;
+ }
+ if (extract_time(PyTuple_GET_ITEM(arg, 1),
+ &(buf[1].tv_sec), &(buf[1].tv_usec)) == -1) {
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ res = futimes(fd, buf);
+ Py_END_ALLOW_THREADS
+ }
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
+#ifdef HAVE_LUTIMES
+PyDoc_STRVAR(posix_lutimes__doc__,
+"lutimes(path, (atime, mtime))\n\
+lutimes(path, None)\n\n\
+Like utime(), but if path is a symbolic link, it is not dereferenced.");
+
+static PyObject *
+posix_lutimes(PyObject *self, PyObject *args)
+{
+ PyObject *opath, *arg;
+ char *path;
+ int res;
+ struct timeval buf[2];
+
+ if (!PyArg_ParseTuple(args, "O&O:lutimes",
+ PyUnicode_FSConverter, &opath, &arg))
+ return NULL;
+ path = PyBytes_AsString(opath);
+ if (arg == Py_None) {
+ /* optional time values not given */
+ Py_BEGIN_ALLOW_THREADS
+ res = lutimes(path, NULL);
+ Py_END_ALLOW_THREADS
+ }
+ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "lutimes() arg 2 must be a tuple (atime, mtime)");
+ Py_DECREF(opath);
+ return NULL;
+ }
+ else {
+ if (extract_time(PyTuple_GET_ITEM(arg, 0),
+ &(buf[0].tv_sec), &(buf[0].tv_usec)) == -1) {
+ Py_DECREF(opath);
+ return NULL;
+ }
+ if (extract_time(PyTuple_GET_ITEM(arg, 1),
+ &(buf[1].tv_sec), &(buf[1].tv_usec)) == -1) {
+ Py_DECREF(opath);
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ res = lutimes(path, buf);
+ Py_END_ALLOW_THREADS
+ }
+ Py_DECREF(opath);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
+#ifdef HAVE_FUTIMENS
+PyDoc_STRVAR(posix_futimens__doc__,
+"futimens(fd, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec))\n\
+futimens(fd, None, None)\n\n\
+Updates the timestamps of a file specified by the file descriptor fd, with\n\
+nanosecond precision.\n\
+The second form sets atime and mtime to the current time.\n\
+If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
+current time.\n\
+If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
+
+static PyObject *
+posix_futimens(PyObject *self, PyObject *args)
+{
+ int res, fd;
+ PyObject *atime, *mtime;
+
+ struct timespec buf[2];
+
+ if (!PyArg_ParseTuple(args, "iOO:futimens",
+ &fd, &atime, &mtime))
+ return NULL;
+ if (atime == Py_None && mtime == Py_None) {
+ /* optional time values not given */
+ Py_BEGIN_ALLOW_THREADS
+ res = futimens(fd, NULL);
+ Py_END_ALLOW_THREADS
+ }
+ else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "futimens() arg 2 must be a tuple (atime_sec, atime_nsec)");
+ return NULL;
+ }
+ else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "futimens() arg 3 must be a tuple (mtime_sec, mtime_nsec)");
+ return NULL;
+ }
+ else {
+ if (!PyArg_ParseTuple(atime, "ll:futimens",
+ &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
+ return NULL;
+ }
+ if (!PyArg_ParseTuple(mtime, "ll:futimens",
+ &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ res = futimens(fd, buf);
+ Py_END_ALLOW_THREADS
+ }
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
/* Process operations */
PyDoc_STRVAR(posix__exit__doc__,
@@ -3616,7 +3792,88 @@
}
#endif /* HAVE_EXECV */
+#ifdef HAVE_FEXECVE
+PyDoc_STRVAR(posix_fexecve__doc__,
+"fexecve(fd, args, env)\n\n\
+Execute the program specified by a file descriptor with arguments and\n\
+environment, replacing the current process.\n\
+\n\
+ fd: file descriptor of executable\n\
+ args: tuple or list of arguments\n\
+ env: dictionary of strings mapping to strings");
+static PyObject *
+posix_fexecve(PyObject *self, PyObject *args)
+{
+ int fd;
+ PyObject *argv, *env;
+ char **argvlist;
+ char **envlist;
+ Py_ssize_t i, argc, envc;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+ Py_ssize_t lastarg = 0;
+
+ /* fexecve has three arguments: (fd, argv, env), where
+ argv is a list or tuple of strings and env is a dictionary
+ like posix.environ. */
+
+ if (!PyArg_ParseTuple(args, "iOO:fexecve",
+ &fd, &argv, &env))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "fexecve() arg 2 must be a tuple or list");
+ return NULL;
+ }
+ if (!PyMapping_Check(env)) {
+ PyErr_SetString(PyExc_TypeError,
+ "fexecve() arg 3 must be a mapping object");
+ return NULL;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ for (i = 0; i < argc; i++) {
+ if (!fsconvert_strdup((*getitem)(argv, i),
+ &argvlist[i]))
+ {
+ lastarg = i;
+ goto fail_1;
+ }
+ }
+ lastarg = argc;
+ argvlist[argc] = NULL;
+
+ envlist = parse_envlist(env, &envc);
+ if (envlist == NULL)
+ goto fail_1;
+
+ fexecve(fd, argvlist, envlist);
+
+ /* If we get here it's definitely an error */
+
+ (void) posix_error();
+
+ while (--envc >= 0)
+ PyMem_DEL(envlist[envc]);
+ PyMem_DEL(envlist);
+ fail_1:
+ free_string_array(argvlist, lastarg);
+ return NULL;
+}
+#endif /* HAVE_FEXECVE */
+
#ifdef HAVE_SPAWNV
PyDoc_STRVAR(posix_spawnv__doc__,
"spawnv(mode, path, args)\n\n\
@@ -4182,6 +4439,41 @@
}
#endif
+#ifdef HAVE_GETHOSTID
+PyDoc_STRVAR(posix_gethostid__doc__,
+"gethostid() -> hostid\n\n\
+Gets the host id, a unique 32-bit identifier for the current machine.");
+
+static PyObject *
+posix_gethostid(PyObject *self, PyObject *noargs)
+{
+ return PyLong_FromLong(gethostid());
+}
+#endif
+
+#ifdef HAVE_SETHOSTNAME
+PyDoc_STRVAR(posix_sethostname__doc__,
+"sethostname(name)\n\n\
+Sets the hostname to name.");
+
+static PyObject *
+posix_sethostname(PyObject *self, PyObject *args)
+{
+ int res;
+ char *hostname;
+
+ if (!PyArg_ParseTuple(args, "s:sethostname", &hostname))
+ return NULL;
+
+ res = sethostname(hostname, strlen(hostname));
+
+ if (res == -1)
+ return posix_error();
+
+ Py_RETURN_NONE;
+}
+#endif
+
#ifdef HAVE_GETEGID
PyDoc_STRVAR(posix_getegid__doc__,
"getegid() -> egid\n\n\
@@ -4972,6 +5264,38 @@
}
#endif /* HAVE_WAIT4 */
+#ifdef HAVE_WAITID
+PyDoc_STRVAR(posix_waitid__doc__,
+"waitid(idtype, id, options) -> siginfo\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.\
+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\
+siginfo is a tuple containing the same data as siginfo_t in the POSIX\n\
+specification.");
+
+static PyObject *
+posix_waitid(PyObject *self, PyObject *args)
+{
+ idtype_t idtype;
+ id_t id;
+ int options, res;
+ siginfo_t si;
+ if (!PyArg_ParseTuple(args, "lli:waitid", &idtype, &id, &options))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = waitid(idtype, id, &si, options);
+ Py_END_ALLOW_THREADS
+ if (res == -1)
+ return posix_error();
+
+ return Py_BuildValue("iiililill", si.si_signo, si.si_code,
+ si.si_errno, si.si_pid, si.si_uid, si.si_addr, si.si_status,
+ si.si_band, si.si_value);
+}
+#endif
+
#ifdef HAVE_WAITPID
PyDoc_STRVAR(posix_waitpid__doc__,
"waitpid(pid, options) -> (pid, status)\n\n\
@@ -5587,7 +5911,46 @@
return Py_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;
+ PyObject *lenobj;
+ if (!PyArg_ParseTuple(args, "iiO:lockf",
+ &fd, &cmd, &lenobj))
+ return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ len = PyLong_AsLong(lenobj);
+#else
+ len = PyLong_Check(lenobj) ?
+ PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = lockf(fd, cmd, len);
+ Py_END_ALLOW_THREADS
+
+ if (res < 0)
+ return posix_error();
+
+ Py_RETURN_NONE;
+}
+#endif
+
+
PyDoc_STRVAR(posix_lseek__doc__,
"lseek(fd, pos, how) -> newpos\n\n\
Set the current position of a file descriptor.");
@@ -5677,7 +6040,135 @@
return buffer;
}
+#ifdef HAVE_READV
+PyDoc_STRVAR(posix_readv__doc__,
+"readv(fd, (size1, size2, ...)) -> strings\n\n\
+Read from a file descriptor into multiple strings, specified by a tuple\n\
+of sizes.");
+static PyObject *
+posix_readv(PyObject *self, PyObject *args)
+{
+ int fd, cnt, i, j, n;
+ PyObject *sizetuple;
+ PyObject *res;
+ Py_ssize_t rem;
+ struct iovec *iov;
+
+ if (!PyArg_ParseTuple(args, "iO:readv", &fd, &sizetuple))
+ return NULL;
+ if (!PyTuple_Check(sizetuple)) {
+ PyErr_SetString(PyExc_TypeError,
+ "readv() arg 2 must be a tuple");
+ return NULL;
+ }
+ cnt = PyTuple_Size(sizetuple);
+
+ res = PyTuple_New(cnt);
+ if (res == NULL)
+ return PyErr_NoMemory();
+
+ iov = PyMem_New(struct iovec, cnt);
+ if (iov == NULL) {
+ Py_DECREF(res);
+ return PyErr_NoMemory();
+ }
+
+ for (i = 0; i < cnt; i++) {
+ Py_ssize_t size = PyLong_AsSsize_t(PyTuple_GetItem(sizetuple, i));
+ if (size == -1) {
+ for (j = 0; j < i ;j++)
+ PyMem_Free(iov[j].iov_base);
+ PyMem_Del(iov);
+ Py_DECREF(res);
+ return NULL;
+ }
+ iov[i].iov_base = PyMem_Malloc(size);
+ iov[i].iov_len = size;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ n = readv(fd, iov, cnt);
+ Py_END_ALLOW_THREADS
+
+ rem = n;
+ for (i = 0; i < cnt && rem > 0; i++) {
+ PyObject *o;
+ if (rem < iov[i].iov_len)
+ o = PyBytes_FromStringAndSize(iov[i].iov_base, rem);
+ else
+ o = PyBytes_FromStringAndSize(iov[i].iov_base, iov[i].iov_len);
+ if (o == NULL) {
+ for (j = 0; j < i ;j++)
+ Py_DECREF(PyTuple_GetItem(res, j));
+ Py_DECREF(res);
+ for (; j < cnt; j++)
+ PyMem_Free(iov[j].iov_base);
+ PyMem_Del(iov);
+ return NULL;
+ }
+ PyMem_Free(iov[i].iov_base);
+ PyTuple_SET_ITEM(res, i, o);
+ rem -= iov[i].iov_len;
+ }
+ _PyTuple_Resize(&res, i);
+ for (; i < cnt; i++) {
+ PyMem_Free(iov[i].iov_base);
+ }
+ PyMem_Del(iov);
+ return res;
+}
+#endif
+
+#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;
+ Py_ssize_t n;
+ PyObject *buffer, *offobj;
+ if (!PyArg_ParseTuple(args, "iiO:pread", &fd, &size, &offobj))
+ return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ offset = PyLong_AsLong(offobj);
+#else
+ offset = PyLong_Check(offobj) ?
+ PyLong_AsLongLong(offobj) : PyLong_AsLong(offobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+
+ if (size < 0) {
+ errno = EINVAL;
+ return posix_error();
+ }
+ buffer = PyBytes_FromStringAndSize((char *)NULL, size);
+ if (buffer == NULL)
+ return NULL;
+ if (!_PyVerify_fd(fd)) {
+ Py_DECREF(buffer);
+ return posix_error();
+ }
+ Py_BEGIN_ALLOW_THREADS
+ n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
+ Py_END_ALLOW_THREADS
+ if (n < 0) {
+ Py_DECREF(buffer);
+ return posix_error();
+ }
+ if (n != size)
+ _PyBytes_Resize(&buffer, n);
+ return buffer;
+}
+#endif
+
PyDoc_STRVAR(posix_write__doc__,
"write(fd, string) -> byteswritten\n\n\
Write a string to a file descriptor.");
@@ -5704,7 +6195,107 @@
return PyLong_FromSsize_t(size);
}
+#ifdef HAVE_WRITEV
+PyDoc_STRVAR(posix_writev__doc__,
+"writev(fd, (bytes1, bytes2, ...)) -> byteswritten\n\n\
+Write to a file descriptor, from bytes1, bytes2, etc.\n\
+Returns the total bytes written.");
+static PyObject *
+posix_writev(PyObject *self, PyObject *args)
+{
+ int fd, cnt, i, j;
+ Py_ssize_t res;
+ PyObject *sizetuple;
+ struct iovec *iov;
+ Py_buffer *buf;
+ if (!PyArg_ParseTuple(args, "iO:writev", &fd, &sizetuple))
+ return NULL;
+ if (!PyTuple_Check(sizetuple)) {
+ PyErr_SetString(PyExc_TypeError,
+ "writev() arg 2 must be a tuple");
+ return NULL;
+ }
+ cnt = PyTuple_Size(sizetuple);
+
+ iov = PyMem_New(struct iovec, cnt);
+ if (iov == NULL)
+ return PyErr_NoMemory();
+ buf = PyMem_New(Py_buffer, cnt);
+ if (buf == NULL) {
+ PyMem_Del(iov);
+ return PyErr_NoMemory();
+ }
+
+ for (i = 0; i < cnt; i++) {
+ if (PyObject_GetBuffer(PyTuple_GetItem(sizetuple, i), &buf[i],
+ PyBUF_SIMPLE) == -1) {
+ PyMem_Del(iov);
+ for (j = 0; j < i; j++) {
+ PyBuffer_Release(&buf[j]);
+ }
+ PyMem_Del(buf);
+ return NULL;
+ }
+ iov[i].iov_base = buf[i].buf;
+ iov[i].iov_len = buf[i].len;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ res = writev(fd, iov, cnt);
+ Py_END_ALLOW_THREADS
+
+ PyMem_Del(iov);
+ for (j = 0; j < cnt; j++) {
+ PyBuffer_Release(&buf[j]);
+ }
+ PyMem_Del(buf);
+
+ return PyLong_FromSsize_t(res);
+}
+#endif
+
+#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;
+ int fd;
+ off_t offset;
+ Py_ssize_t size;
+ PyObject *offobj;
+
+ if (!PyArg_ParseTuple(args, "iy*O:pwrite", &fd, &pbuf, &offobj))
+ return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ offset = PyLong_AsLong(offobj);
+#else
+ offset = PyLong_Check(offobj) ?
+ PyLong_AsLongLong(offobj) : PyLong_AsLong(offobj);
+#endif
+ if (PyErr_Occurred())
+ 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);
+ if (size < 0)
+ return posix_error();
+ return PyLong_FromSsize_t(size);
+}
+#endif
+
PyDoc_STRVAR(posix_fstat__doc__,
"fstat(fd) -> stat result\n\n\
Like stat(), but for an open file descriptor.");
@@ -5939,6 +6530,118 @@
}
#endif
+#ifdef HAVE_TRUNCATE
+PyDoc_STRVAR(posix_truncate__doc__,
+"truncate(path, length)\n\n\
+Truncate the file given by path to length bytes.");
+
+static PyObject *
+posix_truncate(PyObject *self, PyObject *args)
+{
+ PyObject *opath;
+ char *path;
+ off_t length;
+ int res;
+ PyObject *lenobj;
+
+ if (!PyArg_ParseTuple(args, "O&O:truncate",
+ PyUnicode_FSConverter, &opath, &lenobj))
+ return NULL;
+ path = PyBytes_AsString(opath);
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ length = PyLong_AsLong(lenobj);
+#else
+ length = PyLong_Check(lenobj) ?
+ PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
+#endif
+ if (PyErr_Occurred()) {
+ Py_DECREF(opath);
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ res = truncate(path, length);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#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;
+ PyObject *lenobj, *offobj;
+
+ if (!PyArg_ParseTuple(args, "iOO:posix_fallocate",
+ &fd, &offobj, &lenobj))
+ return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ offset = PyLong_AsLong(offobj);
+ len = PyLong_AsLong(lenobj);
+#else
+ offset = PyLong_Check(offobj) ?
+ PyLong_AsLongLong(offobj) : PyLong_AsLong(offobj);
+ len = PyLong_Check(lenobj) ?
+ PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = posix_fallocate(fd, offset, len);
+ Py_END_ALLOW_THREADS
+ if (res != 0) {
+ errno = res;
+ return posix_error();
+ }
+ Py_RETURN_NONE;
+}
+#endif
+
+#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, "illi:posix_fadvise",
+ &fd, &offset, &len, &advice))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = posix_fadvise(fd, offset, len, advice);
+ Py_END_ALLOW_THREADS
+ if (res != 0) {
+ errno = res;
+ return posix_error();
+ }
+ Py_RETURN_NONE;
+}
+#endif
+
#ifdef HAVE_PUTENV
PyDoc_STRVAR(posix_putenv__doc__,
"putenv(key, value)\n\n\
@@ -7819,6 +8522,15 @@
{"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
{"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
{"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
+#ifdef HAVE_FUTIMES
+ {"futimes", posix_futimes, METH_VARARGS, posix_futimes__doc__},
+#endif
+#ifdef HAVE_LUTIMES
+ {"lutimes", posix_lutimes, METH_VARARGS, posix_lutimes__doc__},
+#endif
+#ifdef HAVE_FUTIMENS
+ {"futimens", posix_futimens, METH_VARARGS, posix_futimens__doc__},
+#endif
#ifdef HAVE_TIMES
{"times", posix_times, METH_NOARGS, posix_times__doc__},
#endif /* HAVE_TIMES */
@@ -7827,6 +8539,9 @@
{"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
{"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
#endif /* HAVE_EXECV */
+#ifdef HAVE_FEXECVE
+ {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
+#endif
#ifdef HAVE_SPAWNV
{"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
{"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
@@ -7847,6 +8562,12 @@
#ifdef HAVE_FORKPTY
{"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
#endif /* HAVE_FORKPTY */
+#ifdef HAVE_GETHOSTID
+ {"gethostid", posix_gethostid, METH_NOARGS, posix_gethostid__doc__},
+#endif
+#ifdef HAVE_SETHOSTNAME
+ {"sethostname", posix_sethostname, METH_VARARGS, posix_sethostname__doc__},
+#endif
#ifdef HAVE_GETEGID
{"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
#endif /* HAVE_GETEGID */
@@ -7925,6 +8646,9 @@
#ifdef HAVE_WAIT4
{"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
#endif /* HAVE_WAIT4 */
+#ifdef HAVE_WAITID
+ {"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 */
@@ -7949,9 +8673,24 @@
{"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
{"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
{"dup2", posix_dup2, METH_VARARGS, 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
{"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
{"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
#ifdef HAVE_PIPE
@@ -7971,6 +8710,15 @@
#ifdef HAVE_FTRUNCATE
{"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
#endif
+#ifdef HAVE_TRUNCATE
+ {"truncate", posix_truncate, METH_VARARGS, 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
@@ -7984,6 +8732,9 @@
#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
@@ -8343,6 +9094,64 @@
if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
#endif /* ST_NOSUID */
+ /* constants for posix_fadvise */
+#ifdef POSIX_FADV_NORMAL
+ if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
+#endif
+#ifdef POSIX_FADV_SEQUENTIAL
+ if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
+#endif
+#ifdef POSIX_FADV_RANDOM
+ if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
+#endif
+#ifdef POSIX_FADV_NOREUSE
+ if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
+#endif
+#ifdef POSIX_FADV_WILLNEED
+ if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
+#endif
+#ifdef POSIX_FADV_DONTNEED
+ if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
+#endif
+
+ /* constants for waitid */
+#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
+ if (ins(d, "P_PID", (long)P_PID)) return -1;
+ if (ins(d, "P_PGID", (long)P_PGID)) return -1;
+ if (ins(d, "P_ALL", (long)P_ALL)) return -1;
+#endif
+#ifdef WEXITED
+ if (ins(d, "WEXITED", (long)WEXITED)) return -1;
+#endif
+#ifdef WNOWAIT
+ if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
+#endif
+#ifdef WSTOPPED
+ if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
+#endif
+
+ /* constants for lockf */
+#ifdef F_LOCK
+ if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
+#endif
+#ifdef F_TLOCK
+ if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
+#endif
+#ifdef F_ULOCK
+ if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
+#endif
+#ifdef F_TEST
+ if (ins(d, "F_TEST", (long)F_TEST)) return -1;
+#endif
+
+ /* constants for futimens */
+#ifdef UTIME_NOW
+ if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
+#endif
+#ifdef UTIME_OMIT
+ if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
+#endif
+
#ifdef HAVE_SPAWNV
#if defined(PYOS_OS2) && defined(PYCC_GCC)
if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
Index: pyconfig.h.in
===================================================================
--- pyconfig.h.in (revision 87540)
+++ pyconfig.h.in (working copy)
@@ -220,6 +220,9 @@
/* Define if you have the 'fdatasync' function. */
#undef HAVE_FDATASYNC
+/* Define to 1 if you have the `fexecve' function. */
+#undef HAVE_FEXECVE
+
/* Define to 1 if you have the `finite' function. */
#undef HAVE_FINITE
@@ -259,6 +262,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 `gai_strerror' function. */
#undef HAVE_GAI_STRERROR
@@ -296,6 +305,9 @@
/* Define this if you have the 6-arg version of gethostbyname_r(). */
#undef HAVE_GETHOSTBYNAME_R_6_ARG
+/* Define to 1 if you have the `gethostid' function. */
+#undef HAVE_GETHOSTID
+
/* Define to 1 if you have the `getitimer' function. */
#undef HAVE_GETITIMER
@@ -437,6 +449,9 @@
/* Define to 1 if you have the 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
@@ -449,6 +464,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
@@ -497,6 +515,9 @@
/* Define to 1 if you have the `pause' function. */
#undef HAVE_PAUSE
+/* Define if the OS supports pipe2() */
+#undef HAVE_PIPE2
+
/* Define to 1 if you have the `plock' function. */
#undef HAVE_PLOCK
@@ -506,6 +527,15 @@
/* Define to 1 if you have the 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 header file. */
#undef HAVE_PROCESS_H
@@ -530,9 +560,15 @@
/* 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 `readv' function. */
+#undef HAVE_READV
+
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
@@ -587,6 +623,12 @@
/* Define if you have the 'setgroups' function. */
#undef HAVE_SETGROUPS
+/* Define to 1 if you have the `sethostid' function. */
+#undef HAVE_SETHOSTID
+
+/* Define to 1 if you have the `sethostname' function. */
+#undef HAVE_SETHOSTNAME
+
/* Define to 1 if you have the `setitimer' function. */
#undef HAVE_SETITIMER
@@ -718,6 +760,9 @@
/* Define if you have the 'symlink' function. */
#undef HAVE_SYMLINK
+/* Define to 1 if you have the `sync' function. */
+#undef HAVE_SYNC
+
/* Define to 1 if you have the `sysconf' function. */
#undef HAVE_SYSCONF
@@ -792,6 +837,9 @@
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYS_UIO_H
+
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_UN_H
@@ -883,6 +931,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
@@ -902,6 +953,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