Path: blob/master/waterbox/libc/functions/stdio/_PDCLIB_fvopen.c
2 views
/* _PDCLIB_fvopen( _PDCLIB_fd_t, _PDCLIB_fileops_t * )12This file is part of the Public Domain C Library (PDCLib).3Permission is granted to use, modify, and / or redistribute at will.4*/56#include <stdio.h>7#include <stdlib.h>89#ifndef REGTEST10#include "_PDCLIB_glue.h"11#include "_PDCLIB_io.h"12#include <string.h>13#include <threads.h>1415extern FILE * _PDCLIB_filelist;1617FILE * _PDCLIB_fvopen(18_PDCLIB_fd_t fd,19const _PDCLIB_fileops_t *_PDCLIB_restrict ops,20int mode,21const char *_PDCLIB_restrict filename22)23{24size_t filename_len;25FILE * rc;26if ( mode == NULL )27{28/* Mode invalid */29return NULL;30}31/* To reduce the number of malloc calls, all data fields are concatenated:32* the FILE structure itself,33* ungetc buffer,34* filename buffer,35* data buffer.36Data buffer comes last because it might change in size ( setvbuf() ).37*/38filename_len = filename ? strlen( filename ) + 1 : 1;39if ( ( rc = calloc( 1, sizeof( FILE ) + _PDCLIB_UNGETCBUFSIZE + filename_len + BUFSIZ ) ) == NULL )40{41/* no memory */42return NULL;43}4445if(mtx_init(&rc->lock, mtx_recursive) != thrd_success) {46free(rc);47return NULL;48}4950rc->status = mode;51rc->ops = ops;52rc->handle = fd;53/* Setting pointers into the memory block allocated above */54rc->ungetbuf = (unsigned char *)rc + sizeof( FILE );55rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE;56rc->buffer = rc->filename + filename_len;57/* Copying filename to FILE structure */58if(filename) strcpy( rc->filename, filename );59/* Initializing the rest of the structure */60rc->bufsize = BUFSIZ;61rc->bufidx = 0;62#ifdef _PDCLIB_NEED_EOL_TRANSLATION63rc->bufnlexp = 0;64#endif65rc->ungetidx = 0;66/* Setting buffer to _IOLBF because "when opened, a stream is fully67buffered if and only if it can be determined not to refer to an68interactive device."69*/70rc->status |= _IOLBF;71/* TODO: Setting mbstate */72/* Adding to list of open files */73rc->next = _PDCLIB_filelist;74_PDCLIB_filelist = rc;75return rc;76}7778#endif7980#ifdef TEST81#include "_PDCLIB_test.h"8283int main( void )84{85/* Some of the tests are not executed for regression tests, as the libc on86my system is at once less forgiving (segfaults on mode NULL) and more87forgiving (accepts undefined modes).88*/89FILE * fh;90remove( testfile );91TESTCASE_NOREG( fopen( NULL, NULL ) == NULL );92TESTCASE( fopen( NULL, "w" ) == NULL );93TESTCASE_NOREG( fopen( "", NULL ) == NULL );94TESTCASE( fopen( "", "w" ) == NULL );95TESTCASE( fopen( "foo", "" ) == NULL );96TESTCASE_NOREG( fopen( testfile, "wq" ) == NULL ); /* Undefined mode */97TESTCASE_NOREG( fopen( testfile, "wr" ) == NULL ); /* Undefined mode */98TESTCASE( ( fh = fopen( testfile, "w" ) ) != NULL );99TESTCASE( fclose( fh ) == 0 );100TESTCASE( remove( testfile ) == 0 );101return TEST_RESULTS;102}103104#endif105106107