From c6ef89664b8c0d7aa85bddd5c7014aa6df82cbe7 Mon Sep 17 00:00:00 2001 From: tcsullivan Date: Sat, 17 Nov 2018 13:02:57 -0500 Subject: added pdclib, removed sash --- .../platform/example/functions/stdio/remove.c | 75 ++++++++++++++ .../platform/example/functions/stdio/tmpfile.c | 114 +++++++++++++++++++++ 2 files changed, 189 insertions(+) create mode 100644 src/pdclib/platform/example/functions/stdio/remove.c create mode 100644 src/pdclib/platform/example/functions/stdio/tmpfile.c (limited to 'src/pdclib/platform/example/functions/stdio') diff --git a/src/pdclib/platform/example/functions/stdio/remove.c b/src/pdclib/platform/example/functions/stdio/remove.c new file mode 100644 index 0000000..aca3eaf --- /dev/null +++ b/src/pdclib/platform/example/functions/stdio/remove.c @@ -0,0 +1,75 @@ +/* remove( const char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of remove() fit for use with POSIX kernels. +*/ + +#include + +#ifndef REGTEST + +#include + +#include "/usr/include/errno.h" + +extern struct _PDCLIB_file_t * _PDCLIB_filelist; + +extern int unlink( const char * pathname ); + +int remove( const char * pathname ) +{ + int rc; + struct _PDCLIB_file_t * current = _PDCLIB_filelist; + while ( current != NULL ) + { + if ( ( current->filename != NULL ) && ( strcmp( current->filename, pathname ) == 0 ) ) + { + return EOF; + } + current = current->next; + } + if ( ( rc = unlink( pathname ) ) == -1 ) + { + switch ( errno ) + { + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ + case EACCES: + case EFAULT: + case EIO: + case EISDIR: + case ELOOP: + case ENAMETOOLONG: + case ENOENT: + case ENOMEM: + case ENOTDIR: + case EPERM: + case EROFS: + _PDCLIB_errno = _PDCLIB_ERROR; + break; + default: + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; + break; + } + } + return rc; +} + +#endif + +#ifdef TEST + +#include "_PDCLIB_test.h" + +int main( void ) +{ + /* Testing covered by ftell.c (and several others) */ + return TEST_RESULTS; +} + +#endif diff --git a/src/pdclib/platform/example/functions/stdio/tmpfile.c b/src/pdclib/platform/example/functions/stdio/tmpfile.c new file mode 100644 index 0000000..585a61d --- /dev/null +++ b/src/pdclib/platform/example/functions/stdio/tmpfile.c @@ -0,0 +1,114 @@ +/* tmpfile( void ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +#include "pdclib/_PDCLIB_glue.h" + +#include +#include +#include + +#include +#include +#include +#include + +extern struct _PDCLIB_file_t * _PDCLIB_filelist; + +/* This is an example implementation of tmpfile() fit for use with POSIX + kernels. +*/ +struct _PDCLIB_file_t * tmpfile( void ) +{ + FILE * rc; + /* This is the chosen way to get high-quality randomness. Replace as + appropriate. + */ + FILE * randomsource = fopen( "/proc/sys/kernel/random/uuid", "rb" ); + char filename[ L_tmpnam ]; + _PDCLIB_fd_t fd; + if ( randomsource == NULL ) + { + return NULL; + } + for ( ;; ) + { + /* Get a filename candidate. What constitutes a valid filename and + where temporary files are usually located is platform-dependent, + which is one reason why this function is located in the platform + overlay. The other reason is that a *good* implementation should + use high-quality randomness instead of a pseudo-random sequence to + generate the filename candidate, which is *also* platform-dependent. + */ + unsigned int random; + fscanf( randomsource, "%u", &random ); + sprintf( filename, "/tmp/%u.tmp", random ); + /* Check if file of this name exists. Note that fopen() is a very weak + check, which does not take e.g. access permissions into account + (file might exist but not readable). Replace with something more + appropriate. + */ + fd = open( filename, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR ); + if ( fd != -1 ) + { + break; + } + close( fd ); + } + fclose( randomsource ); + /* See fopen(). */ + if ( ( rc = calloc( 1, sizeof( struct _PDCLIB_file_t ) + _PDCLIB_UNGETCBUFSIZE + L_tmpnam + BUFSIZ ) ) == NULL ) + { + /* No memory to set up FILE structure */ + close( fd ); + return NULL; + } + rc->status = _PDCLIB_filemode( "wb+" ) | _IOLBF | _PDCLIB_DELONCLOSE; + rc->handle = fd; + rc->ungetbuf = (unsigned char *)rc + sizeof( struct _PDCLIB_file_t ); + rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE; + rc->buffer = rc->filename + L_tmpnam; + strcpy( rc->filename, filename ); + rc->bufsize = BUFSIZ; + rc->bufidx = 0; + rc->ungetidx = 0; + rc->next = _PDCLIB_filelist; + _PDCLIB_filelist = rc; + return rc; +} + +#endif + +#ifdef TEST + +#include "_PDCLIB_test.h" + +#include + +int main( void ) +{ + FILE * fh; +#ifndef REGTEST + char filename[ L_tmpnam ]; + FILE * fhtest; +#endif + TESTCASE( ( fh = tmpfile() ) != NULL ); + TESTCASE( fputc( 'x', fh ) == 'x' ); + /* Checking that file is actually there */ + TESTCASE_NOREG( strcpy( filename, fh->filename ) == filename ); + TESTCASE_NOREG( ( fhtest = fopen( filename, "r" ) ) != NULL ); + TESTCASE_NOREG( fclose( fhtest ) == 0 ); + /* Closing tmpfile */ + TESTCASE( fclose( fh ) == 0 ); + /* Checking that file was deleted */ + TESTCASE_NOREG( fopen( filename, "r" ) == NULL ); + return TEST_RESULTS; +} + +#endif -- cgit v1.2.3