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 <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 <unistd.h><br></div>= <div>#include <_ansi.h><br></div><div>+#include <fcntl.h><br></div><d= iv>+#include <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 <unistd.h><br></div><div>+#include <_ansi= .h><br></div><div>+#include <fcntl.h><br></div><div>+#include <io.h><= br></div><div>+#include <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 < 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]) << FILE_MODE_SHIFT;<br></div><div>+ if (mode =3D=3D 0 &= & fd < 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 < 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 < 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 < 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) < 0)<b= r></div><div>- {<br></div><div>- return -1;<br></div><div>- }<= br></div><div>- if (writeUntilDoneOrError(fd, 2, lineEnding) < 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 < nbytes)<br></d= iv><div>- {<br></div><div>- int len =3D nbytes - lastWrite;<br></div><= div>- if (writeUntilDoneOrError(fd, len, stream + lastWrite) < 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 < 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 <_ansi.h= ><br></div><div>+#include <sys/reent.h><br></div><div>+#include <stdi= o.h><br></div><div>+#include <sys/fcntl.h><br></div><div>+#include <s= ys/lock.h><br></div><div>+#include <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 < 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 <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 = <sys/lock.h><br></div><div>+#include <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--