Re: [PATCH] newlib - m68k-atari-elf: Correct handling of CRLF in stdio.

<[email protected]> Sat, 13 Jun 2026 15:18:08 +0200
Newsgroups gmane.comp.lib.newlib
Message-ID <1781356688222.7.178586@webmail-backend-production-7d585bcff8-pbhb7>
This is a multipart message in MIME format.

------------178584-1781356688222-1
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8

Bump.



Den torsdag 14 maj 2026 kl. 11:08:52 +02:00, skrev <[email protected]>:=


> Atari computers uses CRLF as line endings the same way Windows do.
> This patch enables text/binary mode for files and stdin/stdout/stderr str=
eams.
> It should work the same way as Cygwin do.
> This patch have been tested successfully by the Atari community since beg=
inning of March 2026.
> Reconfigure is needed.
>=20
> ---
> libgloss/m68k/Makefile.in | 2 +-
> libgloss/m68k/atari/atari-open.c | 37 +++++----
> libgloss/m68k/atari/atari-setmode.c | 74 ++++++++++++++++++
> libgloss/m68k/atari/atari-tos.ld | 2 +-
> libgloss/m68k/atari/atari-tos.specs | 3 +
> libgloss/m68k/atari/atari-write.c | 61 +--------------
> newlib/configure.host | 6 +-
> newlib/libc/acinclude.m4 | 1 +
> newlib/libc/stdio/flags.c | 2 +-
> newlib/libc/stdio/stdio.c | 4 +
> newlib/libc/sys/Makefile.inc | 3 +
> newlib/libc/sys/atari/Makefile.inc | 1 +
> newlib/libc/sys/atari/filemode.c | 94 +++++++++++++++++++++++
> newlib/libc/sys/atari/include/io.h | 30 ++++++++
> newlib/libc/sys/atari/include/sys/fcntl.h | 11 +++
> newlib/libc/sys/atari/include/sys/stdio.h | 33 ++++++++
> 16 files changed, 283 insertions(+), 81 deletions(-)
> create mode 100644 libgloss/m68k/atari/atari-setmode.c
> create mode 100644 newlib/libc/sys/atari/Makefile.inc
> create mode 100644 newlib/libc/sys/atari/filemode.c
> create mode 100644 newlib/libc/sys/atari/include/io.h
> create mode 100644 newlib/libc/sys/atari/include/sys/fcntl.h
> create mode 100644 newlib/libc/sys/atari/include/sys/stdio.h
>=20
> diff --git a/libgloss/m68k/Makefile.in b/libgloss/m68k/Makefile.in
> index b6d1868bc..43d716a2f 100644
> --- a/libgloss/m68k/Makefile.in
> +++ b/libgloss/m68k/Makefile.in
> @@ -216,7 +216,7 @@ ATARI_SRC_LIBGLOSS :=3D atari-environ.c atari-execve.=
c atari-link.c atari-times.c
> atari-sbrk.c atari-stat.c atari-unlink.c atari-write.c \
> atari-chown.c atari-fork.c atari-getentropy.c atari-gettod.c atari-readli=
nk.c \
> atari-symlink.c atari-chdir.c atari-getcwd.c atari-mkdir.c atari-rmdir.c =
\
> -	atari-rename.c
> +	atari-rename.c atari-setmode.c
>=20
> ATARI_OBJS_LIBGLOSS :=3D $(foreach source,$(ATARI_SRC_LIBGLOSS),$(basenam=
e $(source)).o)
>=20
> diff --git a/libgloss/m68k/atari/atari-open.c b/libgloss/m68k/atari/atari=
-open.c
> index c61071881..6c960b6a6 100644
> --- a/libgloss/m68k/atari/atari-open.c
> +++ b/libgloss/m68k/atari/atari-open.c
> @@ -5,27 +5,15 @@
>=20
> #include <unistd.h>
> #include <_ansi.h>
> +#include <fcntl.h>
> +#include <io.h>
> #include "atari-gem_errno.h"
> #include "atari-traps.h"
>=20
> -// I really don't like having these defines here,
> -// fcntl.h where they are, also defines a function for "open",
> -// that is different from the one libgloss is supposed to provide...
> -#ifndef O_CREAT
> -#define O_CREAT 0x0200
> -#endif // O_CREAT
> -#ifndef O_APPEND
> -#define O_APPEND 0x0008
> -#endif // O_APPEND
> -#ifndef O_EXCL
> -#define O_EXCL 0x0800
> -#endif // O_EXCL
> -#ifndef O_TRUNC
> -#define O_TRUNC 0x0400
> -#endif // O_TRUNC
> +extern int atari_get_fmode(int* mode);
> +extern int atari_setmode(short f, int mode);
>=20
> -// mode is ignored. Those kind of settings is not supported by the st.
> -int open(const char *buf, int flags, int mode)
> +int open(const char *buf, int flags, ...)
> {
> int bios_handle =3D -1;
> unsigned short bios_mode =3D (unsigned short)(flags & 0x3); // bits 0-1 t=
he same for st and linux.
> @@ -71,6 +59,21 @@ int open(const char *buf, int flags, int mode)
> gem_error_to_errno(bios_handle);
> bios_handle =3D -1;
> }
> +	else
> +	{
> + int fmode =3D flags & (O_TEXT | O_BINARY);
> + if (fmode =3D=3D 0)
> + {
> + // Initializes the correct default mode.
> + atari_get_fmode(&fmode);
> + }
> + if (atari_setmode((short)bios_handle, fmode) =3D=3D -1)
> + {
> + // Close file. errno is alredy set.
> + trap1_3e((unsigned short)bios_handle);
> + return -1;
> + }
> +	}
> /*
> If bios_handle is positive, then the low word is the gemdos handle, and t=
he high word is zero.
> */
> diff --git a/libgloss/m68k/atari/atari-setmode.c b/libgloss/m68k/atari/at=
ari-setmode.c
> new file mode 100644
> index 000000000..89fe7511f
> --- /dev/null
> +++ b/libgloss/m68k/atari/atari-setmode.c
> @@ -0,0 +1,74 @@
> +/*
> +	Copyright (C) 2026 Mikael Hildenborg
> +	SPDX-License-Identifier: BSD-2-Clause
> +*/
> +#include <unistd.h>
> +#include <_ansi.h>
> +#include <fcntl.h>
> +#include <io.h>
> +#include <errno.h>
> +
> +/*
> +	EmuTOS allows for a maximum of 75 open files, and ordinary TOS even les=
s.
> +	But MultiTOS and MagiC allows for much more, so to be safe we allow for=
 even more.
> +*/
> +#define MAX_FILE_DESCRIPTORS	256
> +#define FILE_MODE_SHIFT 16
> +
> +static int _fmode =3D O_TEXT;
> +
> +unsigned char file_descriptor_modes[MAX_FILE_DESCRIPTORS] =3D {0};
> +
> +int atari_set_fmode(int mode)
> +{
> +	_fmode =3D mode;
> +	return 0;
> +}
> +
> +int atari_get_fmode(int* mode)
> +{
> +	*mode =3D _fmode;
> +	return 0;
> +}
> +
> +int atari_getmode(short fd)
> +{
> +	if (fd < 0 || fd >=3D MAX_FILE_DESCRIPTORS)
> +	{
> + errno =3D EINVAL;
> + return -1;
> +	}
> +	int mode =3D ((int)file_descriptor_modes[fd]) << FILE_MODE_SHIFT;
> +	if (mode =3D=3D 0 && fd < 2)
> +	{
> + /*
> + stdin, stdout and stderr isn't opened and assumed to exist.
> + So the open function never gets the chance to set default mode for them=
.
> + That's why we do this check and return O_TEXT if nothing else is set.
> + */
> + mode =3D O_TEXT;
> +	}
> +	return mode;
> +}
> +
> +int atari_setmode(short fd, int mode)
> +{
> +	int oldMode =3D atari_getmode(fd);
> +	if (oldMode !=3D -1)
> +	{
> + // We cannot get here without having enough entries in the array.
> + file_descriptor_modes[fd] =3D (unsigned char)((mode & (O_TEXT | O_BINAR=
Y)) >> FILE_MODE_SHIFT);
> +	}
> +	return oldMode;
> +}
> +
> +int atari_istext_for_stdio (short fd)
> +{
> +	int mode =3D atari_getmode(fd);
> +	if (mode !=3D -1)
> +	{
> + // Treat anything else than binary mode as text mode.
> + return (mode & O_BINARY) =3D=3D 0 ? 1 : 0;
> +	}
> +	return 1;
> +}
> diff --git a/libgloss/m68k/atari/atari-tos.ld b/libgloss/m68k/atari/atari=
-tos.ld
> index 6bbecc261..a2f0b7625 100644
> --- a/libgloss/m68k/atari/atari-tos.ld
> +++ b/libgloss/m68k/atari/atari-tos.ld
> @@ -85,7 +85,7 @@ SECTIONS
> LONG(__BSS_SEGMENT__ - __DATA_SEGMENT__);	/* Length of the DATA segment *=
/
> LONG(__BSS_SEGMENT_END - __BSS_SEGMENT__);	/* Length of the BSS segment *=
/
> LONG(0); /* Length of the symbol table */
> - LONG(0); /* Reserved, should be 0 */
> + LONG(0x68e1f001); /* __M68K_ATARI_ELF__ signature */
> LONG(0); /* Program flags */
> SHORT(0); /* 0 =3D Relocation info present */
> }
> diff --git a/libgloss/m68k/atari/atari-tos.specs b/libgloss/m68k/atari/at=
ari-tos.specs
> index 02037132c..232afc3e8 100644
> --- a/libgloss/m68k/atari/atari-tos.specs
> +++ b/libgloss/m68k/atari/atari-tos.specs
> @@ -8,3 +8,6 @@
>=20
> *lib:
> + -latari-tos
> +
> +*cpp:
> ++ -D__M68K_ATARI_ELF__ -D__atari_os__
> diff --git a/libgloss/m68k/atari/atari-write.c b/libgloss/m68k/atari/atar=
i-write.c
> index 9d6e59ed8..eba45038b 100644
> --- a/libgloss/m68k/atari/atari-write.c
> +++ b/libgloss/m68k/atari/atari-write.c
> @@ -8,30 +8,6 @@
> #include "atari-gem_errno.h"
> #include "atari-traps.h"
>=20
> -const char* lineEnding =3D "\r\n";
> -
> -int writeUntilDoneOrError(int fd, size_t len, const char* buf)
> -{
> -	size_t written =3D 0;
> -	if (len =3D=3D 0)
> -	{
> - return 0;
> -	}
> -	do
> -	{
> - int n =3D trap1_40((unsigned short)fd, len, buf);
> - if (n < 0)
> - {
> - gem_error_to_errno(n);
> - return -1;
> - }
> - written +=3D n;
> - buf +=3D n;
> -	} while (written < len);
> -	return 0;
> -}
> -
> -
> _READ_WRITE_RETURN_TYPE write(int fd, const void *buf, size_t nbytes)
> {
> int numWritten =3D GEM_EIHNDL;
> @@ -41,42 +17,7 @@ _READ_WRITE_RETURN_TYPE write(int fd, const void *buf,=
 size_t nbytes)
> {
> fd =3D GSH_CONOUT; // Use console out for stderr.
> }
> - if (fd =3D=3D GSH_CONOUT)
> - {
> - // When we write to stdout on Atari, we must add a \r after \n to
> - // get the correct C output behaviour.
> - const char* stream =3D (const char*)buf;
> - size_t lastWrite =3D 0;
> - for (size_t i =3D 0; i < nbytes; ++i)
> - {
> - if (stream[i] =3D=3D '\n')
> - {
> - int len =3D i - lastWrite; // length up to but not including \n
> - if (writeUntilDoneOrError(fd, len, stream + lastWrite) < 0)
> - {
> - return -1;
> - }
> - if (writeUntilDoneOrError(fd, 2, lineEnding) < 0)
> - {
> - return -1;
> - }
> - lastWrite =3D i + 1;	// Include the \n
> - }
> - }
> - if (lastWrite < nbytes)
> - {
> - int len =3D nbytes - lastWrite;
> - if (writeUntilDoneOrError(fd, len, stream + lastWrite) < 0)
> - {
> - return -1;
> - }
> - }
> - numWritten =3D nbytes;
> - }
> - else
> - {
> - numWritten =3D trap1_40((unsigned short)fd, nbytes, buf);
> - }
> + numWritten =3D trap1_40((unsigned short)fd, nbytes, buf);
> }
> if (numWritten < 0)
> {
> diff --git a/newlib/configure.host b/newlib/configure.host
> index 960cca215..3c30bf8a7 100644
> --- a/newlib/configure.host
> +++ b/newlib/configure.host
> @@ -527,6 +527,10 @@ case "${host}" in
> m68hc11-*-*|m6811-*-*|m6812-*-*|m68hc12-*-*)
> ;;
>=20
> + m68k-atari-elf)
> +	sys_dir=3Datari
> +	have_crt0=3D"no"
> +	;;
> m68k-sun-sunos*)
> unix_dir=3Dunix
> ;;
> @@ -769,7 +773,7 @@ newlib_cflags=3D"${newlib_cflags} -DCLOCK_PROVIDED -D=
MALLOC_PROVIDED -DEXIT_PROVID
> syscall_dir=3D
> ;;
> m68k-atari-elf)
> -	newlib_cflags=3D"${newlib_cflags} -DHAVE_RENAME -DMISSING_SYSCALL_NAMES=
"
> +	newlib_cflags=3D"${newlib_cflags} -D__M68K_ATARI_ELF__ -DHAVE_RENAME -D=
MISSING_SYSCALL_NAMES"
> syscall_dir=3D
> ;;
> mcore-*-*)
> diff --git a/newlib/libc/acinclude.m4 b/newlib/libc/acinclude.m4
> index a1040386b..c70a4aebb 100644
> --- a/newlib/libc/acinclude.m4
> +++ b/newlib/libc/acinclude.m4
> @@ -13,6 +13,7 @@ AM_CONDITIONAL(HAVE_UNIX_DIR, test x${unix_dir} !=3D x)=

> dnl We always recur into sys and machine, and let them decide what to do.=

> m4_foreach_w([SYS_DIR], [
> a29khif amdgcn arm
> + atari
> d10v
> epiphany
> h8300hms h8500hms
> diff --git a/newlib/libc/stdio/flags.c b/newlib/libc/stdio/flags.c
> index d686fa046..7f3b15e2f 100644
> --- a/newlib/libc/stdio/flags.c
> +++ b/newlib/libc/stdio/flags.c
> @@ -72,7 +72,7 @@ __sflags (struct _reent *ptr,
> m |=3D O_BINARY;
> #endif
> break;
> -#ifdef __CYGWIN__
> +#if defined (__CYGWIN__) || defined (__M68K_ATARI_ELF__)
> case 't':
> m |=3D O_TEXT;
> break;
> diff --git a/newlib/libc/stdio/stdio.c b/newlib/libc/stdio/stdio.c
> index 6347949db..e3abdb0ce 100644
> --- a/newlib/libc/stdio/stdio.c
> +++ b/newlib/libc/stdio/stdio.c
> @@ -138,6 +138,10 @@ __stextmode (int fd)
> extern int _cygwin_istext_for_stdio (int);
> return _cygwin_istext_for_stdio (fd);
> #else
> + #ifdef __M68K_ATARI_ELF__
> + extern int atari_istext_for_stdio (int);
> + return atari_istext_for_stdio (fd);
> + #endif
> return 0;
> #endif
> }
> diff --git a/newlib/libc/sys/Makefile.inc b/newlib/libc/sys/Makefile.inc
> index 9f8758934..97ce59a36 100644
> --- a/newlib/libc/sys/Makefile.inc
> +++ b/newlib/libc/sys/Makefile.inc
> @@ -7,6 +7,9 @@ endif
> if HAVE_LIBC_SYS_ARM_DIR
> include %D%/arm/Makefile.inc
> endif
> +if HAVE_LIBC_SYS_ATARI_DIR
> +include %D%/atari/Makefile.inc
> +endif
> if HAVE_LIBC_SYS_D10V_DIR
> include %D%/d10v/Makefile.inc
> endif
> diff --git a/newlib/libc/sys/atari/Makefile.inc b/newlib/libc/sys/atari/M=
akefile.inc
> new file mode 100644
> index 000000000..5ca8259ee
> --- /dev/null
> +++ b/newlib/libc/sys/atari/Makefile.inc
> @@ -0,0 +1 @@
> +libc_a_SOURCES +=3D %D%/filemode.c
> diff --git a/newlib/libc/sys/atari/filemode.c b/newlib/libc/sys/atari/fil=
emode.c
> new file mode 100644
> index 000000000..ea8ff7455
> --- /dev/null
> +++ b/newlib/libc/sys/atari/filemode.c
> @@ -0,0 +1,94 @@
> +/*
> +	Copyright (C) 2026 Mikael Hildenborg
> +	SPDX-License-Identifier: BSD-2-Clause
> +*/
> +
> +#include <_ansi.h>
> +#include <sys/reent.h>
> +#include <stdio.h>
> +#include <sys/fcntl.h>
> +#include <sys/lock.h>
> +#include <errno.h>
> +#include "../../stdio/local.h"
> +
> +
> +/*
> +	Thread safety in case support for MultiTOS or MagiC is added in the fut=
ure.
> +*/
> +#ifndef __SINGLE_THREAD__
> +__LOCK_INIT(static, __setmode_mutex);
> +#endif
> +
> +short setmode_fd;
> +FILE* setmode_fp;
> +
> +int setmode_helper(struct _reent *ptr, FILE *f)
> +{
> +	/*
> + We call __sfileno instead of fileno, as the latter tries to lock the fi=
lepointer.
> + And the filepointer is already locked if we came from fopen etc.
> +	*/
> +	if (setmode_fd =3D=3D __sfileno(f))
> +	{
> + setmode_fp =3D f;
> +	}
> +	return 0;
> +}
> +
> +FILE* GetFilePointer(short fd)
> +{
> +#ifndef __SINGLE_THREAD__
> +	__lock_acquire(__setmode_mutex);
> +#endif
> +	setmode_fd =3D fd;
> +	setmode_fp =3D 0;
> +	_fwalk_sglue (_GLOBAL_REENT, setmode_helper, &__sglue);
> +	FILE* fp =3D setmode_fp;
> +#ifndef __SINGLE_THREAD__
> +	__lock_release(__setmode_mutex);
> +#endif
> +	return fp;
> +}
> +
> +extern int atari_setmode(short f, int mode);
> +extern int atari_istext_for_stdio(short fd);
> +
> +int _setmode (short fd, int mode)
> +{
> +	if (fd < 0)
> +	{
> + errno =3D EBADF;
> + return -1;
> +	}
> +
> +/*
> +	We need to make sure that stdio is set up, as this function most likely=
 will be called before any file operations.
> +	The second parameter in the CHECK_INIT should be a file pointer, but pa=
radoxically enough we cannot have one
> +	before setting up stdio.
> +	This is not a problem however as the file pointer never is used by the =
macro, so we set it to NULL.
> +*/
> +	CHECK_INIT(_REENT, NULL);
> +
> +	FILE* fp =3D GetFilePointer(fd);
> +	if (fp =3D=3D 0)
> +	{
> + errno =3D EBADF;
> + return -1;
> +	}
> +
> +	int oldmode =3D atari_setmode(fd, mode);
> +
> +	/*
> + Set or clear __SCLE for correct CRLF handling.
> +	*/
> +	if (atari_istext_for_stdio(fd) !=3D 0)
> +	{
> + fp->_flags |=3D __SCLE;
> +	}
> +	else
> +	{
> + fp->_flags &=3D ~__SCLE;
> +	}
> +
> +	return oldmode;
> +}
> diff --git a/newlib/libc/sys/atari/include/io.h b/newlib/libc/sys/atari/i=
nclude/io.h
> new file mode 100644
> index 000000000..027ff1626
> --- /dev/null
> +++ b/newlib/libc/sys/atari/include/io.h
> @@ -0,0 +1,30 @@
> +/*
> +	Copyright (C) 2026 Mikael Hildenborg
> +	SPDX-License-Identifier: BSD-2-Clause
> +*/
> +
> +#ifndef _IO_H_
> +#define _IO_H_
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/*
> +	fmode functions is in libgloss atari-setmode.c
> +*/
> +extern int atari_set_fmode(int mode);
> +extern int atari_get_fmode(int* mode);
> +extern int _setmode(short f, int mode);
> +
> +#define _set_fmode(mode) atari_set_fmode((mode))
> +#define _get_fmode(mode) atari_get_fmode((mode))
> +#define set_fmode(mode) atari_set_fmode((mode))
> +#define get_fmode(mode) atari_get_fmode((mode))
> +#define setmode(f, mode) _setmode((f), (mode))
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif
> diff --git a/newlib/libc/sys/atari/include/sys/fcntl.h b/newlib/libc/sys/=
atari/include/sys/fcntl.h
> new file mode 100644
> index 000000000..70c635c72
> --- /dev/null
> +++ b/newlib/libc/sys/atari/include/sys/fcntl.h
> @@ -0,0 +1,11 @@
> +#ifndef _SYS_FCNTL_H_
> +#define _SYS_FCNTL_H_
> +
> +#include <sys/_default_fcntl.h>
> +
> +#define	_FBINARY	0x10000
> +#define	_FTEXT 0x20000
> +#define O_BINARY	_FBINARY
> +#define O_TEXT _FTEXT
> +
> +#endif /* _SYS_FCNTL_H_ */
> diff --git a/newlib/libc/sys/atari/include/sys/stdio.h b/newlib/libc/sys/=
atari/include/sys/stdio.h
> new file mode 100644
> index 000000000..8f3616a8c
> --- /dev/null
> +++ b/newlib/libc/sys/atari/include/sys/stdio.h
> @@ -0,0 +1,33 @@
> +/*
> +	This file is a copy of libc/include/sys/stdio.h
> +	The only difference is the __SCLE define at the bottom.
> +*/
> +#ifndef _NEWLIB_STDIO_H
> +#define _NEWLIB_STDIO_H
> +
> +#include <sys/lock.h>
> +#include <sys/reent.h>
> +
> +/* Internal locking macros, used to protect stdio functions. In the
> + general case, expand to nothing. Use __SSTR flag in FILE _flags to
> + detect if FILE is private to sprintf/sscanf class of functions; if
> + set then do nothing as lock is not initialised. */
> +#if !defined(_flockfile)
> +#ifndef __SINGLE_THREAD__
> +# define _flockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_acquire_re=
cursive((fp)->_lock))
> +#else
> +# define _flockfile(fp)	((void) 0)
> +#endif
> +#endif
> +
> +#if !defined(_funlockfile)
> +#ifndef __SINGLE_THREAD__
> +# define _funlockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_release_=
recursive((fp)->_lock))
> +#else
> +# define _funlockfile(fp)	((void) 0)
> +#endif
> +#endif
> +
> +#define __SCLE	0x4000
> +
> +#endif /* _NEWLIB_STDIO_H */
> --
> 2.43.0
> 
> 
> 


------------178584-1781356688222-1
Content-Type: multipart/related; boundary="----------178584-1781356688222-2"

------------178584-1781356688222-2
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<div>Bump.</div><div><br></div><div><br></div><div><br></div><div><br></div=
><div>Den torsdag 14 maj 2026 kl. 11:08:52 +02:00, skrev &lt;micael@hildenb=
org.com>:<br></div><blockquote type=3D"cite" id=3D"mailText"><div class=3D"=
oneComWebmail-html oneComWebmail-mail"><div class=3D"oneComWebmail-body"><d=
iv>Atari computers uses CRLF as line endings the same way Windows do.<br></=
div><div>This patch enables text/binary mode for files and stdin/stdout/std=
err streams.<br></div><div>It should work the same way as Cygwin do.<br></d=
iv><div>This patch have been tested successfully by the Atari community=C2=
=A0 since beginning of March 2026.<br></div><div>=C2=A0Reconfigure is needed.<=
br></div><div><br></div><div>---<br></div><div>libgloss/m68k/Makefile.in=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 2 +-<br></div><div>libgloss/m68k/atari/atari-ope=
n.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 37 +++++----<br=
></div><div>libgloss/m68k/atari/atari-setmode.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 | 74 ++++++++++++++++++<br></div><div>libgloss/m68k/atari/atari-tos.=
ld=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 2 +-<br></=
div><div>libgloss/m68k/atari/atari-tos.specs=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 |=C2=A0 3 +<br></div><div>libgloss/m68k/atari/atari-write.c=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 61 +--------------<br></div><div>new=
lib/configure.host=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 6 +=
-<br></div><div>newlib/libc/acinclude.m4=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 =
1 +<br></div><div>newlib/libc/stdio/flags.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 2 +=
-<br></div><div>newlib/libc/stdio/stdio.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 4 +<br=
></div><div>newlib/libc/sys/Makefile.inc=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 3 +<br></div><div>newlib=
/libc/sys/atari/Makefile.inc=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=
=C2=A0 1 +<br></div><div>newlib/libc/sys/atari/filemode.c=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 94 +++++++++++++++++++++++<br></div><di=
v>newlib/libc/sys/atari/include/io.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 | 30 ++++++++<br></div><div>newlib/libc/sys/atari/include/sys/fcntl.h |=
 11 +++<br></div><div>newlib/libc/sys/atari/include/sys/stdio.h | 33 ++++++=
++<br></div><div>16 files changed, 283 insertions(+), 81 deletions(-)<br></=
div><div>create mode 100644 libgloss/m68k/atari/atari-setmode.c<br></div><d=
iv>create mode 100644 newlib/libc/sys/atari/Makefile.inc<br></div><div>crea=
te mode 100644 newlib/libc/sys/atari/filemode.c<br></div><div>create mode 1=
00644 newlib/libc/sys/atari/include/io.h<br></div><div>create mode 100644 n=
ewlib/libc/sys/atari/include/sys/fcntl.h<br></div><div>create mode 100644 n=
ewlib/libc/sys/atari/include/sys/stdio.h<br></div><div><br></div><div>diff =
--git a/libgloss/m68k/Makefile.in b/libgloss/m68k/Makefile.in<br></div><div=
>index b6d1868bc..43d716a2f 100644<br></div><div>--- a/libgloss/m68k/Makefi=
le.in<br></div><div>+++ b/libgloss/m68k/Makefile.in<br></div><div>@@ -216,7=
 +216,7 @@ ATARI_SRC_LIBGLOSS :=3D atari-environ.c atari-execve.c atari-lin=
k.c atari-times.c<br></div><div>atari-sbrk.c atari-stat.c atari-unlink.c at=
ari-write.c \<br></div><div>atari-chown.c atari-fork.c atari-getentropy.c a=
tari-gettod.c atari-readlink.c \<br></div><div>atari-symlink.c atari-chdir.=
c atari-getcwd.c atari-mkdir.c atari-rmdir.c \<br></div><div>-	atari-rename=
.c<br></div><div>+	atari-rename.c atari-setmode.c<br></div><div><br></div><=
div>ATARI_OBJS_LIBGLOSS :=3D $(foreach source,$(ATARI_SRC_LIBGLOSS),$(basen=
ame $(source)).o)<br></div><div><br></div><div>diff --git a/libgloss/m68k/a=
tari/atari-open.c b/libgloss/m68k/atari/atari-open.c<br></div><div>index c6=
1071881..6c960b6a6 100644<br></div><div>--- a/libgloss/m68k/atari/atari-ope=
n.c<br></div><div>+++ b/libgloss/m68k/atari/atari-open.c<br></div><div>@@ -=
5,27 +5,15 @@<br></div><div><br></div><div>#include &lt;unistd.h><br></div>=
<div>#include &lt;_ansi.h><br></div><div>+#include &lt;fcntl.h><br></div><d=
iv>+#include &lt;io.h><br></div><div>#include "atari-gem_errno.h"<br></div>=
<div>#include "atari-traps.h"<br></div><div><br></div><div>-// I really don=
't like having these defines here,<br></div><div>-// fcntl.h where they are=
, also defines a function for "open",<br></div><div>-// that is different f=
rom the one libgloss is supposed to provide...<br></div><div>-#ifndef O_CRE=
AT<br></div><div>-#define O_CREAT 0x0200<br></div><div>-#endif // O_CREAT<b=
r></div><div>-#ifndef O_APPEND<br></div><div>-#define O_APPEND 0x0008<br></=
div><div>-#endif // O_APPEND<br></div><div>-#ifndef O_EXCL<br></div><div>-#=
define O_EXCL 0x0800<br></div><div>-#endif // O_EXCL<br></div><div>-#ifndef=
 O_TRUNC<br></div><div>-#define O_TRUNC 0x0400<br></div><div>-#endif // O_T=
RUNC<br></div><div>+extern int atari_get_fmode(int* mode);<br></div><div>+e=
xtern int atari_setmode(short f, int mode);<br></div><div><br></div><div>-/=
/ mode is ignored. Those kind of settings is not supported by the st.<br></=
div><div>-int open(const char *buf, int flags, int mode)<br></div><div>+int=
 open(const char *buf, int flags, ...)<br></div><div>{<br></div><div>int bi=
os_handle =3D -1;<br></div><div>unsigned short bios_mode =3D (unsigned shor=
t)(flags & 0x3); // bits 0-1 the same for st and linux.<br></div><div>@@ -7=
1,6 +59,21 @@ int open(const char *buf, int flags, int mode)<br></div><div>=
gem_error_to_errno(bios_handle);<br></div><div>bios_handle =3D -1;<br></div=
><div>}<br></div><div>+	else<br></div><div>+	{<br></div><div>+		int fmode =
=3D flags & (O_TEXT | O_BINARY);<br></div><div>+		if (fmode =3D=3D 0)<br></div=
><div>+		{<br></div><div>+			// Initializes the correct default mode.<br></=
div><div>+			atari_get_fmode(&fmode);<br></div><div>+		}<br></div><div>+		i=
f (atari_setmode((short)bios_handle, fmode) =3D=3D -1)<br></div><div>+		{<b=
r></div><div>+			// Close file. errno is alredy set.<br></div><div>+			trap=
1_3e((unsigned short)bios_handle);<br></div><div>+			return -1;<br></div><d=
iv>+		}<br></div><div>+	}<br></div><div>/*<br></div><div>If bios_handle is =
positive, then the low word is the gemdos handle, and the high word is zero=
.<br></div><div>*/<br></div><div>diff --git a/libgloss/m68k/atari/atari-set=
mode.c b/libgloss/m68k/atari/atari-setmode.c<br></div><div>new file mode 10=
0644<br></div><div>index 000000000..89fe7511f<br></div><div>--- /dev/null<b=
r></div><div>+++ b/libgloss/m68k/atari/atari-setmode.c<br></div><div>@@ -0,=
0 +1,74 @@<br></div><div>+/*<br></div><div>+	Copyright (C) 2026 Mikael Hild=
enborg<br></div><div>+	SPDX-License-Identifier: BSD-2-Clause<br></div><div>=
+*/<br></div><div>+#include &lt;unistd.h><br></div><div>+#include &lt;_ansi=
.h><br></div><div>+#include &lt;fcntl.h><br></div><div>+#include &lt;io.h><=
br></div><div>+#include &lt;errno.h><br></div><div>+<br></div><div>+/*<br><=
/div><div>+	EmuTOS allows for a maximum of 75 open files, and ordinary TOS =
even less.<br></div><div>+	But MultiTOS and MagiC allows for much more, so =
to be safe we allow for even more.<br></div><div>+*/<br></div><div>+#define=
 MAX_FILE_DESCRIPTORS	256<br></div><div>+#define FILE_MODE_SHIFT			16<br></=
div><div>+<br></div><div>+static int _fmode =3D O_TEXT;<br></div><div>+<br>=
</div><div>+unsigned char file_descriptor_modes[MAX_FILE_DESCRIPTORS] =3D {=
0};<br></div><div>+<br></div><div>+int atari_set_fmode(int mode)<br></div><=
div>+{<br></div><div>+	_fmode =3D mode;<br></div><div>+	return 0;<br></div>=
<div>+}<br></div><div>+<br></div><div>+int atari_get_fmode(int* mode)<br></=
div><div>+{<br></div><div>+	*mode =3D _fmode;<br></div><div>+	return 0;<br>=
</div><div>+}<br></div><div>+<br></div><div>+int atari_getmode(short fd)<br=
></div><div>+{<br></div><div>+	if (fd &lt; 0 || fd >=3D MAX_FILE_DESCRIPTOR=
S)<br></div><div>+	{<br></div><div>+		errno =3D EINVAL;<br></div><div>+		re=
turn -1;<br></div><div>+	}<br></div><div>+	int mode =3D ((int)file_descript=
or_modes[fd]) &lt;&lt; FILE_MODE_SHIFT;<br></div><div>+	if (mode =3D=3D 0 &=
& fd &lt; 2)<br></div><div>+	{<br></div><div>+		/*<br></div><div>+			stdin,=
 stdout and stderr isn't opened and assumed to exist.<br></div><div>+			So =
the open function never gets the chance to set default mode for them.<br></=
div><div>+			That's why we do this check and return O_TEXT if nothing else =
is set.<br></div><div>+		*/<br></div><div>+		mode =3D O_TEXT;<br></div><div=
>+	}<br></div><div>+	return mode;<br></div><div>+}<br></div><div>+<br></div=
><div>+int atari_setmode(short fd, int mode)<br></div><div>+{<br></div><div=
>+	int oldMode =3D atari_getmode(fd);<br></div><div>+	if (oldMode !=3D -1)<=
br></div><div>+	{<br></div><div>+		// We cannot get here without having eno=
ugh entries in the array.<br></div><div>+		file_descriptor_modes[fd] =3D (u=
nsigned char)((mode & (O_TEXT | O_BINARY)) >> FILE_MODE_SHIFT);<br></div><d=
iv>+	}<br></div><div>+	return oldMode;<br></div><div>+}<br></div><div>+<br>=
</div><div>+int atari_istext_for_stdio (short fd)<br></div><div>+{<br></div=
><div>+	int mode =3D atari_getmode(fd);<br></div><div>+	if (mode !=3D -1)<b=
r></div><div>+	{<br></div><div>+		// Treat anything else than binary mode a=
s text mode.<br></div><div>+		return (mode & O_BINARY) =3D=3D 0 ? 1 : 0;<br=
></div><div>+	}<br></div><div>+	return 1;<br></div><div>+}<br></div><div>di=
ff --git a/libgloss/m68k/atari/atari-tos.ld b/libgloss/m68k/atari/atari-tos=
.ld<br></div><div>index 6bbecc261..a2f0b7625 100644<br></div><div>--- a/lib=
gloss/m68k/atari/atari-tos.ld<br></div><div>+++ b/libgloss/m68k/atari/atari=
-tos.ld<br></div><div>@@ -85,7 +85,7 @@ SECTIONS<br></div><div>LONG(__BSS_S=
EGMENT__ - __DATA_SEGMENT__);	/* Length of the DATA segment */<br></div><di=
v>LONG(__BSS_SEGMENT_END - __BSS_SEGMENT__);	/* Length of the BSS segment *=
/<br></div><div>LONG(0);									/* Length of the symbol table */<br></div>=
<div>-		LONG(0);									/* Reserved, should be 0 */<br></div><div>+		LONG(=
0x68e1f001);							/* __M68K_ATARI_ELF__ signature */<br></div><div>LONG(0)=
;									/* Program flags */<br></div><div>SHORT(0);									/*=C2=A0 0 =
=3D Relocation info present */<br></div><div>}<br></div><div>diff --git a/libg=
loss/m68k/atari/atari-tos.specs b/libgloss/m68k/atari/atari-tos.specs<br></=
div><div>index 02037132c..232afc3e8 100644<br></div><div>--- a/libgloss/m68=
k/atari/atari-tos.specs<br></div><div>+++ b/libgloss/m68k/atari/atari-tos.s=
pecs<br></div><div>@@ -8,3 +8,6 @@<br></div><div><br></div><div>*lib:<br></=
div><div>+ -latari-tos<br></div><div>+<br></div><div>+*cpp:<br></div><div>+=
+ -D__M68K_ATARI_ELF__ -D__atari_os__<br></div><div>diff --git a/libgloss/m=
68k/atari/atari-write.c b/libgloss/m68k/atari/atari-write.c<br></div><div>i=
ndex 9d6e59ed8..eba45038b 100644<br></div><div>--- a/libgloss/m68k/atari/at=
ari-write.c<br></div><div>+++ b/libgloss/m68k/atari/atari-write.c<br></div>=
<div>@@ -8,30 +8,6 @@<br></div><div>#include "atari-gem_errno.h"<br></div><=
div>#include "atari-traps.h"<br></div><div><br></div><div>-const char* line=
Ending =3D "\r\n";<br></div><div>-<br></div><div>-int writeUntilDoneOrError=
(int fd, size_t len, const char* buf)<br></div><div>-{<br></div><div>-	size=
_t written =3D 0;<br></div><div>-	if (len =3D=3D 0)<br></div><div>-	{<br></=
div><div>-		return 0;<br></div><div>-	}<br></div><div>-	do<br></div><div>-	=
{<br></div><div>-		int n =3D trap1_40((unsigned short)fd, len, buf);<br></d=
iv><div>-		if (n &lt; 0)<br></div><div>-		{<br></div><div>-			gem_error_to_=
errno(n);<br></div><div>-			return -1;<br></div><div>-		}<br></div><div>-		=
written +=3D n;<br></div><div>-		buf +=3D n;<br></div><div>-	} while (writt=
en &lt; len);<br></div><div>-	return 0;<br></div><div>-}<br></div><div>-<br=
></div><div>-<br></div><div>_READ_WRITE_RETURN_TYPE write(int fd, const voi=
d *buf, size_t nbytes)<br></div><div>{<br></div><div>int numWritten =3D GEM=
_EIHNDL;<br></div><div>@@ -41,42 +17,7 @@ _READ_WRITE_RETURN_TYPE write(int=
 fd, const void *buf, size_t nbytes)<br></div><div>{<br></div><div>fd =3D G=
SH_CONOUT; // Use console out for stderr.<br></div><div>}<br></div><div>-		=
if (fd =3D=3D GSH_CONOUT)<br></div><div>-		{<br></div><div>-			// When we w=
rite to stdout on Atari, we must add a \r after \n to<br></div><div>-			// =
get the correct C output behaviour.<br></div><div>-			const char* stream =
=3D (const char*)buf;<br></div><div>-			size_t lastWrite =3D 0;<br></div><div>=
-			for (size_t i =3D 0; i &lt; nbytes; ++i)<br></div><div>-			{<br></div><=
div>-				if (stream[i] =3D=3D '\n')<br></div><div>-				{<br></div><div>-			=
		int len =3D i - lastWrite; // length up to but not including \n<br></div>=
<div>-					if (writeUntilDoneOrError(fd, len, stream + lastWrite) &lt; 0)<b=
r></div><div>-					{<br></div><div>-						return -1;<br></div><div>-					}<=
br></div><div>-					if (writeUntilDoneOrError(fd, 2, lineEnding) &lt; 0)<br=
></div><div>-					{<br></div><div>-						return -1;<br></div><div>-					}<b=
r></div><div>-					lastWrite =3D i + 1;	// Include the \n<br></div><div>-		=
		}<br></div><div>-			}<br></div><div>-			if (lastWrite &lt; nbytes)<br></d=
iv><div>-			{<br></div><div>-				int len =3D nbytes - lastWrite;<br></div><=
div>-				if (writeUntilDoneOrError(fd, len, stream + lastWrite) &lt; 0)<br>=
</div><div>-				{<br></div><div>-					return -1;<br></div><div>-				}<br></=
div><div>-			}<br></div><div>-			numWritten =3D nbytes;<br></div><div>-		}<=
br></div><div>-		else<br></div><div>-		{<br></div><div>-			numWritten =3D t=
rap1_40((unsigned short)fd, nbytes, buf);<br></div><div>-		}<br></div><div>=
+		numWritten =3D trap1_40((unsigned short)fd, nbytes, buf);<br></div><div>=
}<br></div><div>if (numWritten &lt; 0)<br></div><div>{<br></div><div>diff -=
-git a/newlib/configure.host b/newlib/configure.host<br></div><div>index 96=
0cca215..3c30bf8a7 100644<br></div><div>--- a/newlib/configure.host<br></di=
v><div>+++ b/newlib/configure.host<br></div><div>@@ -527,6 +527,10 @@ case =
"${host}" in<br></div><div>=C2=A0=C2=A0 m68hc11-*-*|m6811-*-*|m6812-*-*|m68=
hc12-*-*)<br></div><div>;;<br></div><div><br></div><div>+=C2=A0 m68k-atari-=
elf)<br></div><div>+	sys_dir=3Datari<br></div><div>+	have_crt0=3D"no"<br></=
div><div>+	;;<br></div><div>=C2=A0=C2=A0 m68k-sun-sunos*)<br></div><div>uni=
x_dir=3Dunix<br></div><div>;;<br></div><div>@@ -769,7 +773,7 @@ newlib_cfla=
gs=3D"${newlib_cflags} -DCLOCK_PROVIDED -DMALLOC_PROVIDED -DEXIT_PROVID<br>=
</div><div>syscall_dir=3D<br></div><div>;;<br></div><div>=C2=A0=C2=A0 m68k-=
atari-elf)<br></div><div>-	newlib_cflags=3D"${newlib_cflags} -DHAVE_RENAME =
-DMISSING_SYSCALL_NAMES"<br></div><div>+	newlib_cflags=3D"${newlib_cflags} =
-D__M68K_ATARI_ELF__ -DHAVE_RENAME -DMISSING_SYSCALL_NAMES"<br></div><div>s=
yscall_dir=3D<br></div><div>;;<br></div><div>=C2=A0=C2=A0 mcore-*-*)<br></d=
iv><div>diff --git a/newlib/libc/acinclude.m4 b/newlib/libc/acinclude.m4<br=
></div><div>index a1040386b..c70a4aebb 100644<br></div><div>--- a/newlib/li=
bc/acinclude.m4<br></div><div>+++ b/newlib/libc/acinclude.m4<br></div><div>=
@@ -13,6 +13,7 @@ AM_CONDITIONAL(HAVE_UNIX_DIR, test x${unix_dir} !=3D x)<b=
r></div><div>dnl We always recur into sys and machine, and let them decide =
what to do.<br></div><div>m4_foreach_w([SYS_DIR], [<br></div><div>=C2=A0=
=C2=A0 a29khif amdgcn arm<br></div><div>+=C2=A0 atari<br></div><div>=C2=A0=C2=
=A0 d10v<br></div><div>=C2=A0=C2=A0 epiphany<br></div><div>=C2=A0=C2=A0 h8300h=
ms h8500hms<br></div><div>diff --git a/newlib/libc/stdio/flags.c b/newlib/l=
ibc/stdio/flags.c<br></div><div>index d686fa046..7f3b15e2f 100644<br></div>=
<div>--- a/newlib/libc/stdio/flags.c<br></div><div>+++ b/newlib/libc/stdio/=
flags.c<br></div><div>@@ -72,7 +72,7 @@ __sflags (struct _reent *ptr,<br></=
div><div>=C2=A0 m |=3D O_BINARY;<br></div><div>#endif<br></div><div>=C2=A0 =
break;<br></div><div>-#ifdef __CYGWIN__<br></div><div>+#if defined (__CYGWI=
N__) || defined (__M68K_ATARI_ELF__)<br></div><div>case 't':<br></div><div>=
=C2=A0 m |=3D O_TEXT;<br></div><div>=C2=A0 break;<br></div><div>diff --git =
a/newlib/libc/stdio/stdio.c b/newlib/libc/stdio/stdio.c<br></div><div>index=
 6347949db..e3abdb0ce 100644<br></div><div>--- a/newlib/libc/stdio/stdio.c<=
br></div><div>+++ b/newlib/libc/stdio/stdio.c<br></div><div>@@ -138,6 +138,=
10 @@ __stextmode (int fd)<br></div><div>=C2=A0=C2=A0 extern int _cygwin_is=
text_for_stdio (int);<br></div><div>=C2=A0=C2=A0 return _cygwin_istext_for_=
stdio (fd);<br></div><div>#else<br></div><div>+=C2=A0 #ifdef __M68K_ATARI_E=
LF__<br></div><div>+=C2=A0=C2=A0=C2=A0 extern int atari_istext_for_stdio (i=
nt);<br></div><div>+=C2=A0=C2=A0=C2=A0 return atari_istext_for_stdio (fd);<=
br></div><div>+=C2=A0 #endif<br></div><div>=C2=A0=C2=A0 return 0;<br></div>=
<div>#endif<br></div><div>}<br></div><div>diff --git a/newlib/libc/sys/Make=
file.inc b/newlib/libc/sys/Makefile.inc<br></div><div>index 9f8758934..97ce=
59a36 100644<br></div><div>--- a/newlib/libc/sys/Makefile.inc<br></div><div=
>+++ b/newlib/libc/sys/Makefile.inc<br></div><div>@@ -7,6 +7,9 @@ endif<br>=
</div><div>if HAVE_LIBC_SYS_ARM_DIR<br></div><div>include %D%/arm/Makefile.=
inc<br></div><div>endif<br></div><div>+if HAVE_LIBC_SYS_ATARI_DIR<br></div>=
<div>+include %D%/atari/Makefile.inc<br></div><div>+endif<br></div><div>if =
HAVE_LIBC_SYS_D10V_DIR<br></div><div>include %D%/d10v/Makefile.inc<br></div=
><div>endif<br></div><div>diff --git a/newlib/libc/sys/atari/Makefile.inc b=
/newlib/libc/sys/atari/Makefile.inc<br></div><div>new file mode 100644<br><=
/div><div>index 000000000..5ca8259ee<br></div><div>--- /dev/null<br></div><=
div>+++ b/newlib/libc/sys/atari/Makefile.inc<br></div><div>@@ -0,0 +1 @@<br=
></div><div>+libc_a_SOURCES +=3D %D%/filemode.c<br></div><div>diff --git a/=
newlib/libc/sys/atari/filemode.c b/newlib/libc/sys/atari/filemode.c<br></di=
v><div>new file mode 100644<br></div><div>index 000000000..ea8ff7455<br></d=
iv><div>--- /dev/null<br></div><div>+++ b/newlib/libc/sys/atari/filemode.c<=
br></div><div>@@ -0,0 +1,94 @@<br></div><div>+/*<br></div><div>+	Copyright =
(C) 2026 Mikael Hildenborg<br></div><div>+	SPDX-License-Identifier: BSD-2-C=
lause<br></div><div>+*/<br></div><div>+<br></div><div>+#include &lt;_ansi.h=
><br></div><div>+#include &lt;sys/reent.h><br></div><div>+#include &lt;stdi=
o.h><br></div><div>+#include &lt;sys/fcntl.h><br></div><div>+#include &lt;s=
ys/lock.h><br></div><div>+#include &lt;errno.h><br></div><div>+#include "..=
/../stdio/local.h"<br></div><div>+<br></div><div>+<br></div><div>+/*<br></d=
iv><div>+	Thread safety in case support for MultiTOS or MagiC is added in t=
he future.<br></div><div>+*/<br></div><div>+#ifndef __SINGLE_THREAD__<br></=
div><div>+__LOCK_INIT(static, __setmode_mutex);<br></div><div>+#endif<br></=
div><div>+<br></div><div>+short setmode_fd;<br></div><div>+FILE* setmode_fp=
;<br></div><div>+<br></div><div>+int setmode_helper(struct _reent *ptr, FIL=
E *f)<br></div><div>+{<br></div><div>+	/*<br></div><div>+		We call __sfilen=
o instead of fileno, as the latter tries to lock the filepointer.<br></div>=
<div>+		And the filepointer is already locked if we came from fopen etc.<br=
></div><div>+	*/<br></div><div>+	if (setmode_fd =3D=3D __sfileno(f))<br></d=
iv><div>+	{<br></div><div>+		setmode_fp =3D f;<br></div><div>+	}<br></div><=
div>+	return 0;<br></div><div>+}<br></div><div>+<br></div><div>+FILE* GetFi=
lePointer(short fd)<br></div><div>+{<br></div><div>+#ifndef __SINGLE_THREAD=
__<br></div><div>+	__lock_acquire(__setmode_mutex);<br></div><div>+#endif<b=
r></div><div>+	setmode_fd =3D fd;<br></div><div>+	setmode_fp =3D 0;<br></di=
v><div>+	_fwalk_sglue (_GLOBAL_REENT, setmode_helper, &__sglue);<br></div><=
div>+	FILE* fp =3D setmode_fp;<br></div><div>+#ifndef __SINGLE_THREAD__<br>=
</div><div>+	__lock_release(__setmode_mutex);<br></div><div>+#endif<br></di=
v><div>+	return fp;<br></div><div>+}<br></div><div>+<br></div><div>+extern =
int atari_setmode(short f, int mode);<br></div><div>+extern int atari_istex=
t_for_stdio(short fd);<br></div><div>+<br></div><div>+int _setmode (short f=
d, int mode)<br></div><div>+{<br></div><div>+	if (fd &lt; 0)<br></div><div>=
+	{<br></div><div>+		errno =3D EBADF;<br></div><div>+		return -1;<br></div>=
<div>+	}<br></div><div>+<br></div><div>+/*<br></div><div>+	We need to make =
sure that stdio is set up, as this function most likely will be called befo=
re any file operations.<br></div><div>+	The second parameter in the CHECK_I=
NIT should be a file pointer, but paradoxically enough we cannot have one<b=
r></div><div>+	before setting up stdio.<br></div><div>+	This is not a probl=
em however as the file pointer never is used by the macro, so we set it to =
NULL.<br></div><div>+*/<br></div><div>+	CHECK_INIT(_REENT, NULL);<br></div>=
<div>+<br></div><div>+	FILE* fp =3D GetFilePointer(fd);<br></div><div>+	if =
(fp =3D=3D 0)<br></div><div>+	{<br></div><div>+		errno =3D EBADF;<br></div>=
<div>+		return -1;<br></div><div>+	}<br></div><div>+<br></div><div>+	int ol=
dmode =3D atari_setmode(fd, mode);<br></div><div>+<br></div><div>+	/*<br></=
div><div>+		Set or clear __SCLE for correct CRLF handling.<br></div><div>+	=
*/<br></div><div>+	if (atari_istext_for_stdio(fd) !=3D 0)<br></div><div>+	{=
<br></div><div>+		fp->_flags |=3D __SCLE;<br></div><div>+	}<br></div><div>+=
	else<br></div><div>+	{<br></div><div>+		fp->_flags &=3D ~__SCLE;<br></div>=
<div>+	}<br></div><div>+<br></div><div>+	return oldmode;<br></div><div>+}<b=
r></div><div>diff --git a/newlib/libc/sys/atari/include/io.h b/newlib/libc/=
sys/atari/include/io.h<br></div><div>new file mode 100644<br></div><div>ind=
ex 000000000..027ff1626<br></div><div>--- /dev/null<br></div><div>+++ b/new=
lib/libc/sys/atari/include/io.h<br></div><div>@@ -0,0 +1,30 @@<br></div><di=
v>+/*<br></div><div>+	Copyright (C) 2026 Mikael Hildenborg<br></div><div>+	=
SPDX-License-Identifier: BSD-2-Clause<br></div><div>+*/<br></div><div>+<br>=
</div><div>+#ifndef _IO_H_<br></div><div>+#define _IO_H_<br></div><div>+<br=
></div><div>+#ifdef __cplusplus<br></div><div>+extern "C" {<br></div><div>+=
#endif<br></div><div>+<br></div><div>+/*<br></div><div>+	fmode functions is=
 in libgloss atari-setmode.c<br></div><div>+*/<br></div><div>+extern int at=
ari_set_fmode(int mode);<br></div><div>+extern int atari_get_fmode(int* mod=
e);<br></div><div>+extern int _setmode(short f, int mode);<br></div><div>+<=
br></div><div>+#define _set_fmode(mode) atari_set_fmode((mode))<br></div><d=
iv>+#define _get_fmode(mode) atari_get_fmode((mode))<br></div><div>+#define=
 set_fmode(mode) atari_set_fmode((mode))<br></div><div>+#define get_fmode(m=
ode) atari_get_fmode((mode))<br></div><div>+#define setmode(f, mode) _setmo=
de((f), (mode))<br></div><div>+<br></div><div>+#ifdef __cplusplus<br></div>=
<div>+}<br></div><div>+#endif<br></div><div>+<br></div><div>+#endif<br></di=
v><div>diff --git a/newlib/libc/sys/atari/include/sys/fcntl.h b/newlib/libc=
/sys/atari/include/sys/fcntl.h<br></div><div>new file mode 100644<br></div>=
<div>index 000000000..70c635c72<br></div><div>--- /dev/null<br></div><div>+=
++ b/newlib/libc/sys/atari/include/sys/fcntl.h<br></div><div>@@ -0,0 +1,11 =
@@<br></div><div>+#ifndef _SYS_FCNTL_H_<br></div><div>+#define _SYS_FCNTL_H=
_<br></div><div>+<br></div><div>+#include &lt;sys/_default_fcntl.h><br></di=
v><div>+<br></div><div>+#define	_FBINARY	0x10000<br></div><div>+#define	_FT=
EXT		0x20000<br></div><div>+#define O_BINARY	_FBINARY<br></div><div>+#defin=
e O_TEXT		_FTEXT<br></div><div>+<br></div><div>+#endif /* _SYS_FCNTL_H_ */<=
br></div><div>diff --git a/newlib/libc/sys/atari/include/sys/stdio.h b/newl=
ib/libc/sys/atari/include/sys/stdio.h<br></div><div>new file mode 100644<br=
></div><div>index 000000000..8f3616a8c<br></div><div>--- /dev/null<br></div=
><div>+++ b/newlib/libc/sys/atari/include/sys/stdio.h<br></div><div>@@ -0,0=
 +1,33 @@<br></div><div>+/*<br></div><div>+	This file is a copy of libc/inc=
lude/sys/stdio.h<br></div><div>+	The only difference is the __SCLE define a=
t the bottom.<br></div><div>+*/<br></div><div>+#ifndef _NEWLIB_STDIO_H<br><=
/div><div>+#define _NEWLIB_STDIO_H<br></div><div>+<br></div><div>+#include =
&lt;sys/lock.h><br></div><div>+#include &lt;sys/reent.h><br></div><div>+<br=
></div><div>+/* Internal locking macros, used to protect stdio functions.=
=C2=A0 In the<br></div><div>+=C2=A0=C2=A0 general case, expand to nothing. Use=
 __SSTR flag in FILE _flags to<br></div><div>+=C2=A0=C2=A0 detect if FILE i=
s private to sprintf/sscanf class of functions; if<br></div><div>+=C2=A0=
=C2=A0 set then do nothing as lock is not initialised. */<br></div><div>+#if !=
defined(_flockfile)<br></div><div>+#ifndef __SINGLE_THREAD__<br></div><div>=
+#=C2=A0 define _flockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_acquir=
e_recursive((fp)->_lock))<br></div><div>+#else<br></div><div>+#=C2=A0 defin=
e _flockfile(fp)	((void) 0)<br></div><div>+#endif<br></div><div>+#endif<br>=
</div><div>+<br></div><div>+#if !defined(_funlockfile)<br></div><div>+#ifnd=
ef __SINGLE_THREAD__<br></div><div>+#=C2=A0 define _funlockfile(fp) (((fp)-=
>_flags & __SSTR) ? 0 : __lock_release_recursive((fp)->_lock))<br></div><di=
v>+#else<br></div><div>+#=C2=A0 define _funlockfile(fp)	((void) 0)<br></div=
><div>+#endif<br></div><div>+#endif<br></div><div>+<br></div><div>+#define =
__SCLE	0x4000<br></div><div>+<br></div><div>+#endif /* _NEWLIB_STDIO_H */<b=
r></div><div>--<br></div><div>2.43.0<br></div><div><br></div><div><br></div=
></div></div></blockquote><div><br></div>

------------178584-1781356688222-2--

------------178584-1781356688222-1--