Thread-secure stdio.

This commit is contained in:
Jonas 'Sortie' Termansen 2013-09-01 01:42:02 +02:00
parent e1db06c1c9
commit 1ddd404ff9
83 changed files with 1685 additions and 417 deletions

View File

@ -66,56 +66,88 @@ signal/signotset.o \
signal/sigorset.o \
stdio/asprintf.o \
stdio/clearerr.o \
stdio/clearerr_unlocked.o \
stdio/dprintf.o \
stdio/fbufsize.o \
stdio/fbufsize_unlocked.o \
stdio/fclose.o \
stdio/fdeletefile.o \
stdio/feof.o \
stdio/feof_unlocked.o \
stdio/ferror.o \
stdio/ferror_unlocked.o \
stdio/fflush.o \
stdio/fflush_stop_reading.o \
stdio/fflush_stop_reading_unlocked.o \
stdio/fflush_stop_writing.o \
stdio/fflush_stop_writing_unlocked.o \
stdio/fflush_unlocked.o \
stdio/fgetc.o \
stdio/fgetc_unlocked.o \
stdio/fgets.o \
stdio/fgets_unlocked.o \
stdio/fileno_unlocked.o \
stdio/flbf.o \
stdio/flbf_unlocked.o \
stdio/flockfile.o \
stdio/flushlbf.o \
stdio/fnewfile.o \
stdio/fpending.o \
stdio/fpending_unlocked.o \
stdio/fprintf_unlocked.o \
stdio/fpurge.o \
stdio/fpurge_unlocked.o \
stdio/fputc.o \
stdio/fputc_unlocked.o \
stdio/fputs.o \
stdio/fputs_unlocked.o \
stdio/freadable.o \
stdio/freadable_unlocked.o \
stdio/freading.o \
stdio/freading_unlocked.o \
stdio/fread.o \
stdio/fread_unlocked.o \
stdio/fregister.o \
stdio/fresetfile.o \
stdio/fscanf.o \
stdio/fscanf_unlocked.o \
stdio/fseek.o \
stdio/fseeko.o \
stdio/fseeko_unlocked.o \
stdio/fsetdefaultbuf.o \
stdio/fsetdefaultbuf_unlocked.o \
stdio/fseterr.o \
stdio/fseterr_unlocked.o \
stdio/fsetlocking.o \
stdio/fsetlocking_unlocked.o \
stdio/fshutdown.o \
stdio/ftell.o \
stdio/ftello.o \
stdio/ftello_unlocked.o \
stdio/ftrylockfile.o \
stdio/funlockfile.o \
stdio/fwritable.o \
stdio/fwritable_unlocked.o \
stdio/fwrite.o \
stdio/fwrite_unlocked.o \
stdio/fwriting.o \
stdio/fwriting_unlocked.o \
stdio/getdelim.o \
stdio/getline.o \
stdio/rewind.o \
stdio/setbuf.o \
stdio/setvbuf.o \
stdio/setvbuf_unlocked.o \
stdio/snprintf.o \
stdio/sprintf.o \
stdio/sscanf.o \
stdio/ungetc.o \
stdio/ungetc_unlocked.o \
stdio/vasprintf.o \
stdio/vdprintf.o \
stdio/vfprintf_unlocked.o \
stdio/vfscanf.o \
stdio/vfscanf_unlocked.o \
stdio/vprintf_callback.o \
stdio/vscanf_callback.o \
stdio/vsnprintf.o \
@ -359,10 +391,12 @@ stdio/fprintf.o \
stdio/freopen.o \
stdio/fsetpos.o \
stdio/getc.o \
stdio/getc_unlocked.o \
stdio/perror.o \
stdio/popen.o \
stdio/printf.o \
stdio/putc.o \
stdio/putc_unlocked.o \
stdio/removeat.o \
stdio/remove.o \
stdio/renameat.o \

View File

@ -29,6 +29,8 @@
#include <sys/__/types.h>
#include <pthread.h>
__BEGIN_DECLS
#ifndef __off_t_defined
@ -80,6 +82,7 @@ struct FILE
int (*close_func)(void* user);
void (*free_func)(void* free_user, struct FILE* fp);
/* Application writers shouldn't use anything beyond this point. */
pthread_mutex_t file_lock;
struct FILE* prev;
struct FILE* next;
int flags;
@ -89,6 +92,12 @@ struct FILE
size_t amount_output_buffered;
};
/* Internally used by standard library. */
#if defined(__is_sortix_libc)
extern FILE* __first_file;
extern __pthread_mutex_t __first_file_lock;
#endif
__END_DECLS
#endif

View File

@ -100,34 +100,51 @@ extern FILE* stderr;
int asprintf(char** __restrict, const char* __restrict, ...);
void clearerr(FILE* stream);
void clearerr_unlocked(FILE* stream);
int dprintf(int fildes, const char* __restrict format, ...);
int fclose(FILE* stream);
FILE* fdopen(int fildes, const char* mode);
int feof(FILE* stream);
int feof_unlocked(FILE* stream);
int ferror(FILE* stream);
int ferror_unlocked(FILE* stream);
int fflush(FILE* stream);
int fflush_unlocked(FILE* stream);
int fileno(FILE* stream);
int fileno_unlocked(FILE* stream);
int fgetc(FILE* stream);
int fgetc_unlocked(FILE* stream);
int fgetpos(FILE* __restrict stream, fpos_t* __restrict pos);
char* fgets(char* __restrict s, int n, FILE* __restrict stream);
char* fgets_unlocked(char* __restrict, int, FILE* __restrict);
void flockfile(FILE* file);
FILE* fopen(const char* __restrict filename, const char* __restrict mode);
int fprintf(FILE* __restrict stream, const char* __restrict format, ...);
int fprintf_unlocked(FILE* __restrict stream, const char* __restrict format, ...);
int fputc(int c, FILE* stream);
int fputs(const char* __restrict s, FILE* __restrict stream);
int fputc_unlocked(int c, FILE* stream);
int fputs(const char* __restrict, FILE* __restrict stream);
int fputs_unlocked(const char* __restrict, FILE* __restrict stream);
size_t fread(void* __restrict ptr, size_t size, size_t nitems, FILE* __restrict stream);
size_t fread_unlocked(void* __restrict ptr, size_t size, size_t nitems, FILE* __restrict stream);
FILE* freopen(const char* __restrict filename, const char *__restrict mode, FILE* __restrict stream);
int fscanf(FILE* __restrict stream, const char* __restrict format, ... );
int fscanf_unlocked(FILE* __restrict stream, const char* __restrict format, ... );
int fseek(FILE* stream, long offset, int whence);
int fseeko(FILE* stream, off_t offset, int whence);
int fseeko_unlocked(FILE* stream, off_t offset, int whence);
int fsetpos(FILE* stream, const fpos_t* pos);
long ftell(FILE* stream);
off_t ftello(FILE* stream);
off_t ftello_unlocked(FILE* stream);
int ftrylockfile(FILE* file);
void funlockfile(FILE* file);
size_t fwrite(const void* __restrict ptr, size_t size, size_t nitems, FILE* __restrict stream);
size_t fwrite_unlocked(const void* __restrict ptr, size_t size, size_t nitems, FILE* __restrict stream);
int getc(FILE* stream);
int getc_unlocked(FILE* stream);
int getchar(void);
int getchar_unlocked(void);
ssize_t getdelim(char** __restrict lineptr, size_t* __restrict n, int delimiter, FILE* __restrict stream);
ssize_t getline(char** __restrict lineptr, size_t* __restrict n, FILE* __restrict stream);
int pclose(FILE* steam);
@ -135,7 +152,9 @@ void perror(const char* s);
FILE* popen(const char* command, const char* mode);
int printf(const char* __restrict format, ...);
int putc(int c, FILE* stream);
int putc_unlocked(int c, FILE* stream);
int putchar(int c);
int putchar_unlocked(int c);
int puts(const char* str);
int removeat(int dirrfd, const char* path);
int remove(const char* path);
@ -145,6 +164,7 @@ void rewind(FILE* stream);
int snprintf(char* __restrict s, size_t n, const char* __restrict format, ...);
void setbuf(FILE* __restrict stream, char* __restrict buf);
int setvbuf(FILE* __restrict stream, char* __restrict buf, int type, size_t size);
int setvbuf_unlocked(FILE* __restrict stream, char* __restrict buf, int type, size_t size);
char* sortix_gets(void);
int sortix_puts(const char* str);
int sprintf(char* __restrict s, const char* __restrict format, ...);
@ -153,10 +173,13 @@ int sscanf(const char* __restrict s, const char* __restrict format, ...);
FILE* tmpfile(void);
char* tmpnam(char* s);
int ungetc(int c, FILE* stream);
int ungetc_unlocked(int c, FILE* stream);
int vasprintf(char** __restrict, const char* __restrict, __gnuc_va_list);
int vdprintf(int fildes, const char* __restrict format, __gnuc_va_list ap);
int vfprintf(FILE* __restrict stream, const char* __restrict format, __gnuc_va_list ap);
int vfprintf_unlocked(FILE* __restrict stream, const char* __restrict format, __gnuc_va_list ap);
int vfscanf(FILE* __restrict stream, const char* __restrict format, __gnuc_va_list arg);
int vfscanf_unlocked(FILE* __restrict stream, const char* __restrict format, __gnuc_va_list arg);
int vprintf(const char* __restrict format, __gnuc_va_list ap);
int vscanf(const char* __restrict format, __gnuc_va_list arg);
int vsnprintf(char* __restrict, size_t, const char* __restrict, __gnuc_va_list);
@ -168,40 +191,45 @@ int vsscanf(const char* __restrict s, const char* __restrict format, __gnuc_va_l
char* ctermid(char* s);
FILE *fmemopen(void* __restrict buf, size_t size, const char* __restrict mode);
FILE* open_memstream(char** bufp, size_t* sizep);
int getchar_unlocked(void);
int getc_unlocked(FILE* stream);
int putchar_unlocked(int c);
int putc_unlocked(int c, FILE* steam);
#endif
#if defined(_SORTIX_SOURCE)
#include <stdio_ext.h>
#define fbufsize __fbufsize
size_t fbufsize_unlocked(FILE* fp);
#define freading __freading
int freading_unlocked(FILE* fp);
#define fwriting __fwriting
int fwriting_unlocked(FILE* fp);
#define freadable __freadable
int freadable_unlocked(FILE* fp);
#define fwritable __fwritable
int fwritable_unlocked(FILE* fp);
#define flbf __flbf
int flbf_unlocked(FILE* fp);
#define fpurge __fpurge
void fpurge_unlocked(FILE* fp);
#define fpending __fpending
size_t fpending_unlocked(FILE* fp);
#define flushlbf _flushlbf
#define fsetlocking __fsetlocking
int fsetlocking_unlocked(FILE* fp, int type);
int fflush_stop_reading(FILE* fp);
int fflush_stop_reading_unlocked(FILE* fp);
int fflush_stop_writing(FILE* fp);
int fflush_stop_writing_unlocked(FILE* fp);
void fdeletefile(FILE* fp);
void fseterr(FILE* fp);
void fseterr_unlocked(FILE* fp);
void fregister(FILE* fp);
void fresetfile(FILE* fp);
void funregister(FILE* fp);
FILE* fnewfile(void);
int fsetdefaultbuf(FILE* fp);
int fsetdefaultbuf_unlocked(FILE* fp);
int fcloseall(void);
int fshutdown(FILE* fp);
int fpipe(FILE* pipes[2]);
/* Internally used by standard library. */
#if defined(__is_sortix_libc)
extern FILE* _firstfile;
#endif
#endif
#if defined(_SORTIX_SOURCE) || defined(_WANT_SORTIX_VPRINTF_CALLBACK)

View File

@ -27,6 +27,7 @@
#include <sys/cdefs.h>
#include <__/pthread.h>
#include <sys/__/types.h>
#include <__/wchar.h>

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,6 +26,7 @@
extern "C" void clearerr(FILE* fp)
{
if ( fp->clearerr_func )
fp->clearerr_func(fp->user);
flockfile(fp);
clearerr_unlocked(fp);
funlockfile(fp);
}

View File

@ -0,0 +1,31 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/clearerr_unlocked.cpp
Clears the error condition on a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C" void clearerr_unlocked(FILE* fp)
{
if ( fp->clearerr_func )
fp->clearerr_func(fp->user);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,5 +26,8 @@
extern "C" size_t fbufsize(FILE* fp)
{
return fp->buffersize;
flockfile(fp);
size_t result = fbufsize_unlocked(fp);
funlockfile(fp);
return result;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fbufsize_unlocked.cpp
Returns the size of the FILE's buffer.
*******************************************************************************/
#include <stdio.h>
extern "C" size_t fbufsize_unlocked(FILE* fp)
{
return fp->buffersize;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -27,6 +27,9 @@
extern "C" int fcloseall(void)
{
int result = 0;
while ( _firstfile ) { result |= fclose(_firstfile); }
return (result) ? EOF : 0;
// We do not lock __first_file_lock here because this function is called on
// process termination and only one thread can call exit(3).
while ( __first_file )
result |= fclose(__first_file);
return result ? EOF : 0;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,10 +26,8 @@
extern "C" int feof(FILE* fp)
{
size_t input_buffered = fp->amount_input_buffered - fp->offset_input_buffer;
if ( input_buffered )
return 0;
if ( fp->eof_func )
return fp->eof_func(fp->user);
return 0;
flockfile(fp);
int ret = feof_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,35 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/feof_unlocked.cpp
Returns whether the end of file condition is set on a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C" int feof_unlocked(FILE* fp)
{
size_t input_buffered = fp->amount_input_buffered - fp->offset_input_buffer;
if ( input_buffered )
return 0;
if ( fp->eof_func )
return fp->eof_func(fp->user);
return 0;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,7 +26,8 @@
extern "C" int ferror(FILE* fp)
{
if ( fp->error_func )
return fp->error_func(fp->user);
return 0;
flockfile(fp);
int ret = ferror_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,32 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/ferror_unlocked.cpp
Returns whether the error condition is set on a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C" int ferror_unlocked(FILE* fp)
{
if ( fp->error_func )
return fp->error_func(fp->user);
return 0;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -22,23 +22,23 @@
*******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
extern "C" int fflush(FILE* fp)
{
if ( !fp )
{
int result = 0;
for ( fp = _firstfile; fp; fp = fp->next ) { result |= fflush(fp); }
pthread_mutex_lock(&__first_file_lock);
for ( fp = __first_file; fp; fp = fp->next )
result |= fflush(fp);
pthread_mutex_unlock(&__first_file_lock);
return result;
}
int mode = fp->flags & (_FILE_LAST_READ | _FILE_LAST_WRITE);
if ( (mode & _FILE_LAST_READ) && fflush_stop_reading(fp) == EOF )
return EOF;
if ( (mode & _FILE_LAST_WRITE) && fflush_stop_writing(fp) == EOF )
return EOF;
fp->flags |= mode;
return 0;
flockfile(fp);
int ret = fflush_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
This file is part of the Sortix C Library.
@ -22,37 +22,12 @@
*******************************************************************************/
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
extern "C" int fflush_stop_reading(FILE* fp)
{
if ( !(fp->flags & _FILE_LAST_READ) )
return 0;
int ret = 0;
size_t bufferahead = fp->amount_input_buffered - fp->offset_input_buffer;
if ( (fp->flags & _FILE_STREAM) )
{
if ( bufferahead )
/* TODO: Data loss!*/{}
}
if ( !(fp->flags & _FILE_STREAM) )
{
off_t rewind_amount = -((off_t) bufferahead);
off_t my_pos = fp->tell_func(fp->user);
off_t expected_pos = my_pos + rewind_amount;
#if 1
if ( fp->seek_func && fp->seek_func(fp->user, expected_pos, SEEK_SET) != 0 )
#else
if ( fp->seek_func && fp->seek_func(fp->user, rewind_amount, SEEK_CUR) != 0 )
#endif
ret = EOF;
off_t newpos = fp->tell_func(fp->user);
assert(ret == EOF || expected_pos == newpos);
}
fp->amount_input_buffered = fp->offset_input_buffer = 0;
fp->flags &= ~_FILE_LAST_READ;
flockfile(fp);
int ret = fflush_stop_reading_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,58 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 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/fflush_stop_reading_unlocked.cpp
Resets the FILE to a consistent state so it is ready for writing.
*******************************************************************************/
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
extern "C" int fflush_stop_reading_unlocked(FILE* fp)
{
if ( !(fp->flags & _FILE_LAST_READ) )
return 0;
int ret = 0;
size_t bufferahead = fp->amount_input_buffered - fp->offset_input_buffer;
if ( (fp->flags & _FILE_STREAM) )
{
if ( bufferahead )
/* TODO: Data loss!*/{}
}
if ( !(fp->flags & _FILE_STREAM) )
{
off_t rewind_amount = -((off_t) bufferahead);
off_t my_pos = fp->tell_func(fp->user);
off_t expected_pos = my_pos + rewind_amount;
#if 1
if ( fp->seek_func && fp->seek_func(fp->user, expected_pos, SEEK_SET) != 0 )
#else
if ( fp->seek_func && fp->seek_func(fp->user, rewind_amount, SEEK_CUR) != 0 )
#endif
ret = EOF;
off_t newpos = fp->tell_func(fp->user);
assert(ret == EOF || expected_pos == newpos);
}
fp->amount_input_buffered = fp->offset_input_buffer = 0;
fp->flags &= ~_FILE_LAST_READ;
return ret;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
This file is part of the Sortix C Library.
@ -27,16 +27,8 @@
extern "C" int fflush_stop_writing(FILE* fp)
{
if ( !(fp->flags & _FILE_LAST_WRITE) )
return 0;
if ( !fp->write_func )
return errno = EBADF, EOF;
size_t size = sizeof(unsigned char);
size_t count = fp->amount_output_buffered;
int ret = 0;
if ( fp->write_func(fp->buffer, size, count, fp->user) != count )
ret = EOF; // TODO: Set errno!
fp->amount_output_buffered = 0;
fp->flags &= ~_FILE_LAST_WRITE;
flockfile(fp);
int ret = fflush_stop_writing_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,42 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 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/fflush_stop_writing_unlocked.cpp
Resets the FILE to a consistent state so it is ready for reading.
*******************************************************************************/
#include <errno.h>
#include <stdio.h>
extern "C" int fflush_stop_writing_unlocked(FILE* fp)
{
if ( !(fp->flags & _FILE_LAST_WRITE) )
return 0;
if ( !fp->write_func )
return errno = EBADF, EOF;
size_t size = sizeof(unsigned char);
size_t count = fp->amount_output_buffered;
int ret = 0;
if ( fp->write_func(fp->buffer, size, count, fp->user) != count )
ret = EOF; // TODO: Set errno!
fp->amount_output_buffered = 0;
fp->flags &= ~_FILE_LAST_WRITE;
return ret;
}

View File

@ -0,0 +1,36 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fflush_unlocked.cpp
Flushes a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C" int fflush_unlocked(FILE* fp)
{
int mode = fp->flags & (_FILE_LAST_READ | _FILE_LAST_WRITE);
if ( (mode & _FILE_LAST_READ) && fflush_stop_reading_unlocked(fp) == EOF )
return EOF;
if ( (mode & _FILE_LAST_WRITE) && fflush_stop_writing_unlocked(fp) == EOF )
return EOF;
fp->flags |= mode;
return 0;
}

View File

@ -22,52 +22,12 @@
*******************************************************************************/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
extern "C" int fgetc(FILE* fp)
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( fp->buffer_mode == _IONBF )
{
unsigned char c;
if ( fread(&c, sizeof(c), 1, fp) != 1 )
return EOF;
return c;
}
if ( !fp->read_func )
return EOF; // TODO: ferror doesn't report error!
if ( fp->flags & _FILE_LAST_WRITE )
fflush_stop_writing(fp);
fp->flags |= _FILE_LAST_READ;
if ( fp->offset_input_buffer < fp->amount_input_buffered )
retry:
return fp->buffer[fp->offset_input_buffer++];
assert(fp->buffer && fp->buffersize);
size_t pushback = _FILE_MAX_PUSHBACK;
if ( fp->buffersize <= pushback )
pushback = 0;
size_t count = fp->buffersize - pushback;
size_t size = sizeof(unsigned char);
size_t numread = fp->read_func(fp->buffer + pushback, size, count, fp->user);
if ( !numread )
return EOF;
fp->offset_input_buffer = pushback;
fp->amount_input_buffered = pushback + numread;
goto retry;
flockfile(fp);
int ret = fgetc_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,73 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fgetc_unlocked.cpp
Reads a single character from a FILE.
*******************************************************************************/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
extern "C" int fgetc_unlocked(FILE* fp)
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf_unlocked(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( fp->buffer_mode == _IONBF )
{
unsigned char c;
if ( fread_unlocked(&c, sizeof(c), 1, fp) != 1 )
return EOF;
return c;
}
if ( !fp->read_func )
return EOF; // TODO: ferror doesn't report error!
if ( fp->flags & _FILE_LAST_WRITE )
fflush_stop_writing_unlocked(fp);
fp->flags |= _FILE_LAST_READ;
if ( fp->offset_input_buffer < fp->amount_input_buffered )
retry:
return fp->buffer[fp->offset_input_buffer++];
assert(fp->buffer && fp->buffersize);
size_t pushback = _FILE_MAX_PUSHBACK;
if ( fp->buffersize <= pushback )
pushback = 0;
size_t count = fp->buffersize - pushback;
size_t size = sizeof(unsigned char);
size_t numread = fp->read_func(fp->buffer + pushback, size, count, fp->user);
if ( !numread )
return EOF;
fp->offset_input_buffer = pushback;
fp->amount_input_buffered = pushback + numread;
goto retry;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2014.
This file is part of the Sortix C Library.
@ -23,25 +23,11 @@
*******************************************************************************/
#include <stdio.h>
#include <errno.h>
extern "C" char* fgets(char* dest, int size, FILE* fp)
extern "C" char* fgets(char* restrict dest, int size, FILE* restrict fp)
{
if ( size <= 0 )
return errno = EINVAL, (char*) NULL;
int i;
for ( i = 0; i < size-1; i++ )
{
int c = getc(fp);
if ( c == EOF )
break;
dest[i] = c;
if ( c == '\n' ) { i++; break; }
}
if ( !i && (ferror(fp) || feof(fp)) )
return NULL;
// TODO: The end-of-file state is lost here if feof(fp) and we are reading
// from a terminal that encountered a soft EOF.
dest[i] = '\0';
return dest;
flockfile(fp);
char* result = fgets_unlocked(dest, size, fp);
funlockfile(fp);
return result;
}

View File

@ -0,0 +1,52 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fgets_unlocked.cpp
Reads a string from a FILE.
*******************************************************************************/
#include <stdio.h>
#include <errno.h>
extern "C"
char* fgets_unlocked(char* restrict dest, int size, FILE* restrict fp)
{
if ( size <= 0 )
return errno = EINVAL, (char*) NULL;
int i;
for ( i = 0; i < size-1; i++ )
{
int c = fgetc_unlocked(fp);
if ( c == EOF )
break;
dest[i] = c;
if ( c == '\n' )
{
i++;
break;
}
}
if ( !i && (ferror_unlocked(fp) || feof_unlocked(fp)) )
return NULL;
// TODO: The end-of-file state is lost here if feof(fp) and we are reading
// from a terminal that encountered a soft EOF.
dest[i] = '\0';
return dest;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -27,7 +27,8 @@
extern "C" int fileno(FILE* fp)
{
int result = fp->fileno_func ? fp->fileno_func(fp->user) : -1;
if ( result < 0 ) { errno = EBADF; }
return result;
flockfile(fp);
int ret = fileno_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,34 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fileno_unlocked.cpp
Returns the underlying file descriptor of a FILE if applicable.
*******************************************************************************/
#include <stdio.h>
#include <errno.h>
extern "C" int fileno_unlocked(FILE* fp)
{
int result = fp->fileno_func ? fp->fileno_func(fp->user) : -1;
if ( result < 0 )
errno = EBADF;
return result;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,5 +26,8 @@
extern "C" int flbf(FILE* fp)
{
return fp->buffer_mode == _IOLBF;
flockfile(fp);
int ret = flbf_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/flbf_unlocked.cpp
Returns whether a FILE is line buffered.
*******************************************************************************/
#include <stdio.h>
extern "C" int flbf_unlocked(FILE* fp)
{
return fp->buffer_mode == _IOLBF;
}

View File

@ -22,9 +22,10 @@
*******************************************************************************/
#include <pthread.h>
#include <stdio.h>
extern "C" void flockfile(FILE* /*fp*/)
extern "C" void flockfile(FILE* fp)
{
// TODO: Thread safety.
pthread_mutex_lock(&fp->file_lock);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -22,10 +22,13 @@
*******************************************************************************/
#include <pthread.h>
#include <stdio.h>
extern "C" void flushlbf(void)
{
for ( FILE* fp = _firstfile; fp; fp = fp->next )
pthread_mutex_lock(&__first_file_lock);
for ( FILE* fp = __first_file; fp; fp = fp->next )
fflush(fp);
pthread_mutex_unlock(&__first_file_lock);
}

View File

@ -22,6 +22,7 @@
*******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,5 +26,8 @@
extern "C" size_t fpending(FILE* fp)
{
return fp->amount_output_buffered;
flockfile(fp);
size_t ret = fpending_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fpending_unlocked.cpp
Returns the number of bytes pending in the output buffer.
*******************************************************************************/
#include <stdio.h>
extern "C" size_t fpending_unlocked(FILE* fp)
{
return fp->amount_output_buffered;
}

View File

@ -29,7 +29,9 @@ extern "C" int fprintf(FILE* fp, const char* restrict format, ...)
{
va_list list;
va_start(list, format);
int result = vfprintf(fp, format, list);
flockfile(fp);
int result = vfprintf_unlocked(fp, format, list);
funlockfile(fp);
va_end(list);
return result;
}

View File

@ -0,0 +1,35 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fprintf_unlocked.cpp
Prints a string to a FILE.
*******************************************************************************/
#include <stdarg.h>
#include <stdio.h>
extern "C" int fprintf_unlocked(FILE* fp, const char* restrict format, ...)
{
va_list list;
va_start(list, format);
int result = vfprintf_unlocked(fp, format, list);
va_end(list);
return result;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,7 +26,7 @@
extern "C" void fpurge(FILE* fp)
{
fp->offset_input_buffer = 0;
fp->amount_input_buffered = 0;
fp->amount_output_buffered = 0;
flockfile(fp);
fpurge_unlocked(fp);
funlockfile(fp);
}

View File

@ -0,0 +1,32 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fpurge_unlocked.cpp
Discards all contents in the FILE's buffer.
*******************************************************************************/
#include <stdio.h>
extern "C" void fpurge_unlocked(FILE* fp)
{
fp->offset_input_buffer = 0;
fp->amount_input_buffered = 0;
fp->amount_output_buffered = 0;
}

View File

@ -26,31 +26,8 @@
extern "C" int fputc(int c, FILE* fp)
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( fp->buffer_mode == _IONBF )
{
unsigned char c_char = c;
if ( fwrite(&c_char, sizeof(c_char), 1, fp) != 1 )
return EOF;
return c;
}
if ( !fp->write_func )
return EOF; // TODO: ferror doesn't report error!
if ( fp->flags & _FILE_LAST_READ )
fflush_stop_reading(fp);
fp->flags |= _FILE_LAST_WRITE;
if ( fp->amount_output_buffered == fp->buffersize && fflush(fp) != 0 )
return EOF;
fp->buffer[fp->amount_output_buffered++] = c;
if ( fp->buffer_mode == _IOLBF && c == '\n' && fflush(fp) != 0 )
return EOF;
return c;
flockfile(fp);
int ret = fputc_unlocked(c, fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,56 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fputc_unlocked.cpp
Writes a character to a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C" int fputc_unlocked(int c, FILE* fp)
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf_unlocked(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( fp->buffer_mode == _IONBF )
{
unsigned char c_char = c;
if ( fwrite_unlocked(&c_char, sizeof(c_char), 1, fp) != 1 )
return EOF;
return c;
}
if ( !fp->write_func )
return EOF; // TODO: ferror doesn't report error!
if ( fp->flags & _FILE_LAST_READ )
fflush_stop_reading_unlocked(fp);
fp->flags |= _FILE_LAST_WRITE;
if ( fp->amount_output_buffered == fp->buffersize && fflush_unlocked(fp) != 0 )
return EOF;
fp->buffer[fp->amount_output_buffered++] = c;
if ( fp->buffer_mode == _IOLBF && c == '\n' && fflush_unlocked(fp) != 0 )
return EOF;
return c;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
This file is part of the Sortix C Library.
@ -23,13 +23,11 @@
*******************************************************************************/
#include <stdio.h>
#include <string.h>
extern "C" int fputs(const char* str, FILE* fp)
{
size_t stringlen = strlen(str);
size_t result = fwrite(str, 1, stringlen, fp);
if ( result < stringlen )
return EOF;
flockfile(fp);
int result = fputs_unlocked(str, fp);
funlockfile(fp);
return result;
}

View File

@ -0,0 +1,35 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fputs_unlocked.cpp
Writes a string to a FILE.
*******************************************************************************/
#include <stdio.h>
#include <string.h>
extern "C" int fputs_unlocked(const char* str, FILE* fp)
{
size_t stringlen = strlen(str);
size_t result = fwrite_unlocked(str, 1, stringlen, fp);
if ( result < stringlen )
return EOF;
return result;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,32 +26,8 @@
extern "C" size_t fread(void* ptr, size_t size, size_t nmemb, FILE* fp)
{
if ( fp->buffer_mode == _IONBF )
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( !fp->read_func )
return 0; // TODO: ferror doesn't report error!
if ( fp->flags & _FILE_LAST_WRITE )
fflush_stop_writing(fp);
fp->flags |= _FILE_LAST_READ;
return fp->read_func(ptr, size, nmemb, fp->user);
}
unsigned char* buf = (unsigned char*) ptr;
for ( size_t n = 0; n < nmemb; n++ )
{
size_t offset = n * size;
for ( size_t i = 0; i < size; i++ )
{
int c = fgetc(fp);
if ( c == EOF )
return n;
size_t index = i + offset;
buf[index] = c;
}
}
return nmemb;
flockfile(fp);
size_t ret = fread_unlocked(ptr, size, nmemb, fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,58 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fread_unlocked.cpp
Reads data from a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C"
size_t fread_unlocked(void* ptr, size_t size, size_t nmemb, FILE* fp)
{
if ( fp->buffer_mode == _IONBF )
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf_unlocked(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( !fp->read_func )
return 0; // TODO: ferror doesn't report error!
if ( fp->flags & _FILE_LAST_WRITE )
fflush_stop_writing_unlocked(fp);
fp->flags |= _FILE_LAST_READ;
return fp->read_func(ptr, size, nmemb, fp->user);
}
unsigned char* buf = (unsigned char*) ptr;
for ( size_t n = 0; n < nmemb; n++ )
{
size_t offset = n * size;
for ( size_t i = 0; i < size; i++ )
{
int c = fgetc_unlocked(fp);
if ( c == EOF )
return n;
size_t index = i + offset;
buf[index] = c;
}
}
return nmemb;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,5 +26,8 @@
extern "C" int freadable(FILE* fp)
{
return fp->read_func != NULL;
flockfile(fp);
int ret = freadable_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/freadable_unlocked.cpp
Returns whether this FILE can be read from.
*******************************************************************************/
#include <stdio.h>
extern "C" int freadable_unlocked(FILE* fp)
{
return fp->read_func != NULL;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,7 +26,8 @@
extern "C" int freading(FILE* fp)
{
if ( fp->read_func ) { return 1; }
if ( fp->flags & _FILE_LAST_READ ) { return 1; }
return 0;
flockfile(fp);
int ret = freading_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,34 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/freading_unlocked.cpp
Returns whether the last operation was a read or FILE is read only.
*******************************************************************************/
#include <stdio.h>
extern "C" int freading_unlocked(FILE* fp)
{
if ( fp->read_func )
return 1;
if ( fp->flags & _FILE_LAST_READ )
return 1;
return 0;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -23,24 +23,39 @@
*******************************************************************************/
#include <pthread.h>
#include <stdio.h>
extern "C" { FILE* _firstfile = NULL; }
extern "C"
{
FILE* __first_file = NULL;
pthread_mutex_t __first_file_lock = PTHREAD_MUTEX_INITIALIZER;
}
extern "C" void fregister(FILE* fp)
{
pthread_mutex_lock(&__first_file_lock);
fp->flags |= _FILE_REGISTERED;
if ( !_firstfile ) { _firstfile = fp; return; }
fp->next = _firstfile;
_firstfile->prev = fp;
_firstfile = fp;
if ( __first_file )
{
fp->next = __first_file;
__first_file->prev = fp;
}
__first_file = fp;
pthread_mutex_unlock(&__first_file_lock);
}
extern "C" void funregister(FILE* fp)
{
if ( !(fp->flags & _FILE_REGISTERED) ) { return; }
if ( !fp->prev ) { _firstfile = fp->next; }
if ( fp->prev ) { fp->prev->next = fp->next; }
if ( fp->next ) { fp->next->prev = fp->prev; }
if ( !(fp->flags & _FILE_REGISTERED) )
return;
pthread_mutex_lock(&__first_file_lock);
if ( !fp->prev )
__first_file = fp->next;
if ( fp->prev )
fp->prev->next = fp->next;
if ( fp->next )
fp->next->prev = fp->prev;
fp->flags &= ~_FILE_REGISTERED;
pthread_mutex_unlock(&__first_file_lock);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
This file is part of the Sortix C Library.
@ -37,6 +37,7 @@ extern "C" void fresetfile(FILE* fp)
void (*free_func)(void*, FILE*) = fp->free_func;
int kept_flags = fp->flags & (_FILE_REGISTERED | 0);
memset(fp, 0, sizeof(*fp));
fp->file_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
fp->flags = kept_flags | _FILE_AUTO_LOCK;
fp->buffer_mode = -1;
fp->free_user = free_user;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
This file is part of the Sortix C Library.

View File

@ -0,0 +1,37 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 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/fscanf_unlocked.cpp
Input format conversion.
*******************************************************************************/
#include <stdarg.h>
#include <stdio.h>
extern "C" int fscanf_unlocked(FILE* fp, const char* format, ...)
{
va_list ap;
va_start(ap, format);
flockfile(fp);
int ret = vfscanf_unlocked(fp, format, ap);
funlockfile(fp);
va_end(ap);
return ret;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -22,15 +22,12 @@
*******************************************************************************/
#include <errno.h>
#include <stdio.h>
extern "C" int fseeko(FILE* fp, off_t offset, int whence)
{
if ( fflush(fp) != 0 )
return -1;
if ( !fp->seek_func )
return errno = EBADF, -1;
int ret = fp->seek_func(fp->user, offset, whence);
flockfile(fp);
int ret = fseeko_unlocked(fp, offset, whence);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,36 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fseeko_unlocked.cpp
Changes the current offset in a FILE.
*******************************************************************************/
#include <errno.h>
#include <stdio.h>
extern "C" int fseeko_unlocked(FILE* fp, off_t offset, int whence)
{
if ( fflush_unlocked(fp) != 0 )
return -1;
if ( !fp->seek_func )
return errno = EBADF, -1;
int ret = fp->seek_func(fp->user, offset, whence);
return ret;
}

View File

@ -23,44 +23,11 @@
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
extern "C" int fsetdefaultbuf(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(fp, NULL, _IONBF, 0);
}
// Determine the buffering semantics depending on whether the destination is
// an interactive device or not.
#if defined(__is_sortix_kernel)
int mode = _IOLBF; // TODO: Detect this?
#else
int mode = fp->buffer_mode != -1 ? fp->buffer_mode
: isatty(fileno(fp)) ? _IOLBF : _IOFBF;
#endif
int ret = setvbuf(fp, buf, mode, BUFSIZ);
if ( ret )
{
free(buf);
return -1;
}
// The buffer now belongs to the FILE.
fp->flags |= _FILE_BUFFER_OWNED;
flockfile(fp);
int ret = fsetdefaultbuf_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,67 @@
/*******************************************************************************
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_unlocked.cpp
Sets up default buffering semantics for a FILE.
*******************************************************************************/
#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.
#if defined(__is_sortix_kernel)
int mode = _IOLBF; // TODO: Detect this?
#else
int mode = fp->buffer_mode != -1 ? fp->buffer_mode
: isatty(fileno_unlocked(fp)) ? _IOLBF
: _IOFBF;
#endif
int ret = setvbuf_unlocked(fp, buf, mode, BUFSIZ);
if ( ret )
{
free(buf);
return -1;
}
// The buffer now belongs to the FILE.
fp->flags |= _FILE_BUFFER_OWNED;
return ret;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,6 +26,7 @@
extern "C" void fseterr(FILE* fp)
{
if ( fp->seterr_func )
fp->seterr_func(fp->user);
flockfile(fp);
fseterr_unlocked(fp);
funlockfile(fp);
}

View File

@ -0,0 +1,31 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fseterr_unlocked.cpp
Sets the error condition bit on a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C" void fseterr_unlocked(FILE* fp)
{
if ( fp->seterr_func )
fp->seterr_func(fp->user);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,11 +26,8 @@
extern "C" int fsetlocking(FILE* fp, int type)
{
switch ( type )
{
case FSETLOCKING_INTERNAL: fp->flags |= _FILE_AUTO_LOCK;
case FSETLOCKING_BYCALLER: fp->flags &= ~_FILE_AUTO_LOCK;
}
return (fp->flags & _FILE_AUTO_LOCK) ? FSETLOCKING_INTERNAL
: FSETLOCKING_BYCALLER;
flockfile(fp);
int ret = fsetlocking_unlocked(fp, type);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,37 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fsetlocking_unlocked.cpp
Sets the desired locking semantics on a FILE.
*******************************************************************************/
#include <stdio.h>
// TODO: What is this? This looks like something I ought to support!
extern "C" int fsetlocking_unlocked(FILE* fp, int type)
{
switch ( type )
{
case FSETLOCKING_INTERNAL: fp->flags |= _FILE_AUTO_LOCK;
case FSETLOCKING_BYCALLER: fp->flags &= ~_FILE_AUTO_LOCK;
}
return (fp->flags & _FILE_AUTO_LOCK) ? FSETLOCKING_INTERNAL
: FSETLOCKING_BYCALLER;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -22,22 +22,12 @@
*******************************************************************************/
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
extern "C" off_t ftello(FILE* fp)
{
if ( !fp->tell_func )
return errno = EBADF, -1;
off_t offset = fp->tell_func(fp->user);
if ( offset < 0 )
return -1;
off_t readahead = fp->amount_input_buffered - fp->offset_input_buffer;
off_t writebehind = fp->amount_output_buffered;
off_t result = offset - readahead + writebehind;
if ( result < 0 ) // Too much ungetc'ing.
return 0;
return result;
flockfile(fp);
off_t ret = ftello_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,43 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/ftello_unlocked.cpp
Returns the current offset of a FILE.
*******************************************************************************/
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
extern "C" off_t ftello_unlocked(FILE* fp)
{
if ( !fp->tell_func )
return errno = EBADF, -1;
off_t offset = fp->tell_func(fp->user);
if ( offset < 0 )
return -1;
off_t readahead = fp->amount_input_buffered - fp->offset_input_buffer;
off_t writebehind = fp->amount_output_buffered;
off_t result = offset - readahead + writebehind;
if ( result < 0 ) // Too much ungetc'ing.
return 0;
return result;
}

View File

@ -22,10 +22,10 @@
*******************************************************************************/
#include <pthread.h>
#include <stdio.h>
extern "C" int ftrylockfile(FILE* /*fp*/)
extern "C" int ftrylockfile(FILE* fp)
{
// TODO: Thread safety.
return 0;
return pthread_mutex_lock(&fp->file_lock) ? -1 : 0;
}

View File

@ -22,9 +22,10 @@
*******************************************************************************/
#include <pthread.h>
#include <stdio.h>
extern "C" void funlockfile(FILE* /*fp*/)
extern "C" void funlockfile(FILE* fp)
{
// TODO: Thread safety.
pthread_mutex_unlock(&fp->file_lock);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,5 +26,8 @@
extern "C" int fwritable(FILE* fp)
{
return fp->write_func != NULL;
flockfile(fp);
int ret = fwritable_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fwritable_unlocked.cpp
Returns whether this FILE can be written to.
*******************************************************************************/
#include <stdio.h>
extern "C" int fwritable_unlocked(FILE* fp)
{
return fp->write_func != NULL;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,31 +26,8 @@
extern "C" size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* fp)
{
if ( fp->buffer_mode == _IONBF )
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( !fp->write_func )
return 0; // TODO: ferror doesn't report error!
if ( fp->flags & _FILE_LAST_READ )
fflush_stop_reading(fp);
fp->flags |= _FILE_LAST_WRITE;
return fp->write_func(ptr, size, nmemb, fp->user);
}
const unsigned char* buf = (const unsigned char*) ptr;
for ( size_t n = 0; n < nmemb; n++ )
{
size_t offset = n * size;
for ( size_t i = 0; i < size; i++ )
{
size_t index = offset + i;
if ( fputc(buf[index], fp) == EOF )
return n;
}
}
return nmemb;
flockfile(fp);
size_t ret = fwrite_unlocked(ptr, size, nmemb, fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,57 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fwrite_unlocked.cpp
Writes data to a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C"
size_t fwrite_unlocked(const void* ptr, size_t size, size_t nmemb, FILE* fp)
{
if ( fp->buffer_mode == _IONBF )
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf_unlocked(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( !fp->write_func )
return 0; // TODO: ferror doesn't report error!
if ( fp->flags & _FILE_LAST_READ )
fflush_stop_reading_unlocked(fp);
fp->flags |= _FILE_LAST_WRITE;
return fp->write_func(ptr, size, nmemb, fp->user);
}
const unsigned char* buf = (const unsigned char*) ptr;
for ( size_t n = 0; n < nmemb; n++ )
{
size_t offset = n * size;
for ( size_t i = 0; i < size; i++ )
{
size_t index = offset + i;
if ( fputc_unlocked(buf[index], fp) == EOF )
return n;
}
}
return nmemb;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,7 +26,8 @@
extern "C" int fwriting(FILE* fp)
{
if ( fp->write_func ) { return 1; }
if ( fp->flags & _FILE_LAST_WRITE ) { return 1; }
return 0;
flockfile(fp);
int ret = fwriting_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,34 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/fwriting_unlocked.cpp
Returns whether the last operation was a write or FILE is write only.
*******************************************************************************/
#include <stdio.h>
extern "C" int fwriting_unlocked(FILE* fp)
{
if ( fp->write_func )
return 1;
if ( fp->flags & _FILE_LAST_WRITE )
return 1;
return 0;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,5 +26,8 @@
extern "C" int getc(FILE* fp)
{
return fgetc(fp);
flockfile(fp);
int ret = getc_unlocked(fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/getc_unlocked.cpp
Reads a single character from a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C" int getc_unlocked(FILE* fp)
{
return fgetc_unlocked(fp);
}

View File

@ -37,9 +37,10 @@ extern "C" ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* fp)
if ( n ) { *n = bufsize; }
ssize_t written = 0;
int c;
flockfile(fp);
do
{
if ( (c = getc(fp)) == EOF )
if ( (c = getc_unlocked(fp)) == EOF )
{
if ( written ) { break; } else { goto cleanup; }
}
@ -54,10 +55,12 @@ extern "C" ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* fp)
}
(*lineptr)[written++] = c;
} while ( c != delim );
funlockfile(fp);
(*lineptr)[written] = 0;
return written;
cleanup:
funlockfile(fp);
free(malloced ? *lineptr : NULL);
return -1;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -26,5 +26,8 @@
extern "C" int putc(int c, FILE* fp)
{
return fputc(c, fp);
flockfile(fp);
int ret = putc_unlocked(c, fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,30 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/putc_unlocked.cpp
Writes a character to a FILE.
*******************************************************************************/
#include <stdio.h>
extern "C" int putc_unlocked(int c, FILE* fp)
{
return fputc_unlocked(c, fp);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2014.
This file is part of the Sortix C Library.
@ -26,6 +26,8 @@
extern "C" void rewind(FILE* fp)
{
fseek(fp, 0L, SEEK_SET);
clearerr(fp);
flockfile(fp);
fseeko_unlocked(fp, 0, SEEK_SET);
clearerr_unlocked(fp);
funlockfile(fp);
}

View File

@ -22,19 +22,12 @@
*******************************************************************************/
#include <errno.h>
#include <stdio.h>
extern "C" int setvbuf(FILE* fp, char* buf, int mode, size_t size)
{
if ( fp->flags & _FILE_BUFFER_MODE_SET )
return errno = EINVAL, -1;
fp->buffer_mode = mode;
if ( buf )
{
fp->buffer = (unsigned char*) buf;
fp->buffersize = size;
fp->flags |= _FILE_BUFFER_MODE_SET;
}
return 0;
flockfile(fp);
int ret = setvbuf_unlocked(fp, buf, mode, size);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,40 @@
/*******************************************************************************
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/setvbuf_unlocked.cpp
Sets up buffering semantics for a FILE.
*******************************************************************************/
#include <errno.h>
#include <stdio.h>
extern "C" int setvbuf_unlocked(FILE* fp, char* buf, int mode, size_t size)
{
if ( fp->flags & _FILE_BUFFER_MODE_SET )
return errno = EINVAL, -1;
fp->buffer_mode = mode;
if ( buf )
{
fp->buffer = (unsigned char*) buf;
fp->buffersize = size;
fp->flags |= _FILE_BUFFER_MODE_SET;
}
return 0;
}

View File

@ -47,14 +47,30 @@ extern "C" int init_stdio()
return 0;
}
extern "C" int getchar_unlocked(void)
{
return fgetc_unlocked(stdin);
}
extern "C" int putchar_unlocked(int c)
{
return fputc_unlocked(c, stdout);
}
extern "C" int getchar(void)
{
return fgetc(stdin);
flockfile(stdin);
int ret = getchar_unlocked();
funlockfile(stdin);
return ret;
}
extern "C" int putchar(int c)
{
return fputc(c, stdout);
flockfile(stdin);
int ret = putchar_unlocked(c);
funlockfile(stdin);
return ret;
}
extern "C" int puts(const char* str)

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
This file is part of the Sortix C Library.
@ -24,33 +24,11 @@
*******************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
extern "C" int ungetc(int c, FILE* fp)
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( !fp->read_func || fp->buffer_mode == _IONBF )
return EOF;
if ( fp->flags & _FILE_LAST_WRITE )
fflush_stop_writing(fp);
fp->flags |= _FILE_LAST_READ;
if ( fp->offset_input_buffer == 0 )
{
size_t amount = fp->amount_input_buffered - fp->offset_input_buffer;
size_t offset = fp->buffersize - amount;
if ( !offset )
return EOF;
memmove(fp->buffer + offset, fp->buffer, sizeof(fp->buffer[0]) * amount);
fp->offset_input_buffer = offset;
fp->amount_input_buffered = offset + amount;
}
fp->buffer[--fp->offset_input_buffer] = c;
return c;
flockfile(fp);
int ret = ungetc_unlocked(c, fp);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,56 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/ungetc_unlocked.cpp
Inserts data in front of the current read queue, allowing applications to
peek the incoming data and pretend they didn't.
*******************************************************************************/
#include <errno.h>
#include <stdio.h>
#include <string.h>
extern "C" int ungetc_unlocked(int c, FILE* fp)
{
if ( !(fp->flags & _FILE_BUFFER_MODE_SET) )
if ( fsetdefaultbuf_unlocked(fp) != 0 )
return EOF; // TODO: ferror doesn't report error!
if ( !fp->read_func || fp->buffer_mode == _IONBF )
return EOF;
if ( fp->flags & _FILE_LAST_WRITE )
fflush_stop_writing_unlocked(fp);
fp->flags |= _FILE_LAST_READ;
if ( fp->offset_input_buffer == 0 )
{
size_t amount = fp->amount_input_buffered - fp->offset_input_buffer;
size_t offset = fp->buffersize - amount;
if ( !offset )
return EOF;
memmove(fp->buffer + offset, fp->buffer, sizeof(fp->buffer[0]) * amount);
fp->offset_input_buffer = offset;
fp->amount_input_buffered = offset + amount;
}
fp->buffer[--fp->offset_input_buffer] = c;
return c;
}

View File

@ -26,15 +26,10 @@
#include <stdio.h>
#include <stdint.h>
static size_t FileWriteCallback(void* user, const char* string, size_t stringlen)
{
return fwrite(string, sizeof(char), stringlen, (FILE*) user);
}
extern "C" int vfprintf(FILE* fp, const char* restrict format, va_list list)
{
size_t result = vprintf_callback(FileWriteCallback, fp, format, list);
if ( result == SIZE_MAX )
return -1;
return (int) result;
flockfile(fp);
int ret = vfprintf_unlocked(fp, format, list);
funlockfile(fp);
return ret;
}

View File

@ -0,0 +1,41 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 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/vfprintf_unlocked.cpp
Prints a string to a FILE.
*******************************************************************************/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
static size_t FileWriteCallback(void* user, const char* string, size_t stringlen)
{
return fwrite_unlocked(string, sizeof(char), stringlen, (FILE*) user);
}
extern "C"
int vfprintf_unlocked(FILE* fp, const char* restrict format, va_list list)
{
size_t result = vprintf_callback(FileWriteCallback, fp, format, list);
if ( result == SIZE_MAX )
return -1;
return (int) result;
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014.
This file is part of the Sortix C Library.
@ -24,17 +24,10 @@
#include <stdio.h>
static int wrap_fgetc(void* fp)
{
return fgetc((FILE*) fp);
}
static int wrap_ungetc(int c, void* fp)
{
return ungetc(c, (FILE*) fp);
}
extern "C" int vfscanf(FILE* fp, const char* format, va_list ap)
{
return vscanf_callback(fp, wrap_fgetc, wrap_ungetc, format, ap);
flockfile(fp);
int result = vfscanf_unlocked(fp, format, ap);
funlockfile(fp);
return result;
}

View File

@ -0,0 +1,40 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 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/vfscanf_unlocked.cpp
Input format conversion.
*******************************************************************************/
#include <stdio.h>
static int wrap_fgetc(void* fp)
{
return fgetc_unlocked((FILE*) fp);
}
static int wrap_ungetc(int c, void* fp)
{
return ungetc_unlocked(c, (FILE*) fp);
}
extern "C" int vfscanf_unlocked(FILE* fp, const char* format, va_list ap)
{
return vscanf_callback(fp, wrap_fgetc, wrap_ungetc, format, ap);
}