libcc.ansi: add support for O_TEXT, O_BINARY file status flags

This commit is contained in:
Tee-Kiah Chia 2021-03-27 06:59:07 +00:00
parent aaf3ef695b
commit 2dfddf3fa8
6 changed files with 45 additions and 3 deletions

View file

@ -15,6 +15,10 @@
#define ACKCONF_WANT_STANDARD_O 1 #define ACKCONF_WANT_STANDARD_O 1
#endif #endif
#ifndef ACKCONF_WANT_O_TEXT_O_BINARY
#define ACKCONF_WANT_O_TEXT_O_BINARY 0
#endif
#ifndef ACKCONF_WANT_STANDARD_SIGNALS #ifndef ACKCONF_WANT_STANDARD_SIGNALS
#define ACKCONF_WANT_STANDARD_SIGNALS 1 #define ACKCONF_WANT_STANDARD_SIGNALS 1
#endif #endif

View file

@ -24,6 +24,7 @@ struct FILE {
#define _IOREADING 0x080 #define _IOREADING 0x080
#define _IOWRITING 0x100 #define _IOWRITING 0x100
#define _IOAPPEND 0x200 #define _IOAPPEND 0x200
#define _IOBINARY 0x400
#if !defined BUFSIZ #if !defined BUFSIZ
#define BUFSIZ 1024 #define BUFSIZ 1024

View file

@ -24,6 +24,10 @@
O_WRONLY = 1, O_WRONLY = 1,
O_RDWR = 2, O_RDWR = 2,
#if ACKCONF_WANT_O_TEXT_O_BINARY
O_TEXT = 010000,
O_BINARY = 020000,
#endif
O_CREAT = 0100, O_CREAT = 0100,
O_TRUNC = 01000, O_TRUNC = 01000,
O_APPEND = 02000, O_APPEND = 02000,

View file

@ -5,6 +5,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#if ACKCONF_WANT_O_TEXT_O_BINARY
#include <unistd.h>
#include <fcntl.h>
#endif
#if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
@ -38,6 +42,9 @@ FILE* fdopen(int fd, const char* mode)
switch (*mode++) switch (*mode++)
{ {
case 'b': case 'b':
#if ACKCONF_WANT_O_TEXT_O_BINARY
flags |= _IOBINARY;
#endif
continue; continue;
case '+': case '+':
flags |= _IOREAD | _IOWRITE; flags |= _IOREAD | _IOWRITE;
@ -57,6 +64,17 @@ FILE* fdopen(int fd, const char* mode)
if ((flags & _IOREAD) && (flags & _IOWRITE)) if ((flags & _IOREAD) && (flags & _IOWRITE))
flags &= ~(_IOREADING | _IOWRITING); flags &= ~(_IOREADING | _IOWRITING);
#if ACKCONF_WANT_O_TEXT_O_BINARY
{
/*
* FIXME: this assumes that any platform that has O_TEXT and
* O_BINARY will also have a _setmode() function.
*/
extern int _setmode(int, int);
_setmode(fd, (flags & _IOBINARY) ? O_BINARY : O_TEXT);
}
#endif
stream->_count = 0; stream->_count = 0;
stream->_fd = fd; stream->_fd = fd;
stream->_flags = flags; stream->_flags = flags;

View file

@ -7,7 +7,6 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h>
#if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE #if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
@ -68,6 +67,9 @@ FILE* fopen(const char* name, const char* mode)
switch (*mode++) switch (*mode++)
{ {
case 'b': case 'b':
#if ACKCONF_WANT_O_TEXT_O_BINARY
flags |= _IOBINARY;
#endif
continue; continue;
case '+': case '+':
rwmode = O_RDWR; rwmode = O_RDWR;
@ -80,6 +82,7 @@ FILE* fopen(const char* name, const char* mode)
break; break;
} }
#if !ACKCONF_WANT_O_TEXT_O_BINARY
/* Perform a creat() when the file should be truncated or when /* Perform a creat() when the file should be truncated or when
* the file is opened for writing and the open() failed. * the file is opened for writing and the open() failed.
*/ */
@ -87,12 +90,16 @@ FILE* fopen(const char* name, const char* mode)
|| (((fd = open(name, rwmode)) < 0) || (((fd = open(name, rwmode)) < 0)
&& (rwflags & O_CREAT))) && (rwflags & O_CREAT)))
{ {
if (((fd = creat(name, PMODE)) > 0) && flags | _IOREAD) if (((fd = creat(name, PMODE)) >= 0) && (flags & _IOREAD))
{ {
(void)close(fd); (void)close(fd);
fd = open(name, rwmode); fd = open(name, rwmode);
} }
} }
#else
rwflags |= (flags & _IOBINARY) ? O_BINARY : O_TEXT;
fd = open(name, rwmode | rwflags, PMODE);
#endif
if (fd < 0) if (fd < 0)
return (FILE*)NULL; return (FILE*)NULL;

View file

@ -50,6 +50,9 @@ FILE* freopen(const char* name, const char* mode, FILE* stream)
switch (*mode++) switch (*mode++)
{ {
case 'b': case 'b':
#if ACKCONF_WANT_O_TEXT_O_BINARY
flags |= _IOBINARY;
#endif
continue; continue;
case '+': case '+':
rwmode = O_RDWR; rwmode = O_RDWR;
@ -62,16 +65,21 @@ FILE* freopen(const char* name, const char* mode, FILE* stream)
break; break;
} }
#if !ACKCONF_WANT_O_TEXT_O_BINARY
if ((rwflags & O_TRUNC) if ((rwflags & O_TRUNC)
|| (((fd = open(name, rwmode)) < 0) || (((fd = open(name, rwmode)) < 0)
&& (rwflags & O_CREAT))) && (rwflags & O_CREAT)))
{ {
if (((fd = creat(name, PMODE)) < 0) && flags | _IOREAD) if (((fd = creat(name, PMODE)) >= 0) && (flags & _IOREAD))
{ {
(void)close(fd); (void)close(fd);
fd = open(name, rwmode); fd = open(name, rwmode);
} }
} }
#else
rwflags |= (flags & _IOBINARY) ? O_BINARY : O_TEXT;
fd = open(name, rwmode | rwflags, PMODE);
#endif
if (fd < 0) if (fd < 0)
{ {