]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/io/fileio/v2_0/src/dir.cxx
32fc03b0cb4974c6e7eae4f774b6aea71938aac7
[karo-tx-redboot.git] / packages / io / fileio / v2_0 / src / dir.cxx
1 //==========================================================================
2 //
3 //      dir.cxx
4 //
5 //      Fileio directory support
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
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 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):           nickg
44 // Contributors:        nickg
45 // Date:                2000-05-25
46 // Purpose:             Fileio directory support
47 // Description:         Support for directory operations.
48 //                      
49 //              
50 //              
51 //
52 //####DESCRIPTIONEND####
53 //
54 //==========================================================================
55
56 #include <pkgconf/hal.h>
57 #include <pkgconf/io_fileio.h>
58
59 #include <cyg/infra/cyg_trac.h>        // tracing macros
60 #include <cyg/infra/cyg_ass.h>         // assertion macros
61
62 #include <stdarg.h>                     // for fcntl()
63
64 #include "fio.h"                       // Private header
65
66 #include <dirent.h>                    // struct dirent
67
68 //==========================================================================
69
70 #define DIROPEN_RETURN_ERR( err )               \
71 CYG_MACRO_START                                 \
72     errno = err;                                \
73     CYG_REPORT_RETVAL( NULL );                  \
74     return NULL;                                \
75 CYG_MACRO_END
76
77 //==========================================================================
78 // Implement filesystem locking protocol. 
79
80 #define LOCK_FS( _mte_ )  {                             \
81    CYG_ASSERT(_mte_ != NULL, "Bad mount table entry");  \
82    cyg_fs_lock( _mte_, (_mte_)->fs->syncmode);          \
83 }
84
85 #define UNLOCK_FS( _mte_ ) cyg_fs_unlock( _mte_, (_mte_)->fs->syncmode)
86
87 //==========================================================================
88 // Open a directory for reading
89
90 extern DIR *opendir( const char *dirname )
91 {
92     FILEIO_ENTRY();
93
94     CYG_CANCELLATION_POINT;
95
96     int ret = 0;
97     int fd;
98     cyg_file *file;
99     cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
100     cyg_dir dir = cyg_cdir_dir;
101     const char *name = dirname;
102
103     fd = cyg_fd_alloc(1); // Never return fd 0
104
105     if( fd < 0 )
106         DIROPEN_RETURN_ERR(EMFILE);
107     
108     file = cyg_file_alloc();
109
110     if( file == NULL )
111     {
112         cyg_fd_free(fd);
113         DIROPEN_RETURN_ERR(ENFILE);
114     }
115     
116     ret = cyg_mtab_lookup( &dir, &name, &mte );
117     
118     if( 0 != ret )
119     {
120         cyg_fd_free(fd);
121         cyg_file_free(file);
122         DIROPEN_RETURN_ERR(ENOENT);
123     }
124
125     LOCK_FS( mte );
126     
127     ret = mte->fs->opendir( mte, dir, name, file );
128     
129     UNLOCK_FS( mte );
130     
131     if( 0 != ret )
132     {
133         cyg_fd_free(fd);
134         cyg_file_free(file);
135         DIROPEN_RETURN_ERR(ret);
136     }
137
138     file->f_flag |= CYG_FDIR|CYG_FREAD;
139     file->f_mte = mte;
140     file->f_syncmode = mte->fs->syncmode;
141     
142     cyg_fd_assign( fd, file );
143
144     DIR *dirp = (DIR *)fd;
145     
146     FILEIO_RETURN_VALUE(dirp);
147 }
148
149 //==========================================================================
150 // Read a directory entry.
151 // This is the thread-unsafe version that uses a static result buffer.
152 // It just calls the thread-safe version to do the work.
153
154 extern struct dirent *readdir( DIR *dirp )
155 {
156     FILEIO_ENTRY();
157     
158     static struct dirent ent;
159     struct dirent *result;
160     int err;
161
162     err = readdir_r( dirp, &ent, &result );
163
164     if( err != 0 )
165     {
166         errno = err;
167         FILEIO_RETURN_VALUE( NULL );
168     }
169     
170     FILEIO_RETURN_VALUE( result );
171 }
172
173 //==========================================================================
174
175 extern int readdir_r( DIR *dirp, struct dirent *entry, struct dirent **result )
176 {
177     FILEIO_ENTRY();
178
179     int fd = (int)dirp;    
180     ssize_t res;
181
182     *result = NULL;
183
184     if( NULL == dirp )
185     {
186         FILEIO_RETURN_VALUE( EBADF );
187     }
188
189     res = read( fd, (void *)entry, sizeof(struct dirent));
190
191     if( res < 0 )
192     {
193         FILEIO_RETURN_VALUE( errno );
194     }
195     
196     if( res > 0 )
197         *result = entry;
198     
199     FILEIO_RETURN( ENOERR );
200 }
201
202 //==========================================================================
203
204 extern void rewinddir( DIR *dirp )
205 {
206     FILEIO_ENTRY();
207
208     int fd = (int)dirp;
209
210     lseek( fd, 0, SEEK_SET );
211     
212     FILEIO_RETURN_VOID();
213 }
214
215 //==========================================================================
216
217 extern int closedir( DIR *dirp )
218 {
219     FILEIO_ENTRY();
220
221     int fd = (int)dirp;
222     int err = close( fd );
223
224     FILEIO_RETURN_VALUE( err );
225 }
226
227 // -------------------------------------------------------------------------
228 // EOF dir.cxx