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 <stephane.smith@titansensor.com>
This commit is contained in:
parent
633599cdd5
commit
1c047742a2
|
@ -153,12 +153,17 @@ STATIC mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
|
||||||
switch (request) {
|
switch (request) {
|
||||||
case MP_STREAM_FLUSH: {
|
case MP_STREAM_FLUSH: {
|
||||||
int ret;
|
int ret;
|
||||||
|
// fsync(stdin/stdout/stderr) may fail with EINVAL (or ENOTSUP on macos),
|
||||||
|
// but don't propagate that error out. Because data is not buffered by
|
||||||
|
// us, and stdin/out/err.flush() should just be a no-op.
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == ENOTSUP)
|
||||||
|
#else
|
||||||
|
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL)
|
||||||
|
#endif
|
||||||
MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), {
|
MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), {
|
||||||
if (err == EINVAL
|
if (VFS_POSIX_STREAM_STDIO_ERR_CATCH
|
||||||
&& (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) {
|
&& (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) {
|
||||||
// fsync(stdin/stdout/stderr) may fail with EINVAL, but don't propagate that
|
|
||||||
// error out. Because data is not buffered by us, and stdin/out/err.flush()
|
|
||||||
// should just be a no-op.
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*errcode = err;
|
*errcode = err;
|
||||||
|
|
Loading…
Reference in New Issue