Skip to content

Commit 6835743

Browse files
stinosdpgeorge
authored andcommitted
extmod/vfs_posix_file: Skip flush of tty handles in msvc debug builds.
In MSVC debug builds with debug error reporting set to showing a dialog (to allow attaching the debugger), any application which imports the logging module and leaves the default handlers would result in this dialog because logging.shutdown is called at exit and that flushes the default handler which has stderr as its stream. This commit fixes that by not fsync'ing stdin/out/err. Also adds a comment related to checking whether a file is stdin/out/err, which is difficult to fix properly. Signed-off-by: stijn <stijn@ignitron.net>
1 parent d50e36e commit 6835743

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

extmod/vfs_posix_file.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,27 @@ static mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
160160
#if defined(__APPLE__)
161161
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == ENOTSUP)
162162
#elif defined(_MSC_VER)
163+
// In debug builds fsync (i.e. _commit on windows) will generate a debug report via _ASSERTE when
164+
// called with non-redirected stdin/stdout/stderr (i.e. _isatty) handles because FlushFileBuffers,
165+
// which it calls internally, will fail since console output is not buffered.
166+
// In release builds it also fails, but merely returns an error which is handled appropriately below.
167+
// The check for the handle being stdin/stdout/stderr is added explicitly because according to
168+
// the documentation _isatty is also true for serial ports for instance.
169+
#ifdef _DEBUG
170+
if ((o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO) && _isatty(o->fd)) {
171+
return 0;
172+
}
173+
#endif
163174
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == EBADF)
164175
#else
165176
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL)
166177
#endif
167178
MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), {
168179
if (VFS_POSIX_STREAM_STDIO_ERR_CATCH
180+
// Note: comparing fd against the standard FILENOs is technically not correct, for example:
181+
// sys.stderr.close() in Python code results in close(STDERR_FILENO) here, but because
182+
// open() uses the next available file descriptor, opening an arbitrary file with
183+
// fd = open('/some/file') means that fd becomes STDERR_FILENO.
169184
&& (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) {
170185
return 0;
171186
}

0 commit comments

Comments
 (0)