Skip to content

Commit 1c04774

Browse files
stephanelsmithdpgeorge
authored andcommitted
extmod/vfs_posix_file: Fix flush handling on macOS.
On macOS, if running micropython from subprocess.check_output, then a stdout.flush() raises error 45. Here's a test case. This will run fine on linux, but crashes on macOS with error 45. import sys import subprocess import tempfile with tempfile.NamedTemporaryFile('w') as fp: fp.write(''' import sys sys.stdout.write('hello world') sys.stdout.flush() print('') ''') fp.flush() print('py3') o = subprocess.check_output(f'python3 {fp.name}'.split()) print(o) print('upy') o = subprocess.check_output(f'micropython {fp.name}'.split()) print(o) On macOS: py3 b'hello world\n' upy Traceback (most recent call last): File "...", line 4, in <module> OSError: 45 On unix: py3 b'hello world\n' upy b'hello world\n' Signed-off-by: stephanelsmith <[email protected]>
1 parent 633599c commit 1c04774

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

extmod/vfs_posix_file.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,17 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
153153
switch (request) {
154154
case MP_STREAM_FLUSH: {
155155
int ret;
156+
// fsync(stdin/stdout/stderr) may fail with EINVAL (or ENOTSUP on macos),
157+
// but don't propagate that error out. Because data is not buffered by
158+
// us, and stdin/out/err.flush() should just be a no-op.
159+
#ifdef __APPLE__
160+
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == ENOTSUP)
161+
#else
162+
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL)
163+
#endif
156164
MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), {
157-
if (err == EINVAL
165+
if (VFS_POSIX_STREAM_STDIO_ERR_CATCH
158166
&& (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) {
159-
// fsync(stdin/stdout/stderr) may fail with EINVAL, but don't propagate that
160-
// error out. Because data is not buffered by us, and stdin/out/err.flush()
161-
// should just be a no-op.
162167
return 0;
163168
}
164169
*errcode = err;

0 commit comments

Comments
 (0)