]> pd.if.org Git - pdclib/blob - platform/example/functions/_PDCLIB/open.c
Closer to functional printf().
[pdclib] / platform / example / functions / _PDCLIB / open.c
1 /* $Id$ */
2
3 /* _PDCLIB_open( char const * const, int )
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 /* This is an example implementation of _PDCLIB_open() fit for use with POSIX
10    kernels.
11 */
12
13 #include <stdio.h>
14
15 #ifndef REGTEST
16 #include <_PDCLIB_glue.h>
17
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22
23 _PDCLIB_fd_t _PDCLIB_open( char const * const filename, unsigned int mode )
24 {
25     /* FIXME: THIS IS NOT TO BE USED OUT-OF-THE-BOX.
26        It is a proof-of-concept implementation. E.g. a stream may only be fully
27        buffered IF IT CAN BE DETERMINED NOT TO REFER TO AN INTERACTIVE DEVICE.
28        This logic is not represented here, as this is the EXAMPLE platform, and
29        actual platform overlays may differ widely. Another point is the value
30        for permissions being hardcoded to 0664 for file creations.
31     */
32     int osmode;
33     switch ( mode & ~_PDCLIB_FBIN )
34     {
35         case _PDCLIB_FREAD: /* "r" */
36             osmode = O_RDONLY;
37             break;
38         case _PDCLIB_FWRITE: /* "w" */
39             osmode = O_WRONLY | O_CREAT | O_TRUNC;
40             break;
41         case _PDCLIB_FAPPEND: /* "a" */
42             osmode = O_WRONLY | O_APPEND | O_CREAT;
43             break;
44         case _PDCLIB_FREAD | _PDCLIB_FRW: /* "r+" */
45             osmode = O_RDWR;
46             break;
47         case _PDCLIB_FWRITE | _PDCLIB_FRW: /* "w+" */
48             osmode = O_RDWR | O_CREAT | O_TRUNC;
49             break;
50         case _PDCLIB_FAPPEND | _PDCLIB_FRW: /* "a+" */
51             osmode = O_RDWR | O_APPEND | O_CREAT;
52             break;
53         default: /* Invalid mode */
54             return -1;
55     }
56     if ( osmode & O_CREAT )
57     {
58         return open( filename, osmode, S_IRUSR | S_IWUSR );
59     }
60     else
61     {
62         return open( filename, osmode );
63     }
64 }
65
66 #endif
67
68 #ifdef TEST
69 #include <_PDCLIB_test.h>
70
71 #include <stdlib.h>
72 #include <string.h>
73
74 #include <errno.h>
75
76 int main( void )
77 {
78     /* This testdriver assumes POSIX, i.e. _PDCLIB_fd_t being int and being
79        incremented by one on each successful open.
80     */
81     _PDCLIB_fd_t fh;
82     char buffer[ 10 ];
83     /* Trying to read non-existent file. */
84     TESTCASE( _PDCLIB_open( "testfile", _PDCLIB_FREAD ) == _PDCLIB_NOHANDLE );
85     /* Writing to file, trying to read from it. */
86     TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FWRITE ) ) != _PDCLIB_NOHANDLE );
87     TESTCASE( write( fh, "test", 4 ) == 4 );
88     TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 );
89     TESTCASE( read( fh, buffer, 4 ) == -1 );
90     TESTCASE( _PDCLIB_close( fh ) == 0 );
91     /* Reading from file, trying to write to it. */
92     TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FREAD ) ) != _PDCLIB_NOHANDLE );
93     TESTCASE( write( fh, "test", 4 ) == -1 );
94     TESTCASE( _PDCLIB_close( fh ) == 0 );
95     /* Appending to file, trying to read from it. */
96     TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FAPPEND ) ) != _PDCLIB_NOHANDLE );
97     TESTCASE( write( fh, "app", 3 ) == 3 );
98     TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 );
99     TESTCASE( read( fh, buffer, 10 ) == -1 );
100     TESTCASE( write( fh, "end", 3 ) == 3 );
101     TESTCASE( _PDCLIB_close( fh ) == 0 );
102     /* Reading and writing from file ("r+"). */
103     TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FREAD | _PDCLIB_FRW ) ) != _PDCLIB_NOHANDLE );
104     TESTCASE( read( fh, buffer, 10 ) == 10 );
105     TESTCASE( memcmp( buffer, "testappend", 10 ) == 0 );
106     TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 );
107     TESTCASE( write( fh, "wedo", 4 ) == 4 );
108     TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 );
109     TESTCASE( read( fh, buffer, 10 ) == 10 );
110     TESTCASE( memcmp( buffer, "wedoappend", 10 ) == 0 );
111     TESTCASE( _PDCLIB_close( fh ) == 0 );
112     /* Writing and reading from file ("w+"). */
113     TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FWRITE | _PDCLIB_FRW ) ) != _PDCLIB_NOHANDLE );
114     TESTCASE( write( fh, "test", 4 ) == 4 );
115     TESTCASE( lseek( fh, 1, SEEK_SET ) == 1 );
116     TESTCASE( read( fh, buffer, 2 ) == 2 );
117     TESTCASE( memcmp( buffer, "es", 2 ) == 0 );
118     TESTCASE( write( fh, "sie", 3 ) == 3 );
119     TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 );
120     TESTCASE( read( fh, buffer, 6 ) == 6 );
121     TESTCASE( memcmp( buffer, "tessie", 6 ) == 0 );
122     TESTCASE( _PDCLIB_close( fh ) == 0 );
123     /* Appending and reading from file ("a+"). */
124     TESTCASE( ( fh = _PDCLIB_open( "testfile", _PDCLIB_FAPPEND | _PDCLIB_FRW ) ) != _PDCLIB_NOHANDLE );
125     TESTCASE( write( fh, "baby", 4 ) == 4 );
126     TESTCASE( lseek( fh, 0, SEEK_SET ) == 0 );
127     TESTCASE( read( fh, buffer, 10 ) == 10 );
128     TESTCASE( memcmp( buffer, "tessiebaby", 10 ) == 0 );
129     TESTCASE( _PDCLIB_close( fh ) == 0 );
130     /* Cleaning up. */
131     system( "rm testfile" );
132     return TEST_RESULTS;
133 }
134
135 #endif