mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Create stdio buffers at FILE creation time.
This removes support for user-supplied buffers with setvbuf.
This commit is contained in:
parent
fe067c5150
commit
bb73362d23
16 changed files with 65 additions and 172 deletions
|
@ -126,8 +126,6 @@ stdio/fscanf_unlocked.o \
|
||||||
stdio/fseek.o \
|
stdio/fseek.o \
|
||||||
stdio/fseeko.o \
|
stdio/fseeko.o \
|
||||||
stdio/fseeko_unlocked.o \
|
stdio/fseeko_unlocked.o \
|
||||||
stdio/fsetdefaultbuf.o \
|
|
||||||
stdio/fsetdefaultbuf_unlocked.o \
|
|
||||||
stdio/fshutdown.o \
|
stdio/fshutdown.o \
|
||||||
stdio/ftell.o \
|
stdio/ftell.o \
|
||||||
stdio/ftello.o \
|
stdio/ftello.o \
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#if !defined(BUFSIZ)
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -72,11 +76,6 @@ typedef struct __FILE FILE;
|
||||||
changed if you make changes to this structure. */
|
changed if you make changes to this structure. */
|
||||||
struct __FILE
|
struct __FILE
|
||||||
{
|
{
|
||||||
/* This is non-standard, but useful. If you allocate your own FILE and
|
|
||||||
register it with fregister, feel free to use modify the following members
|
|
||||||
to customize how it works. Don't call the functions directly, though, as
|
|
||||||
the standard library does various kinds of buffering and conversion. */
|
|
||||||
size_t buffersize;
|
|
||||||
unsigned char* buffer;
|
unsigned char* buffer;
|
||||||
void* user;
|
void* user;
|
||||||
void* free_user;
|
void* free_user;
|
||||||
|
@ -87,10 +86,8 @@ struct __FILE
|
||||||
int (*fileno_func)(void* user);
|
int (*fileno_func)(void* user);
|
||||||
int (*close_func)(void* user);
|
int (*close_func)(void* user);
|
||||||
void (*free_func)(void* free_user, FILE* fp);
|
void (*free_func)(void* free_user, FILE* fp);
|
||||||
/* Application writers shouldn't use anything beyond this point. */
|
|
||||||
pthread_mutex_t file_lock;
|
pthread_mutex_t file_lock;
|
||||||
int (*fflush_indirect)(FILE*);
|
int (*fflush_indirect)(FILE*);
|
||||||
void (*buffer_free_indirect)(void*);
|
|
||||||
FILE* prev;
|
FILE* prev;
|
||||||
FILE* next;
|
FILE* next;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
|
@ -40,10 +40,6 @@
|
||||||
#endif
|
#endif
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#if defined(__is_sortix_libc)
|
|
||||||
#include <FILE.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -121,9 +117,9 @@ typedef __off_t fpos_t;
|
||||||
#define FILE_MODE_CLOEXEC (1 << 7)
|
#define FILE_MODE_CLOEXEC (1 << 7)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern FILE* stdin;
|
extern FILE* const stdin;
|
||||||
extern FILE* stdout;
|
extern FILE* const stdout;
|
||||||
extern FILE* stderr;
|
extern FILE* const stderr;
|
||||||
|
|
||||||
#define stdin stdin
|
#define stdin stdin
|
||||||
#define stdout stdout
|
#define stdout stdout
|
||||||
|
@ -300,8 +296,6 @@ void fregister(FILE* fp);
|
||||||
void fresetfile(FILE* fp);
|
void fresetfile(FILE* fp);
|
||||||
void funregister(FILE* fp);
|
void funregister(FILE* fp);
|
||||||
FILE* fnewfile(void);
|
FILE* fnewfile(void);
|
||||||
int fsetdefaultbuf(FILE* fp);
|
|
||||||
int fsetdefaultbuf_unlocked(FILE* fp);
|
|
||||||
int fshutdown(FILE* fp);
|
int fshutdown(FILE* fp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -323,4 +317,8 @@ int vscanf_callback(void* fp,
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__is_sortix_libc)
|
||||||
|
#include <FILE.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -38,8 +38,7 @@ extern "C" int fgetc_unlocked(FILE* fp)
|
||||||
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, EOF;
|
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, EOF;
|
||||||
|
|
||||||
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
||||||
if ( fsetdefaultbuf_unlocked(fp) != 0 )
|
setvbuf_unlocked(fp, NULL, fp->buffer_mode, 0);
|
||||||
return EOF;
|
|
||||||
|
|
||||||
if ( fp->buffer_mode == _IONBF )
|
if ( fp->buffer_mode == _IONBF )
|
||||||
{
|
{
|
||||||
|
@ -60,12 +59,12 @@ extern "C" int fgetc_unlocked(FILE* fp)
|
||||||
|
|
||||||
if ( !(fp->offset_input_buffer < fp->amount_input_buffered) )
|
if ( !(fp->offset_input_buffer < fp->amount_input_buffered) )
|
||||||
{
|
{
|
||||||
assert(fp->buffer && fp->buffersize);
|
assert(fp->buffer && BUFSIZ);
|
||||||
|
|
||||||
size_t pushback = _FILE_MAX_PUSHBACK;
|
size_t pushback = _FILE_MAX_PUSHBACK;
|
||||||
if ( fp->buffersize <= pushback )
|
if ( BUFSIZ <= pushback )
|
||||||
pushback = 0;
|
pushback = 0;
|
||||||
size_t count = fp->buffersize - pushback;
|
size_t count = BUFSIZ - pushback;
|
||||||
if ( (size_t) SSIZE_MAX < count )
|
if ( (size_t) SSIZE_MAX < count )
|
||||||
count = SSIZE_MAX;
|
count = SSIZE_MAX;
|
||||||
ssize_t numread = fp->read_func(fp->user, fp->buffer + pushback, count);
|
ssize_t numread = fp->read_func(fp->user, fp->buffer + pushback, count);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static void fnewfile_destroyer(void* /*user*/, FILE* fp)
|
static void fnewfile_destroyer(void* /*user*/, FILE* fp)
|
||||||
{
|
{
|
||||||
|
@ -33,9 +34,11 @@ static void fnewfile_destroyer(void* /*user*/, FILE* fp)
|
||||||
|
|
||||||
extern "C" FILE* fnewfile(void)
|
extern "C" FILE* fnewfile(void)
|
||||||
{
|
{
|
||||||
FILE* fp = (FILE*) calloc(sizeof(FILE), 1);
|
FILE* fp = (FILE*) malloc(sizeof(FILE) + BUFSIZ);
|
||||||
if ( !fp )
|
if ( !fp )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
memset(fp, 0, sizeof(FILE));
|
||||||
|
fp->buffer = (unsigned char*) (fp + 1);
|
||||||
fp->free_user = NULL;
|
fp->free_user = NULL;
|
||||||
fp->free_func = fnewfile_destroyer;
|
fp->free_func = fnewfile_destroyer;
|
||||||
fresetfile(fp);
|
fresetfile(fp);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -31,8 +31,7 @@ extern "C" int fputc_unlocked(int c, FILE* fp)
|
||||||
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, EOF;
|
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, EOF;
|
||||||
|
|
||||||
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
||||||
if ( fsetdefaultbuf_unlocked(fp) != 0 )
|
setvbuf_unlocked(fp, NULL, fp->buffer_mode, 0);
|
||||||
return EOF;
|
|
||||||
|
|
||||||
if ( fp->buffer_mode == _IONBF )
|
if ( fp->buffer_mode == _IONBF )
|
||||||
{
|
{
|
||||||
|
@ -51,7 +50,7 @@ extern "C" int fputc_unlocked(int c, FILE* fp)
|
||||||
fp->flags |= _FILE_LAST_WRITE;
|
fp->flags |= _FILE_LAST_WRITE;
|
||||||
fp->flags &= ~_FILE_STATUS_EOF;
|
fp->flags &= ~_FILE_STATUS_EOF;
|
||||||
|
|
||||||
if ( fp->amount_output_buffered == fp->buffersize )
|
if ( fp->amount_output_buffered == BUFSIZ )
|
||||||
{
|
{
|
||||||
if ( fflush_unlocked(fp) == EOF )
|
if ( fflush_unlocked(fp) == EOF )
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -46,8 +46,7 @@ size_t fread_unlocked(void* ptr,
|
||||||
if ( fp->buffer_mode == _IONBF )
|
if ( fp->buffer_mode == _IONBF )
|
||||||
{
|
{
|
||||||
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
||||||
if ( fsetdefaultbuf_unlocked(fp) != 0 )
|
setvbuf_unlocked(fp, NULL, fp->buffer_mode, 0);
|
||||||
return EOF;
|
|
||||||
if ( !fp->read_func )
|
if ( !fp->read_func )
|
||||||
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, 0;
|
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, 0;
|
||||||
if ( fp->flags & _FILE_LAST_WRITE )
|
if ( fp->flags & _FILE_LAST_WRITE )
|
||||||
|
|
|
@ -33,10 +33,12 @@ extern "C" void fresetfile(FILE* fp)
|
||||||
{
|
{
|
||||||
FILE* prev = fp->prev;
|
FILE* prev = fp->prev;
|
||||||
FILE* next = fp->next;
|
FILE* next = fp->next;
|
||||||
|
unsigned char* keep_buffer = fp->buffer;
|
||||||
void* free_user = fp->free_user;
|
void* free_user = fp->free_user;
|
||||||
void (*free_func)(void*, FILE*) = fp->free_func;
|
void (*free_func)(void*, FILE*) = fp->free_func;
|
||||||
int kept_flags = fp->flags & (_FILE_REGISTERED | 0);
|
int kept_flags = fp->flags & (_FILE_REGISTERED | 0);
|
||||||
memset(fp, 0, sizeof(*fp));
|
memset(fp, 0, sizeof(*fp));
|
||||||
|
fp->buffer = keep_buffer;
|
||||||
fp->file_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
fp->file_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||||
fp->flags = kept_flags;
|
fp->flags = kept_flags;
|
||||||
fp->buffer_mode = -1;
|
fp->buffer_mode = -1;
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
|
||||||
|
|
||||||
The Sortix C Library is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
The Sortix C Library is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
stdio/fsetdefaultbuf.cpp
|
|
||||||
Sets up default buffering semantics for a FILE.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
extern "C" int fsetdefaultbuf(FILE* fp)
|
|
||||||
{
|
|
||||||
flockfile(fp);
|
|
||||||
int ret = fsetdefaultbuf_unlocked(fp);
|
|
||||||
funlockfile(fp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
|
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
|
||||||
|
|
||||||
The Sortix C Library is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
The Sortix C Library is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
stdio/fsetdefaultbuf_unlocked.cpp
|
|
||||||
Sets up default buffering semantics for a FILE.
|
|
||||||
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
extern "C" int fsetdefaultbuf_unlocked(FILE* fp)
|
|
||||||
{
|
|
||||||
char* buf = (char*) malloc(sizeof(char) * BUFSIZ);
|
|
||||||
if ( !buf )
|
|
||||||
{
|
|
||||||
// TODO: Determine whether this is truly what we would want and whether
|
|
||||||
// a buffer should be pre-allocated when the FILE is created such that
|
|
||||||
// this situation _cannot_ occur.
|
|
||||||
|
|
||||||
// Alright, we're in a bit of a situation here. Normally, we'd go
|
|
||||||
// buffered but we are out of memory. We could either fail, but that
|
|
||||||
// would mean subsequent calls such as fgetc and fputc would also fail -
|
|
||||||
// however that we are out of memory doesn't mean that IO would also
|
|
||||||
// fail. Therefore we'll revert to unbuffered semantics and hope that's
|
|
||||||
// good enough.
|
|
||||||
|
|
||||||
return setvbuf_unlocked(fp, NULL, _IONBF, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the buffering semantics depending on whether the destination is
|
|
||||||
// an interactive device or not.
|
|
||||||
int mode = fp->buffer_mode;
|
|
||||||
if ( mode == -1 )
|
|
||||||
{
|
|
||||||
#if defined(__is_sortix_kernel)
|
|
||||||
mode = _IOLBF;
|
|
||||||
#else
|
|
||||||
mode = _IOFBF;
|
|
||||||
int saved_errno = errno;
|
|
||||||
if ( isatty(fileno_unlocked(fp)) )
|
|
||||||
mode = _IOLBF;
|
|
||||||
errno = saved_errno;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if ( setvbuf_unlocked(fp, buf, mode, BUFSIZ) )
|
|
||||||
return fp->flags |= _FILE_STATUS_ERROR, free(buf), -1;
|
|
||||||
|
|
||||||
// The buffer now belongs to the FILE.
|
|
||||||
fp->flags |= _FILE_BUFFER_OWNED;
|
|
||||||
fp->buffer_free_indirect = free;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
|
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -34,10 +34,8 @@ extern "C" int fshutdown(FILE* fp)
|
||||||
exact error value, for instance, as with popen/pclose. */;
|
exact error value, for instance, as with popen/pclose. */;
|
||||||
}
|
}
|
||||||
ret = fp->close_func ? fp->close_func(fp->user) : ret;
|
ret = fp->close_func ? fp->close_func(fp->user) : ret;
|
||||||
if ( fp->flags & _FILE_BUFFER_OWNED && fp->buffer_free_indirect )
|
|
||||||
fp->buffer_free_indirect(fp->buffer);
|
|
||||||
// Resetting the FILE here isn't needed in the case where fclose calls us,
|
// Resetting the FILE here isn't needed in the case where fclose calls us,
|
||||||
// but it's nice to zero it out anyway (avoiding state) data, and it's a
|
// but it's nice to zero it out anyway (avoiding stale) data, and it's a
|
||||||
// feature when called by freopen that wishes to reuse the FILE. It also
|
// feature when called by freopen that wishes to reuse the FILE. It also
|
||||||
// means that the file is always in a consistent state.
|
// means that the file is always in a consistent state.
|
||||||
fresetfile(fp);
|
fresetfile(fp);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -46,8 +46,7 @@ size_t fwrite_unlocked(const void* ptr,
|
||||||
if ( fp->buffer_mode == _IONBF )
|
if ( fp->buffer_mode == _IONBF )
|
||||||
{
|
{
|
||||||
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
||||||
if ( fsetdefaultbuf_unlocked(fp) != 0 )
|
setvbuf_unlocked(fp, NULL, fp->buffer_mode, 0);
|
||||||
return EOF;
|
|
||||||
if ( !fp->write_func )
|
if ( !fp->write_func )
|
||||||
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, 0;
|
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, 0;
|
||||||
if ( fp->flags & _FILE_LAST_READ )
|
if ( fp->flags & _FILE_LAST_READ )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
|
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -24,18 +24,28 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
extern "C" int setvbuf_unlocked(FILE* fp, char* buf, int mode, size_t size)
|
extern "C" int setvbuf_unlocked(FILE* fp, char* buf, int mode, size_t size)
|
||||||
{
|
{
|
||||||
if ( fp->flags & _FILE_BUFFER_MODE_SET )
|
(void) buf;
|
||||||
return fp->flags |= _FILE_STATUS_ERROR, errno = EINVAL, -1;
|
(void) size;
|
||||||
fp->buffer_mode = mode;
|
if ( mode == -1 )
|
||||||
if ( buf )
|
|
||||||
{
|
{
|
||||||
fp->buffer = (unsigned char*) buf;
|
#if defined(__is_sortix_kernel)
|
||||||
fp->buffersize = size;
|
mode = _IOLBF;
|
||||||
fp->flags |= _FILE_BUFFER_MODE_SET;
|
#else
|
||||||
fp->fflush_indirect = fflush;
|
mode = _IOFBF;
|
||||||
|
int saved_errno = errno;
|
||||||
|
if ( isatty(fileno_unlocked(fp)) )
|
||||||
|
mode = _IOLBF;
|
||||||
|
errno = saved_errno;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
if ( !fp->buffer )
|
||||||
|
mode = _IONBF;
|
||||||
|
fp->buffer_mode = mode;
|
||||||
|
fp->flags |= _FILE_BUFFER_MODE_SET;
|
||||||
|
fp->fflush_indirect = fflush;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2014, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -29,6 +29,9 @@
|
||||||
|
|
||||||
#include "fdio.h"
|
#include "fdio.h"
|
||||||
|
|
||||||
|
static unsigned char stdin_buffer[BUFSIZ];
|
||||||
|
static unsigned char stdout_buffer[BUFSIZ];
|
||||||
|
|
||||||
static struct fdio_state stdin_fdio = { NULL, 0 };
|
static struct fdio_state stdin_fdio = { NULL, 0 };
|
||||||
static struct fdio_state stdout_fdio = { NULL, 1 };
|
static struct fdio_state stdout_fdio = { NULL, 1 };
|
||||||
static struct fdio_state stderr_fdio = { NULL, 2 };
|
static struct fdio_state stderr_fdio = { NULL, 2 };
|
||||||
|
@ -41,8 +44,7 @@ extern FILE __stderr_file;
|
||||||
|
|
||||||
FILE __stdin_file =
|
FILE __stdin_file =
|
||||||
{
|
{
|
||||||
/* buffersize = */ 0,
|
/* buffer = */ stdin_buffer,
|
||||||
/* buffer = */ NULL,
|
|
||||||
/* user = */ &stdin_fdio,
|
/* user = */ &stdin_fdio,
|
||||||
/* free_user = */ NULL,
|
/* free_user = */ NULL,
|
||||||
/* reopen_func = */ fdio_reopen,
|
/* reopen_func = */ fdio_reopen,
|
||||||
|
@ -54,7 +56,6 @@ FILE __stdin_file =
|
||||||
/* free_func = */ NULL,
|
/* free_func = */ NULL,
|
||||||
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
|
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
|
||||||
/* fflush_indirect = */ NULL,
|
/* fflush_indirect = */ NULL,
|
||||||
/* buffer_free_indirect = */ NULL,
|
|
||||||
/* prev = */ NULL,
|
/* prev = */ NULL,
|
||||||
/* next = */ &__stdout_file,
|
/* next = */ &__stdout_file,
|
||||||
/* flags = */ _FILE_REGISTERED | _FILE_READABLE,
|
/* flags = */ _FILE_REGISTERED | _FILE_READABLE,
|
||||||
|
@ -66,8 +67,7 @@ FILE __stdin_file =
|
||||||
|
|
||||||
FILE __stdout_file
|
FILE __stdout_file
|
||||||
{
|
{
|
||||||
/* buffersize = */ 0,
|
/* buffer = */ stdout_buffer,
|
||||||
/* buffer = */ NULL,
|
|
||||||
/* user = */ &stdout_fdio,
|
/* user = */ &stdout_fdio,
|
||||||
/* free_user = */ NULL,
|
/* free_user = */ NULL,
|
||||||
/* reopen_func = */ fdio_reopen,
|
/* reopen_func = */ fdio_reopen,
|
||||||
|
@ -79,7 +79,6 @@ FILE __stdout_file
|
||||||
/* free_func = */ NULL,
|
/* free_func = */ NULL,
|
||||||
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
|
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
|
||||||
/* fflush_indirect = */ NULL,
|
/* fflush_indirect = */ NULL,
|
||||||
/* buffer_free_indirect = */ NULL,
|
|
||||||
/* prev = */ &__stdin_file,
|
/* prev = */ &__stdin_file,
|
||||||
/* next = */ &__stderr_file,
|
/* next = */ &__stderr_file,
|
||||||
/* flags = */ _FILE_REGISTERED | _FILE_WRITABLE,
|
/* flags = */ _FILE_REGISTERED | _FILE_WRITABLE,
|
||||||
|
@ -91,7 +90,6 @@ FILE __stdout_file
|
||||||
|
|
||||||
FILE __stderr_file
|
FILE __stderr_file
|
||||||
{
|
{
|
||||||
/* buffersize = */ 0,
|
|
||||||
/* buffer = */ NULL,
|
/* buffer = */ NULL,
|
||||||
/* user = */ &stderr_fdio,
|
/* user = */ &stderr_fdio,
|
||||||
/* free_user = */ NULL,
|
/* free_user = */ NULL,
|
||||||
|
@ -104,7 +102,6 @@ FILE __stderr_file
|
||||||
/* free_func = */ NULL,
|
/* free_func = */ NULL,
|
||||||
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
|
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
|
||||||
/* fflush_indirect = */ NULL,
|
/* fflush_indirect = */ NULL,
|
||||||
/* buffer_free_indirect = */ NULL,
|
|
||||||
/* prev = */ &__stdout_file,
|
/* prev = */ &__stdout_file,
|
||||||
/* next = */ NULL,
|
/* next = */ NULL,
|
||||||
/* flags = */ _FILE_REGISTERED | _FILE_WRITABLE,
|
/* flags = */ _FILE_REGISTERED | _FILE_WRITABLE,
|
||||||
|
@ -114,8 +111,8 @@ FILE __stderr_file
|
||||||
/* amount_output_buffered = */ 0,
|
/* amount_output_buffered = */ 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
FILE* stdin = &__stdin_file;
|
FILE* const stdin = &__stdin_file;
|
||||||
FILE* stdout = &__stdout_file;
|
FILE* const stdout = &__stdout_file;
|
||||||
FILE* stderr = &__stderr_file;
|
FILE* const stderr = &__stderr_file;
|
||||||
|
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -36,8 +36,7 @@ extern "C" int ungetc_unlocked(int c, FILE* fp)
|
||||||
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, EOF;
|
return errno = EBADF, fp->flags |= _FILE_STATUS_ERROR, EOF;
|
||||||
|
|
||||||
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
|
||||||
if ( fsetdefaultbuf_unlocked(fp) != 0 )
|
setvbuf_unlocked(fp, NULL, fp->buffer_mode, 0);
|
||||||
return EOF;
|
|
||||||
|
|
||||||
if ( fp->flags & _FILE_LAST_WRITE )
|
if ( fp->flags & _FILE_LAST_WRITE )
|
||||||
fflush_stop_writing_unlocked(fp);
|
fflush_stop_writing_unlocked(fp);
|
||||||
|
@ -51,7 +50,7 @@ extern "C" int ungetc_unlocked(int c, FILE* fp)
|
||||||
if ( fp->offset_input_buffer == 0 )
|
if ( fp->offset_input_buffer == 0 )
|
||||||
{
|
{
|
||||||
size_t amount = fp->amount_input_buffered - fp->offset_input_buffer;
|
size_t amount = fp->amount_input_buffered - fp->offset_input_buffer;
|
||||||
size_t offset = fp->buffersize - amount;
|
size_t offset = BUFSIZ - amount;
|
||||||
if ( !offset )
|
if ( !offset )
|
||||||
return EOF;
|
return EOF;
|
||||||
memmove(fp->buffer + offset, fp->buffer, sizeof(fp->buffer[0]) * amount);
|
memmove(fp->buffer + offset, fp->buffer, sizeof(fp->buffer[0]) * amount);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
extern "C" size_t __fbufsize(FILE* fp)
|
extern "C" size_t __fbufsize(FILE* fp)
|
||||||
{
|
{
|
||||||
flockfile(fp);
|
flockfile(fp);
|
||||||
size_t result = fp->buffersize;
|
int mode = fp->buffer_mode;
|
||||||
funlockfile(fp);
|
funlockfile(fp);
|
||||||
return result;
|
return mode == _IONBF ? 0 : BUFSIZ;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue