Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
7807c354
Commit
7807c354
authored
Mar 17, 2011
by
Ross Lagerwall
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #10812: Add some extra posix functions to the os module.
parent
eb8cee83
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1313 additions
and
222 deletions
+1313
-222
Doc/library/os.rst
Doc/library/os.rst
+238
-0
Lib/test/test_posix.py
Lib/test/test_posix.py
+151
-1
Misc/NEWS
Misc/NEWS
+1
-0
Modules/posixmodule.c
Modules/posixmodule.c
+867
-207
configure
configure
+9
-8
configure.in
configure.in
+8
-6
pyconfig.h.in
pyconfig.h.in
+39
-0
No files found.
Doc/library/os.rst
View file @
7807c354
...
...
@@ -743,6 +743,17 @@ as internal buffering of data.
.. versionadded:: 3.3
.. function:: fexecve(fd, args, env)
Execute the program specified by a file descriptor *fd* with arguments given
by *args* and environment given by *env*, replacing the current process.
*args* and *env* are given as in :func:`execve`.
Availability: Unix.
.. versionadded:: 3.3
.. function:: fpathconf(fd, name)
Return system configuration information relevant to an open file. *name*
...
...
@@ -819,6 +830,45 @@ as internal buffering of data.
.. versionadded:: 3.3
.. function:: futimens(fd, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec))
futimens(fd, None, None)
Updates the timestamps of a file specified by the file descriptor *fd*, with
nanosecond precision.
The second form sets *atime* and *mtime* to the current time.
If *atime_nsec* or *mtime_nsec* is specified as :data:`UTIME_NOW`, the corresponding
timestamp is updated to the current time.
If *atime_nsec* or *mtime_nsec* is specified as :data:`UTIME_OMIT`, the corresponding
timestamp is not updated.
Availability: Unix.
.. versionadded:: 3.3
.. data:: UTIME_NOW
UTIME_OMIT
Flags used with :func:`futimens` to specify that the timestamp must be
updated either to the current time or not updated at all.
Availability: Unix.
.. versionadded:: 3.3
.. function:: futimes(fd, (atime, mtime))
futimes(fd, None)
Set the access and modified time of the file specified by the file
descriptor *fd* to the given values. If the second form is used, set the
access and modified times to the current time.
Availability: Unix.
.. versionadded:: 3.3
.. function:: isatty(fd)
Return ``True`` if the file descriptor *fd* is open and connected to a
...
...
@@ -841,6 +891,30 @@ as internal buffering of data.
.. versionadded:: 3.3
.. function:: lockf(fd, cmd, len)
Apply, test or remove a POSIX lock on an open file descriptor.
*fd* is an open file descriptor.
*cmd* specifies the command to use - one of :data:`F_LOCK`, :data:`F_TLOCK`,
:data:`F_ULOCK` or :data:`F_TEST`.
*len* specifies the section of the file to lock.
Availability: Unix.
.. versionadded:: 3.3
.. data:: F_LOCK
F_TLOCK
F_ULOCK
F_TEST
Flags that specify what action :func:`lockf` will take.
Availability: Unix.
.. versionadded:: 3.3
.. function:: lseek(fd, pos, how)
Set the current position of file descriptor *fd* to position *pos*, modified
...
...
@@ -945,6 +1019,66 @@ as internal buffering of data.
Availability: Unix, Windows.
.. function:: posix_fallocate(fd, offset, len)
Ensures that enough disk space is allocated for the file specified by *fd*
starting from *offset* and continuing for *len* bytes.
Availability: Unix.
.. versionadded:: 3.3
.. function:: posix_fadvise(fd, offset, len, advice)
Announces an intention to access data in a specific pattern thus allowing
the kernel to make optimizations.
The advice applies to the region of the file specified by *fd* starting at
*offset* and continuing for *len* bytes.
*advice* is one of :data:`POSIX_FADV_NORMAL`, :data:`POSIX_FADV_SEQUENTIAL`,
:data:`POSIX_FADV_RANDOM`, :data:`POSIX_FADV_NOREUSE`,
:data:`POSIX_FADV_WILLNEED` or :data:`POSIX_FADV_DONTNEED`.
Availability: Unix.
.. versionadded:: 3.3
.. data:: POSIX_FADV_NORMAL
POSIX_FADV_SEQUENTIAL
POSIX_FADV_RANDOM
POSIX_FADV_NOREUSE
POSIX_FADV_WILLNEED
POSIX_FADV_DONTNEED
Flags that can be used in *advice* in :func:`posix_fadvise` that specify
the access pattern that is likely to be used.
Availability: Unix.
.. versionadded:: 3.3
.. function:: pread(fd, buffersize, offset)
Read from a file descriptor, *fd*, at a position of *offset*. It will read up
to *buffersize* number of bytes. The file offset remains unchanged.
Availability: Unix.
.. versionadded:: 3.3
.. function:: pwrite(fd, string, offset)
Write *string* to a file descriptor, *fd*, from *offset*, leaving the file
offset unchanged.
Availability: Unix.
.. versionadded:: 3.3
.. function:: read(fd, n)
Read at most *n* bytes from file descriptor *fd*. Return a bytestring containing the
...
...
@@ -1038,6 +1172,17 @@ as internal buffering of data.
.. versionadded:: 3.3
.. function:: readv(fd, buffers)
Read from a file descriptor into a number of writable buffers. *buffers* is
an arbitrary sequence of writable buffers. Returns the total number of bytes
read.
Availability: Unix.
.. versionadded:: 3.3
.. function:: tcgetpgrp(fd)
Return the process group associated with the terminal given by *fd* (an open
...
...
@@ -1111,6 +1256,17 @@ as internal buffering of data.
:meth:`~file.write` method.
.. function:: writev(fd, buffers)
Write the the contents of *buffers* to file descriptor *fd*, where *buffers*
is an arbitrary sequence of buffers.
Returns the total number of bytes written.
Availability: Unix.
.. versionadded:: 3.3
.. _open-constants:
``open()`` flag constants
...
...
@@ -1384,6 +1540,17 @@ Files and Directories
Added support for Windows 6.0 (Vista) symbolic links.
.. function:: lutimes(path, (atime, mtime))
lutimes(path, None)
Like :func:`utime`, but if *path* is a symbolic link, it is not
dereferenced.
Availability: Unix.
.. versionadded:: 3.3
.. function:: mkfifo(path[, mode])
Create a FIFO (a named pipe) named *path* with numeric mode *mode*. The
...
...
@@ -1727,6 +1894,25 @@ Files and Directories
Added support for Windows 6.0 (Vista) symbolic links.
.. function:: sync()
Force write of everything to disk.
Availability: Unix.
.. versionadded:: 3.3
.. function:: truncate(path, length)
Truncate the file corresponding to *path*, so that it is at most
*length* bytes in size.
Availability: Unix.
.. versionadded:: 3.3
.. function:: unlink(path)
Remove (delete) the file *path*. This is the same function as
...
...
@@ -2306,6 +2492,58 @@ written in Python, such as a mail server's external command delivery program.
Availability: Unix.
.. function:: waitid(idtype, id, options)
Wait for the completion of one or more child processes.
*idtype* can be :data:`P_PID`, :data:`P_PGID` or :data:`P_ALL`.
*id* specifies the pid to wait on.
*options* is constructed from the ORing of one or more of :data:`WEXITED`,
:data:`WSTOPPED` or :data:`WCONTINUED` and additionally may be ORed with
:data:`WNOHANG` or :data:`WNOWAIT`. The return value is an object
representing the data contained in the :c:type:`siginfo_t` structure, namely:
:attr:`si_pid`, :attr:`si_uid`, :attr:`si_signo`, :attr:`si_status`,
:attr:`si_code` or ``None`` if :data:`WNOHANG` is specified and there are no
children in a waitable state.
Availability: Unix.
.. versionadded:: 3.3
.. data:: P_PID
P_PGID
P_ALL
These are the possible values for *idtype* in :func:`waitid`. They affect
how *id* is interpreted.
Availability: Unix.
.. versionadded:: 3.3
.. data:: WEXITED
WSTOPPED
WNOWAIT
Flags that can be used in *options* in :func:`waitid` that specify what
child signal to wait for.
Availability: Unix.
.. versionadded:: 3.3
.. data:: CLD_EXITED
CLD_DUMPED
CLD_TRAPPED
CLD_CONTINUED
These are the possible values for :attr:`si_code` in the result returned by
:func:`waitid`.
Availability: Unix.
.. versionadded:: 3.3
.. function:: waitpid(pid, options)
...
...
Lib/test/test_posix.py
View file @
7807c354
...
...
@@ -37,7 +37,7 @@ class PosixTester(unittest.TestCase):
NO_ARG_FUNCTIONS
=
[
"ctermid"
,
"getcwd"
,
"getcwdb"
,
"uname"
,
"times"
,
"getloadavg"
,
"getegid"
,
"geteuid"
,
"getgid"
,
"getgroups"
,
"getpid"
,
"getpgrp"
,
"getppid"
,
"getuid"
,
"getpid"
,
"getpgrp"
,
"getppid"
,
"getuid"
,
"sync"
,
]
for
name
in
NO_ARG_FUNCTIONS
:
...
...
@@ -132,6 +132,156 @@ class PosixTester(unittest.TestCase):
finally
:
fp
.
close
()
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'truncate'
),
"test needs posix.truncate()"
)
def
test_truncate
(
self
):
with
open
(
support
.
TESTFN
,
'w'
)
as
fp
:
fp
.
write
(
'test'
)
fp
.
flush
()
posix
.
truncate
(
support
.
TESTFN
,
0
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'fexecve'
),
"test needs posix.fexecve()"
)
@
unittest
.
skipUnless
(
hasattr
(
os
,
'fork'
),
"test needs os.fork()"
)
@
unittest
.
skipUnless
(
hasattr
(
os
,
'wait'
),
"test needs os.wait()"
)
def
test_fexecve
(
self
):
fp
=
os
.
open
(
sys
.
executable
,
os
.
O_RDONLY
)
try
:
pid
=
os
.
fork
()
if
pid
==
0
:
os
.
chdir
(
os
.
path
.
split
(
sys
.
executable
)[
0
])
posix
.
fexecve
(
fp
,
[
sys
.
executable
,
'-c'
,
'pass'
],
os
.
environ
)
else
:
self
.
assertEqual
(
os
.
wait
(),
(
pid
,
0
))
finally
:
os
.
close
(
fp
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'waitid'
),
"test needs posix.waitid()"
)
@
unittest
.
skipUnless
(
hasattr
(
os
,
'fork'
),
"test needs os.fork()"
)
def
test_waitid
(
self
):
pid
=
os
.
fork
()
if
pid
==
0
:
os
.
chdir
(
os
.
path
.
split
(
sys
.
executable
)[
0
])
posix
.
execve
(
sys
.
executable
,
[
sys
.
executable
,
'-c'
,
'pass'
],
os
.
environ
)
else
:
res
=
posix
.
waitid
(
posix
.
P_PID
,
pid
,
posix
.
WEXITED
)
self
.
assertEqual
(
pid
,
res
.
si_pid
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'lockf'
),
"test needs posix.lockf()"
)
def
test_lockf
(
self
):
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_WRONLY
|
os
.
O_CREAT
)
try
:
os
.
write
(
fd
,
b'test'
)
os
.
lseek
(
fd
,
0
,
os
.
SEEK_SET
)
posix
.
lockf
(
fd
,
posix
.
F_LOCK
,
4
)
# section is locked
posix
.
lockf
(
fd
,
posix
.
F_ULOCK
,
4
)
finally
:
os
.
close
(
fd
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'pread'
),
"test needs posix.pread()"
)
def
test_pread
(
self
):
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_RDWR
|
os
.
O_CREAT
)
try
:
os
.
write
(
fd
,
b'test'
)
os
.
lseek
(
fd
,
0
,
os
.
SEEK_SET
)
self
.
assertEqual
(
b'es'
,
posix
.
pread
(
fd
,
2
,
1
))
# the first pread() shoudn't disturb the file offset
self
.
assertEqual
(
b'te'
,
posix
.
read
(
fd
,
2
))
finally
:
os
.
close
(
fd
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'pwrite'
),
"test needs posix.pwrite()"
)
def
test_pwrite
(
self
):
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_RDWR
|
os
.
O_CREAT
)
try
:
os
.
write
(
fd
,
b'test'
)
os
.
lseek
(
fd
,
0
,
os
.
SEEK_SET
)
posix
.
pwrite
(
fd
,
b'xx'
,
1
)
self
.
assertEqual
(
b'txxt'
,
posix
.
read
(
fd
,
4
))
finally
:
os
.
close
(
fd
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'posix_fallocate'
),
"test needs posix.posix_fallocate()"
)
def
test_posix_fallocate
(
self
):
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_WRONLY
|
os
.
O_CREAT
)
try
:
posix
.
posix_fallocate
(
fd
,
0
,
10
)
except
OSError
as
inst
:
# issue10812, ZFS doesn't appear to support posix_fallocate,
# so skip Solaris-based since they are likely to have ZFS.
if
inst
.
errno
!=
errno
.
EINVAL
or
not
sys
.
platform
.
startswith
(
"sunos"
):
raise
finally
:
os
.
close
(
fd
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'posix_fadvise'
),
"test needs posix.posix_fadvise()"
)
def
test_posix_fadvise
(
self
):
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_RDONLY
)
try
:
posix
.
posix_fadvise
(
fd
,
0
,
0
,
posix
.
POSIX_FADV_WILLNEED
)
finally
:
os
.
close
(
fd
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'futimes'
),
"test needs posix.futimes()"
)
def
test_futimes
(
self
):
now
=
time
.
time
()
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_RDONLY
)
try
:
posix
.
futimes
(
fd
,
None
)
self
.
assertRaises
(
TypeError
,
posix
.
futimes
,
fd
,
(
None
,
None
))
self
.
assertRaises
(
TypeError
,
posix
.
futimes
,
fd
,
(
now
,
None
))
self
.
assertRaises
(
TypeError
,
posix
.
futimes
,
fd
,
(
None
,
now
))
posix
.
futimes
(
fd
,
(
int
(
now
),
int
(
now
)))
posix
.
futimes
(
fd
,
(
now
,
now
))
finally
:
os
.
close
(
fd
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'lutimes'
),
"test needs posix.lutimes()"
)
def
test_lutimes
(
self
):
now
=
time
.
time
()
posix
.
lutimes
(
support
.
TESTFN
,
None
)
self
.
assertRaises
(
TypeError
,
posix
.
lutimes
,
support
.
TESTFN
,
(
None
,
None
))
self
.
assertRaises
(
TypeError
,
posix
.
lutimes
,
support
.
TESTFN
,
(
now
,
None
))
self
.
assertRaises
(
TypeError
,
posix
.
lutimes
,
support
.
TESTFN
,
(
None
,
now
))
posix
.
lutimes
(
support
.
TESTFN
,
(
int
(
now
),
int
(
now
)))
posix
.
lutimes
(
support
.
TESTFN
,
(
now
,
now
))
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'futimens'
),
"test needs posix.futimens()"
)
def
test_futimens
(
self
):
now
=
time
.
time
()
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_RDONLY
)
try
:
self
.
assertRaises
(
TypeError
,
posix
.
futimens
,
fd
,
(
None
,
None
),
(
None
,
None
))
self
.
assertRaises
(
TypeError
,
posix
.
futimens
,
fd
,
(
now
,
0
),
None
)
self
.
assertRaises
(
TypeError
,
posix
.
futimens
,
fd
,
None
,
(
now
,
0
))
posix
.
futimens
(
fd
,
(
int
(
now
),
int
((
now
-
int
(
now
))
*
1e9
)),
(
int
(
now
),
int
((
now
-
int
(
now
))
*
1e9
)))
finally
:
os
.
close
(
fd
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'writev'
),
"test needs posix.writev()"
)
def
test_writev
(
self
):
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_RDWR
|
os
.
O_CREAT
)
try
:
os
.
writev
(
fd
,
(
b'test1'
,
b'tt2'
,
b't3'
))
os
.
lseek
(
fd
,
0
,
os
.
SEEK_SET
)
self
.
assertEqual
(
b'test1tt2t3'
,
posix
.
read
(
fd
,
10
))
finally
:
os
.
close
(
fd
)
@
unittest
.
skipUnless
(
hasattr
(
posix
,
'readv'
),
"test needs posix.readv()"
)
def
test_readv
(
self
):
fd
=
os
.
open
(
support
.
TESTFN
,
os
.
O_RDWR
|
os
.
O_CREAT
)
try
:
os
.
write
(
fd
,
b'test1tt2t3'
)
os
.
lseek
(
fd
,
0
,
os
.
SEEK_SET
)
buf
=
[
bytearray
(
i
)
for
i
in
[
5
,
3
,
2
]]
self
.
assertEqual
(
posix
.
readv
(
fd
,
buf
),
10
)
self
.
assertEqual
([
b'test1'
,
b'tt2'
,
b't3'
],
[
bytes
(
i
)
for
i
in
buf
])
finally
:
os
.
close
(
fd
)
def
test_dup
(
self
):
if
hasattr
(
posix
,
'dup'
):
fp
=
open
(
support
.
TESTFN
)
...
...
Misc/NEWS
View file @
7807c354
...
...
@@ -72,6 +72,7 @@ Core and Builtins
Library
-------
-
Issue
#
10812
:
Add
some
extra
posix
functions
to
the
os
module
.
-
Issue
#
10979
:
unittest
stdout
buffering
now
works
with
class
and
module
setup
and
teardown
.
...
...
Modules/posixmodule.c
View file @
7807c354
...
...
@@ -1503,6 +1503,33 @@ static PyStructSequence_Desc statvfs_result_desc = {
10
};
#if defined(HAVE_WAITID) && !defined(__APPLE__)
PyDoc_STRVAR
(
waitid_result__doc__
,
"waitid_result: Result from waitid.
\n\n
\
This object may be accessed either as a tuple of
\n
\
(si_pid, si_uid, si_signo, si_status, si_code),
\n
\
or via the attributes si_pid, si_uid, and so on.
\n
\
\n
\
See os.waitid for more information."
);
static
PyStructSequence_Field
waitid_result_fields
[]
=
{
{
"si_pid"
,
},
{
"si_uid"
,
},
{
"si_signo"
,
},
{
"si_status"
,
},
{
"si_code"
,
},
{
0
}
};
static
PyStructSequence_Desc
waitid_result_desc
=
{
"waitid_result"
,
/* name */
waitid_result__doc__
,
/* doc */
waitid_result_fields
,
5
};
static
PyTypeObject
WaitidResultType
;
#endif
static
int
initialized
;
static
PyTypeObject
StatResultType
;
static
PyTypeObject
StatVFSResultType
;
...
...
@@ -2102,6 +2129,21 @@ posix_fsync(PyObject *self, PyObject *fdobj)
}
#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
...
...
@@ -3488,6 +3530,167 @@ done:
#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
];
long
ausec
,
musec
;
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
),
&
ausec
)
==
-
1
)
{
return
NULL
;
}
if
(
extract_time
(
PyTuple_GET_ITEM
(
arg
,
1
),
&
(
buf
[
1
].
tv_sec
),
&
musec
)
==
-
1
)
{
return
NULL
;
}
buf
[
0
].
tv_usec
=
ausec
;
buf
[
1
].
tv_usec
=
musec
;
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
;
const
char
*
path
;
int
res
;
struct
timeval
buf
[
2
];
long
ausec
,
musec
;
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
),
&
ausec
)
==
-
1
)
{
Py_DECREF
(
opath
);
return
NULL
;
}
if
(
extract_time
(
PyTuple_GET_ITEM
(
arg
,
1
),
&
(
buf
[
1
].
tv_sec
),
&
musec
)
==
-
1
)
{
Py_DECREF
(
opath
);
return
NULL
;
}
buf
[
0
].
tv_usec
=
ausec
;
buf
[
1
].
tv_usec
=
musec
;
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 */
...
...
@@ -3532,79 +3735,7 @@ int fsconvert_strdup(PyObject *o, char**out)
}
#endif
#ifdef HAVE_EXECV
PyDoc_STRVAR
(
posix_execv__doc__
,
"execv(path, args)
\n\n
\
Execute an executable path with arguments, replacing current process.
\n
\
\n
\
path: path of executable file
\n
\
args: tuple or list of strings"
);
static
PyObject
*
posix_execv
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
opath
;
char
*
path
;
PyObject
*
argv
;
char
**
argvlist
;
Py_ssize_t
i
,
argc
;
PyObject
*
(
*
getitem
)(
PyObject
*
,
Py_ssize_t
);
/* execv has two arguments: (path, argv), where
argv is a list or tuple of strings. */
if
(
!
PyArg_ParseTuple
(
args
,
"O&O:execv"
,
PyUnicode_FSConverter
,
&
opath
,
&
argv
))
return
NULL
;
path
=
PyBytes_AsString
(
opath
);
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
,
"execv() arg 2 must be a tuple or list"
);
Py_DECREF
(
opath
);
return
NULL
;
}
if
(
argc
<
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"execv() arg 2 must not be empty"
);
Py_DECREF
(
opath
);
return
NULL
;
}
argvlist
=
PyMem_NEW
(
char
*
,
argc
+
1
);
if
(
argvlist
==
NULL
)
{
Py_DECREF
(
opath
);
return
PyErr_NoMemory
();
}
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
if
(
!
fsconvert_strdup
((
*
getitem
)(
argv
,
i
),
&
argvlist
[
i
]))
{
free_string_array
(
argvlist
,
i
);
PyErr_SetString
(
PyExc_TypeError
,
"execv() arg 2 must contain only strings"
);
Py_DECREF
(
opath
);
return
NULL
;
}
}
argvlist
[
argc
]
=
NULL
;
execv
(
path
,
argvlist
);
/* If we get here it's definitely an error */
free_string_array
(
argvlist
,
argc
);
Py_DECREF
(
opath
);
return
posix_error
();
}
#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
static
char
**
parse_envlist
(
PyObject
*
env
,
Py_ssize_t
*
envc_ptr
)
{
...
...
@@ -3686,6 +3817,84 @@ error:
return
NULL
;
}
static
char
**
parse_arglist
(
PyObject
*
argv
,
Py_ssize_t
*
argc
)
{
int
i
;
char
**
argvlist
=
PyMem_NEW
(
char
*
,
*
argc
+
1
);
if
(
argvlist
==
NULL
)
{
PyErr_NoMemory
();
return
NULL
;
}
for
(
i
=
0
;
i
<
*
argc
;
i
++
)
{
if
(
!
fsconvert_strdup
(
PySequence_ITEM
(
argv
,
i
),
&
argvlist
[
i
]))
{
*
argc
=
i
;
goto
fail
;
}
}
argvlist
[
*
argc
]
=
NULL
;
return
argvlist
;
fail:
free_string_array
(
argvlist
,
*
argc
);
return
NULL
;
}
#endif
#ifdef HAVE_EXECV
PyDoc_STRVAR
(
posix_execv__doc__
,
"execv(path, args)
\n\n
\
Execute an executable path with arguments, replacing current process.
\n
\
\n
\
path: path of executable file
\n
\
args: tuple or list of strings"
);
static
PyObject
*
posix_execv
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
opath
;
char
*
path
;
PyObject
*
argv
;
char
**
argvlist
;
Py_ssize_t
argc
;
/* execv has two arguments: (path, argv), where
argv is a list or tuple of strings. */
if
(
!
PyArg_ParseTuple
(
args
,
"O&O:execv"
,
PyUnicode_FSConverter
,
&
opath
,
&
argv
))
return
NULL
;
path
=
PyBytes_AsString
(
opath
);
if
(
!
PyList_Check
(
argv
)
&&
!
PyTuple_Check
(
argv
))
{
PyErr_SetString
(
PyExc_TypeError
,
"execv() arg 2 must be a tuple or list"
);
Py_DECREF
(
opath
);
return
NULL
;
}
argc
=
PySequence_Size
(
argv
);
if
(
argc
<
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"execv() arg 2 must not be empty"
);
Py_DECREF
(
opath
);
return
NULL
;
}
argvlist
=
parse_arglist
(
argv
,
&
argc
);
if
(
argvlist
==
NULL
)
{
Py_DECREF
(
opath
);
return
NULL
;
}
execv
(
path
,
argvlist
);
/* If we get here it's definitely an error */
free_string_array
(
argvlist
,
argc
);
Py_DECREF
(
opath
);
return
posix_error
();
}
PyDoc_STRVAR
(
posix_execve__doc__
,
"execve(path, args, env)
\n\n
\
Execute a path with arguments and environment, replacing current process.
\n
\
...
...
@@ -3702,9 +3911,7 @@ posix_execve(PyObject *self, PyObject *args)
PyObject
*
argv
,
*
env
;
char
**
argvlist
;
char
**
envlist
;
Py_ssize_t
i
,
argc
,
envc
;
PyObject
*
(
*
getitem
)(
PyObject
*
,
Py_ssize_t
);
Py_ssize_t
lastarg
=
0
;
Py_ssize_t
argc
,
envc
;
/* execve has three arguments: (path, argv, env), where
argv is a list or tuple of strings and env is a dictionary
...
...
@@ -3715,40 +3922,22 @@ posix_execve(PyObject *self, PyObject *args)
&
opath
,
&
argv
,
&
env
))
return
NULL
;
path
=
PyBytes_AsString
(
opath
);
if
(
PyList_Check
(
argv
))
{
argc
=
PyList_Size
(
argv
);
getitem
=
PyList_GetItem
;
}
else
if
(
PyTuple_Check
(
argv
))
{
argc
=
PyTuple_Size
(
argv
);
getitem
=
PyTuple_GetItem
;
}
else
{
if
(
!
PyList_Check
(
argv
)
&&
!
PyTuple_Check
(
argv
))
{
PyErr_SetString
(
PyExc_TypeError
,
"execve() arg 2 must be a tuple or list"
);
goto
fail_0
;
}
argc
=
PySequence_Size
(
argv
);
if
(
!
PyMapping_Check
(
env
))
{
PyErr_SetString
(
PyExc_TypeError
,
"execve() arg 3 must be a mapping object"
);
goto
fail_0
;
}
argvlist
=
PyMem_NEW
(
char
*
,
argc
+
1
);
argvlist
=
parse_arglist
(
argv
,
&
argc
);
if
(
argvlist
==
NULL
)
{
PyErr_NoMemory
();
goto
fail_0
;
}
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
)
...
...
@@ -3764,13 +3953,69 @@ posix_execve(PyObject *self, PyObject *args)
PyMem_DEL
(
envlist
[
envc
]);
PyMem_DEL
(
envlist
);
fail_1:
free_string_array
(
argvlist
,
lastarg
);
free_string_array
(
argvlist
,
argc
);
fail_0:
Py_DECREF
(
opath
);
return
NULL
;
}
#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
argc
,
envc
;
if
(
!
PyArg_ParseTuple
(
args
,
"iOO:fexecve"
,
&
fd
,
&
argv
,
&
env
))
return
NULL
;
if
(
!
PyList_Check
(
argv
)
&&
!
PyTuple_Check
(
argv
))
{
PyErr_SetString
(
PyExc_TypeError
,
"fexecve() arg 2 must be a tuple or list"
);
return
NULL
;
}
argc
=
PySequence_Size
(
argv
);
if
(
!
PyMapping_Check
(
env
))
{
PyErr_SetString
(
PyExc_TypeError
,
"fexecve() arg 3 must be a mapping object"
);
return
NULL
;
}
argvlist
=
parse_arglist
(
argv
,
&
argc
);
if
(
argvlist
==
NULL
)
return
NULL
;
envlist
=
parse_envlist
(
env
,
&
envc
);
if
(
envlist
==
NULL
)
goto
fail
;
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:
free_string_array
(
argvlist
,
argc
);
return
NULL
;
}
#endif
/* HAVE_FEXECVE */
#ifdef HAVE_SPAWNV
PyDoc_STRVAR
(
posix_spawnv__doc__
,
...
...
@@ -4337,6 +4582,7 @@ posix_forkpty(PyObject *self, PyObject *noargs)
}
#endif
#ifdef HAVE_GETEGID
PyDoc_STRVAR
(
posix_getegid__doc__
,
"getegid() -> egid
\n\n
\
...
...
@@ -5127,6 +5373,55 @@ posix_wait4(PyObject *self, PyObject *args)
}
#endif
/* HAVE_WAIT4 */
#if defined(HAVE_WAITID) && !defined(__APPLE__)
PyDoc_STRVAR
(
posix_waitid__doc__
,
"waitid(idtype, id, options) -> waitid_result
\n\n
\
Wait for the completion of one or more child processes.
\n\n
\
idtype can be P_PID, P_PGID or P_ALL.
\n
\
id specifies the pid to wait on.
\n
\
options is constructed from the ORing of one or more of WEXITED, WSTOPPED
\n
\
or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
\n
\
Returns either waitid_result or None if WNOHANG is specified and there are
\n
\
no children in a waitable state."
);
static
PyObject
*
posix_waitid
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
result
;
idtype_t
idtype
;
id_t
id
;
int
options
,
res
;
siginfo_t
si
;
si
.
si_pid
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"i"
_Py_PARSE_PID
"i:waitid"
,
&
idtype
,
&
id
,
&
options
))
return
NULL
;
Py_BEGIN_ALLOW_THREADS
res
=
waitid
(
idtype
,
id
,
&
si
,
options
);
Py_END_ALLOW_THREADS
if
(
res
==
-
1
)
return
posix_error
();
if
(
si
.
si_pid
==
0
)
Py_RETURN_NONE
;
result
=
PyStructSequence_New
(
&
WaitidResultType
);
if
(
!
result
)
return
NULL
;
PyStructSequence_SET_ITEM
(
result
,
0
,
PyLong_FromPid
(
si
.
si_pid
));
PyStructSequence_SET_ITEM
(
result
,
1
,
PyLong_FromPid
(
si
.
si_uid
));
PyStructSequence_SET_ITEM
(
result
,
2
,
PyLong_FromLong
((
long
)(
si
.
si_signo
)));
PyStructSequence_SET_ITEM
(
result
,
3
,
PyLong_FromLong
((
long
)(
si
.
si_status
)));
PyStructSequence_SET_ITEM
(
result
,
4
,
PyLong_FromLong
((
long
)(
si
.
si_code
)));
if
(
PyErr_Occurred
())
{
Py_DECREF
(
result
);
return
NULL
;
}
return
result
;
}
#endif
#ifdef HAVE_WAITPID
PyDoc_STRVAR
(
posix_waitpid__doc__
,
"waitpid(pid, options) -> (pid, status)
\n\n
\
...
...
@@ -5742,72 +6037,223 @@ posix_dup2(PyObject *self, PyObject *args)
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
;
if
(
!
PyArg_ParseTuple
(
args
,
"iiO&:lockf"
,
&
fd
,
&
cmd
,
_parse_off_t
,
&
len
))
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."
);
static
PyObject
*
posix_lseek
(
PyObject
*
self
,
PyObject
*
args
)
{
int
fd
,
how
;
#if defined(MS_WIN64) || defined(MS_WINDOWS)
PY_LONG_LONG
pos
,
res
;
#else
off_t
pos
,
res
;
#endif
if
(
!
PyArg_ParseTuple
(
args
,
"iO&i:lseek"
,
&
fd
,
_parse_off_t
,
&
pos
,
&
how
))
return
NULL
;
#ifdef SEEK_SET
/* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
switch
(
how
)
{
case
0
:
how
=
SEEK_SET
;
break
;
case
1
:
how
=
SEEK_CUR
;
break
;
case
2
:
how
=
SEEK_END
;
break
;
}
#endif
/* SEEK_END */
if
(
PyErr_Occurred
())
return
NULL
;
if
(
!
_PyVerify_fd
(
fd
))
return
posix_error
();
Py_BEGIN_ALLOW_THREADS
#if defined(MS_WIN64) || defined(MS_WINDOWS)
res
=
_lseeki64
(
fd
,
pos
,
how
);
#else
res
=
lseek
(
fd
,
pos
,
how
);
#endif
Py_END_ALLOW_THREADS
if
(
res
<
0
)
return
posix_error
();
#if !defined(HAVE_LARGEFILE_SUPPORT)
return
PyLong_FromLong
(
res
);
#else
return
PyLong_FromLongLong
(
res
);
#endif
}
PyDoc_STRVAR
(
posix_read__doc__
,
"read(fd, buffersize) -> string
\n\n
\
Read a file descriptor."
);
static
PyObject
*
posix_read
(
PyObject
*
self
,
PyObject
*
args
)
{
int
fd
,
size
;
Py_ssize_t
n
;
PyObject
*
buffer
;
if
(
!
PyArg_ParseTuple
(
args
,
"ii:read"
,
&
fd
,
&
size
))
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
=
read
(
fd
,
PyBytes_AS_STRING
(
buffer
),
size
);
Py_END_ALLOW_THREADS
if
(
n
<
0
)
{
Py_DECREF
(
buffer
);
return
posix_error
();
}
if
(
n
!=
size
)
_PyBytes_Resize
(
&
buffer
,
n
);
return
buffer
;
}
#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
|| defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
static
Py_ssize_t
iov_setup
(
struct
iovec
**
iov
,
Py_buffer
**
buf
,
PyObject
*
seq
,
int
cnt
,
int
type
)
{
int
i
,
j
;
Py_ssize_t
blen
,
total
=
0
;
*
iov
=
PyMem_New
(
struct
iovec
,
cnt
);
if
(
*
iov
==
NULL
)
{
PyErr_NoMemory
();
return
total
;
}
*
buf
=
PyMem_New
(
Py_buffer
,
cnt
);
if
(
*
buf
==
NULL
)
{
PyMem_Del
(
*
iov
);
PyErr_NoMemory
();
return
total
;
}
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
if
(
PyObject_GetBuffer
(
PySequence_GetItem
(
seq
,
i
),
&
(
*
buf
)[
i
],
type
)
==
-
1
)
{
PyMem_Del
(
*
iov
);
for
(
j
=
0
;
j
<
i
;
j
++
)
{
PyBuffer_Release
(
&
(
*
buf
)[
j
]);
}
PyMem_Del
(
*
buf
);
total
=
0
;
return
total
;
}
(
*
iov
)[
i
].
iov_base
=
(
*
buf
)[
i
].
buf
;
blen
=
(
*
buf
)[
i
].
len
;
(
*
iov
)[
i
].
iov_len
=
blen
;
total
+=
blen
;
}
return
total
;
}
static
void
iov_cleanup
(
struct
iovec
*
iov
,
Py_buffer
*
buf
,
int
cnt
)
{
int
i
;
PyMem_Del
(
iov
);
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
PyBuffer_Release
(
&
buf
[
i
]);
}
PyMem_Del
(
buf
);
}
#endif
PyDoc_STRVAR
(
posix_lseek__doc__
,
"lseek(fd, pos, how) -> newpos
\n\n
\
Set the current position of a file descriptor."
);
#ifdef HAVE_READV
PyDoc_STRVAR
(
posix_readv__doc__
,
"readv(fd, buffers) -> bytesread
\n\n
\
Read from a file descriptor into a number of writable buffers. buffers
\n
\
is an arbitrary sequence of writable buffers.
\n
\
Returns the total number of bytes read."
);
static
PyObject
*
posix_
lseek
(
PyObject
*
self
,
PyObject
*
args
)
posix_
readv
(
PyObject
*
self
,
PyObject
*
args
)
{
int
fd
,
how
;
#if defined(MS_WIN64) || defined(MS_WINDOWS)
PY_LONG_LONG
pos
,
res
;
#else
off_t
pos
,
res
;
#endif
PyObject
*
posobj
;
if
(
!
PyArg_ParseTuple
(
args
,
"iOi:lseek"
,
&
fd
,
&
posobj
,
&
how
))
int
fd
,
cnt
;
Py_ssize_t
n
;
PyObject
*
seq
;
struct
iovec
*
iov
;
Py_buffer
*
buf
;
if
(
!
PyArg_ParseTuple
(
args
,
"iO:readv"
,
&
fd
,
&
seq
))
return
NULL
;
if
(
!
PySequence_Check
(
seq
))
{
PyErr_SetString
(
PyExc_TypeError
,
"readv() arg 2 must be a sequence"
);
return
NULL
;
#ifdef SEEK_SET
/* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
switch
(
how
)
{
case
0
:
how
=
SEEK_SET
;
break
;
case
1
:
how
=
SEEK_CUR
;
break
;
case
2
:
how
=
SEEK_END
;
break
;
}
#endif
/* SEEK_END */
cnt
=
PySequence_Size
(
seq
);
#if !defined(HAVE_LARGEFILE_SUPPORT)
pos
=
PyLong_AsLong
(
posobj
);
#else
pos
=
PyLong_AsLongLong
(
posobj
);
#endif
if
(
PyErr_Occurred
())
if
(
!
iov_setup
(
&
iov
,
&
buf
,
seq
,
cnt
,
PyBUF_WRITABLE
))
return
NULL
;
if
(
!
_PyVerify_fd
(
fd
))
return
posix_error
();
Py_BEGIN_ALLOW_THREADS
#if defined(MS_WIN64) || defined(MS_WINDOWS)
res
=
_lseeki64
(
fd
,
pos
,
how
);
#else
res
=
lseek
(
fd
,
pos
,
how
);
#endif
n
=
readv
(
fd
,
iov
,
cnt
);
Py_END_ALLOW_THREADS
if
(
res
<
0
)
return
posix_error
();
#if !defined(HAVE_LARGEFILE_SUPPORT)
return
PyLong_FromLong
(
res
);
#else
return
PyLong_FromLongLong
(
res
);
#endif
iov_cleanup
(
iov
,
buf
,
cnt
);
return
PyLong_FromSsize_t
(
n
);
}
#endif
PyDoc_STRVAR
(
posix_read__doc__
,
"read(fd, buffersize) -> string
\n\n
\
Read a file descriptor."
);
#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_read
(
PyObject
*
self
,
PyObject
*
args
)
posix_
p
read
(
PyObject
*
self
,
PyObject
*
args
)
{
int
fd
,
size
;
off_t
offset
;
Py_ssize_t
n
;
PyObject
*
buffer
;
if
(
!
PyArg_ParseTuple
(
args
,
"ii
:read"
,
&
fd
,
&
size
))
if
(
!
PyArg_ParseTuple
(
args
,
"ii
O&:pread"
,
&
fd
,
&
size
,
_parse_off_t
,
&
offset
))
return
NULL
;
if
(
size
<
0
)
{
errno
=
EINVAL
;
return
posix_error
();
...
...
@@ -5820,7 +6266,7 @@ posix_read(PyObject *self, PyObject *args)
return
posix_error
();
}
Py_BEGIN_ALLOW_THREADS
n
=
read
(
fd
,
PyBytes_AS_STRING
(
buffer
),
size
);
n
=
pread
(
fd
,
PyBytes_AS_STRING
(
buffer
),
size
,
offset
);
Py_END_ALLOW_THREADS
if
(
n
<
0
)
{
Py_DECREF
(
buffer
);
...
...
@@ -5830,7 +6276,7 @@ posix_read(PyObject *self, PyObject *args)
_PyBytes_Resize
(
&
buffer
,
n
);
return
buffer
;
}
#endif
PyDoc_STRVAR
(
posix_write__doc__
,
"write(fd, string) -> byteswritten
\n\n
\
...
...
@@ -5866,57 +6312,6 @@ posix_write(PyObject *self, PyObject *args)
}
#ifdef HAVE_SENDFILE
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
static
Py_ssize_t
iov_setup
(
struct
iovec
**
iov
,
Py_buffer
**
buf
,
PyObject
*
seq
,
int
cnt
,
int
type
)
{
int
i
,
j
;
Py_ssize_t
blen
,
total
=
0
;
*
iov
=
PyMem_New
(
struct
iovec
,
cnt
);
if
(
*
iov
==
NULL
)
{
PyErr_NoMemory
();
return
total
;
}
*
buf
=
PyMem_New
(
Py_buffer
,
cnt
);
if
(
*
buf
==
NULL
)
{
PyMem_Del
(
*
iov
);
PyErr_NoMemory
();
return
total
;
}
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
if
(
PyObject_GetBuffer
(
PySequence_GetItem
(
seq
,
i
),
&
(
*
buf
)[
i
],
type
)
==
-
1
)
{
PyMem_Del
(
*
iov
);
for
(
j
=
0
;
j
<
i
;
j
++
)
{
PyBuffer_Release
(
&
(
*
buf
)[
j
]);
}
PyMem_Del
(
*
buf
);
total
=
0
;
return
total
;
}
(
*
iov
)[
i
].
iov_base
=
(
*
buf
)[
i
].
buf
;
blen
=
(
*
buf
)[
i
].
len
;
(
*
iov
)[
i
].
iov_len
=
blen
;
total
+=
blen
;
}
return
total
;
}
static
void
iov_cleanup
(
struct
iovec
*
iov
,
Py_buffer
*
buf
,
int
cnt
)
{
int
i
;
PyMem_Del
(
iov
);
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
PyBuffer_Release
(
&
buf
[
i
]);
}
PyMem_Del
(
buf
);
}
#endif
PyDoc_STRVAR
(
posix_sendfile__doc__
,
"sendfile(out, in, offset, nbytes) -> byteswritten
\n
\
sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)
\n
\
...
...
@@ -6150,6 +6545,73 @@ posix_pipe(PyObject *self, PyObject *noargs)
}
#endif
/* HAVE_PIPE */
#ifdef HAVE_WRITEV
PyDoc_STRVAR
(
posix_writev__doc__
,
"writev(fd, buffers) -> byteswritten
\n\n
\
Write the contents of buffers to a file descriptor, where buffers is an
\n
\
arbitrary sequence of buffers.
\n
\
Returns the total bytes written."
);
static
PyObject
*
posix_writev
(
PyObject
*
self
,
PyObject
*
args
)
{
int
fd
,
cnt
;
Py_ssize_t
res
;
PyObject
*
seq
;
struct
iovec
*
iov
;
Py_buffer
*
buf
;
if
(
!
PyArg_ParseTuple
(
args
,
"iO:writev"
,
&
fd
,
&
seq
))
return
NULL
;
if
(
!
PySequence_Check
(
seq
))
{
PyErr_SetString
(
PyExc_TypeError
,
"writev() arg 2 must be a sequence"
);
return
NULL
;
}
cnt
=
PySequence_Size
(
seq
);
if
(
!
iov_setup
(
&
iov
,
&
buf
,
seq
,
cnt
,
PyBUF_SIMPLE
))
{
return
NULL
;
}
Py_BEGIN_ALLOW_THREADS
res
=
writev
(
fd
,
iov
,
cnt
);
Py_END_ALLOW_THREADS
iov_cleanup
(
iov
,
buf
,
cnt
);
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
;
if
(
!
PyArg_ParseTuple
(
args
,
"iy*O&:pwrite"
,
&
fd
,
&
pbuf
,
_parse_off_t
,
&
offset
))
return
NULL
;
if
(
!
_PyVerify_fd
(
fd
))
{
PyBuffer_Release
(
&
pbuf
);
return
posix_error
();
}
Py_BEGIN_ALLOW_THREADS
size
=
pwrite
(
fd
,
pbuf
.
buf
,
(
size_t
)
pbuf
.
len
,
offset
);
Py_END_ALLOW_THREADS
PyBuffer_Release
(
&
pbuf
);
if
(
size
<
0
)
return
posix_error
();
return
PyLong_FromSsize_t
(
size
);
}
#endif
#ifdef HAVE_MKFIFO
PyDoc_STRVAR
(
posix_mkfifo__doc__
,
...
...
@@ -6266,18 +6728,8 @@ posix_ftruncate(PyObject *self, PyObject *args)
int
fd
;
off_t
length
;
int
res
;
PyObject
*
lenobj
;
if
(
!
PyArg_ParseTuple
(
args
,
"iO:ftruncate"
,
&
fd
,
&
lenobj
))
return
NULL
;
#if !defined(HAVE_LARGEFILE_SUPPORT)
length
=
PyLong_AsLong
(
lenobj
);
#else
length
=
PyLong_Check
(
lenobj
)
?
PyLong_AsLongLong
(
lenobj
)
:
PyLong_AsLong
(
lenobj
);
#endif
if
(
PyErr_Occurred
())
if
(
!
PyArg_ParseTuple
(
args
,
"iO&:ftruncate"
,
&
fd
,
_parse_off_t
,
&
length
))
return
NULL
;
Py_BEGIN_ALLOW_THREADS
...
...
@@ -6290,6 +6742,93 @@ posix_ftruncate(PyObject *self, PyObject *args)
}
#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
;
const
char
*
path
;
off_t
length
;
int
res
;
if
(
!
PyArg_ParseTuple
(
args
,
"O&O&:truncate"
,
PyUnicode_FSConverter
,
&
opath
,
_parse_off_t
,
&
length
))
return
NULL
;
path
=
PyBytes_AsString
(
opath
);
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
;
if
(
!
PyArg_ParseTuple
(
args
,
"iO&O&:posix_fallocate"
,
&
fd
,
_parse_off_t
,
&
offset
,
_parse_off_t
,
&
len
))
return
NULL
;
Py_BEGIN_ALLOW_THREADS
res
=
posix_fallocate
(
fd
,
offset
,
len
);
Py_END_ALLOW_THREADS
if
(
res
!=
0
)
{
errno
=
res
;
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
,
"iO&O&i:posix_fadvise"
,
&
fd
,
_parse_off_t
,
&
offset
,
_parse_off_t
,
&
len
,
&
advice
))
return
NULL
;
Py_BEGIN_ALLOW_THREADS
res
=
posix_fadvise
(
fd
,
offset
,
len
,
advice
);
Py_END_ALLOW_THREADS
if
(
res
!=
0
)
{
errno
=
res
;
return
posix_error
();
}
Py_RETURN_NONE
;
}
#endif
#ifdef HAVE_PUTENV
PyDoc_STRVAR
(
posix_putenv__doc__
,
"putenv(key, value)
\n\n
\
...
...
@@ -8725,6 +9264,15 @@ static PyMethodDef posix_methods[] = {
{
"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 */
...
...
@@ -8733,6 +9281,9 @@ static PyMethodDef posix_methods[] = {
{
"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__
},
...
...
@@ -8831,6 +9382,9 @@ static PyMethodDef posix_methods[] = {
#ifdef HAVE_WAIT4
{
"wait4"
,
posix_wait4
,
METH_VARARGS
,
posix_wait4__doc__
},
#endif
/* HAVE_WAIT4 */
#if defined(HAVE_WAITID) && !defined(__APPLE__)
{
"waitid"
,
posix_waitid
,
METH_VARARGS
,
posix_waitid__doc__
},
#endif
#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
{
"waitpid"
,
posix_waitpid
,
METH_VARARGS
,
posix_waitpid__doc__
},
#endif
/* HAVE_WAITPID */
...
...
@@ -8855,9 +9409,24 @@ static PyMethodDef posix_methods[] = {
{
"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
#ifdef HAVE_SENDFILE
{
"sendfile"
,
(
PyCFunction
)
posix_sendfile
,
METH_VARARGS
|
METH_KEYWORDS
,
posix_sendfile__doc__
},
...
...
@@ -8881,6 +9450,15 @@ static PyMethodDef posix_methods[] = {
#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
...
...
@@ -8894,6 +9472,9 @@ static PyMethodDef posix_methods[] = {
#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
...
...
@@ -9342,6 +9923,76 @@ all_ins(PyObject *d)
if
(
ins
(
d
,
"SF_SYNC"
,
(
long
)
SF_SYNC
))
return
-
1
;
#endif
/* 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
#ifdef CLD_EXITED
if
(
ins
(
d
,
"CLD_EXITED"
,
(
long
)
CLD_EXITED
))
return
-
1
;
#endif
#ifdef CLD_DUMPED
if
(
ins
(
d
,
"CLD_DUMPED"
,
(
long
)
CLD_DUMPED
))
return
-
1
;
#endif
#ifdef CLD_TRAPPED
if
(
ins
(
d
,
"CLD_TRAPPED"
,
(
long
)
CLD_TRAPPED
))
return
-
1
;
#endif
#ifdef CLD_CONTINUED
if
(
ins
(
d
,
"CLD_CONTINUED"
,
(
long
)
CLD_CONTINUED
))
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
;
...
...
@@ -9441,6 +10092,11 @@ INITFUNC(void)
#endif
if
(
!
initialized
)
{
#if defined(HAVE_WAITID) && !defined(__APPLE__)
waitid_result_desc
.
name
=
MODNAME
".waitid_result"
;
PyStructSequence_InitType
(
&
WaitidResultType
,
&
waitid_result_desc
);
#endif
stat_result_desc
.
name
=
MODNAME
".stat_result"
;
stat_result_desc
.
fields
[
7
].
name
=
PyStructSequence_UnnamedField
;
stat_result_desc
.
fields
[
8
].
name
=
PyStructSequence_UnnamedField
;
...
...
@@ -9461,6 +10117,10 @@ INITFUNC(void)
# endif
#endif
}
#if defined(HAVE_WAITID) && !defined(__APPLE__)
Py_INCREF
((
PyObject
*
)
&
WaitidResultType
);
PyModule_AddObject
(
m
,
"waitid_result"
,
(
PyObject
*
)
&
WaitidResultType
);
#endif
Py_INCREF
((
PyObject
*
)
&
StatResultType
);
PyModule_AddObject
(
m
,
"stat_result"
,
(
PyObject
*
)
&
StatResultType
);
Py_INCREF
((
PyObject
*
)
&
StatVFSResultType
);
...
...
configure
View file @
7807c354
...
...
@@ -776,8 +776,7 @@ CFLAGS
LDFLAGS
LIBS
CPPFLAGS
CPP
CPPFLAGS'
CPP'
# Initialize some variables set by options.
...
...
@@ -9251,19 +9250,21 @@ $as_echo "MACHDEP_OBJS" >&6; }
# checks for library functions
for
ac_func
in
alarm accept4 setitimer getitimer bind_textdomain_codeset
chown
\
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat
\
fdopendir fork fpathconf fstatat ftime ftruncate futimesat
\
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat
\
futimens futimes
\
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid
\
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd
\
initgroups
kill
killpg lchmod lchown l
inkat lstat
mbrtowc mkdirat
mkfifo
\
initgroups
kill
killpg lchmod lchown l
ockf linkat lstat lutimes
mbrtowc mkdirat
mkfifo
\
mkfifoat
mknod
mknodat mktime mremap
nice
openat pathconf pause plock poll
\
pthread_init putenv
readlink
readlinkat
realpath
renameat
\
posix_fallocate posix_fadvise pread
\
pthread_init putenv pwrite
readlink
readlinkat readv
realpath
renameat
\
select
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid
\
setgid sethostname
\
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf
\
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat
\
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat
sync
\
sysconf tcgetpgrp tcsetpgrp tempnam timegm
times
tmpfile tmpnam tmpnam_r
\
truncate uname
unlinkat unsetenv utimensat utimes waitpid wait3 wait4
\
wcscoll wcsftime wcsxfrm _getpty
truncate uname
unlinkat unsetenv utimensat utimes wait
id wait
pid 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
"
...
...
configure.in
View file @
7807c354
...
...
@@ -2496,19 +2496,21 @@ AC_MSG_RESULT(MACHDEP_OBJS)
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \
fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes \
gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
initgroups kill killpg lchmod lchown l
inkat lstat
mbrtowc mkdirat mkfifo \
initgroups kill killpg lchmod lchown l
ockf linkat lstat lutimes
mbrtowc mkdirat mkfifo \
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
pthread_init putenv readlink readlinkat realpath renameat \
posix_fallocate posix_fadvise pread \
pthread_init putenv pwrite readlink readlinkat readv realpath renameat \
select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
setgid sethostname \
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat \
sigaction siginterrupt sigrelse snprintf strftime strlcpy symlinkat
sync
\
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
truncate uname unlinkat unsetenv utimensat utimes waitpid wait3 wait4 \
wcscoll wcsftime wcsxfrm _getpty)
truncate uname unlinkat unsetenv utimensat utimes wait
id wait
pid wait3 wait4 \
wcscoll wcsftime wcsxfrm
writev
_getpty)
# For some functions, having a definition is not sufficient, since
# we want to take their address.
...
...
pyconfig.h.in
View file @
7807c354
...
...
@@ -232,6 +232,9 @@
/* Define to 1 if you have the `fdopendir' function. */
#undef HAVE_FDOPENDIR
/* Define to 1 if you have the `fexecve' function. */
#undef HAVE_FEXECVE
/* Define to 1 if you have the `finite' function. */
#undef HAVE_FINITE
...
...
@@ -274,6 +277,12 @@
/* Define to 1 if you have the `ftruncate' function. */
#undef HAVE_FTRUNCATE
/* Define to 1 if you have the `futimens' function. */
#undef HAVE_FUTIMENS
/* Define to 1 if you have the `futimes' function. */
#undef HAVE_FUTIMES
/* Define to 1 if you have the `futimesat' function. */
#undef HAVE_FUTIMESAT
...
...
@@ -461,6 +470,9 @@
/* Define to 1 if you have the <linux/tipc.h> header file. */
#undef HAVE_LINUX_TIPC_H
/* Define to 1 if you have the `lockf' function. */
#undef HAVE_LOCKF
/* Define to 1 if you have the `log1p' function. */
#undef HAVE_LOG1P
...
...
@@ -473,6 +485,9 @@
/* Define to 1 if you have the `lstat' function. */
#undef HAVE_LSTAT
/* Define to 1 if you have the `lutimes' function. */
#undef HAVE_LUTIMES
/* Define this if you have the makedev macro. */
#undef HAVE_MAKEDEV
...
...
@@ -545,6 +560,15 @@
/* Define to 1 if you have the <poll.h> header file. */
#undef HAVE_POLL_H
/* Define to 1 if you have the `posix_fadvise' function. */
#undef HAVE_POSIX_FADVISE
/* Define to 1 if you have the `posix_fallocate' function. */
#undef HAVE_POSIX_FALLOCATE
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
/* Define to 1 if you have the <process.h> header file. */
#undef HAVE_PROCESS_H
...
...
@@ -569,12 +593,18 @@
/* Define to 1 if you have the `putenv' function. */
#undef HAVE_PUTENV
/* Define to 1 if you have the `pwrite' function. */
#undef HAVE_PWRITE
/* Define to 1 if you have the `readlink' function. */
#undef HAVE_READLINK
/* Define to 1 if you have the `readlinkat' function. */
#undef HAVE_READLINKAT
/* Define to 1 if you have the `readv' function. */
#undef HAVE_READV
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
...
...
@@ -775,6 +805,9 @@
/* Define to 1 if you have the `symlinkat' function. */
#undef HAVE_SYMLINKAT
/* Define to 1 if you have the `sync' function. */
#undef HAVE_SYNC
/* Define to 1 if you have the `sysconf' function. */
#undef HAVE_SYSCONF
...
...
@@ -952,6 +985,9 @@
/* Define to 1 if you have the `wait4' function. */
#undef HAVE_WAIT4
/* Define to 1 if you have the `waitid' function. */
#undef HAVE_WAITID
/* Define to 1 if you have the `waitpid' function. */
#undef HAVE_WAITPID
...
...
@@ -971,6 +1007,9 @@
*/
#undef HAVE_WORKING_TZSET
/* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV
/* Define if the zlib library has inflateCopy */
#undef HAVE_ZLIB_COPY
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment