OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [io/] [fileio/] [current/] [src/] [misc.cxx] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      misc.cxx
4
//
5
//      Fileio miscellaneous functions
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, 2003 Free Software Foundation, 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      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):           nickg
43
// Contributors:        nickg
44
// Date:                2000-05-25
45
// Purpose:             Fileio miscellaneous functions
46
// Description:         This file contains various miscellaneous functions
47
//                      for use with the fileio system. These include startup,
48
//                      table management, and other service routines.
49
//
50
//####DESCRIPTIONEND####
51
//
52
//==========================================================================
53
 
54
#include <pkgconf/system.h>
55
#include <pkgconf/hal.h>
56
#include <pkgconf/io_fileio.h>
57
#ifdef CYGPKG_LIBC_TIME
58
#include <pkgconf/libc_time.h>
59
#endif
60
 
61
 
62
#include <cyg/infra/cyg_trac.h>        // tracing macros
63
#include <cyg/infra/cyg_ass.h>         // assertion macros
64
#include <string.h>                    // strcmp()
65
#include <time.h>                      // time()
66
 
67
#ifdef CYGPKG_IO_WALLCLOCK
68
# include <cyg/io/wallclock.hxx>       // Wallclock class
69
#endif
70
 
71
#ifdef CYGPKG_KERNEL
72
#include <pkgconf/kernel.h>
73
#include <cyg/kernel/ktypes.h>         // base kernel types
74
#include <cyg/kernel/clock.inl>         // Clock inlines
75
#endif
76
 
77
#include "fio.h"                       // Private header
78
 
79
//==========================================================================
80
// forward definitions
81
 
82
static void cyg_mtab_init();
83
 
84
__externC int chdir( const char *path );
85
 
86
//==========================================================================
87
// Filesystem tables
88
 
89
// -------------------------------------------------------------------------
90
// Filesystem table.
91
 
92
// This array contains entries for all filesystem that are installed in
93
// the system.
94
__externC cyg_fstab_entry cyg_fstab[];
95
CYG_HAL_TABLE_BEGIN( cyg_fstab, fstab );
96
 
97
// end of filesystem table, set in linker script.
98
__externC cyg_fstab_entry cyg_fstab_end;
99
CYG_HAL_TABLE_END( cyg_fstab_end, fstab );
100
 
101
#ifdef CYGPKG_KERNEL
102
// Array of mutexes for locking the fstab entries
103
static Cyg_Mutex fstab_lock[CYGNUM_FILEIO_FSTAB_MAX] CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
104
#endif
105
 
106
// -------------------------------------------------------------------------
107
// Mount table.
108
 
109
// This array contains entries for all valid running filesystems.
110
__externC cyg_mtab_entry cyg_mtab[];
111
CYG_HAL_TABLE_BEGIN( cyg_mtab, mtab );
112
 
113
// Extra entries at end of mtab for dynamic mount points.
114
#if CYGNUM_FILEIO_MTAB_EXTRA > 0
115
cyg_mtab_entry cyg_mtab_extra[CYGNUM_FILEIO_MTAB_EXTRA] CYG_HAL_TABLE_EXTRA(mtab) = { { NULL } };
116
#endif
117
// End of mount table, set in the linker script.
118
__externC cyg_mtab_entry cyg_mtab_end;
119
CYG_HAL_TABLE_END( cyg_mtab_end, mtab );
120
 
121
#ifdef CYGPKG_KERNEL
122
// Array of mutexes for locking the mtab entries
123
static Cyg_Mutex mtab_lock[CYGNUM_FILEIO_MTAB_MAX] CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
124
#endif
125
 
126
//==========================================================================
127
// Current directory
128
 
129
cyg_mtab_entry *cyg_cdir_mtab_entry = NULL;
130
cyg_dir cyg_cdir_dir = CYG_DIR_NULL;
131
 
132
//==========================================================================
133
// Initialization object
134
 
135
class Cyg_Fileio_Init_Class
136
{
137
public:
138
    Cyg_Fileio_Init_Class();
139
};
140
 
141
static Cyg_Fileio_Init_Class fileio_initializer CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
142
 
143
Cyg_Fileio_Init_Class::Cyg_Fileio_Init_Class()
144
{
145
    cyg_fd_init();
146
 
147
    cyg_mtab_init();
148
 
149
    chdir("/");
150
}
151
 
152
//==========================================================================
153
// Mount table initializer
154
 
155
static void cyg_mtab_init()
156
{
157
    cyg_mtab_entry *m;
158
 
159
    for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
160
    {
161
        const char *fsname = m->fsname;
162
        cyg_fstab_entry *f;
163
 
164
        // Ignore empty entries
165
        if( m->name == NULL )
166
            continue;
167
 
168
        // stop if there are more than the configured maximum
169
        if( m-&cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX )
170
            break;
171
 
172
        for( f = &cyg_fstab[0]; f != &cyg_fstab_end; f++ )
173
        {
174
            // stop if there are more than the configured maximum
175
            if( f-&cyg_fstab[0] >= CYGNUM_FILEIO_FSTAB_MAX )
176
                break;
177
 
178
            if( strcmp( fsname, f->name) == 0 )
179
            {
180
                // We have a match.
181
 
182
                if( f->mount( f, m ) == 0 )
183
                {
184
                    m->valid    = true;
185
                    m->fs       = f;
186
                    // m->root installed by fs.
187
                }
188
                else
189
                {
190
                    m->valid = false;
191
                }
192
 
193
                break;
194
            }
195
        }
196
    }
197
}
198
 
199
//==========================================================================
200
// Mount table matching
201
 
202
// -------------------------------------------------------------------------
203
// matchlen() compares two strings and returns the number of bytes by which
204
// they match.
205
 
206
static int matchlen( const char *s1, const char *s2 )
207
{
208
    int len = 0;
209
    while( s1[len] == s2[len] && s1[len] && s2[len] ) len++;
210
 
211
    // Return length only if s2 is an initial substring of s1,
212
    // and it terminates in s1 at end-of-string or a '/'.
213
 
214
    // Special case for s2 == "/"
215
    if( len == 1 && s2[0] == '/' && s2[1] == 0 )
216
        return len;
217
 
218
    if( (s2[len] == 0) && (s1[len] == 0 || s1[len] == '/'))
219
         return len;
220
    else return 0;
221
}
222
 
223
// -------------------------------------------------------------------------
224
// Simple strlen implementation
225
 
226
static int my_strlen(const char *c)
227
{
228
    int l = 0;
229
    while (*c++) l++;
230
    return l;
231
}
232
 
233
// -------------------------------------------------------------------------
234
// Search the mtab for the entry that matches the longest substring of
235
// **name. 
236
 
237
__externC int cyg_mtab_lookup( cyg_dir *dir, const char **name, cyg_mtab_entry **mte)
238
{
239
    cyg_mtab_entry *m, *best = NULL;
240
    int best_len = 0;
241
 
242
    // Unrooted file names start from current dir
243
    if( **name != '/' ) {
244
        int cwd_len;
245
        if (*mte == (cyg_mtab_entry *)NULL) {
246
            // No known current directory
247
            return -1;
248
        }
249
 
250
        best = *mte;
251
        cwd_len = my_strlen((*mte)->name);
252
 
253
        // current dir is not the correct mte if the relative path crosses
254
        // mount points -  search for best matching mount point
255
        for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
256
        {
257
            if( m->name != NULL && m->valid )
258
            {
259
                int len = matchlen(m->name, (*mte)->name);
260
                // mount point under cwd?
261
                if (len == cwd_len)
262
                {
263
                    if (m->name[len] == '/')
264
                        len++;
265
 
266
                    len = matchlen(*name, &m->name[len]);
267
                    if (len > best_len)
268
                        best = m, best_len = len;
269
                }
270
            }
271
        }
272
 
273
        // did we find a better match?
274
        if (best != *mte)
275
          *dir = best->root;
276
    }
277
    else
278
    {
279
        // Otherwise search the mount table.
280
        for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
281
        {
282
            if( m->name != NULL && m->valid )
283
            {
284
                int len = matchlen(*name,m->name);
285
                if( len > best_len )
286
                    best = m, best_len = len;
287
            }
288
        }
289
 
290
        // No match found, bad path name...
291
        if( best_len == 0 ) return -1;
292
 
293
        *dir = best->root;
294
    }
295
 
296
    *name += best_len;
297
    if( **name == '/' )
298
        (*name)++;
299
    *mte = best;
300
 
301
    return 0;
302
}
303
 
304
//==========================================================================
305
// mount filesystem
306
 
307
__externC int mount( const char *devname,
308
                     const char *dir,
309
                     const char *fsname)
310
{
311
 
312
    FILEIO_ENTRY();
313
 
314
    cyg_mtab_entry *m;
315
    cyg_fstab_entry *f;
316
    int result = ENOERR;
317
 
318
    // Search the mount table for an empty entry
319
    for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
320
    {
321
        // stop if there are more than the configured maximum
322
        if( m-&cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX )
323
        {
324
            m = &cyg_mtab_end;
325
            break;
326
        }
327
 
328
         if( m->name == NULL ) break;
329
    }
330
 
331
    if( m == &cyg_mtab_end )
332
        FILEIO_RETURN(ENOMEM);
333
 
334
    // Now search the fstab for the filesystem implementation
335
    for( f = &cyg_fstab[0]; f != &cyg_fstab_end; f++ )
336
    {
337
        // stop if there are more than the configured maximum
338
        if( f-&cyg_fstab[0] >= CYGNUM_FILEIO_FSTAB_MAX )
339
            break;
340
 
341
        if( strcmp( fsname, f->name) == 0 )
342
            break;
343
    }
344
 
345
    if( f == &cyg_fstab_end )
346
        FILEIO_RETURN(ENODEV);
347
 
348
    // We have a match.
349
 
350
    m->name = dir;
351
    m->fsname = fsname;
352
    m->devname = devname;
353
 
354
    if( (result = f->mount( f, m )) == 0 )
355
    {
356
        m->valid    = true;
357
        m->fs       = f;
358
        // m->root installed by fs.
359
    }
360
    else
361
    {
362
        m->valid = false;
363
        m->name = NULL;
364
    }
365
 
366
    // Make sure that there is something to search (for open)
367
 
368
    if (cyg_cdir_mtab_entry == (cyg_mtab_entry *)NULL) {
369
        cyg_cdir_mtab_entry = m;
370
    }
371
 
372
    FILEIO_RETURN(result);
373
}
374
 
375
//==========================================================================
376
// unmount filesystem
377
 
378
__externC int umount( const char *name)
379
{
380
    int err = ENOERR;
381
 
382
    FILEIO_ENTRY();
383
 
384
    cyg_mtab_entry *m;
385
 
386
    // Search the mount table for a matching entry
387
    for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
388
    {
389
        // stop if there are more than the configured maximum
390
        if( m-&cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX )
391
        {
392
            m = &cyg_mtab_end;
393
            break;
394
        }
395
 
396
        // Ignore empty or invalid entries
397
         if( m->name == NULL || !m->valid ) continue;
398
 
399
         // match names.
400
         if( strcmp(name,m->name) == 0 ) break;
401
 
402
         // Match device name too?
403
    }
404
 
405
    if( m == &cyg_mtab_end )
406
        FILEIO_RETURN(EINVAL);
407
 
408
    // We have a match, call the umount function
409
 
410
    err = m->fs->umount( m );
411
 
412
    if( err == ENOERR )
413
    {
414
        m->valid        = false;
415
        m->name         = NULL;
416
    }
417
 
418
    FILEIO_RETURN(err);
419
}
420
 
421
//==========================================================================
422
// Implement filesystem locking protocol. 
423
 
424
void cyg_fs_lock( cyg_mtab_entry *mte, cyg_uint32 syncmode )
425
{
426
    CYG_ASSERT(mte != NULL, "Bad mount table entry");
427
 
428
    if( syncmode & CYG_SYNCMODE_FILE_FILESYSTEM ) {
429
        CYG_ASSERT(mte->fs-&cyg_fstab[0] < CYGNUM_FILEIO_FSTAB_MAX, "Bad file system");
430
        FILEIO_MUTEX_LOCK( fstab_lock[mte->fs-&cyg_fstab[0]] );
431
    }
432
 
433
    if( syncmode & CYG_SYNCMODE_FILE_MOUNTPOINT ) {
434
        CYG_ASSERT(mte-&cyg_mtab[0] < CYGNUM_FILEIO_MTAB_MAX, "Bad mount point");
435
        FILEIO_MUTEX_LOCK( mtab_lock[mte-&cyg_mtab[0]] );
436
    }
437
}
438
 
439
void cyg_fs_unlock( cyg_mtab_entry *mte, cyg_uint32 syncmode )
440
{
441
    CYG_ASSERT(mte != NULL, "Bad mount table entry");
442
 
443
    if( syncmode & CYG_SYNCMODE_FILE_FILESYSTEM ) {
444
        CYG_ASSERT(mte->fs-&cyg_fstab[0] < CYGNUM_FILEIO_FSTAB_MAX, "Bad file system");
445
        FILEIO_MUTEX_UNLOCK( fstab_lock[mte->fs-&cyg_fstab[0]] );
446
    }
447
 
448
    if( syncmode & CYG_SYNCMODE_FILE_MOUNTPOINT ) {
449
        CYG_ASSERT(mte-&cyg_mtab[0] < CYGNUM_FILEIO_MTAB_MAX, "Bad mount point");
450
        FILEIO_MUTEX_UNLOCK( mtab_lock[mte-&cyg_mtab[0]] );
451
    }
452
}
453
 
454
//==========================================================================
455
// Search mount table for a filesystems root. 
456
 
457
__externC cyg_mtab_entry * cyg_fs_root_lookup( cyg_dir *root )
458
{
459
     cyg_mtab_entry *m;
460
 
461
     for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
462
     {
463
          if( (cyg_dir *)m->root == root )
464
          {
465
               return m;
466
          }
467
     }
468
     return NULL;
469
}
470
 
471
//==========================================================================
472
// Timestamp support
473
// This provides access to the current time/date, expressed as a
474
// time_t.  It uses a number of mechanisms to do this, selecting
475
// whichever is available in the current configuration.
476
 
477
__externC time_t cyg_timestamp()
478
{
479
#if defined(CYGPKG_IO_WALLCLOCK)
480
 
481
    // First, try to get the time from the wallclock device.
482
 
483
    return (time_t) Cyg_WallClock::wallclock->get_current_time();
484
 
485
#elif defined(CYGINT_ISO_POSIX_TIMERS)
486
 
487
    // If POSIX is present, use the current value of the realtime
488
    // clock.
489
 
490
    struct timespec tp;
491
 
492
    clock_gettime( CLOCK_REALTIME, &tp );
493
 
494
    return (time_t) tp.tv_sec;
495
 
496
#elif defined(CYGPKG_KERNEL) 
497
 
498
    // If all else fails, get the current realtime clock value and
499
    // convert it to seconds ourself.
500
 
501
    static struct Cyg_Clock::converter sec_converter;
502
    static cyg_bool initialized = false;
503
    cyg_tick_count ticks;
504
 
505
    if( !initialized )
506
    {
507
        Cyg_Clock::real_time_clock->get_clock_to_other_converter( 1000000000, &sec_converter );
508
        initialized = true;
509
    }
510
 
511
    ticks = Cyg_Clock::real_time_clock->current_value();
512
 
513
    return (time_t) Cyg_Clock::convert( ticks, &sec_converter );
514
#else    
515
    /* No clock support at all. */
516
    return (time_t) 0;
517
#endif    
518
 
519
}
520
 
521
//==========================================================================
522
// Default functions
523
 
524
__externC int cyg_fileio_enosys() { return ENOSYS; }
525
__externC int cyg_fileio_erofs() { return EROFS; }
526
__externC int cyg_fileio_enoerr() { return ENOERR; }
527
__externC int cyg_fileio_enotdir() { return ENOTDIR; }
528
 
529
__externC cyg_bool cyg_fileio_seltrue (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info)
530
{ return 1; }
531
 
532
// -------------------------------------------------------------------------
533
// EOF misc.cxx

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.