]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/language/c/libc/stdio/v2_0/src/common/fileops.cxx
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / language / c / libc / stdio / v2_0 / src / common / fileops.cxx
1 /*========================================================================
2 //
3 //      fileops.cxx
4 //
5 //      Implementation of ISO C rename(),remove(),tmpnam(),tmpfile() functions
6 //
7 //========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 2004 eCosCentric Ltd.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 // -------------------------------------------
36 //####ECOSGPLCOPYRIGHTEND####
37 //========================================================================
38 //#####DESCRIPTIONBEGIN####
39 //
40 // Author(s):     jlarmour
41 // Contributors:  
42 // Date:          2004-02-30
43 // Purpose:       Implementation of ISO C rename(),remove(),tmpnam(),tmpfile()
44 // Description:   
45 // Usage:         
46 //
47 //####DESCRIPTIONEND####
48 //======================================================================*/
49
50 // CONFIGURATION
51
52 #include <pkgconf/system.h>
53 #include <pkgconf/isoinfra.h>
54 #include <pkgconf/libc_stdio.h>          // Configuration header
55
56 // INCLUDES
57
58 #include <cyg/infra/cyg_type.h>           // Common type definitions and support
59 #include <cyg/infra/cyg_ass.h>            // Common assertion functions
60 #include <cyg/infra/cyg_trac.h>           // Common tracing functions
61 #include <stdio.h>                        // Header for this file
62 #include <errno.h>                        // errno
63 #ifdef CYGPKG_LIBC_STDIO_FILEIO           // unix-y functions, e.g. stat,rmdir,unlink,...
64 # include <unistd.h>
65 # include <fcntl.h>
66 # include <sys/stat.h>
67 #endif
68 #include <cyg/libc/stdio/io.hxx>          // I/O definitions
69 #ifdef CYGPKG_POSIX
70 # include <pkgconf/posix.h>
71 # include <cyg/posix/export.h>
72 #endif
73
74 #if defined(CYGINT_ISO_EXIT) && (CYGINT_ISO_EXIT+0)
75 # include <stdlib.h>         // used by tmpfile() for atexit()
76 #endif
77
78 // DEFINES
79
80 #ifdef CYGPKG_POSIX
81 # define CYG_STDIO_FUNCTION_START() CYG_POSIX_FUNCTION_START()
82 # define CYG_STDIO_FUNCTION_FINISH() CYG_POSIX_FUNCTION_FINISH()
83 #else
84 # define CYG_STDIO_FUNCTION_START() CYG_EMPTY_STATEMENT
85 # define CYG_STDIO_FUNCTION_FINISH() CYG_EMPTY_STATEMENT
86 #endif
87
88 // Handle entry 
89 #define STDIO_ENTRY()                           \
90     CYG_REPORT_FUNCTYPE( "returning %d" );      \
91     CYG_STDIO_FUNCTION_START();                 \
92
93 #define STDIO_RETURN(err)                       \
94 CYG_MACRO_START                                 \
95     int __retval = 0;                           \
96     CYG_STDIO_FUNCTION_FINISH();                \
97     if( err != 0 ) __retval = -1, errno = err;  \
98     CYG_REPORT_RETVAL( __retval );              \
99     return __retval;                            \
100 CYG_MACRO_END
101
102 #define STDIO_RETURN_VALUE(val)                 \
103 CYG_MACRO_START                                 \
104     CYG_STDIO_FUNCTION_FINISH();                \
105     CYG_REPORT_RETVAL( val );                   \
106     return val;                                 \
107 CYG_MACRO_END
108
109 // FUNCTIONS
110
111 ///////////////////////////////////////////////////////////////////////////
112 // remove()
113
114 __externC int remove( const char *path ) __THROW
115 {
116     int ret;
117     STDIO_ENTRY();
118     CYG_CHECK_DATA_PTR( path, "path pointer invalid" );
119
120 #ifdef CYGPKG_LIBC_STDIO_FILEIO
121     struct stat sbuf;
122     ret = stat( path, &sbuf );
123
124     if (0 == ret)
125     {
126         if ( S_ISDIR(sbuf.st_mode) )
127         {
128             ret = rmdir( path );
129         } else {
130             ret = unlink( path );
131         }
132     }
133 #else // !defined(CYGPKG_LIBC_STDIO_FILEIO)
134     ret = ENOSYS;
135 #endif    
136     STDIO_RETURN(ret);
137 } // remove()
138
139 ///////////////////////////////////////////////////////////////////////////
140 // rename()
141 //
142 // The File I/O package supplies its own complete version of this, so we
143 // only implement a dummy here.
144
145 #ifndef CYGPKG_LIBC_STDIO_FILEIO
146 __externC int rename( const char *oldname, const char *newname ) __THROW
147 {
148     STDIO_ENTRY();
149     CYG_CHECK_DATA_PTR(oldname, "oldname pointer invalid");
150     CYG_CHECK_DATA_PTR(newname, "newname pointer invalid");
151     STDIO_RETURN(ENOSYS);
152 }
153 #endif // ifndef CYGPKG_LIBC_STDIO_FILEIO
154
155 ///////////////////////////////////////////////////////////////////////////
156 // tmpnam()
157
158 __externC char *tmpnam( char *s ) __THROW
159 {
160     STDIO_ENTRY();
161     static char staticbuf[ L_tmpnam ];
162 #if (TMP_MAX < 256)
163     typedef cyg_uint8 counttype;
164 #elif (TMP_MAX < 65536)
165     typedef cyg_uint16 counttype;
166 #else
167     typedef cyg_ucount32 counttype;
168 #endif
169     static counttype count;
170     counttype totaliters=0;
171     int i;
172
173     if ( NULL != s )
174         CYG_CHECK_DATA_PTR( s, "supplied string pointer invalid" );
175     else
176         s = staticbuf;
177
178     // start off by making it "tmp00000" etc. so we can fill backwards
179     // from end without spaces
180     s[0] = 't'; s[1] = 'm'; s[2] = 'p';
181
182     while (totaliters < TMP_MAX)
183     {
184         for (i=3; i < (L_tmpnam-1); i++)
185         {
186             s[i] = '0';
187         }
188         s[i] = '\0';
189
190         counttype counttmp = count;
191         for (i=(L_tmpnam-1); i>2; i--)
192         {
193             const char tohex[] = "0123456789abcdef";
194             s[i] = tohex[counttmp & 0xf];
195             counttmp = counttmp >> 4;
196         }
197         count++;
198         count %= TMP_MAX; // cycle round
199         totaliters++;
200
201         // s now points to a name candidate
202 #ifdef CYGPKG_LIBC_STDIO_FILEIO
203         int fd = open( s, O_RDONLY );
204         if (fd >= 0)
205             close(fd);
206         else if ( ENOENT == errno ) // we have a winner
207             break;
208 #else
209         break; // no real filesystem, so just go with what we've come up with
210 #endif
211     }
212
213     if ( totaliters == TMP_MAX ) // oops, looped right the way round
214         s = NULL;
215
216     STDIO_RETURN_VALUE( s );
217 } // tmpnam()
218
219 ///////////////////////////////////////////////////////////////////////////
220 // tmpfile()
221
222 __externC FILE *tmpfile( void ) __THROW
223 {
224     FILE *f;
225     char fname[L_tmpnam];
226     char *s;
227
228     STDIO_ENTRY();
229
230     s = tmpnam( fname );
231     if ( s == NULL)
232         f = NULL;
233     else
234     {
235         // fname is now a valid name to use
236         f = fopen( fname, "wb+" );
237 #ifdef CYGPKG_LIBC_STDIO_FILEIO
238         // We can use remove which should mean the file is removed on program
239         // exit.We ignore the return code though - the standard seems to
240         // indicate that the return status from this function is solely
241         // dictated by whether the file could be created.
242         if (f)
243             remove( fname );
244 #endif
245     }    
246
247     STDIO_RETURN_VALUE( f );
248 } // tmpfile()
249
250 ///////////////////////////////////////////////////////////////////////////
251 // EOF fileops.cxx