diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 5217037ae9d812..1686695300acb8 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2580,6 +2580,14 @@ def test_ftruncate(self): def test_lseek(self): self.check(os.lseek, 0, 0) + @unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()') + @unittest.skipUnless(hasattr(os, 'pipe'), "need os.pipe()") + def test_lseek_on_pipe(self): + rfd, wfd = os.pipe() + self.addCleanup(os.close, rfd) + self.addCleanup(os.close, wfd) + self.assertRaises(OSError, os.lseek, rfd, 123, os.SEEK_END) + @unittest.skipUnless(hasattr(os, 'read'), 'test needs os.read()') def test_read(self): self.check(os.read, 1) diff --git a/Misc/NEWS.d/next/Windows/2025-04-29-17-55-55.gh-issue-86768.uIDTHc.rst b/Misc/NEWS.d/next/Windows/2025-04-29-17-55-55.gh-issue-86768.uIDTHc.rst new file mode 100644 index 00000000000000..6f02f60dc092a7 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2025-04-29-17-55-55.gh-issue-86768.uIDTHc.rst @@ -0,0 +1,2 @@ +:exc:`OSError` will be raised if call :func:`os.lseek` with non seekable +object on Windows. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b570f81b7cf7c2..bf62d826394fa0 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -11433,7 +11433,7 @@ static Py_off_t os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) /*[clinic end generated code: output=971e1efb6b30bd2f input=f096e754c5367504]*/ { - Py_off_t result; + Py_off_t result = -1; #ifdef SEEK_SET /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ @@ -11447,14 +11447,23 @@ os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS - result = _lseeki64(fd, position, how); + HANDLE h = (HANDLE)_get_osfhandle(fd); + if (h != INVALID_HANDLE_VALUE) { + if (GetFileType(h) == FILE_TYPE_DISK) { + result = _lseeki64(fd, position, how); + } else { + // Only file is seekable + errno = ESPIPE; + } + } #else result = lseek(fd, position, how); #endif _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS - if (result < 0) + if (result < 0) { posix_error(); + } return result; }