Issue #4761: Add the *at() family of functions (openat(), etc.) to the posix
module. Patch by Ross Lagerwall.
This commit is contained in:
parent
68e5c044e8
commit
f65132de3d
|
@ -606,6 +606,21 @@ associated with a :term:`file object` when required. Note that using the file
|
||||||
descriptor directly will bypass the file object methods, ignoring aspects such
|
descriptor directly will bypass the file object methods, ignoring aspects such
|
||||||
as internal buffering of data.
|
as internal buffering of data.
|
||||||
|
|
||||||
|
.. data:: AT_SYMLINK_NOFOLLOW
|
||||||
|
AT_EACCESS
|
||||||
|
AT_FDCWD
|
||||||
|
AT_REMOVEDIR
|
||||||
|
AT_SYMLINK_FOLLOW
|
||||||
|
UTIME_NOW
|
||||||
|
UTIME_OMIT
|
||||||
|
|
||||||
|
These parameters are used as flags to the \*at family of functions.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: close(fd)
|
.. function:: close(fd)
|
||||||
|
|
||||||
Close file descriptor *fd*.
|
Close file descriptor *fd*.
|
||||||
|
@ -654,6 +669,19 @@ as internal buffering of data.
|
||||||
Availability: Unix, Windows.
|
Availability: Unix, Windows.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: faccessat(dirfd, path, mode, flags=0)
|
||||||
|
|
||||||
|
Like :func:`access` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
*flags* is optional and can be constructed by ORing together zero or more
|
||||||
|
of these values: :data:`AT_SYMLINK_NOFOLLOW`, :data:`AT_EACCESS`.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: fchmod(fd, mode)
|
.. function:: fchmod(fd, mode)
|
||||||
|
|
||||||
Change the mode of the file given by *fd* to the numeric *mode*. See the docs
|
Change the mode of the file given by *fd* to the numeric *mode*. See the docs
|
||||||
|
@ -662,6 +690,18 @@ as internal buffering of data.
|
||||||
Availability: Unix.
|
Availability: Unix.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: fchmodat(dirfd, path, mode, flags=0)
|
||||||
|
|
||||||
|
Like :func:`chmod` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
*flags* is optional and may be 0 or :data:`AT_SYMLINK_NOFOLLOW`.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: fchown(fd, uid, gid)
|
.. function:: fchown(fd, uid, gid)
|
||||||
|
|
||||||
Change the owner and group id of the file given by *fd* to the numeric *uid*
|
Change the owner and group id of the file given by *fd* to the numeric *uid*
|
||||||
|
@ -670,6 +710,18 @@ as internal buffering of data.
|
||||||
Availability: Unix.
|
Availability: Unix.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: fchownat(dirfd, path, uid, gid, flags=0)
|
||||||
|
|
||||||
|
Like :func:`chown` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
*flags* is optional and may be 0 or :data:`AT_SYMLINK_NOFOLLOW`.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: fdatasync(fd)
|
.. function:: fdatasync(fd)
|
||||||
|
|
||||||
Force write of file with filedescriptor *fd* to disk. Does not force update of
|
Force write of file with filedescriptor *fd* to disk. Does not force update of
|
||||||
|
@ -705,6 +757,17 @@ as internal buffering of data.
|
||||||
|
|
||||||
Availability: Unix, Windows.
|
Availability: Unix, Windows.
|
||||||
|
|
||||||
|
.. function:: fstatat(dirfd, path, flags=0)
|
||||||
|
|
||||||
|
Like :func:`stat` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
*flags* is optional and may be 0 or :data:`AT_SYMLINK_NOFOLLOW`.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: fstatvfs(fd)
|
.. function:: fstatvfs(fd)
|
||||||
|
|
||||||
|
@ -734,6 +797,18 @@ as internal buffering of data.
|
||||||
Availability: Unix.
|
Availability: Unix.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: futimesat(dirfd, path, (atime, mtime))
|
||||||
|
futimesat(dirfd, path, None)
|
||||||
|
|
||||||
|
Like :func:`utime` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: isatty(fd)
|
.. function:: isatty(fd)
|
||||||
|
|
||||||
Return ``True`` if the file descriptor *fd* is open and connected to a
|
Return ``True`` if the file descriptor *fd* is open and connected to a
|
||||||
|
@ -742,6 +817,20 @@ as internal buffering of data.
|
||||||
Availability: Unix.
|
Availability: Unix.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: linkat(srcfd, srcpath, dstfd, dstpath, flags=0)
|
||||||
|
|
||||||
|
Like :func:`link` but if *srcpath* is relative, it is taken as relative to *srcfd*
|
||||||
|
and if *dstpath* is relative, it is taken as relative to *dstfd*.
|
||||||
|
*flags* is optional and may be 0 or :data:`AT_SYMLINK_FOLLOW`.
|
||||||
|
If *srcpath* is relative and *srcfd* is the special value :data:`AT_FDCWD`, then
|
||||||
|
*srcpath* is interpreted relative to the current working directory. This
|
||||||
|
also applies for *dstpath*.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: lseek(fd, pos, how)
|
.. function:: lseek(fd, pos, how)
|
||||||
|
|
||||||
Set the current position of file descriptor *fd* to position *pos*, modified
|
Set the current position of file descriptor *fd* to position *pos*, modified
|
||||||
|
@ -761,6 +850,39 @@ as internal buffering of data.
|
||||||
respectively. Availability: Windows, Unix.
|
respectively. Availability: Windows, Unix.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: mkdirat(dirfd, path, mode=0o777)
|
||||||
|
|
||||||
|
Like :func:`mkdir` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: mkfifoat(dirfd, path, mode=0o666)
|
||||||
|
|
||||||
|
Like :func:`mkfifo` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: mknodat(dirfd, path, mode=0o600, device=0)
|
||||||
|
|
||||||
|
Like :func:`mknod` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: open(file, flags[, mode])
|
.. function:: open(file, flags[, mode])
|
||||||
|
|
||||||
Open the file *file* and set various flags according to *flags* and possibly
|
Open the file *file* and set various flags according to *flags* and possibly
|
||||||
|
@ -783,6 +905,17 @@ as internal buffering of data.
|
||||||
wrap a file descriptor in a file object, use :func:`fdopen`.
|
wrap a file descriptor in a file object, use :func:`fdopen`.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: openat(dirfd, path, flags, mode=0o777)
|
||||||
|
|
||||||
|
Like :func:`open` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: openpty()
|
.. function:: openpty()
|
||||||
|
|
||||||
.. index:: module: pty
|
.. index:: module: pty
|
||||||
|
@ -860,6 +993,41 @@ as internal buffering of data.
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: readlinkat(dirfd, path)
|
||||||
|
|
||||||
|
Like :func:`readlink` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: renameat(olddirfd, oldpath, newdirfd, newpath)
|
||||||
|
|
||||||
|
Like :func:`rename` but if *oldpath* is relative, it is taken as relative to
|
||||||
|
*olddirfd* and if *newpath* is relative, it is taken as relative to *newdirfd*.
|
||||||
|
If *oldpath* is relative and *olddirfd* is the special value :data:`AT_FDCWD`, then
|
||||||
|
*oldpath* is interpreted relative to the current working directory. This
|
||||||
|
also applies for *newpath*.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: symlinkat(src, dstfd, dst)
|
||||||
|
|
||||||
|
Like :func:`symlink` but if *dst* is relative, it is taken as relative to *dstfd*.
|
||||||
|
If *dst* is relative and *dstfd* is the special value :data:`AT_FDCWD`, then *dst*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: tcgetpgrp(fd)
|
.. function:: tcgetpgrp(fd)
|
||||||
|
|
||||||
Return the process group associated with the terminal given by *fd* (an open
|
Return the process group associated with the terminal given by *fd* (an open
|
||||||
|
@ -885,6 +1053,38 @@ as internal buffering of data.
|
||||||
Availability: Unix.
|
Availability: Unix.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: unlinkat(dirfd, path, flags=0)
|
||||||
|
|
||||||
|
Like :func:`unlink` but if *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
*flags* is optional and may be 0 or :data:`AT_REMOVEDIR`. If :data:`AT_REMOVEDIR` is
|
||||||
|
specified, :func:`unlinkat` behaves like :func:`rmdir`.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: utimensat(dirfd, path, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec), flags)
|
||||||
|
utimensat(dirfd, path, None, None, flags)
|
||||||
|
|
||||||
|
Updates the timestamps of a file 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.
|
||||||
|
If *path* is relative, it is taken as relative to *dirfd*.
|
||||||
|
*flags* is optional and may be 0 or :data:`AT_SYMLINK_NOFOLLOW`.
|
||||||
|
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
|
||||||
|
is interpreted relative to the current working directory.
|
||||||
|
|
||||||
|
Availability: Unix.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: write(fd, str)
|
.. function:: write(fd, str)
|
||||||
|
|
||||||
Write the bytestring in *str* to file descriptor *fd*. Return the number of
|
Write the bytestring in *str* to file descriptor *fd*. Return the number of
|
||||||
|
|
|
@ -389,6 +389,198 @@ class PosixTester(unittest.TestCase):
|
||||||
set([int(x) for x in groups.split()]),
|
set([int(x) for x in groups.split()]),
|
||||||
set(posix.getgroups() + [posix.getegid()]))
|
set(posix.getgroups() + [posix.getegid()]))
|
||||||
|
|
||||||
|
# tests for the posix *at functions follow
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'faccessat'), "test needs posix.faccessat()")
|
||||||
|
def test_faccessat(self):
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
self.assertTrue(posix.faccessat(f, support.TESTFN, os.R_OK))
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'fchmodat'), "test needs posix.fchmodat()")
|
||||||
|
def test_fchmodat(self):
|
||||||
|
os.chmod(support.TESTFN, stat.S_IRUSR)
|
||||||
|
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
posix.fchmodat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
|
||||||
|
|
||||||
|
s = posix.stat(support.TESTFN)
|
||||||
|
self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()")
|
||||||
|
def test_fchownat(self):
|
||||||
|
support.unlink(support.TESTFN)
|
||||||
|
open(support.TESTFN, 'w').close()
|
||||||
|
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
posix.fchownat(f, support.TESTFN, os.getuid(), os.getgid())
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'fstatat'), "test needs posix.fstatat()")
|
||||||
|
def test_fstatat(self):
|
||||||
|
support.unlink(support.TESTFN)
|
||||||
|
with open(support.TESTFN, 'w') as outfile:
|
||||||
|
outfile.write("testline\n")
|
||||||
|
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
s1 = posix.stat(support.TESTFN)
|
||||||
|
s2 = posix.fstatat(f, support.TESTFN)
|
||||||
|
self.assertEqual(s1, s2)
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'futimesat'), "test needs posix.futimesat()")
|
||||||
|
def test_futimesat(self):
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
now = time.time()
|
||||||
|
posix.futimesat(f, support.TESTFN, None)
|
||||||
|
self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, None))
|
||||||
|
self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (now, None))
|
||||||
|
self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, now))
|
||||||
|
posix.futimesat(f, support.TESTFN, (int(now), int(now)))
|
||||||
|
posix.futimesat(f, support.TESTFN, (now, now))
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'linkat'), "test needs posix.linkat()")
|
||||||
|
def test_linkat(self):
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
posix.linkat(f, support.TESTFN, f, support.TESTFN + 'link')
|
||||||
|
# should have same inodes
|
||||||
|
self.assertEqual(posix.stat(support.TESTFN)[1],
|
||||||
|
posix.stat(support.TESTFN + 'link')[1])
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
support.unlink(support.TESTFN + 'link')
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'mkdirat'), "test needs posix.mkdirat()")
|
||||||
|
def test_mkdirat(self):
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
posix.mkdirat(f, support.TESTFN + 'dir')
|
||||||
|
posix.stat(support.TESTFN + 'dir') # should not raise exception
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
support.rmtree(support.TESTFN + 'dir')
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'mknodat') and hasattr(stat, 'S_IFIFO'),
|
||||||
|
"don't have mknodat()/S_IFIFO")
|
||||||
|
def test_mknodat(self):
|
||||||
|
# Test using mknodat() to create a FIFO (the only use specified
|
||||||
|
# by POSIX).
|
||||||
|
support.unlink(support.TESTFN)
|
||||||
|
mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
posix.mknodat(f, support.TESTFN, mode, 0)
|
||||||
|
except OSError as e:
|
||||||
|
# Some old systems don't allow unprivileged users to use
|
||||||
|
# mknod(), or only support creating device nodes.
|
||||||
|
self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
|
||||||
|
else:
|
||||||
|
self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'openat'), "test needs posix.openat()")
|
||||||
|
def test_openat(self):
|
||||||
|
support.unlink(support.TESTFN)
|
||||||
|
with open(support.TESTFN, 'w') as outfile:
|
||||||
|
outfile.write("testline\n")
|
||||||
|
a = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
b = posix.openat(a, support.TESTFN, posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
res = posix.read(b, 9).decode(encoding="utf-8")
|
||||||
|
self.assertEqual("testline\n", res)
|
||||||
|
finally:
|
||||||
|
posix.close(a)
|
||||||
|
posix.close(b)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'readlinkat'), "test needs posix.readlinkat()")
|
||||||
|
def test_readlinkat(self):
|
||||||
|
os.symlink(support.TESTFN, support.TESTFN + 'link')
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
self.assertEqual(posix.readlink(support.TESTFN + 'link'),
|
||||||
|
posix.readlinkat(f, support.TESTFN + 'link'))
|
||||||
|
finally:
|
||||||
|
support.unlink(support.TESTFN + 'link')
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()")
|
||||||
|
def test_renameat(self):
|
||||||
|
support.unlink(support.TESTFN)
|
||||||
|
open(support.TESTFN + 'ren', 'w').close()
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN)
|
||||||
|
except:
|
||||||
|
posix.rename(support.TESTFN + 'ren', support.TESTFN)
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
posix.stat(support.TESTFN) # should not throw exception
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'symlinkat'), "test needs posix.symlinkat()")
|
||||||
|
def test_symlinkat(self):
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
posix.symlinkat(support.TESTFN, f, support.TESTFN + 'link')
|
||||||
|
self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
support.unlink(support.TESTFN + 'link')
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()")
|
||||||
|
def test_unlinkat(self):
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
open(support.TESTFN + 'del', 'w').close()
|
||||||
|
posix.stat(support.TESTFN + 'del') # should not throw exception
|
||||||
|
try:
|
||||||
|
posix.unlinkat(f, support.TESTFN + 'del')
|
||||||
|
except:
|
||||||
|
support.unlink(support.TESTFN + 'del')
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'utimensat'), "test needs posix.utimensat()")
|
||||||
|
def test_utimensat(self):
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
now = time.time()
|
||||||
|
posix.utimensat(f, support.TESTFN, None, None)
|
||||||
|
self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
|
||||||
|
self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
|
||||||
|
self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
|
||||||
|
posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
|
||||||
|
(int(now), int((now - int(now)) * 1e9)))
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(posix, 'mkfifoat'), "don't have mkfifoat()")
|
||||||
|
def test_mkfifoat(self):
|
||||||
|
support.unlink(support.TESTFN)
|
||||||
|
f = posix.open(posix.getcwd(), posix.O_RDONLY)
|
||||||
|
try:
|
||||||
|
posix.mkfifoat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
|
||||||
|
self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
|
||||||
|
finally:
|
||||||
|
posix.close(f)
|
||||||
|
|
||||||
class PosixGroupsTester(unittest.TestCase):
|
class PosixGroupsTester(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
|
@ -35,6 +35,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #4761: Add the *at() family of functions (openat(), etc.) to the posix
|
||||||
|
module. Patch by Ross Lagerwall.
|
||||||
|
|
||||||
- Issue #7322: Trying to read from a socket's file-like object after a timeout
|
- Issue #7322: Trying to read from a socket's file-like object after a timeout
|
||||||
occurred now raises an error instead of silently losing data.
|
occurred now raises an error instead of silently losing data.
|
||||||
|
|
||||||
|
|
|
@ -8009,6 +8009,552 @@ posix_getresgid (PyObject *self, PyObject *noargs)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Posix *at family of functions:
|
||||||
|
faccessat, fchmodat, fchownat, fstatat, futimesat,
|
||||||
|
linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
|
||||||
|
unlinkat, utimensat, mkfifoat */
|
||||||
|
|
||||||
|
#ifdef HAVE_FACCESSAT
|
||||||
|
PyDoc_STRVAR(posix_faccessat__doc__,
|
||||||
|
"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
|
||||||
|
Like access() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
flags is optional and can be constructed by ORing together zero or more\n\
|
||||||
|
of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_faccessat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *opath;
|
||||||
|
char *path;
|
||||||
|
int mode;
|
||||||
|
int res;
|
||||||
|
int dirfd, flags = 0;
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
|
||||||
|
return NULL;
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = faccessat(dirfd, path, mode, flags);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
return PyBool_FromLong(res == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FCHMODAT
|
||||||
|
PyDoc_STRVAR(posix_fchmodat__doc__,
|
||||||
|
"fchmodat(dirfd, path, mode, flags=0)\n\n\
|
||||||
|
Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_fchmodat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int dirfd, mode, res;
|
||||||
|
int flags = 0;
|
||||||
|
PyObject *opath;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = fchmodat(dirfd, path, mode, flags);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_FCHMODAT */
|
||||||
|
|
||||||
|
#ifdef HAVE_FCHOWNAT
|
||||||
|
PyDoc_STRVAR(posix_fchownat__doc__,
|
||||||
|
"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
|
||||||
|
Like chown() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_fchownat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *opath;
|
||||||
|
int dirfd, res;
|
||||||
|
long uid, gid;
|
||||||
|
int flags = 0;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_FCHOWNAT */
|
||||||
|
|
||||||
|
#ifdef HAVE_FSTATAT
|
||||||
|
PyDoc_STRVAR(posix_fstatat__doc__,
|
||||||
|
"fstatat(dirfd, path, flags=0) -> stat result\n\n\
|
||||||
|
Like stat() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_fstatat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *opath;
|
||||||
|
char *path;
|
||||||
|
STRUCT_STAT st;
|
||||||
|
int dirfd, res, flags = 0;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &flags))
|
||||||
|
return NULL;
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = fstatat(dirfd, path, &st, flags);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res != 0)
|
||||||
|
return posix_error();
|
||||||
|
|
||||||
|
return _pystat_fromstructstat(&st);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FUTIMESAT
|
||||||
|
PyDoc_STRVAR(posix_futimesat__doc__,
|
||||||
|
"futimesat(dirfd, path, (atime, mtime))\n\
|
||||||
|
futimesat(dirfd, path, None)\n\n\
|
||||||
|
Like utime() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_futimesat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *opath;
|
||||||
|
char *path;
|
||||||
|
int res, dirfd;
|
||||||
|
PyObject* arg;
|
||||||
|
|
||||||
|
struct timeval buf[2];
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&O:futimesat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &arg))
|
||||||
|
return NULL;
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
if (arg == Py_None) {
|
||||||
|
/* optional time values not given */
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = futimesat(dirfd, path, NULL);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
|
else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"futimesat() arg 3 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 = futimesat(dirfd, path, buf);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res < 0) {
|
||||||
|
return posix_error();
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LINKAT
|
||||||
|
PyDoc_STRVAR(posix_linkat__doc__,
|
||||||
|
"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
|
||||||
|
Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
|
||||||
|
and if dstpath is relative, it is taken as relative to dstfd.\n\
|
||||||
|
flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
|
||||||
|
If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
|
||||||
|
srcpath is interpreted relative to the current working directory. This\n\
|
||||||
|
also applies for dstpath.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_linkat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *osrc, *odst;
|
||||||
|
char *src, *dst;
|
||||||
|
int res, srcfd, dstfd;
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
|
||||||
|
&srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
|
||||||
|
return NULL;
|
||||||
|
src = PyBytes_AsString(osrc);
|
||||||
|
dst = PyBytes_AsString(odst);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = linkat(srcfd, src, dstfd, dst, flags);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(osrc);
|
||||||
|
Py_DECREF(odst);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_LINKAT */
|
||||||
|
|
||||||
|
#ifdef HAVE_MKDIRAT
|
||||||
|
PyDoc_STRVAR(posix_mkdirat__doc__,
|
||||||
|
"mkdirat(dirfd, path, mode=0o777)\n\n\
|
||||||
|
Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_mkdirat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int res, dirfd;
|
||||||
|
PyObject *opath;
|
||||||
|
char *path;
|
||||||
|
int mode = 0777;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &mode))
|
||||||
|
return NULL;
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = mkdirat(dirfd, path, mode);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
|
||||||
|
PyDoc_STRVAR(posix_mknodat__doc__,
|
||||||
|
"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
|
||||||
|
Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_mknodat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *opath;
|
||||||
|
char *filename;
|
||||||
|
int mode = 0600;
|
||||||
|
int device = 0;
|
||||||
|
int res, dirfd;
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
|
||||||
|
PyUnicode_FSConverter, &opath, &mode, &device))
|
||||||
|
return NULL;
|
||||||
|
filename = PyBytes_AS_STRING(opath);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = mknodat(dirfd, filename, mode, device);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENAT
|
||||||
|
PyDoc_STRVAR(posix_openat__doc__,
|
||||||
|
"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
|
||||||
|
Like open() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_openat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *ofile;
|
||||||
|
char *file;
|
||||||
|
int flag, dirfd, fd;
|
||||||
|
int mode = 0777;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&i|i:openat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &ofile,
|
||||||
|
&flag, &mode))
|
||||||
|
return NULL;
|
||||||
|
file = PyBytes_AsString(ofile);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
fd = openat(dirfd, file, flag, mode);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(ofile);
|
||||||
|
if (fd < 0)
|
||||||
|
return posix_error();
|
||||||
|
return PyLong_FromLong((long)fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_READLINKAT
|
||||||
|
PyDoc_STRVAR(posix_readlinkat__doc__,
|
||||||
|
"readlinkat(dirfd, path) -> path\n\n\
|
||||||
|
Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_readlinkat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *v, *opath;
|
||||||
|
char buf[MAXPATHLEN];
|
||||||
|
char *path;
|
||||||
|
int n, dirfd;
|
||||||
|
int arg_is_unicode = 0;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&:readlinkat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath))
|
||||||
|
return NULL;
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
v = PySequence_GetItem(args, 1);
|
||||||
|
if (v == NULL) {
|
||||||
|
Py_DECREF(opath);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyUnicode_Check(v)) {
|
||||||
|
arg_is_unicode = 1;
|
||||||
|
}
|
||||||
|
Py_DECREF(v);
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
n = readlinkat(dirfd, path, buf, (int) sizeof buf);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (n < 0)
|
||||||
|
return posix_error();
|
||||||
|
|
||||||
|
if (arg_is_unicode)
|
||||||
|
return PyUnicode_DecodeFSDefaultAndSize(buf, n);
|
||||||
|
else
|
||||||
|
return PyBytes_FromStringAndSize(buf, n);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_READLINKAT */
|
||||||
|
|
||||||
|
#ifdef HAVE_RENAMEAT
|
||||||
|
PyDoc_STRVAR(posix_renameat__doc__,
|
||||||
|
"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
|
||||||
|
Like rename() but if oldpath is relative, it is taken as relative to\n\
|
||||||
|
olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
|
||||||
|
If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
|
||||||
|
oldpath is interpreted relative to the current working directory. This\n\
|
||||||
|
also applies for newpath.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_renameat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
PyObject *opathold, *opathnew;
|
||||||
|
char *opath, *npath;
|
||||||
|
int oldfd, newfd;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
|
||||||
|
&oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
|
||||||
|
return NULL;
|
||||||
|
opath = PyBytes_AsString(opathold);
|
||||||
|
npath = PyBytes_AsString(opathnew);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = renameat(oldfd, opath, newfd, npath);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opathold);
|
||||||
|
Py_DECREF(opathnew);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_SYMLINKAT
|
||||||
|
PyDoc_STRVAR(posix_symlinkat__doc__,
|
||||||
|
"symlinkat(src, dstfd, dst)\n\n\
|
||||||
|
Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
|
||||||
|
If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_symlinkat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int res, dstfd;
|
||||||
|
PyObject *osrc, *odst;
|
||||||
|
char *src, *dst;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
|
||||||
|
PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
|
||||||
|
return NULL;
|
||||||
|
src = PyBytes_AsString(osrc);
|
||||||
|
dst = PyBytes_AsString(odst);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = symlinkat(src, dstfd, dst);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(osrc);
|
||||||
|
Py_DECREF(odst);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SYMLINKAT */
|
||||||
|
|
||||||
|
#ifdef HAVE_UNLINKAT
|
||||||
|
PyDoc_STRVAR(posix_unlinkat__doc__,
|
||||||
|
"unlinkat(dirfd, path, flags=0)\n\n\
|
||||||
|
Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
|
||||||
|
specified, unlinkat() behaves like rmdir().\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_unlinkat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int dirfd, res, flags = 0;
|
||||||
|
PyObject *opath;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &flags))
|
||||||
|
return NULL;
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = unlinkat(dirfd, path, flags);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_UTIMENSAT
|
||||||
|
PyDoc_STRVAR(posix_utimensat__doc__,
|
||||||
|
"utimensat(dirfd, path, (atime_sec, atime_nsec),\n\
|
||||||
|
(mtime_sec, mtime_nsec), flags)\n\
|
||||||
|
utimensat(dirfd, path, None, None, flags)\n\n\
|
||||||
|
Updates the timestamps of a file with nanosecond precision. If path is\n\
|
||||||
|
relative, it is taken as relative to dirfd.\n\
|
||||||
|
The second form sets atime and mtime to the current time.\n\
|
||||||
|
flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.\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_utimensat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *opath;
|
||||||
|
char *path;
|
||||||
|
int res, dirfd, flags = 0;
|
||||||
|
PyObject *atime, *mtime;
|
||||||
|
|
||||||
|
struct timespec buf[2];
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&OO|i:utimensat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
|
||||||
|
return NULL;
|
||||||
|
path = PyBytes_AsString(opath);
|
||||||
|
if (atime == Py_None && mtime == Py_None) {
|
||||||
|
/* optional time values not given */
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = utimensat(dirfd, path, NULL, flags);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
|
else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
|
||||||
|
Py_DECREF(opath);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
|
||||||
|
Py_DECREF(opath);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!PyArg_ParseTuple(atime, "ll:utimensat",
|
||||||
|
&(buf[0].tv_sec), &(buf[0].tv_nsec))) {
|
||||||
|
Py_DECREF(opath);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!PyArg_ParseTuple(mtime, "ll:utimensat",
|
||||||
|
&(buf[1].tv_sec), &(buf[1].tv_nsec))) {
|
||||||
|
Py_DECREF(opath);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = utimensat(dirfd, path, buf, flags);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res < 0) {
|
||||||
|
return posix_error();
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_MKFIFOAT
|
||||||
|
PyDoc_STRVAR(posix_mkfifoat__doc__,
|
||||||
|
"mkfifoat(dirfd, path, mode=0o666)\n\n\
|
||||||
|
Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
|
||||||
|
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
|
||||||
|
is interpreted relative to the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_mkfifoat(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *opath;
|
||||||
|
char *filename;
|
||||||
|
int mode = 0666;
|
||||||
|
int res, dirfd;
|
||||||
|
if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
|
||||||
|
&dirfd, PyUnicode_FSConverter, &opath, &mode))
|
||||||
|
return NULL;
|
||||||
|
filename = PyBytes_AS_STRING(opath);
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
res = mkfifoat(dirfd, filename, mode);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_DECREF(opath);
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static PyMethodDef posix_methods[] = {
|
static PyMethodDef posix_methods[] = {
|
||||||
{"access", posix_access, METH_VARARGS, posix_access__doc__},
|
{"access", posix_access, METH_VARARGS, posix_access__doc__},
|
||||||
#ifdef HAVE_TTYNAME
|
#ifdef HAVE_TTYNAME
|
||||||
|
@ -8335,6 +8881,52 @@ static PyMethodDef posix_methods[] = {
|
||||||
{"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
|
{"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* posix *at family of functions */
|
||||||
|
#ifdef HAVE_FACCESSAT
|
||||||
|
{"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FCHMODAT
|
||||||
|
{"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
|
||||||
|
#endif /* HAVE_FCHMODAT */
|
||||||
|
#ifdef HAVE_FCHOWNAT
|
||||||
|
{"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
|
||||||
|
#endif /* HAVE_FCHOWNAT */
|
||||||
|
#ifdef HAVE_FSTATAT
|
||||||
|
{"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FUTIMESAT
|
||||||
|
{"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LINKAT
|
||||||
|
{"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
|
||||||
|
#endif /* HAVE_LINKAT */
|
||||||
|
#ifdef HAVE_MKDIRAT
|
||||||
|
{"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
|
||||||
|
{"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_OPENAT
|
||||||
|
{"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_READLINKAT
|
||||||
|
{"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
|
||||||
|
#endif /* HAVE_READLINKAT */
|
||||||
|
#ifdef HAVE_RENAMEAT
|
||||||
|
{"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
|
||||||
|
#endif
|
||||||
|
#if HAVE_SYMLINKAT
|
||||||
|
{"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
|
||||||
|
#endif /* HAVE_SYMLINKAT */
|
||||||
|
#ifdef HAVE_UNLINKAT
|
||||||
|
{"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UTIMENSAT
|
||||||
|
{"utimensat", posix_utimensat, METH_VARARGS, posix_utimensat__doc__},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MKFIFOAT
|
||||||
|
{"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
|
||||||
|
#endif
|
||||||
{NULL, NULL} /* Sentinel */
|
{NULL, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8520,6 +9112,28 @@ all_ins(PyObject *d)
|
||||||
#ifdef PRIO_USER
|
#ifdef PRIO_USER
|
||||||
if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
|
if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
|
||||||
#endif
|
#endif
|
||||||
|
/* posix - constants for *at functions */
|
||||||
|
#ifdef AT_SYMLINK_NOFOLLOW
|
||||||
|
if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
|
||||||
|
#endif
|
||||||
|
#ifdef AT_EACCESS
|
||||||
|
if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
|
||||||
|
#endif
|
||||||
|
#ifdef AT_FDCWD
|
||||||
|
if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
|
||||||
|
#endif
|
||||||
|
#ifdef AT_REMOVEDIR
|
||||||
|
if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
|
||||||
|
#endif
|
||||||
|
#ifdef AT_SYMLINK_FOLLOW
|
||||||
|
if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
|
||||||
|
#endif
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
||||||
/* MS Windows */
|
/* MS Windows */
|
||||||
|
|
13
configure.in
13
configure.in
|
@ -2534,18 +2534,19 @@ AC_MSG_RESULT(MACHDEP_OBJS)
|
||||||
|
|
||||||
# checks for library functions
|
# checks for library functions
|
||||||
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \
|
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat fork \
|
||||||
|
fpathconf fstatat ftime ftruncate futimesat \
|
||||||
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
|
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
|
||||||
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
|
||||||
initgroups kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \
|
initgroups kill killpg lchmod lchown linkat lstat mbrtowc mkdirat mkfifo \
|
||||||
mremap nice pathconf pause plock poll pthread_init \
|
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
|
||||||
putenv readlink realpath \
|
pthread_init putenv readlink readlinkat realpath renameat \
|
||||||
select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
|
select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
|
||||||
setgid \
|
setgid \
|
||||||
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
||||||
sigaction siginterrupt sigrelse snprintf strftime strlcpy \
|
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat \
|
||||||
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
|
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
|
||||||
truncate uname unsetenv utimes waitpid wait3 wait4 \
|
truncate uname unlinkat unsetenv utimensat utimes waitpid wait3 wait4 \
|
||||||
wcscoll wcsftime wcsxfrm _getpty)
|
wcscoll wcsftime wcsxfrm _getpty)
|
||||||
|
|
||||||
# For some functions, having a definition is not sufficient, since
|
# For some functions, having a definition is not sufficient, since
|
||||||
|
|
|
@ -205,15 +205,24 @@
|
||||||
/* Define to 1 if you have the `expm1' function. */
|
/* Define to 1 if you have the `expm1' function. */
|
||||||
#undef HAVE_EXPM1
|
#undef HAVE_EXPM1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `faccessat' function. */
|
||||||
|
#undef HAVE_FACCESSAT
|
||||||
|
|
||||||
/* Define if you have the 'fchdir' function. */
|
/* Define if you have the 'fchdir' function. */
|
||||||
#undef HAVE_FCHDIR
|
#undef HAVE_FCHDIR
|
||||||
|
|
||||||
/* Define to 1 if you have the `fchmod' function. */
|
/* Define to 1 if you have the `fchmod' function. */
|
||||||
#undef HAVE_FCHMOD
|
#undef HAVE_FCHMOD
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fchmodat' function. */
|
||||||
|
#undef HAVE_FCHMODAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `fchown' function. */
|
/* Define to 1 if you have the `fchown' function. */
|
||||||
#undef HAVE_FCHOWN
|
#undef HAVE_FCHOWN
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fchownat' function. */
|
||||||
|
#undef HAVE_FCHOWNAT
|
||||||
|
|
||||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||||
#undef HAVE_FCNTL_H
|
#undef HAVE_FCNTL_H
|
||||||
|
|
||||||
|
@ -241,6 +250,9 @@
|
||||||
/* Define to 1 if you have the `fseeko' function. */
|
/* Define to 1 if you have the `fseeko' function. */
|
||||||
#undef HAVE_FSEEKO
|
#undef HAVE_FSEEKO
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fstatat' function. */
|
||||||
|
#undef HAVE_FSTATAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `fstatvfs' function. */
|
/* Define to 1 if you have the `fstatvfs' function. */
|
||||||
#undef HAVE_FSTATVFS
|
#undef HAVE_FSTATVFS
|
||||||
|
|
||||||
|
@ -259,6 +271,9 @@
|
||||||
/* Define to 1 if you have the `ftruncate' function. */
|
/* Define to 1 if you have the `ftruncate' function. */
|
||||||
#undef HAVE_FTRUNCATE
|
#undef HAVE_FTRUNCATE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `futimesat' function. */
|
||||||
|
#undef HAVE_FUTIMESAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `gai_strerror' function. */
|
/* Define to 1 if you have the `gai_strerror' function. */
|
||||||
#undef HAVE_GAI_STRERROR
|
#undef HAVE_GAI_STRERROR
|
||||||
|
|
||||||
|
@ -431,6 +446,9 @@
|
||||||
/* Define if you have the 'link' function. */
|
/* Define if you have the 'link' function. */
|
||||||
#undef HAVE_LINK
|
#undef HAVE_LINK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `linkat' function. */
|
||||||
|
#undef HAVE_LINKAT
|
||||||
|
|
||||||
/* Define to 1 if you have the <linux/netlink.h> header file. */
|
/* Define to 1 if you have the <linux/netlink.h> header file. */
|
||||||
#undef HAVE_LINUX_NETLINK_H
|
#undef HAVE_LINUX_NETLINK_H
|
||||||
|
|
||||||
|
@ -461,12 +479,21 @@
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
#undef HAVE_MEMORY_H
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `mkdirat' function. */
|
||||||
|
#undef HAVE_MKDIRAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `mkfifo' function. */
|
/* Define to 1 if you have the `mkfifo' function. */
|
||||||
#undef HAVE_MKFIFO
|
#undef HAVE_MKFIFO
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `mkfifoat' function. */
|
||||||
|
#undef HAVE_MKFIFOAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `mknod' function. */
|
/* Define to 1 if you have the `mknod' function. */
|
||||||
#undef HAVE_MKNOD
|
#undef HAVE_MKNOD
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `mknodat' function. */
|
||||||
|
#undef HAVE_MKNODAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `mktime' function. */
|
/* Define to 1 if you have the `mktime' function. */
|
||||||
#undef HAVE_MKTIME
|
#undef HAVE_MKTIME
|
||||||
|
|
||||||
|
@ -485,6 +512,9 @@
|
||||||
/* Define to 1 if you have the `nice' function. */
|
/* Define to 1 if you have the `nice' function. */
|
||||||
#undef HAVE_NICE
|
#undef HAVE_NICE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `openat' function. */
|
||||||
|
#undef HAVE_OPENAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `openpty' function. */
|
/* Define to 1 if you have the `openpty' function. */
|
||||||
#undef HAVE_OPENPTY
|
#undef HAVE_OPENPTY
|
||||||
|
|
||||||
|
@ -500,6 +530,9 @@
|
||||||
/* Define if the OS supports pipe2() */
|
/* Define if the OS supports pipe2() */
|
||||||
#undef HAVE_PIPE2
|
#undef HAVE_PIPE2
|
||||||
|
|
||||||
|
/* Define if the OS supports pipe2() */
|
||||||
|
#undef HAVE_PIPE2
|
||||||
|
|
||||||
/* Define to 1 if you have the `plock' function. */
|
/* Define to 1 if you have the `plock' function. */
|
||||||
#undef HAVE_PLOCK
|
#undef HAVE_PLOCK
|
||||||
|
|
||||||
|
@ -536,9 +569,15 @@
|
||||||
/* Define to 1 if you have the `readlink' function. */
|
/* Define to 1 if you have the `readlink' function. */
|
||||||
#undef HAVE_READLINK
|
#undef HAVE_READLINK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `readlinkat' function. */
|
||||||
|
#undef HAVE_READLINKAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `realpath' function. */
|
/* Define to 1 if you have the `realpath' function. */
|
||||||
#undef HAVE_REALPATH
|
#undef HAVE_REALPATH
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `renameat' function. */
|
||||||
|
#undef HAVE_RENAMEAT
|
||||||
|
|
||||||
/* Define if you have readline 2.1 */
|
/* Define if you have readline 2.1 */
|
||||||
#undef HAVE_RL_CALLBACK
|
#undef HAVE_RL_CALLBACK
|
||||||
|
|
||||||
|
@ -724,6 +763,9 @@
|
||||||
/* Define if you have the 'symlink' function. */
|
/* Define if you have the 'symlink' function. */
|
||||||
#undef HAVE_SYMLINK
|
#undef HAVE_SYMLINK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `symlinkat' function. */
|
||||||
|
#undef HAVE_SYMLINKAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `sysconf' function. */
|
/* Define to 1 if you have the `sysconf' function. */
|
||||||
#undef HAVE_SYSCONF
|
#undef HAVE_SYSCONF
|
||||||
|
|
||||||
|
@ -866,6 +908,9 @@
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
#undef HAVE_UNISTD_H
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `unlinkat' function. */
|
||||||
|
#undef HAVE_UNLINKAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `unsetenv' function. */
|
/* Define to 1 if you have the `unsetenv' function. */
|
||||||
#undef HAVE_UNSETENV
|
#undef HAVE_UNSETENV
|
||||||
|
|
||||||
|
@ -877,6 +922,9 @@
|
||||||
/* Define to 1 if you have the <util.h> header file. */
|
/* Define to 1 if you have the <util.h> header file. */
|
||||||
#undef HAVE_UTIL_H
|
#undef HAVE_UTIL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `utimensat' function. */
|
||||||
|
#undef HAVE_UTIMENSAT
|
||||||
|
|
||||||
/* Define to 1 if you have the `utimes' function. */
|
/* Define to 1 if you have the `utimes' function. */
|
||||||
#undef HAVE_UTIMES
|
#undef HAVE_UTIMES
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue