return NULL;
#endif
+ buf = cwd = NULL;
Py_BEGIN_ALLOW_THREADS
- res = getcwd(buf, sizeof buf);
+ do {
+ buflen += chunk;
+ tmpbuf = PyMem_RawRealloc(buf, buflen);
+ if (tmpbuf == NULL)
+ break;
+
+ buf = tmpbuf;
+ cwd = getcwd(buf, buflen);
+ } while (cwd == NULL && errno == ERANGE);
Py_END_ALLOW_THREADS
- if (res == NULL)
+
+ if (cwd == NULL) {
+ PyMem_RawFree(buf);
return posix_error();
+ }
+
if (use_bytes)
- return PyBytes_FromStringAndSize(buf, strlen(buf));
- return PyUnicode_DecodeFSDefault(buf);
+ obj = PyBytes_FromStringAndSize(buf, strlen(buf));
+ else
+ obj = PyUnicode_DecodeFSDefault(buf);
+ PyMem_RawFree(buf);
+
+ return obj;
}
-PyDoc_STRVAR(posix_getcwd__doc__,
-"getcwd() -> path\n\n\
-Return a unicode string representing the current working directory.");
+
+/*[clinic input]
+os.getcwd
+
+Return a unicode string representing the current working directory.
+[clinic start generated code]*/
static PyObject *
-posix_getcwd_unicode(PyObject *self)
+os_getcwd_impl(PyModuleDef *module)
+/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/
{
return posix_getcwd(0);
}
}
#endif /* HAVE_PIPE2 */
+
#ifdef HAVE_WRITEV
-PyDoc_STRVAR(posix_writev__doc__,
-"writev(fd, buffers) -> byteswritten\n\n\
-Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\
-must be a sequence of bytes-like objects.\n\n\
-writev writes the contents of each object to the file descriptor\n\
-and returns the total number of bytes written.");
+/*[clinic input]
+os.writev -> Py_ssize_t
+ fd: int
+ buffers: object
+ /
-static PyObject *
-posix_writev(PyObject *self, PyObject *args)
+Iterate over buffers, and write the contents of each to a file descriptor.
+
+Returns the total number of bytes written.
+buffers must be a sequence of bytes-like objects.
+[clinic start generated code]*/
+
+static Py_ssize_t
+os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
+/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
{
- int fd, cnt;
- Py_ssize_t res;
- PyObject *seq;
+ int cnt;
+ Py_ssize_t result;
+ int async_err = 0;
struct iovec *iov;
Py_buffer *buf;
- if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
- return NULL;
- if (!PySequence_Check(seq)) {
+
+ if (!PySequence_Check(buffers)) {
PyErr_SetString(PyExc_TypeError,
"writev() arg 2 must be a sequence");
- return NULL;
+ return -1;
}
- cnt = PySequence_Size(seq);
+ cnt = PySequence_Size(buffers);
- if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
- return NULL;
+ if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
+ return -1;
}
- Py_BEGIN_ALLOW_THREADS
- res = writev(fd, iov, cnt);
- Py_END_ALLOW_THREADS
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ result = writev(fd, iov, cnt);
+ Py_END_ALLOW_THREADS
+ } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
iov_cleanup(iov, buf, cnt);
- if (res < 0)
- return posix_error();
+ if (result < 0 && !async_err)
+ posix_error();
- return PyLong_FromSsize_t(res);
+ return result;
}
-#endif
+#endif /* HAVE_WRITEV */
+
#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.");
+/*[clinic input]
+os.pwrite -> Py_ssize_t
-static PyObject *
-posix_pwrite(PyObject *self, PyObject *args)
+ fd: int
+ buffer: Py_buffer
+ offset: Py_off_t
+ /
+
+Write bytes to a file descriptor starting at a particular offset.
+
+Write buffer to fd, starting at offset bytes from the beginning of
+the file. Returns the number of bytes writte. Does not change the
+current file offset.
+[clinic start generated code]*/
+
+static Py_ssize_t
+os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer,
+ Py_off_t offset)
+/*[clinic end generated code: output=93aabdb40e17d325 input=19903f1b3dd26377]*/
{
- 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;
+ int async_err = 0;
if (!_PyVerify_fd(fd)) {
- PyBuffer_Release(&pbuf);
- return posix_error();
+ posix_error();
+ return -1;
}
- 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);
+
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ _Py_BEGIN_SUPPRESS_IPH
+ size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
+ _Py_END_SUPPRESS_IPH
+ Py_END_ALLOW_THREADS
+ } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
+
+ if (size < 0 && !async_err)
+ posix_error();
+ return size;
}
-#endif
+#endif /* HAVE_PWRITE */
+
#ifdef HAVE_MKFIFO
-PyDoc_STRVAR(posix_mkfifo__doc__,
-"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
-Create a FIFO (a POSIX named pipe).\n\
-\n\
-If dir_fd is not None, it should be a file descriptor open to a directory,\n\
- and path should be relative; path will then be relative to that directory.\n\
-dir_fd may not be implemented on your platform.\n\
- If it is unavailable, using it will raise a NotImplementedError.");
+/*[clinic input]
+os.mkfifo
+
+ path: path_t
+ mode: int=0o666
+ *
+ dir_fd: dir_fd(requires='mkfifoat')=None
+
+Create a "fifo" (a POSIX named pipe).
+
+If dir_fd is not None, it should be a file descriptor open to a directory,
+ and path should be relative; path will then be relative to that directory.
+dir_fd may not be implemented on your platform.
+ If it is unavailable, using it will raise a NotImplementedError.
+[clinic start generated code]*/
static PyObject *
-posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
+os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
+/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
{
- path_t path;
- int mode = 0666;
- int dir_fd = DEFAULT_DIR_FD;
int result;
- PyObject *return_value = NULL;
- static char *keywords[] = {"path", "mode", "dir_fd", NULL};
+ int async_err = 0;
- memset(&path, 0, sizeof(path));
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
- path_converter, &path,
- &mode,
+ do {
+ Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_MKFIFOAT
- dir_fd_converter, &dir_fd
-#else
- dir_fd_unavailable, &dir_fd
+ if (dir_fd != DEFAULT_DIR_FD)
+ result = mkfifoat(dir_fd, path->narrow, mode);
+ else
#endif
- ))
- return NULL;
+ result = mkfifo(path->narrow, mode);
+ Py_END_ALLOW_THREADS
+ } while (result != 0 && errno == EINTR &&
+ !(async_err = PyErr_CheckSignals()));
+ if (result != 0)
+ return (!async_err) ? posix_error() : NULL;
- Py_BEGIN_ALLOW_THREADS
-#ifdef HAVE_MKFIFOAT
- if (dir_fd != DEFAULT_DIR_FD)
- result = mkfifoat(dir_fd, path.narrow, mode);
- else
-#endif
- result = mkfifo(path.narrow, mode);
- Py_END_ALLOW_THREADS
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_MKFIFO */
- if (result < 0) {
- return_value = posix_error();
- goto exit;
- }
- return_value = Py_None;
- Py_INCREF(Py_None);
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
+/*[clinic input]
+os.mknod
-exit:
- path_cleanup(&path);
- return return_value;
-}
-#endif
+ path: path_t
+ mode: int=0o600
+ device: dev_t=0
+ *
+ dir_fd: dir_fd(requires='mknodat')=None
-#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
-PyDoc_STRVAR(posix_mknod__doc__,
-"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
-Create a filesystem node (file, device special file or named pipe)\n\
-named filename. mode specifies both the permissions to use and the\n\
-type of node to be created, being combined (bitwise OR) with one of\n\
-S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
-device defines the newly created device special file (probably using\n\
-os.makedev()), otherwise it is ignored.\n\
-\n\
-If dir_fd is not None, it should be a file descriptor open to a directory,\n\
- and path should be relative; path will then be relative to that directory.\n\
-dir_fd may not be implemented on your platform.\n\
- If it is unavailable, using it will raise a NotImplementedError.");
+Create a node in the file system.
+
+Create a node in the file system (file, device special file or named pipe)
+at path. mode specifies both the permissions to use and the
+type of node to be created, being combined (bitwise OR) with one of
+S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
+device defines the newly created device special file (probably using
+os.makedev()). Otherwise device is ignored.
+If dir_fd is not None, it should be a file descriptor open to a directory,
+ and path should be relative; path will then be relative to that directory.
+dir_fd may not be implemented on your platform.
+ If it is unavailable, using it will raise a NotImplementedError.
+[clinic start generated code]*/
static PyObject *
-posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
+os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device,
+ int dir_fd)
+/*[clinic end generated code: output=5151a8a9f754d272 input=ee44531551a4d83b]*/
{
- path_t path;
- int mode = 0666;
- dev_t device = 0;
- int dir_fd = DEFAULT_DIR_FD;
int result;
- PyObject *return_value = NULL;
- static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
+ int async_err = 0;
- memset(&path, 0, sizeof(path));
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords,
- path_converter, &path,
- &mode, _Py_Dev_Converter, &device,
+ do {
+ Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_MKNODAT
- dir_fd_converter, &dir_fd
-#else
- dir_fd_unavailable, &dir_fd
+ if (dir_fd != DEFAULT_DIR_FD)
+ result = mknodat(dir_fd, path->narrow, mode, device);
+ else
#endif
- ))
- return NULL;
+ result = mknod(path->narrow, mode, device);
+ Py_END_ALLOW_THREADS
+ } while (result != 0 && errno == EINTR &&
+ !(async_err = PyErr_CheckSignals()));
+ if (result != 0)
+ return (!async_err) ? posix_error() : NULL;
- Py_BEGIN_ALLOW_THREADS
-#ifdef HAVE_MKNODAT
- if (dir_fd != DEFAULT_DIR_FD)
- result = mknodat(dir_fd, path.narrow, mode, device);
- else
-#endif
- result = mknod(path.narrow, mode, device);
- Py_END_ALLOW_THREADS
+ Py_RETURN_NONE;
+}
+#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
- if (result < 0) {
- return_value = posix_error();
- goto exit;
- }
- return_value = Py_None;
- Py_INCREF(Py_None);
+#ifdef HAVE_DEVICE_MACROS
+/*[clinic input]
+os.major -> unsigned_int
-exit:
- path_cleanup(&path);
- return return_value;
-}
-#endif
+ device: dev_t
+ /
-#ifdef HAVE_DEVICE_MACROS
-PyDoc_STRVAR(posix_major__doc__,
-"major(device) -> major number\n\
-Extracts a device major number from a raw device number.");
+Extracts a device major number from a raw device number.
+[clinic start generated code]*/
-static PyObject *
-posix_major(PyObject *self, PyObject *args)
+static unsigned int
+os_major_impl(PyModuleDef *module, dev_t device)
+/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
{
- dev_t device;
- if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
- return NULL;
- return PyLong_FromLong((long)major(device));
+ return major(device);
}
-PyDoc_STRVAR(posix_minor__doc__,
-"minor(device) -> minor number\n\
-Extracts a device minor number from a raw device number.");
-static PyObject *
-posix_minor(PyObject *self, PyObject *args)
+/*[clinic input]
+os.minor -> unsigned_int
+
+ device: dev_t
+ /
+
+Extracts a device minor number from a raw device number.
+[clinic start generated code]*/
+
+static unsigned int
+os_minor_impl(PyModuleDef *module, dev_t device)
+/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
{
- dev_t device;
- if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
- return NULL;
- return PyLong_FromLong((long)minor(device));
+ return minor(device);
}
-PyDoc_STRVAR(posix_makedev__doc__,
-"makedev(major, minor) -> device number\n\
-Composes a raw device number from the major and minor device numbers.");
-static PyObject *
-posix_makedev(PyObject *self, PyObject *args)
+/*[clinic input]
+os.makedev -> dev_t
+
+ major: int
+ minor: int
+ /
+
+Composes a raw device number from the major and minor device numbers.
+[clinic start generated code]*/
+
+static dev_t
+os_makedev_impl(PyModuleDef *module, int major, int minor)
+/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
{
- int major, minor;
- if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
- return NULL;
- return _PyLong_FromDev(makedev(major, minor));
+ return makedev(major, minor);
}
-#endif /* device macros */
+#endif /* HAVE_DEVICE_MACROS */
-#ifdef HAVE_FTRUNCATE
-PyDoc_STRVAR(posix_ftruncate__doc__,
-"ftruncate(fd, length)\n\n\
-Truncate a file to a specified length.");
+#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
+/*[clinic input]
+os.ftruncate
+
+ fd: int
+ length: Py_off_t
+ /
+
+Truncate a file, specified by file descriptor, to a specific length.
+[clinic start generated code]*/
static PyObject *
-posix_ftruncate(PyObject *self, PyObject *args)
+os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
+/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
{
- int fd;
- off_t length;
- int res;
-
- if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
- return NULL;
+ int result;
+ int async_err = 0;
- Py_BEGIN_ALLOW_THREADS
- res = ftruncate(fd, length);
- Py_END_ALLOW_THREADS
- if (res < 0)
+ if (!_PyVerify_fd(fd))
return posix_error();
- Py_INCREF(Py_None);
- return Py_None;
-}
+
+ do {
+ Py_BEGIN_ALLOW_THREADS
+ _Py_BEGIN_SUPPRESS_IPH
+#ifdef MS_WINDOWS
+ result = _chsize_s(fd, length);
+#else
+ result = ftruncate(fd, length);
#endif
+ _Py_END_SUPPRESS_IPH
+ Py_END_ALLOW_THREADS
+ } while (result != 0 && errno == EINTR &&
+ !(async_err = PyErr_CheckSignals()));
+ if (result != 0)
+ return (!async_err) ? posix_error() : NULL;
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
+
+
+#if defined HAVE_TRUNCATE || defined MS_WINDOWS
+/*[clinic input]
+os.truncate
+ path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
+ length: Py_off_t
+
+Truncate a file, specified by path, to a specific length.
-#ifdef HAVE_TRUNCATE
-PyDoc_STRVAR(posix_truncate__doc__,
-"truncate(path, length)\n\n\
-Truncate the file given by path to length bytes.\n\
-On some platforms, path may also be specified as an open file descriptor.\n\
- If this functionality is unavailable, using it raises an exception.");
+On some platforms, path may also be specified as an open file descriptor.
+ If this functionality is unavailable, using it raises an exception.
+[clinic start generated code]*/
static PyObject *
-posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
+os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
+/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
{
- path_t path;
- off_t length;
- int res;
- PyObject *result = NULL;
- static char *keywords[] = {"path", "length", NULL};
-
- memset(&path, 0, sizeof(path));
- path.function_name = "truncate";
-#ifdef HAVE_FTRUNCATE
- path.allow_fd = 1;
+ int result;
+#ifdef MS_WINDOWS
+ int fd;
#endif
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
- path_converter, &path,
- _parse_off_t, &length))
- return NULL;
+
+ if (path->fd != -1)
+ return os_ftruncate_impl(module, path->fd, length);
Py_BEGIN_ALLOW_THREADS
-#ifdef HAVE_FTRUNCATE
- if (path.fd != -1)
- res = ftruncate(path.fd, length);
+ _Py_BEGIN_SUPPRESS_IPH
+#ifdef MS_WINDOWS
+ if (path->wide)
+ fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
else
-#endif
- res = truncate(path.narrow, length);
- Py_END_ALLOW_THREADS
- if (res < 0)
- result = path_error(&path);
+ fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
- if (fd < 0)
++ if (fd < 0)
+ result = -1;
else {
- Py_INCREF(Py_None);
- result = Py_None;
+ result = _chsize_s(fd, length);
+ close(fd);
+ if (result < 0)
+ errno = result;
}
- path_cleanup(&path);
- return result;
-}
+#else
+ result = truncate(path->narrow, length);
#endif
+ _Py_END_SUPPRESS_IPH
+ Py_END_ALLOW_THREADS
+ if (result < 0)
+ return path_error(path);
-/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
- and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
- defined, which is the case in Python on AIX. AIX bug report:
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_TRUNCATE || MS_WINDOWS */
+
+
+/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
+ and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
+ defined, which is the case in Python on AIX. AIX bug report:
http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
# define POSIX_FADVISE_AIX_BUG