summaryrefslogtreecommitdiff
path: root/cesar/ecos/packages/io/fileio/current/src
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/ecos/packages/io/fileio/current/src')
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/devfs.cxx497
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/dir.cxx228
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/fd.cxx398
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/file.cxx906
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/fio.h232
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/inocache.cxx216
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/io.cxx544
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/misc.cxx495
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/select.cxx402
-rw-r--r--cesar/ecos/packages/io/fileio/current/src/socket.cxx735
10 files changed, 4653 insertions, 0 deletions
diff --git a/cesar/ecos/packages/io/fileio/current/src/devfs.cxx b/cesar/ecos/packages/io/fileio/current/src/devfs.cxx
new file mode 100644
index 0000000000..e407dc8691
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/devfs.cxx
@@ -0,0 +1,497 @@
+//==========================================================================
+//
+// devfs.cxx
+//
+// Fileio device filesystem
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg, gthomas
+// Date: 2000-05-25
+// Purpose: Fileio device filesystem
+// Description: This file implements a simple filesystem that interfaces
+// to the existing device IO subsystem.
+//
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_fileio.h>
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include "fio.h" // Private header
+
+#include <cyg/io/devtab.h> // device subsystem
+#include <cyg/io/config_keys.h> // CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
+
+//==========================================================================
+// Forward definitions
+
+// Filesystem operations
+static int dev_mount ( cyg_fstab_entry *fste, cyg_mtab_entry *mte );
+static int dev_umount ( cyg_mtab_entry *mte );
+static int dev_open ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ int mode, cyg_file *fte );
+static int dev_unlink ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
+static int dev_mkdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
+static int dev_rmdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
+static int dev_rename ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
+ cyg_dir dir2, const char *name2 );
+static int dev_link ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
+ cyg_dir dir2, const char *name2, int type );
+static int dev_opendir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ cyg_file *fte );
+static int dev_chdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ cyg_dir *dir_out );
+static int dev_stat ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ struct stat *buf);
+static int dev_getinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ int key, void *buf, int len );
+static int dev_setinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ int key, void *buf, int len );
+
+// File operations
+static int dev_fo_read (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
+static int dev_fo_write (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);
+static int dev_fo_lseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence );
+static int dev_fo_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
+ CYG_ADDRWORD data);
+static cyg_bool dev_fo_select (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info);
+static int dev_fo_fsync (struct CYG_FILE_TAG *fp, int mode );
+static int dev_fo_close (struct CYG_FILE_TAG *fp);
+static int dev_fo_fstat (struct CYG_FILE_TAG *fp, struct stat *buf );
+static int dev_fo_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len );
+static int dev_fo_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len );
+
+
+//==========================================================================
+// Filesystem table entries
+
+FSTAB_ENTRY( dev_fste, "devfs", 0,
+ CYG_SYNCMODE_NONE, // dev system has its own sync mechanism
+ dev_mount,
+ dev_umount,
+ dev_open,
+ dev_unlink,
+ dev_mkdir,
+ dev_rmdir,
+ dev_rename,
+ dev_link,
+ dev_opendir,
+ dev_chdir,
+ dev_stat,
+ dev_getinfo,
+ dev_setinfo);
+
+MTAB_ENTRY( dev_mte,
+ "/dev",
+ "devfs",
+ "",
+ 0);
+
+static cyg_fileops dev_fileops =
+{
+ dev_fo_read,
+ dev_fo_write,
+ dev_fo_lseek,
+ dev_fo_ioctl,
+ dev_fo_select,
+ dev_fo_fsync,
+ dev_fo_close,
+ dev_fo_fstat,
+ dev_fo_getinfo,
+ dev_fo_setinfo
+};
+
+//==========================================================================
+// Filesystem operations
+
+// -------------------------------------------------------------------------
+
+static int dev_mount ( cyg_fstab_entry *fste, cyg_mtab_entry *mte )
+{
+ // Nothing to do here. The device IO subsystem has already initialized
+ // iteslf, and the fileio infrastructure will do the rest.
+
+ return 0;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_umount ( cyg_mtab_entry *mte )
+{
+ // Nothing to do here.
+
+ return 0;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_open ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ int mode, cyg_file *file )
+{
+ Cyg_ErrNo err;
+ cyg_io_handle_t handle;
+
+ // The name we are passed will point to the first character after
+ // "/dev/". We know that the full string contains the prefix string,
+ // so we back the pointer up by 5 chars.
+ // A better approach would be for the device table entries to only
+ // contain the part of the string after the prefix.
+
+ name -= 5;
+
+ err = cyg_io_lookup( name, &handle );
+
+ if( err < 0 )
+ return -err;
+
+ // If we want non-blocking mode, configure the device for it.
+ if( (mode & (O_NONBLOCK|O_RDONLY)) == (O_NONBLOCK|O_RDONLY) )
+ {
+ cyg_uint32 f = 0;
+ cyg_uint32 fsize = sizeof(f);
+ err = cyg_io_set_config( handle, CYG_IO_SET_CONFIG_READ_BLOCKING,
+ (void *)&f, &fsize);
+ if( err < 0 )
+ return -err;
+ }
+
+ if( (mode & (O_NONBLOCK|O_WRONLY)) == (O_NONBLOCK|O_WRONLY) )
+ {
+ cyg_uint32 f = 0;
+ cyg_uint32 fsize = sizeof(f);
+ err = cyg_io_set_config( handle, CYG_IO_SET_CONFIG_WRITE_BLOCKING,
+ (void *)&f, &fsize);
+ if( err < 0 )
+ return -err;
+ }
+
+ // Initialize the file object
+
+ file->f_flag |= mode & CYG_FILE_MODE_MASK;
+ file->f_type = CYG_FILE_TYPE_FILE;
+ file->f_ops = &dev_fileops;
+ file->f_offset = 0;
+ file->f_data = (CYG_ADDRWORD)handle;
+ file->f_xops = 0;
+
+ return 0;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_unlink ( cyg_mtab_entry *mte, cyg_dir dir, const char *name )
+{
+ return EROFS;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_mkdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name )
+{
+ return EROFS;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_rmdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name )
+{
+ return EROFS;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_rename ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
+ cyg_dir dir2, const char *name2 )
+{
+ return EROFS;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_link ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
+ cyg_dir dir2, const char *name2, int type )
+{
+ return EROFS;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_opendir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ cyg_file *fte )
+{
+ return ENOTDIR;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_chdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ cyg_dir *dir_out )
+{
+ return ENOTDIR;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_stat ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ struct stat *buf)
+{
+ Cyg_ErrNo err;
+ cyg_io_handle_t handle;
+ cyg_devtab_entry_t *dev;
+
+ name -= 5; // See comment in dev_open()
+
+ err = cyg_io_lookup( name, &handle );
+
+ if( err < 0 )
+ return -err;
+
+ // Just fill in the stat buffer with some constant values.
+ dev = (cyg_devtab_entry_t *)handle;
+
+ if (dev->status & CYG_DEVTAB_STATUS_BLOCK)
+ buf->st_mode = __stat_mode_BLK;
+ else
+ buf->st_mode = __stat_mode_CHR;
+
+ buf->st_ino = (ino_t)handle; // map dev handle to inode
+ buf->st_dev = 0; // (dev_t)handle; // same with dev id
+ buf->st_nlink = 1;
+ buf->st_uid = 0;
+ buf->st_gid = 0;
+ buf->st_size = 0;
+ buf->st_atime = 0;
+ buf->st_mtime = 0;
+ buf->st_ctime = 0;
+
+ return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_getinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ int key, void *buf, int len )
+{
+ return ENOSYS;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_setinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
+ int key, void *buf, int len )
+{
+ return ENOSYS;
+}
+
+//==========================================================================
+// File operations
+
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_read (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
+{
+ Cyg_ErrNo err = 0;
+ int i;
+
+ // Now loop over the iovecs until they are all done, or
+ // we get an error.
+ for( i = 0; i < uio->uio_iovcnt; i++ )
+ {
+ cyg_iovec *iov = &uio->uio_iov[i];
+ cyg_uint32 len = iov->iov_len;
+ cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)fp->f_data;
+
+ if (t->status & CYG_DEVTAB_STATUS_BLOCK)
+ err = cyg_io_bread( (cyg_io_handle_t)t,
+ iov->iov_base,
+ &len, fp->f_offset);
+ else
+ err = cyg_io_read( (cyg_io_handle_t)t,
+ iov->iov_base,
+ &len);
+
+ if( err < 0 ) break;
+
+ uio->uio_resid -= len;
+ }
+
+ return -err;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_write (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio)
+{
+ Cyg_ErrNo err = 0;
+ int i;
+
+ // Now loop over the iovecs until they are all done, or
+ // we get an error.
+ for( i = 0; i < uio->uio_iovcnt; i++ )
+ {
+ cyg_iovec *iov = &uio->uio_iov[i];
+ cyg_uint32 len = iov->iov_len;
+ cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)fp->f_data;
+
+ if (t->status & CYG_DEVTAB_STATUS_BLOCK)
+ err = cyg_io_bwrite( (cyg_io_handle_t)t,
+ iov->iov_base,
+ &len, fp->f_offset);
+ else
+ err = cyg_io_write( (cyg_io_handle_t)t,
+ iov->iov_base,
+ &len);
+
+ if( err < 0 ) break;
+
+ uio->uio_resid -= len;
+ }
+
+ return -err;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_lseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence )
+{
+ // All current devices have no notion of position. Just return zero
+ // as the new position.
+
+ *pos = 0;
+
+ return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,
+ CYG_ADDRWORD data)
+{
+ return ENOSYS;
+}
+
+// -------------------------------------------------------------------------
+
+static cyg_bool dev_fo_select (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info)
+{
+ return cyg_io_select( (cyg_io_handle_t)fp->f_data,
+ which,
+ info);
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_fsync (struct CYG_FILE_TAG *fp, int mode )
+{
+ Cyg_ErrNo err;
+
+ err = cyg_io_get_config((cyg_io_handle_t)fp->f_data,
+ CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,
+ NULL, NULL);
+
+ return -err;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_close (struct CYG_FILE_TAG *fp)
+{
+ return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_fstat (struct CYG_FILE_TAG *fp, struct stat *buf )
+{
+ cyg_devtab_entry_t *dev = (cyg_devtab_entry_t *)fp->f_data;
+
+ // Just fill in the stat buffer with some constant values.
+ if (dev->status & CYG_DEVTAB_STATUS_BLOCK)
+ buf->st_mode = __stat_mode_BLK;
+ else
+ buf->st_mode = __stat_mode_CHR;
+
+ buf->st_ino = (ino_t)fp->f_data; // map dev handle to inode
+ buf->st_dev = 0; //(dev_t)fp->f_data; // same with dev id
+ buf->st_nlink = 1;
+ buf->st_uid = 0;
+ buf->st_gid = 0;
+ buf->st_size = 0;
+ buf->st_atime = 0;
+ buf->st_mtime = 0;
+ buf->st_ctime = 0;
+
+ return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len )
+{
+ Cyg_ErrNo err = 0;
+ cyg_uint32 ll = len;
+
+ err = cyg_io_get_config( (cyg_io_handle_t)fp->f_data, key, buf, &ll );
+
+ return -err;
+}
+
+// -------------------------------------------------------------------------
+
+static int dev_fo_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len )
+{
+ Cyg_ErrNo err = 0;
+ cyg_uint32 ll = len;
+
+ err = cyg_io_set_config( (cyg_io_handle_t)fp->f_data, key, buf, &ll );
+
+ return -err;
+}
+
+// -------------------------------------------------------------------------
+// EOF devfs.cxx
diff --git a/cesar/ecos/packages/io/fileio/current/src/dir.cxx b/cesar/ecos/packages/io/fileio/current/src/dir.cxx
new file mode 100644
index 0000000000..32fc03b0cb
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/dir.cxx
@@ -0,0 +1,228 @@
+//==========================================================================
+//
+// dir.cxx
+//
+// Fileio directory support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-05-25
+// Purpose: Fileio directory support
+// Description: Support for directory operations.
+//
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_fileio.h>
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <stdarg.h> // for fcntl()
+
+#include "fio.h" // Private header
+
+#include <dirent.h> // struct dirent
+
+//==========================================================================
+
+#define DIROPEN_RETURN_ERR( err ) \
+CYG_MACRO_START \
+ errno = err; \
+ CYG_REPORT_RETVAL( NULL ); \
+ return NULL; \
+CYG_MACRO_END
+
+//==========================================================================
+// Implement filesystem locking protocol.
+
+#define LOCK_FS( _mte_ ) { \
+ CYG_ASSERT(_mte_ != NULL, "Bad mount table entry"); \
+ cyg_fs_lock( _mte_, (_mte_)->fs->syncmode); \
+}
+
+#define UNLOCK_FS( _mte_ ) cyg_fs_unlock( _mte_, (_mte_)->fs->syncmode)
+
+//==========================================================================
+// Open a directory for reading
+
+extern DIR *opendir( const char *dirname )
+{
+ FILEIO_ENTRY();
+
+ CYG_CANCELLATION_POINT;
+
+ int ret = 0;
+ int fd;
+ cyg_file *file;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = dirname;
+
+ fd = cyg_fd_alloc(1); // Never return fd 0
+
+ if( fd < 0 )
+ DIROPEN_RETURN_ERR(EMFILE);
+
+ file = cyg_file_alloc();
+
+ if( file == NULL )
+ {
+ cyg_fd_free(fd);
+ DIROPEN_RETURN_ERR(ENFILE);
+ }
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ {
+ cyg_fd_free(fd);
+ cyg_file_free(file);
+ DIROPEN_RETURN_ERR(ENOENT);
+ }
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->opendir( mte, dir, name, file );
+
+ UNLOCK_FS( mte );
+
+ if( 0 != ret )
+ {
+ cyg_fd_free(fd);
+ cyg_file_free(file);
+ DIROPEN_RETURN_ERR(ret);
+ }
+
+ file->f_flag |= CYG_FDIR|CYG_FREAD;
+ file->f_mte = mte;
+ file->f_syncmode = mte->fs->syncmode;
+
+ cyg_fd_assign( fd, file );
+
+ DIR *dirp = (DIR *)fd;
+
+ FILEIO_RETURN_VALUE(dirp);
+}
+
+//==========================================================================
+// Read a directory entry.
+// This is the thread-unsafe version that uses a static result buffer.
+// It just calls the thread-safe version to do the work.
+
+extern struct dirent *readdir( DIR *dirp )
+{
+ FILEIO_ENTRY();
+
+ static struct dirent ent;
+ struct dirent *result;
+ int err;
+
+ err = readdir_r( dirp, &ent, &result );
+
+ if( err != 0 )
+ {
+ errno = err;
+ FILEIO_RETURN_VALUE( NULL );
+ }
+
+ FILEIO_RETURN_VALUE( result );
+}
+
+//==========================================================================
+
+extern int readdir_r( DIR *dirp, struct dirent *entry, struct dirent **result )
+{
+ FILEIO_ENTRY();
+
+ int fd = (int)dirp;
+ ssize_t res;
+
+ *result = NULL;
+
+ if( NULL == dirp )
+ {
+ FILEIO_RETURN_VALUE( EBADF );
+ }
+
+ res = read( fd, (void *)entry, sizeof(struct dirent));
+
+ if( res < 0 )
+ {
+ FILEIO_RETURN_VALUE( errno );
+ }
+
+ if( res > 0 )
+ *result = entry;
+
+ FILEIO_RETURN( ENOERR );
+}
+
+//==========================================================================
+
+extern void rewinddir( DIR *dirp )
+{
+ FILEIO_ENTRY();
+
+ int fd = (int)dirp;
+
+ lseek( fd, 0, SEEK_SET );
+
+ FILEIO_RETURN_VOID();
+}
+
+//==========================================================================
+
+extern int closedir( DIR *dirp )
+{
+ FILEIO_ENTRY();
+
+ int fd = (int)dirp;
+ int err = close( fd );
+
+ FILEIO_RETURN_VALUE( err );
+}
+
+// -------------------------------------------------------------------------
+// EOF dir.cxx
diff --git a/cesar/ecos/packages/io/fileio/current/src/fd.cxx b/cesar/ecos/packages/io/fileio/current/src/fd.cxx
new file mode 100644
index 0000000000..be6faad156
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/fd.cxx
@@ -0,0 +1,398 @@
+//==========================================================================
+//
+// fd.cxx
+//
+// Fileio file descriptor implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-05-25
+// Purpose: Fileio file descriptor implementation
+// Description: This file contains the implementation of the file
+// descriptor functions.
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_fileio.h>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#include <cyg/kernel/ktypes.h> // base kernel types
+#endif
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include "fio.h" // Private header
+
+//-----------------------------------------------------------------------------
+// File data structures
+
+#ifdef CYGPKG_KERNEL
+// Mutex for controlling access to file desriptor arrays
+Cyg_Mutex fdlock CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
+
+// Array of per-file mutexes
+static Cyg_Mutex file_lock[CYGNUM_FILEIO_NFILE] \
+ CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
+#endif // ifdef CYGPKG_KERNEL
+
+// Array of open file objects
+static cyg_file file[CYGNUM_FILEIO_NFILE];
+
+// Descriptor array
+static cyg_file *desc[CYGNUM_FILEIO_NFD];
+
+#define FD_ALLOCATED ((cyg_file *)1)
+
+//==========================================================================
+// Initialization
+
+__externC void cyg_fd_init()
+{
+ int i;
+
+ for( i = 0; i < CYGNUM_FILEIO_NFILE; i++ )
+ file[i].f_flag = 0;
+
+ for( i = 0; i < CYGNUM_FILEIO_NFD; i++ )
+ desc[i] = NULL;
+}
+
+//==========================================================================
+// File object allocation
+
+//--------------------------------------------------------------------------
+// Locate and allocate a free file object.
+
+__externC cyg_file *cyg_file_alloc()
+{
+ int i;
+ cyg_file *fp = NULL;
+
+ FILEIO_MUTEX_LOCK(fdlock);
+
+ for( i = 0; i < CYGNUM_FILEIO_NFILE; i++ )
+ {
+ if( (file[i].f_flag & CYG_FALLOC) == 0 )
+ {
+ fp = &file[i];
+ fp->f_flag = CYG_FALLOC;
+ fp->f_ucount = 0;
+ break;
+ }
+ }
+
+ FILEIO_MUTEX_UNLOCK(fdlock);
+
+ return fp;
+}
+
+//--------------------------------------------------------------------------
+// Free a file object. This is a straightforward freeing, usually used
+// during error recovery. File objects are normally freed as a side
+// effect of cyg_fd_assign() or cyg_fd_free().
+
+__externC void cyg_file_free(cyg_file * fp)
+{
+ FILEIO_MUTEX_LOCK(fdlock);
+
+ fp->f_flag = 0;
+
+ FILEIO_MUTEX_UNLOCK(fdlock);
+}
+
+//==========================================================================
+// Internal routines for handling descriptor deallocation
+// These must all be called with the fdlock already locked.
+
+//--------------------------------------------------------------------------
+// Decrement the use count on a file object and if it goes to zero,
+// close the file and deallocate the file object.
+
+static int fp_ucount_dec( cyg_file *fp )
+{
+ int error = 0;
+ if( (--fp->f_ucount) <= 0 )
+ {
+ cyg_file_lock( fp, fp->f_syncmode );
+
+ error = fp->f_ops->fo_close(fp);
+
+ cyg_file_unlock( fp, fp->f_syncmode );
+
+ if( error == 0 )
+ fp->f_flag = 0;
+ }
+
+ return error;
+}
+
+//--------------------------------------------------------------------------
+// Clear out a descriptor. If this is the last reference to the file
+// object, then that will be closed and deallocated.
+
+static int fd_close( int fd )
+{
+ int error = 0;
+ cyg_file *fp;
+
+ CYG_ASSERT(((0 <= fd) && (fd<CYGNUM_FILEIO_NFD)), "fd out of range");
+
+ fp = desc[fd];
+
+ if( fp != FD_ALLOCATED && fp != NULL)
+ {
+ // The descriptor is occupied, decrement its usecount and
+ // close the file if it goes zero.
+
+ error = fp_ucount_dec( fp );
+ }
+
+ desc[fd] = FD_ALLOCATED;
+
+ return error;
+}
+
+
+//==========================================================================
+// File descriptor allocation
+
+//--------------------------------------------------------------------------
+// Allocate a file descriptor. The allocated descriptor is set to the value
+// FD_ALLOCATED to prevent it being reallocated by another thread.
+
+__externC int cyg_fd_alloc(int low)
+{
+ int fd;
+
+ CYG_ASSERT(((0 <= low) && (low<CYGNUM_FILEIO_NFD)),"fd out of range");
+
+ FILEIO_MUTEX_LOCK(fdlock);
+
+ for( fd = low; fd < CYGNUM_FILEIO_NFD; fd++ )
+ {
+ if( desc[fd] == NULL )
+ {
+ desc[fd] = FD_ALLOCATED;
+ FILEIO_MUTEX_UNLOCK(fdlock);
+ return fd;
+ }
+ }
+
+ FILEIO_MUTEX_UNLOCK(fdlock);
+
+ return -1;
+}
+
+//--------------------------------------------------------------------------
+// Assign a file object to a descriptor. If the descriptor is already
+// occupied, the occupying files usecount is decrement and it may be
+// closed.
+
+__externC void cyg_fd_assign(int fd, cyg_file *fp)
+{
+
+ CYG_ASSERT(((0 <= fd) && (fd<CYGNUM_FILEIO_NFD)),"fd out of range");
+
+ FILEIO_MUTEX_LOCK(fdlock);
+
+ fd_close( fd );
+
+ fp->f_ucount++;
+ desc[fd] = fp;
+
+ FILEIO_MUTEX_UNLOCK(fdlock);
+}
+
+//--------------------------------------------------------------------------
+// Free a descriptor. Any occupying files usecount is decremented and
+// it may be closed.
+
+__externC int cyg_fd_free(int fd)
+{
+ int error;
+
+ CYG_ASSERT(((0 <= fd) && (fd<CYGNUM_FILEIO_NFD)),"fd out of range");
+
+ FILEIO_MUTEX_LOCK(fdlock);
+
+ error = fd_close( fd );
+
+ desc[fd] = NULL;
+
+ FILEIO_MUTEX_UNLOCK(fdlock);
+
+ return error;
+}
+
+//==========================================================================
+// Descriptor to file object mapping
+
+
+//--------------------------------------------------------------------------
+// Map a descriptor to a file object. This is just a straightforward index
+// into the descriptor array complicated by the need to lock the mutex and
+// increment the usecount.
+
+__externC cyg_file *cyg_fp_get( int fd )
+{
+ CYG_ASSERT(((0 <= fd) && (fd<CYGNUM_FILEIO_NFD)),"fd out of range");
+
+ FILEIO_MUTEX_LOCK(fdlock);
+
+ cyg_file *fp = desc[fd];
+
+ if( fp != FD_ALLOCATED && fp != NULL)
+ {
+ // Increment use count while we work on this file
+
+ fp->f_ucount++;
+ }
+ else fp = NULL;
+
+ FILEIO_MUTEX_UNLOCK(fdlock);
+
+ return fp;
+}
+
+//--------------------------------------------------------------------------
+// Free the usecount reference we acquired in cyg_fp_get(). If the usecount
+// is zeroed, the file will be closed.
+
+__externC void cyg_fp_free( cyg_file *fp )
+{
+ FILEIO_MUTEX_LOCK(fdlock);
+
+ fp_ucount_dec( fp );
+
+ FILEIO_MUTEX_UNLOCK(fdlock);
+}
+
+//==========================================================================
+// File locking protocol
+
+void cyg_file_lock( cyg_file *fp , cyg_uint32 syncmode )
+{
+ cyg_fs_lock( fp->f_mte, syncmode>>CYG_SYNCMODE_IO_SHIFT);
+
+ if( syncmode & CYG_SYNCMODE_IO_FILE )
+ {
+ fp->f_flag |= CYG_FLOCKED;
+ FILEIO_MUTEX_LOCK(file_lock[fp-&file[0]]);
+ }
+}
+
+void cyg_file_unlock( cyg_file *fp, cyg_uint32 syncmode )
+{
+ cyg_fs_unlock( fp->f_mte, syncmode>>CYG_SYNCMODE_IO_SHIFT);
+
+ if( syncmode & CYG_SYNCMODE_IO_FILE )
+ {
+ fp->f_flag &= ~CYG_FLOCKED;
+ FILEIO_MUTEX_UNLOCK(file_lock[fp-&file[0]]);
+ }
+}
+
+
+//==========================================================================
+// POSIX API routines
+
+//--------------------------------------------------------------------------
+// dup() - duplicate an FD into a random descriptor
+
+__externC int dup( int fd )
+{
+ cyg_file *fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ int fd2 = cyg_fd_alloc(0);
+
+ if( fd2 == -1 )
+ {
+ errno = EMFILE;
+ return -1;
+ }
+
+ cyg_fd_assign( fd2, fp );
+
+ cyg_fp_free(fp);
+
+ return fd2;
+}
+
+//--------------------------------------------------------------------------
+// dup2() - duplicate an FD into a chosen descriptor
+
+__externC int dup2( int fd, int fd2 )
+{
+ if( fd2 == fd ) return fd2;
+
+ if( fd2 < 0 || fd2 >= OPEN_MAX )
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ cyg_file *fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ cyg_fd_assign( fd2, fp );
+
+ cyg_fp_free(fp);
+
+ return fd2;
+}
+
+// -------------------------------------------------------------------------
+// EOF fd.cxx
diff --git a/cesar/ecos/packages/io/fileio/current/src/file.cxx b/cesar/ecos/packages/io/fileio/current/src/file.cxx
new file mode 100644
index 0000000000..11e0049bad
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/file.cxx
@@ -0,0 +1,906 @@
+//==========================================================================
+//
+// file.cxx
+//
+// Fileio file operations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-05-25
+// Purpose: Fileio file operations
+// Description: These are the functions that operate on files as a whole,
+// such as open(), creat(), mkdir() etc.
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_fileio.h>
+#include <pkgconf/isoinfra.h>
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <string.h> // string functions
+#include <dirent.h>
+#include <stdio.h> // stdin, stdout, stderr
+
+#include "fio.h" // Private header
+
+//==========================================================================
+// Implement filesystem locking protocol.
+
+#define LOCK_FS( _mte_ ) { \
+ CYG_ASSERT(_mte_ != NULL, "Bad mount table entry"); \
+ CYG_ASSERT(_mte_->fs != NULL, "Bad mount filesystem entry"); \
+ cyg_fs_lock( _mte_, (_mte_)->fs->syncmode); \
+}
+
+#define UNLOCK_FS( _mte_ ) cyg_fs_unlock( _mte_, (_mte_)->fs->syncmode)
+
+//==========================================================================
+// A local strcpy clone that returns a pointer to the end of the copied
+// string, not the beginning.
+
+static char *my_strcpy( char *s1, const char *s2 )
+{
+ while( (*s1++ = *s2++) != 0);
+ return s1-1;
+}
+
+//==========================================================================
+// Compare a pathname fragment with an element in a pathname. This
+// deals with zero or separator termination and avoids substring
+// matches.
+
+static int pathcmp( const char *path, const char *name )
+{
+ while( *path == *name && *path != '\0' )
+ path++, name++;
+ if( *name != '\0' ) return false;
+ if( *path == '/' || *path == '\0' ) return true;
+ return false;
+}
+
+//==========================================================================
+// CWD support
+
+#ifdef CYGPKG_IO_FILEIO_TRACK_CWD
+
+// buffer for storing CWD path
+static char cwd[PATH_MAX];
+static size_t cwd_size = 0;
+
+
+static void update_cwd( cyg_mtab_entry *mte, cyg_dir dir, const char *path )
+{
+ char *p = cwd;
+
+ if( mte != cyg_cdir_mtab_entry || dir != cyg_cdir_dir )
+ {
+ // Here, the path is relative to the root of the filesystem,
+ // or in a totally new filesystem, initialize the cwd with the
+ // mount point name of the filesystem.
+
+ p = my_strcpy( p, mte->name );
+ }
+ else p = cwd+cwd_size;
+
+ // We must now copy the path into the cwd buffer while dealing
+ // with any "." and ".." components textually.
+
+ while( *path != '\0' )
+ {
+ // skip any stray directory separators.
+ if( *path == '/' ) path++;
+
+ // Look for a "." entry and just ignore it.
+ if( pathcmp( path, "." ) )
+ {
+ path++;
+ continue;
+ }
+
+ // Look for a ".." entry. If found, chew off the last cwd
+ // entry.
+ if( pathcmp( path, ".." ) )
+ {
+ while( *(--p) != '/' ); // back up to last '/'
+ path += 2; // skip "..".
+ continue;
+ }
+
+ // Otherwise just copy the name fragment over to the cwd.
+
+ if( *(p-1) != '/' )
+ *p++ = '/'; // add a directory separator
+ while( *path != '/' && *path != '\0' )
+ *p++ = *path++;
+
+ }
+
+ // Zero terminate the cwd.
+ *p = '\0';
+
+ // update size
+ cwd_size = p-cwd;
+}
+
+#else
+
+#ifdef CYGPKG_KERNEL
+static Cyg_Mutex getcwd_lock CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
+#endif
+
+#endif
+
+
+//==========================================================================
+// Open a file
+
+__externC int open( const char *path, int oflag, ... )
+{
+ FILEIO_ENTRY();
+
+ // we want to be sure we pull in stdin/out/err, so they can be
+ // assigned to fds 0, 1 and 2
+#ifdef CYGINT_ISO_STDIO_STREAMS
+ CYG_REFERENCE_OBJECT(stdin);
+ CYG_REFERENCE_OBJECT(stdout);
+ CYG_REFERENCE_OBJECT(stderr);
+#endif
+
+ CYG_CANCELLATION_POINT;
+
+ int ret = 0;
+ int fd;
+ cyg_file *file;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ // At least one of O_RDONLY, O_WRONLY, O_RDWR must be provided
+ if( (oflag & O_RDWR) == 0 )
+ FILEIO_RETURN(EINVAL);
+
+ fd = cyg_fd_alloc(0);
+
+ if( fd < 0 )
+ FILEIO_RETURN(EMFILE);
+
+ file = cyg_file_alloc();
+
+ if( file == NULL )
+ {
+ cyg_fd_free(fd);
+ FILEIO_RETURN(ENFILE);
+ }
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ {
+ cyg_fd_free(fd);
+ cyg_file_free(file);
+ FILEIO_RETURN(ENOENT);
+ }
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->open( mte, dir, name, oflag, file );
+
+ UNLOCK_FS( mte );
+
+ if( 0 != ret )
+ {
+ cyg_fd_free(fd);
+ cyg_file_free(file);
+ FILEIO_RETURN(ret);
+ }
+
+ file->f_mte = mte;
+ file->f_syncmode = mte->fs->syncmode;
+
+ cyg_fd_assign( fd, file );
+
+ FILEIO_RETURN_VALUE(fd);
+}
+
+//==========================================================================
+// create a file
+
+__externC int creat( const char *path, mode_t mode )
+{
+ return open( path, O_WRONLY | O_CREAT | O_TRUNC, mode );
+}
+
+
+//==========================================================================
+// Unlink/remove a file
+
+__externC int unlink( const char *path )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->unlink( mte, dir, name );
+
+ UNLOCK_FS( mte );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// Make a directory
+
+__externC int mkdir( const char *path, mode_t mode )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ mode=mode;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->mkdir( mte, dir, name );
+
+ UNLOCK_FS( mte );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// Remove a directory
+
+__externC int rmdir( const char *path )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->rmdir( mte, dir, name );
+
+ UNLOCK_FS( mte );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// Rename a file
+
+__externC int rename( const char *path1, const char *path2 ) __THROW
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte1 = cyg_cdir_mtab_entry;
+ cyg_mtab_entry *mte2 = cyg_cdir_mtab_entry;
+ cyg_dir dir1 = cyg_cdir_dir;
+ cyg_dir dir2 = cyg_cdir_dir;
+ const char *name1 = path1;
+ const char *name2 = path2;
+
+ ret = cyg_mtab_lookup( &dir1, &name1, &mte1 );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ ret = cyg_mtab_lookup( &dir2, &name2, &mte2 );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ // Cannot rename between different filesystems
+ if( mte1 != mte2 )
+ FILEIO_RETURN(EXDEV);
+
+ LOCK_FS( mte1 );
+
+ ret = mte1->fs->rename( mte1, dir1, name1, dir2, name2 );
+
+ UNLOCK_FS( mte1 );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// Create a link from an existing file (path1) to a new one (path2)
+
+__externC int link( const char *path1, const char *path2 )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte1 = cyg_cdir_mtab_entry;
+ cyg_mtab_entry *mte2 = cyg_cdir_mtab_entry;
+ cyg_dir dir1 = cyg_cdir_dir;
+ cyg_dir dir2 = cyg_cdir_dir;
+ const char *name1 = path1;
+ const char *name2 = path2;
+
+ ret = cyg_mtab_lookup( &dir1, &name1, &mte1 );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ ret = cyg_mtab_lookup( &dir2, &name2, &mte2 );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ // Cannot hard-link between different filesystems
+ if( mte1 != mte2 )
+ FILEIO_RETURN(EXDEV);
+
+ LOCK_FS( mte1 );
+
+ ret = mte1->fs->link( mte1, dir1, name1, dir2, name2, CYG_FSLINK_HARD );
+
+ UNLOCK_FS( mte1 );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// Change current directory
+
+__externC int chdir( const char *path )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ cyg_dir newdir;
+ const char *name = path;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS(mte);
+
+ ret = mte->fs->chdir( mte, dir, name, &newdir );
+
+ UNLOCK_FS(mte);
+
+ if( 0 != ret )
+ FILEIO_RETURN(ret);
+
+#ifdef CYGPKG_IO_FILEIO_TRACK_CWD
+ update_cwd( mte, dir, name );
+#endif
+
+ if( cyg_cdir_mtab_entry != NULL && cyg_cdir_dir != CYG_DIR_NULL )
+ {
+ // Now detach from current cyg_cdir. We call the current directory's
+ // chdir routine with a NULL dir_out pointer.
+
+ LOCK_FS(cyg_cdir_mtab_entry);
+
+ ret = cyg_cdir_mtab_entry->fs->chdir( cyg_cdir_mtab_entry, cyg_cdir_dir, NULL, NULL );
+
+ UNLOCK_FS(cyg_cdir_mtab_entry);
+
+ // We really shouldn't get an error here.
+ if( 0 != ret )
+ FILEIO_RETURN(ret);
+ }
+
+ cyg_cdir_mtab_entry = mte;
+ cyg_cdir_dir = newdir;
+
+ FILEIO_RETURN(ENOERR);
+}
+
+//==========================================================================
+// Get file statistics
+
+__externC int stat( const char *path, struct stat *buf )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->stat( mte, dir, name, buf );
+
+ UNLOCK_FS( mte );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// Get file configurable pathname variables
+
+__externC long pathconf( const char *path, int vname )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ struct cyg_pathconf_info info;
+
+ info.name = vname;
+ info.value = 0;
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->getinfo( mte, dir, name,
+ FS_INFO_CONF, (char *)&info, sizeof(info) );
+
+ UNLOCK_FS( mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ret);
+
+ FILEIO_RETURN_VALUE(info.value);
+}
+
+//==========================================================================
+// Sync filesystem without unmounting
+
+__externC int cyg_fs_fssync( const char *path )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->setinfo( mte, dir, name, FS_INFO_SYNC, NULL, 0 );
+
+ UNLOCK_FS( mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ret);
+
+ FILEIO_RETURN_VALUE(ENOERR);
+}
+
+//==========================================================================
+// Set file attributes
+
+__externC int cyg_fs_set_attrib( const char *fname,
+ const cyg_fs_attrib_t new_attrib )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = fname;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->setinfo( mte, dir, name,
+ FS_INFO_ATTRIB,
+ (char *)&new_attrib, sizeof(new_attrib) );
+
+ UNLOCK_FS( mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ret);
+
+ FILEIO_RETURN(ENOERR);
+}
+
+//==========================================================================
+// Get file attributes
+
+__externC int cyg_fs_get_attrib( const char *fname,
+ cyg_fs_attrib_t * const file_attrib )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = fname;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->getinfo( mte, dir, name,
+ FS_INFO_ATTRIB,
+ (char *)file_attrib, sizeof(*file_attrib) );
+
+ UNLOCK_FS( mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ret);
+
+ FILEIO_RETURN(ENOERR);
+}
+
+//==========================================================================
+// Access() function.
+// This simply piggybacks onto stat().
+
+extern int access(const char *path, int amode)
+{
+ FILEIO_ENTRY();
+
+ int ret;
+ struct stat buf;
+
+ ret = stat( path, &buf );
+
+ // Translate not found into EACCES if the F_OK bit is
+ // set.
+ if( (amode & F_OK) && (ret < 0) && (errno == ENOENT) )
+ FILEIO_RETURN(EACCES);
+
+ // All other errors go straight back to the user.
+ if( ret < 0 )
+ FILEIO_RETURN_VALUE(ret);
+
+ // At present we do not have any access modes, so there is nothing
+ // to test. Just return success for all access modes.
+
+ FILEIO_RETURN(ENOERR);
+}
+
+//==========================================================================
+// getcwd()
+
+__externC char *getcwd( char *buf, size_t size )
+{
+ FILEIO_ENTRY();
+
+ int err = ENOERR;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ cyg_getcwd_info info;
+
+ if( size == 0 )
+ {
+ errno = EINVAL;
+ FILEIO_RETURN_VALUE(NULL);
+ }
+
+ info.buf = buf;
+ info.size = size;
+
+ LOCK_FS( mte );
+
+ err = mte->fs->getinfo( mte, dir, "",
+ FS_INFO_GETCWD, (char *)&info, sizeof(info) );
+
+ UNLOCK_FS( mte );
+
+ if( err == ENOERR )
+ FILEIO_RETURN_VALUE(buf);
+
+ // Attempting to use filesystem support for getcwd() has
+ // failed.
+
+#ifdef CYGPKG_IO_FILEIO_TRACK_CWD
+
+ // If this option is set, the current directory path has been
+ // tracked in chdir(). Just report that value here.
+
+ if( size < cwd_size+1 )
+ {
+ errno = ERANGE;
+ FILEIO_RETURN_VALUE(NULL);
+ }
+
+ char *p = my_strcpy( buf, cwd );
+ *p = '\0';
+
+#else
+
+ // As a fallback we try to use ".." entries in the directory tree
+ // to climb back up to the root. Because we cannot assume that
+ // any filesystem can handle more than one directory pointer we
+ // have to do the climbing textually, by manufacturing a path name
+ // consisting of ".."s. At each level we then scan the parent
+ // directory looking for the entry for the lower level directory
+ // by matching st_ino values. This is not guaranteed to work at
+ // all since there is no requirement on filesystems to support "."
+ // and "..", or for them to report distinct inode values in
+ // stat().
+
+ static char ddbuf[PATH_MAX];
+ char *p = buf+size-1;
+ int ddbufpos;
+
+ // Claim lock to serialize use of ddbuf.
+ FILEIO_MUTEX_LOCK(getcwd_lock);
+
+ // Initialize ddbuf with ".".
+ ddbuf[0] = '.';
+ ddbuf[1] = '\0';
+ ddbufpos = 1;
+
+ // Start result buffer with a zero terminator. We accumulate the
+ // path name in the top end of the result buffer.
+ *p = '\0';
+
+ for(;;)
+ {
+ struct stat sdbuf;
+ struct stat sddbuf;
+
+ // Get status for "." and "..". If the filesystem does not
+ // support these, then this whole function will fail here.
+
+ err = stat( ddbuf, &sdbuf );
+ if( err < 0 ) break;
+
+ ddbuf[ddbufpos++] = '/';
+ ddbuf[ddbufpos++] = '.';
+ ddbuf[ddbufpos++] = '.';
+ ddbuf[ddbufpos] = '\0';
+
+ err = stat( ddbuf, &sddbuf );
+ if( err < 0 ) break;
+
+ // See whether we are at the root. This will be true when
+ // the inode numbers of "." and ".." are the same.
+ if( sdbuf.st_ino == sddbuf.st_ino )
+ break;
+
+ // We now need to find an entry in the ".." directory that
+ // matches the inode number of ".".
+
+ struct dirent de;
+ DIR *d = opendir( ddbuf );
+ if( d == NULL )
+ {
+ err = -1;
+ break;
+ }
+
+ for(;;)
+ {
+ struct dirent *res;
+ struct stat objstat;
+ int i;
+
+ err = readdir_r( d, &de, &res );
+ if( err < 0 || res == NULL ) break;
+
+ // Skip "." and ".." entries.
+ if( pathcmp( de.d_name, "." ) || pathcmp( de.d_name, ".." ) )
+ continue;
+
+ // Tack the name of the directory entry on to the ddbuf
+ // and stat the object.
+
+ ddbuf[ddbufpos] = '/';
+ for( i = 0; de.d_name[i] != '\0'; i++ )
+ ddbuf[ddbufpos+i+1] = de.d_name[i];
+ ddbuf[ddbufpos+i+1] = '\0';
+
+ // Take a look at it
+ err = stat( ddbuf, &objstat );
+ if( err < 0 ) break;
+
+ // Cast out directories
+ if( !S_ISDIR(objstat.st_mode) )
+ continue;
+
+ // We have a directory. Compare its inode with that of "."
+ // and if they are the same, we have found our entry.
+
+ if( sdbuf.st_ino == objstat.st_ino )
+ break;
+ }
+
+ ddbuf[ddbufpos] = '\0'; // reterminate ddbuf
+
+ closedir( d );
+
+ // Halt on any errors.
+ if( err < 0 )
+ break;
+
+ // Here de contains the name of the directory entry in ".."
+ // that has the same inode as ".". Add the name to the path we
+ // are accumulating in the buffer.
+
+ char *q = de.d_name;
+ while( *q != '\0' ) q++; // skip to end of name
+
+ do
+ {
+ *--p = *--q;
+ } while( q != de.d_name );
+
+ *--p = '/'; // add a separator
+ }
+
+ // We have finished using ddbuf now.
+ FILEIO_MUTEX_UNLOCK(getcwd_lock);
+
+ if( err < 0 )
+ FILEIO_RETURN_VALUE(NULL);
+
+ // We have the directory path in the top end of the buffer. Add
+ // the mount point name at the beginning and copy the rest of the
+ // name down.
+
+ char *bp = buf;
+
+ bp = my_strcpy( bp, mte->name );
+
+ // Sort out the separators between the mount name and the
+ // pathname. This is a bit messy since we have to deal with mount
+ // names of both "/" and "/foo" and pathnames that start with '/'
+ // or are empty.
+ if( *(bp-1) != '/' && *p != '\0' ) *bp++ = '/';
+ if( *p == '/' ) p++;
+
+ // Now copy the path over.
+ while( *p )
+ *bp++ = *p++;
+
+ *bp = '\0'; // Terminate the string
+
+ // All done!
+
+#endif
+
+ FILEIO_RETURN_VALUE(buf);
+}
+
+//==========================================================================
+// FS get info.
+
+__externC int cyg_fs_getinfo( const char *path, int key, void *buf, int len )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->getinfo( mte, dir, name, key, buf, len );
+
+ UNLOCK_FS( mte );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// FS set info.
+
+__externC int cyg_fs_setinfo( const char *path, int key, void *buf, int len )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ cyg_mtab_entry *mte = cyg_cdir_mtab_entry;
+ cyg_dir dir = cyg_cdir_dir;
+ const char *name = path;
+
+ ret = cyg_mtab_lookup( &dir, &name, &mte );
+
+ if( 0 != ret )
+ FILEIO_RETURN(ENOENT);
+
+ LOCK_FS( mte );
+
+ ret = mte->fs->setinfo( mte, dir, name, key, buf, len );
+
+ UNLOCK_FS( mte );
+
+ FILEIO_RETURN(ret);
+}
+
+// -------------------------------------------------------------------------
+// EOF file.cxx
diff --git a/cesar/ecos/packages/io/fileio/current/src/fio.h b/cesar/ecos/packages/io/fileio/current/src/fio.h
new file mode 100644
index 0000000000..ee4bdb506b
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/fio.h
@@ -0,0 +1,232 @@
+#ifndef CYGONCE_FIO_H
+#define CYGONCE_FIO_H
+//=============================================================================
+//
+// fio.h
+//
+// Fileio private header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Nick Garnett
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-05-25
+// Purpose: Fileio private header
+// Description: This file contains private definitions for communication
+// between the parts of the fileio package.
+//
+// Usage:
+// #include "fio.h"
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_fileio.h>
+#include <pkgconf/isoinfra.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <stddef.h> // NULL, size_t
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+
+#include <cyg/fileio/fileio.h>
+#include <cyg/fileio/sockio.h>
+
+#include <errno.h>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#include <cyg/kernel/mutex.hxx> // mutex definitions
+
+#define FILEIO_MUTEX_LOCK(_m_) ((_m_).lock())
+#define FILEIO_MUTEX_UNLOCK(_m_) ((_m_).unlock())
+
+#else
+#define FILEIO_MUTEX_LOCK(_m_)
+#define FILEIO_MUTEX_UNLOCK(_m_)
+#endif
+
+
+//=============================================================================
+// POSIX API support
+
+#ifdef CYGPKG_POSIX
+#include <pkgconf/posix.h>
+#include <cyg/posix/export.h>
+
+#define CYG_FILEIO_FUNCTION_START() CYG_POSIX_FUNCTION_START()
+
+#define CYG_FILEIO_FUNCTION_FINISH() CYG_POSIX_FUNCTION_FINISH()
+
+#else
+
+#define CYG_FILEIO_FUNCTION_START() CYG_EMPTY_STATEMENT
+
+#define CYG_FILEIO_FUNCTION_FINISH() CYG_EMPTY_STATEMENT
+
+#endif
+
+#ifdef CYGPKG_POSIX_SIGNALS
+
+#define CYG_FILEIO_SIGMASK_SET( __set, __oset ) \
+ CYG_PTHREAD_SIGMASK_SET( __set, __oset )
+
+#define CYG_FILEIO_SIGPENDING() CYG_POSIX_SIGPENDING()
+
+#define CYG_FILEIO_DELIVER_SIGNALS( __mask ) \
+ CYG_POSIX_DELIVER_SIGNALS( __mask )
+
+#else
+
+#define CYG_FILEIO_SIGMASK_SET( __set, __oset ) \
+CYG_MACRO_START \
+CYG_UNUSED_PARAM( const sigset_t*, __set ); \
+CYG_UNUSED_PARAM( const sigset_t*, __oset ); \
+CYG_MACRO_END
+
+#define CYG_FILEIO_SIGPENDING() (0)
+
+#define CYG_FILEIO_DELIVER_SIGNALS( __mask ) CYG_UNUSED_PARAM( const sigset_t*, __mask )
+
+typedef int sigset_t;
+
+#endif
+
+//=============================================================================
+// Fileio function entry and return macros.
+
+// Handle entry to a fileio package function.
+#define FILEIO_ENTRY() \
+ CYG_REPORT_FUNCTYPE( "returning %d" ); \
+ CYG_FILEIO_FUNCTION_START(); \
+
+// Do a fileio package defined return. This requires the error code
+// to be placed in errno, and if it is non-zero, -1 returned as the
+// result of the function. This also gives us a place to put any
+// generic tidyup handling needed for things like signal delivery and
+// cancellation.
+#define FILEIO_RETURN(err) \
+CYG_MACRO_START \
+ int __retval = 0; \
+ CYG_FILEIO_FUNCTION_FINISH(); \
+ if( err != 0 ) __retval = -1, errno = err; \
+ CYG_REPORT_RETVAL( __retval ); \
+ return __retval; \
+CYG_MACRO_END
+
+#define FILEIO_RETURN_VALUE(val) \
+CYG_MACRO_START \
+ CYG_FILEIO_FUNCTION_FINISH(); \
+ CYG_REPORT_RETVAL( val ); \
+ return val; \
+CYG_MACRO_END
+
+#define FILEIO_RETURN_VOID() \
+CYG_MACRO_START \
+ CYG_FILEIO_FUNCTION_FINISH(); \
+ CYG_REPORT_RETURN(); \
+ return; \
+CYG_MACRO_END
+
+//=============================================================================
+// Cancellation support
+// If the POSIX package is present we want to include cancellation points
+// in the routines that are defined to contain them.
+// The macro CYG_CANCELLATION_POINT does this.
+
+#ifdef CYGINT_ISO_PTHREAD_IMPL
+
+# include <pthread.h>
+
+# define CYG_CANCELLATION_POINT pthread_testcancel()
+
+#else
+
+# define CYG_CANCELLATION_POINT CYG_EMPTY_STATEMENT
+
+#endif
+
+//=============================================================================
+// Internal exports
+
+//-----------------------------------------------------------------------------
+// Exports from misc.cxx
+
+// Current directory info
+__externC cyg_mtab_entry *cyg_cdir_mtab_entry;
+__externC cyg_dir cyg_cdir_dir;
+
+__externC int cyg_mtab_lookup( cyg_dir *dir, const char **name, cyg_mtab_entry **mte);
+
+//-----------------------------------------------------------------------------
+// Exports from fd.cxx
+
+__externC void cyg_fd_init();
+
+__externC cyg_file *cyg_file_alloc();
+
+__externC void cyg_file_free(cyg_file * fp);
+
+__externC int cyg_fd_alloc(int low);
+
+__externC void cyg_fd_assign(int fd, cyg_file *fp);
+
+__externC int cyg_fd_free(int fd);
+
+__externC cyg_file *cyg_fp_get( int fd );
+
+__externC void cyg_fp_free( cyg_file *fp );
+
+__externC void cyg_file_lock( cyg_file *fp, cyg_uint32 syncmode );
+
+__externC void cyg_file_unlock( cyg_file *fp, cyg_uint32 syncmode );
+
+//-----------------------------------------------------------------------------
+// Exports from socket.cxx
+
+__externC void cyg_nstab_init();
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_FIO_H
+// End of fio.h
diff --git a/cesar/ecos/packages/io/fileio/current/src/inocache.cxx b/cesar/ecos/packages/io/fileio/current/src/inocache.cxx
new file mode 100644
index 0000000000..38f754bed8
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/inocache.cxx
@@ -0,0 +1,216 @@
+//=============================================================================
+//
+// inocache.cxx
+//
+// Implementation of inode cache
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2002-01-18
+// Purpose:
+// Description:
+// Usage:
+// #include <cyg/fileio/inode.h>
+// ...
+//
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/system.h>
+#include <cyg/infra/cyg_type.h>
+#include <stdlib.h>
+#include <cyg/fileio/inode.h>
+
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+# include <cyg/kernel/mutex.hxx>
+# if 0
+# define LOCK_ICACHE(_ic_) \
+ CYG_MACRO_START \
+ (_ic_)->icmutex.lock(); \
+ CYG_MACRO_END
+
+# define UNLOCK_ICACHE(_ic_) \
+ CYG_MACRO_START \
+ (_ic_)->icmutex.unlock(); \
+ CYG_MACRO_END
+# define LOCK_INO(_ic_,_ino_) \
+ CYG_MACRO_START \
+ (_ic_)->icmutex.lock(); \
+ CYG_MACRO_END
+# define UNLOCK_INO(_ic_,_ino_) \
+ CYG_MACRO_START \
+ (_ic_)->icmutex.unlock(); \
+ CYG_MACRO_END
+# endif
+#endif
+
+# define LOCK_ICACHE(_ic_) CYG_EMPTY_STATEMENT
+# define UNLOCK_ICACHE(_ic_) CYG_EMPTY_STATEMENT
+# define LOCK_INO(_ic_,_ino_) CYG_EMPTY_STATEMENT
+# define UNLOCK_INO(_ic_,_ino_) CYG_EMPTY_STATEMENT
+
+// Tried to make this implementation use tables, but the requirement to
+// allow for extra space makes this difficult
+
+__externC void
+cyg_inodecache_destroy( cyg_inodecache *ic )
+{
+ cyg_inode *tmp;
+ for ( tmp=ic->head; tmp != NULL; tmp=tmp->i_cache_next )
+ free(tmp);
+#if CYGNUM_IO_FILEIO_MAX_INODE_CACHE_DEAD > 0
+ for ( tmp=ic->freeable; tmp != NULL; tmp=tmp->i_cache_next )
+ free(tmp);
+#endif
+} // cyg_inodecache_destroy()
+
+static __inline__ void
+insert_in_list( cyg_inode **i, cyg_inode *ino )
+{
+ cyg_inode *here = *i;
+ if ( here == NULL ) {
+ ino->i_cache_prev = ino->i_cache_next = ino;
+ } else {
+ ino->i_cache_prev = here->i_cache_prev;
+ ino->i_cache_next = here;
+ here->i_cache_prev = ino;
+ ino->i_cache_prev->i_cache_next = ino;
+ }
+ // put at start, as this is more likely to come off sooner than later
+ *i = ino;
+}
+
+// Create an inode. Returns a negative error code on error.
+__externC cyg_inode *
+cyg_inode_create( cyg_inodecache *ic )
+{
+ cyg_inode *ni;
+
+ ni = (cyg_inode *)malloc( sizeof(cyg_inode)+ic->privatespace );
+ if ( !ni )
+ return ni;
+ ni->i_count = 1;
+
+ LOCK_ICACHE(ic);
+ insert_in_list( &ic->head, ni );
+ UNLOCK_ICACHE(ic);
+
+ return ni;
+} // cyg_inode_create()
+
+__externC cyg_inode *
+cyg_inode_get( cyg_inodecache *ic, cyg_uint32 ino )
+{
+ cyg_inode *head = ic->head;
+ // first try the (live) cache
+ if (head) {
+ cyg_inode *tmp=head;
+ while (1) {
+ if ( tmp->i_ino == ino ) {
+ tmp->i_count++;
+ return tmp;
+ }
+ tmp = tmp->i_cache_next;
+ if ( tmp == head )
+ break;
+ }
+ }
+#if CYGNUM_IO_FILEIO_MAX_INODE_CACHE_DEAD > 0
+ // now try the cache of dead inodes
+ head = ic->freeable;
+ if (head) {
+ cyg_inode *tmp=head;
+ while (1) {
+ if ( tmp->i_ino == ino ) {
+ tmp->i_count++;
+ LOCK_ICACHE(ic);
+ ic->freeablelistlen--;
+ if ( ic->freeablelistlen ) {
+ tmp->i_cache_prev->i_cache_next = tmp->i_cache_next;
+ tmp->i_cache_next->i_cache_prev = tmp->i_cache_prev;
+ } else
+ ic->freeable = NULL;
+ insert_in_list( &ic->head, tmp );
+ UNLOCK_ICACHE(ic);
+ return tmp;
+ }
+ tmp = tmp->i_cache_next;
+ if ( tmp == head )
+ break;
+ }
+ }
+#endif
+ // not found so make it
+ return cyg_inode_create( ic );
+
+} // cyg_inode_get()
+
+__externC void
+cyg_inode_put( cyg_inodecache *ic, cyg_inode *ino )
+{
+ if ( --ino->i_count == 0 )
+ {
+ LOCK_ICACHE(ic);
+ if ( ino->i_cache_next == ino ) {
+ ic->head = NULL;
+ } else {
+ ino->i_cache_prev->i_cache_next = ino->i_cache_next;
+ ino->i_cache_next->i_cache_prev = ino->i_cache_prev;
+ }
+#if CYGNUM_IO_FILEIO_MAX_INODE_CACHE_DEAD > 0
+ ic->freeablelistlen++;
+ insert_in_list( &ic->freeable, ino );
+ if ( ic->freeablelistlen > CYGNUM_IO_FILEIO_MAX_INODE_CACHE_DEAD ) {
+ cyg_inode *prev = ino->i_cache_prev;
+ prev->i_cache_prev->i_cache_next = ino;
+ ino->i_cache_prev = prev->i_cache_prev;
+ ic->freecallback(prev);
+ free(prev);
+ }
+#else
+ ic->freecallback(ino);
+ free(ino);
+#endif
+ }
+} // cyg_inode_put()
+
+// EOF inode.h
diff --git a/cesar/ecos/packages/io/fileio/current/src/io.cxx b/cesar/ecos/packages/io/fileio/current/src/io.cxx
new file mode 100644
index 0000000000..743211f1ec
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/io.cxx
@@ -0,0 +1,544 @@
+//==========================================================================
+//
+// io.cxx
+//
+// Fileio IO operations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-05-25
+// Purpose: Fileio IO operations
+// Description: These are the functions that operate on open files,
+// such as read(), write(), fstat() etc.
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_fileio.h>
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <stdarg.h> // for fcntl()
+
+#include "fio.h" // Private header
+
+
+//==========================================================================
+// File object locking
+
+#define LOCK_FILE( fp ) cyg_file_lock( fp, fp->f_syncmode )
+
+#define UNLOCK_FILE( fp ) cyg_file_unlock( fp, fp->f_syncmode )
+
+//==========================================================================
+// Common wrapper for read/write using an iovec descriptor
+// 'direction' should be O_RDONLY for readv, O_WRONLY for writev
+
+static ssize_t
+readwritev( int fd, const cyg_iovec *_iov, int iov_len, int direction )
+{
+ FILEIO_ENTRY();
+
+ CYG_CANCELLATION_POINT;
+
+ ssize_t cnt, len;
+ int ret, _idx;
+ cyg_file *fp;
+ cyg_iovec iov[CYGNUM_FILEIO_IOVEC_MAX];
+
+ if( iov_len > CYGNUM_FILEIO_IOVEC_MAX )
+ FILEIO_RETURN(EINVAL);
+
+ // Copy 'iovec' structure since it's supposed to be "const"
+ // and some lower level routines might want to change it.
+ // Also accumulate the length of the total I/O request
+ len = 0;
+ for (_idx = 0; _idx < iov_len; _idx++) {
+ len += _iov[_idx].iov_len;
+ iov[_idx].iov_base = _iov[_idx].iov_base;
+ iov[_idx].iov_len = _iov[_idx].iov_len;
+ }
+
+ if( len > SSIZE_MAX )
+ FILEIO_RETURN(EINVAL);
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( (fp->f_flag & direction) == 0 )
+ {
+ cyg_fp_free( fp );
+ FILEIO_RETURN(EBADF);
+ }
+
+ cyg_uio uio;
+ cyg_fileop_readwrite *op;
+
+ uio.uio_iov = iov;
+ uio.uio_iovcnt = iov_len;
+ uio.uio_resid = len;
+ uio.uio_segflg = UIO_USERSPACE;
+
+ cnt = len;
+
+ if( direction == O_RDONLY )
+ uio.uio_rw = UIO_READ, op = fp->f_ops->fo_read;
+ else
+ uio.uio_rw = UIO_WRITE, op = fp->f_ops->fo_write;
+
+ LOCK_FILE( fp );
+
+ ret = op( fp, &uio );
+
+ UNLOCK_FILE( fp );
+
+ cnt -= uio.uio_resid;
+
+ cyg_fp_free( fp );
+
+ CYG_CANCELLATION_POINT;
+
+ if( ret != 0 )
+ {
+ if ((ret == EWOULDBLOCK || ret == EAGAIN) && cnt)
+ FILEIO_RETURN_VALUE(cnt);
+ else
+ FILEIO_RETURN(ret);
+ }
+
+ FILEIO_RETURN_VALUE(cnt);
+}
+
+//==========================================================================
+// Read from file
+
+__externC ssize_t read( int fd, void *buf, size_t len )
+{
+ cyg_iovec _iov;
+
+ _iov.iov_base = buf;
+ _iov.iov_len = len;
+ return readwritev(fd, &_iov, 1, O_RDONLY);
+}
+
+//==========================================================================
+// Write to a file
+
+__externC ssize_t write( int fd, const void *buf, size_t len )
+{
+ cyg_iovec _iov;
+
+ _iov.iov_base = (void *)buf;
+ _iov.iov_len = len;
+ return readwritev(fd, &_iov, 1, O_WRONLY);
+}
+
+//==========================================================================
+// Read via an iovec
+__externC ssize_t readv( int fd, const cyg_iovec *_iov, int iov_len )
+{
+ return readwritev(fd, _iov, iov_len, O_RDONLY);
+}
+
+//==========================================================================
+// Write via an iovec
+__externC ssize_t writev( int fd, const cyg_iovec *_iov, int iov_len )
+{
+ return readwritev(fd, _iov, iov_len, O_WRONLY);
+}
+
+
+//==========================================================================
+// Close a file
+
+__externC int close( int fd )
+{
+ FILEIO_ENTRY();
+
+ CYG_CANCELLATION_POINT;
+
+ int ret;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ cyg_fp_free( fp );
+
+ // The file's fo_close entry may be called as a side
+ // effect of this operation...
+ ret = cyg_fd_free( fd );
+
+ CYG_CANCELLATION_POINT;
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// Seek a file
+
+__externC off_t lseek( int fd, off_t pos, int whence )
+{
+ FILEIO_ENTRY();
+
+ int ret;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ LOCK_FILE( fp );
+
+ ret = fp->f_ops->fo_lseek( fp, &pos, whence );
+
+ UNLOCK_FILE( fp );
+
+ cyg_fp_free( fp );
+
+ if( ret != 0 )
+ FILEIO_RETURN(ret);
+
+ FILEIO_RETURN_VALUE(pos);
+}
+
+//==========================================================================
+// ioctl
+
+__externC int ioctl( int fd, CYG_ADDRWORD com, ... )
+{
+ FILEIO_ENTRY();
+
+ int ret;
+ cyg_file *fp;
+ va_list ap;
+ CYG_ADDRWORD data;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ va_start(ap, com);
+ data = va_arg(ap, CYG_ADDRWORD);
+ va_end(ap);
+
+ LOCK_FILE( fp );
+
+ ret = fp->f_ops->fo_ioctl( fp, com, data );
+
+ UNLOCK_FILE( fp );
+
+ cyg_fp_free( fp );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// fsync
+
+__externC int fsync( int fd )
+{
+ FILEIO_ENTRY();
+
+ CYG_CANCELLATION_POINT;
+
+ int ret;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ LOCK_FILE( fp );
+
+ ret = fp->f_ops->fo_fsync( fp, CYG_FSYNC );
+
+ UNLOCK_FILE( fp );
+
+ cyg_fp_free( fp );
+
+ CYG_CANCELLATION_POINT;
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// fdatasync()
+
+__externC int fdatasync( int fd )
+{
+ FILEIO_ENTRY();
+
+ CYG_CANCELLATION_POINT;
+
+ int ret;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ LOCK_FILE( fp );
+
+ ret = fp->f_ops->fo_fsync( fp, CYG_FDATASYNC );
+
+ UNLOCK_FILE( fp );
+
+ cyg_fp_free( fp );
+
+ CYG_CANCELLATION_POINT;
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// fstat
+
+__externC int fstat( int fd, struct stat *buf )
+{
+ FILEIO_ENTRY();
+
+ int ret;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ LOCK_FILE( fp );
+
+ ret = fp->f_ops->fo_fstat( fp, buf );
+
+ UNLOCK_FILE( fp );
+
+ cyg_fp_free( fp );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// fpathconf
+
+__externC long fpathconf( int fd, int name )
+{
+ FILEIO_ENTRY();
+
+ int ret;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ struct cyg_pathconf_info info;
+
+ info.name = name;
+ info.value = 0;
+
+ LOCK_FILE( fp );
+
+ ret = fp->f_ops->fo_getinfo( fp, FILE_INFO_CONF, (char *)&info, sizeof(info) );
+
+ UNLOCK_FILE( fp );
+
+ cyg_fp_free( fp );
+
+ if( ret != 0 )
+ FILEIO_RETURN(ret);
+
+ FILEIO_RETURN_VALUE(info.value);
+}
+
+//==========================================================================
+// fcntl
+
+__externC int fcntl( int fd, int cmd, ... )
+{
+ FILEIO_ENTRY();
+
+ CYG_CANCELLATION_POINT;
+
+ int ret = 0;
+ cyg_file *fp;
+ va_list a;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ va_start( a, cmd );
+
+ switch( cmd )
+ {
+ case F_DUPFD:
+ {
+ int fda = va_arg(a, int);
+
+ if( fda < 0 || fda >= OPEN_MAX )
+ {
+ errno = EBADF;
+ break;
+ }
+
+ int fd2 = cyg_fd_alloc( fda );
+
+ if( fd2 == -1 )
+ {
+ ret = EMFILE;
+ break;
+ }
+
+ cyg_fd_assign( fd2, fp );
+
+ break;
+ }
+
+ default:
+ ret = ENOTSUP;
+ break;
+ }
+
+ va_end(a);
+
+ cyg_fp_free( fp );
+
+ CYG_CANCELLATION_POINT;
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// isatty()
+
+__externC int isatty( int fd )
+{
+ FILEIO_ENTRY();
+
+ int ret = 0;
+ struct stat buf;
+ int err;
+
+ err = fstat( fd, &buf );
+
+ // Any error and we return zero. If the client wants to
+ // they can always pick up the error code from errno.
+ if( err < 0 )
+ FILEIO_RETURN_VALUE(0);
+
+ // For now we assume that all char devices are ttys.
+ // In future we may need to have a special getinfo()
+ // call to decide this more specifically.
+
+ if( S_ISCHR( buf.st_mode ) )
+ ret = 1;
+
+ FILEIO_RETURN_VALUE(ret);
+}
+
+//==========================================================================
+// File get info.
+
+__externC int cyg_fs_fgetinfo( int fd, int key, void *buf, int len )
+{
+ FILEIO_ENTRY();
+
+ int ret;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ LOCK_FILE( fp );
+
+ ret = fp->f_ops->fo_getinfo( fp, key, buf, len );
+
+ UNLOCK_FILE( fp );
+
+ cyg_fp_free( fp );
+
+ FILEIO_RETURN(ret);
+}
+
+//==========================================================================
+// File set info.
+
+__externC int cyg_fs_fsetinfo( int fd, int key, void *buf, int len )
+{
+ FILEIO_ENTRY();
+
+ int ret;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( fd );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ LOCK_FILE( fp );
+
+ ret = fp->f_ops->fo_setinfo( fp, key, buf, len );
+
+ UNLOCK_FILE( fp );
+
+ cyg_fp_free( fp );
+
+ FILEIO_RETURN(ret);
+}
+
+// -------------------------------------------------------------------------
+// EOF io.cxx
diff --git a/cesar/ecos/packages/io/fileio/current/src/misc.cxx b/cesar/ecos/packages/io/fileio/current/src/misc.cxx
new file mode 100644
index 0000000000..f878cf6f99
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/misc.cxx
@@ -0,0 +1,495 @@
+//==========================================================================
+//
+// misc.cxx
+//
+// Fileio miscellaneous functions
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Gary Thomas
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-05-25
+// Purpose: Fileio miscellaneous functions
+// Description: This file contains various miscellaneous functions
+// for use with the fileio system. These include startup,
+// table management, and other service routines.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/io_fileio.h>
+#ifdef CYGPKG_LIBC_TIME
+#include <pkgconf/libc_time.h>
+#endif
+
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <string.h> // strcmp()
+#include <time.h> // time()
+
+#ifdef CYGPKG_IO_WALLCLOCK
+# include <cyg/io/wallclock.hxx> // Wallclock class
+#endif
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#include <cyg/kernel/ktypes.h> // base kernel types
+#include <cyg/kernel/clock.inl> // Clock inlines
+#endif
+
+#include "fio.h" // Private header
+
+//==========================================================================
+// forward definitions
+
+static void cyg_mtab_init();
+
+__externC int chdir( const char *path );
+
+//==========================================================================
+// Filesystem tables
+
+// -------------------------------------------------------------------------
+// Filesystem table.
+
+// This array contains entries for all filesystem that are installed in
+// the system.
+__externC cyg_fstab_entry cyg_fstab[];
+CYG_HAL_TABLE_BEGIN( cyg_fstab, fstab );
+
+// end of filesystem table, set in linker script.
+__externC cyg_fstab_entry cyg_fstab_end;
+CYG_HAL_TABLE_END( cyg_fstab_end, fstab );
+
+#ifdef CYGPKG_KERNEL
+// Array of mutexes for locking the fstab entries
+static Cyg_Mutex fstab_lock[CYGNUM_FILEIO_FSTAB_MAX] CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
+#endif
+
+// -------------------------------------------------------------------------
+// Mount table.
+
+// This array contains entries for all valid running filesystems.
+__externC cyg_mtab_entry cyg_mtab[];
+CYG_HAL_TABLE_BEGIN( cyg_mtab, mtab );
+
+// Extra entries at end of mtab for dynamic mount points.
+cyg_mtab_entry cyg_mtab_extra[CYGNUM_FILEIO_MTAB_EXTRA] CYG_HAL_TABLE_EXTRA(mtab) = { { NULL } };
+
+// End of mount table, set in the linker script.
+__externC cyg_mtab_entry cyg_mtab_end;
+CYG_HAL_TABLE_END( cyg_mtab_end, mtab );
+
+#ifdef CYGPKG_KERNEL
+// Array of mutexes for locking the mtab entries
+static Cyg_Mutex mtab_lock[CYGNUM_FILEIO_MTAB_MAX] CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
+#endif
+
+//==========================================================================
+// Current directory
+
+cyg_mtab_entry *cyg_cdir_mtab_entry = NULL;
+cyg_dir cyg_cdir_dir = CYG_DIR_NULL;
+
+//==========================================================================
+// Initialization object
+
+class Cyg_Fileio_Init_Class
+{
+public:
+ Cyg_Fileio_Init_Class();
+};
+
+static Cyg_Fileio_Init_Class fileio_initializer CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
+
+Cyg_Fileio_Init_Class::Cyg_Fileio_Init_Class()
+{
+ cyg_fd_init();
+
+ cyg_mtab_init();
+
+ chdir("/");
+}
+
+//==========================================================================
+// Mount table initializer
+
+static void cyg_mtab_init()
+{
+ cyg_mtab_entry *m;
+
+ for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
+ {
+ const char *fsname = m->fsname;
+ cyg_fstab_entry *f;
+
+ // Ignore empty entries
+ if( m->name == NULL )
+ continue;
+
+ // stop if there are more than the configured maximum
+ if( m-&cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX )
+ break;
+
+ for( f = &cyg_fstab[0]; f != &cyg_fstab_end; f++ )
+ {
+ // stop if there are more than the configured maximum
+ if( f-&cyg_fstab[0] >= CYGNUM_FILEIO_FSTAB_MAX )
+ break;
+
+ if( strcmp( fsname, f->name) == 0 )
+ {
+ // We have a match.
+
+ if( f->mount( f, m ) == 0 )
+ {
+ m->valid = true;
+ m->fs = f;
+ // m->root installed by fs.
+ }
+ else
+ {
+ m->valid = false;
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+//==========================================================================
+// Mount table matching
+
+// -------------------------------------------------------------------------
+// matchlen() compares two strings and returns the number of bytes by which
+// they match.
+
+static int matchlen( const char *s1, const char *s2 )
+{
+ int len = 0;
+ while( s1[len] == s2[len] && s1[len] && s2[len] ) len++;
+
+ // Return length only if s2 is an initial substring of s1,
+ // and it terminates in s1 at end-of-string or a '/'.
+
+ // Special case for s2 == "/"
+ if( len == 1 && s2[0] == '/' && s2[1] == 0 )
+ return len;
+
+ if( (s2[len] == 0) && (s1[len] == 0 || s1[len] == '/'))
+ return len;
+ else return 0;
+}
+
+// -------------------------------------------------------------------------
+// Search the mtab for the entry that matches the longest substring of
+// **name.
+
+__externC int cyg_mtab_lookup( cyg_dir *dir, const char **name, cyg_mtab_entry **mte)
+{
+ cyg_mtab_entry *m, *best = NULL;
+ int best_len = 0;
+
+ // Unrooted file names go straight to current dir
+ if( **name != '/' ) {
+ if (*mte == (cyg_mtab_entry *)NULL) {
+ // No known current directory
+ return -1;
+ }
+ // Current directory is well known
+ return 0;
+ }
+
+ // Otherwise search the mount table.
+ for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
+ {
+ if( m->name != NULL && m->valid )
+ {
+ int len = matchlen(*name,m->name);
+ if( len > best_len )
+ best = m, best_len = len;
+ }
+ }
+
+ // No match found, bad path name...
+ if( best_len == 0 ) return -1;
+
+ *name += best_len;
+ if( **name == '/' )
+ (*name)++;
+ *mte = best;
+ *dir = best->root;
+
+ return 0;
+}
+
+//==========================================================================
+// mount filesystem
+
+__externC int mount( const char *devname,
+ const char *dir,
+ const char *fsname)
+{
+
+ FILEIO_ENTRY();
+
+ cyg_mtab_entry *m;
+ cyg_fstab_entry *f;
+ int result = ENOERR;
+
+ // Search the mount table for an empty entry
+ for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
+ {
+ // stop if there are more than the configured maximum
+ if( m-&cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX )
+ {
+ m = &cyg_mtab_end;
+ break;
+ }
+
+ if( m->name == NULL ) break;
+ }
+
+ if( m == &cyg_mtab_end )
+ FILEIO_RETURN(ENOMEM);
+
+ // Now search the fstab for the filesystem implementation
+ for( f = &cyg_fstab[0]; f != &cyg_fstab_end; f++ )
+ {
+ // stop if there are more than the configured maximum
+ if( f-&cyg_fstab[0] >= CYGNUM_FILEIO_FSTAB_MAX )
+ break;
+
+ if( strcmp( fsname, f->name) == 0 )
+ break;
+ }
+
+ if( f == &cyg_fstab_end )
+ FILEIO_RETURN(ENODEV);
+
+ // We have a match.
+
+ m->name = dir;
+ m->fsname = fsname;
+ m->devname = devname;
+
+ if( (result = f->mount( f, m )) == 0 )
+ {
+ m->valid = true;
+ m->fs = f;
+ // m->root installed by fs.
+ }
+ else
+ {
+ m->valid = false;
+ m->name = NULL;
+ }
+
+ // Make sure that there is something to search (for open)
+
+ if (cyg_cdir_mtab_entry == (cyg_mtab_entry *)NULL) {
+ cyg_cdir_mtab_entry = m;
+ }
+
+ FILEIO_RETURN(result);
+}
+
+//==========================================================================
+// unmount filesystem
+
+__externC int umount( const char *name)
+{
+ int err = ENOERR;
+
+ FILEIO_ENTRY();
+
+ cyg_mtab_entry *m;
+
+ // Search the mount table for a matching entry
+ for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
+ {
+ // stop if there are more than the configured maximum
+ if( m-&cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX )
+ {
+ m = &cyg_mtab_end;
+ break;
+ }
+
+ // Ignore empty or invalid entries
+ if( m->name == NULL || !m->valid ) continue;
+
+ // match names.
+ if( strcmp(name,m->name) == 0 ) break;
+
+ // Match device name too?
+ }
+
+ if( m == &cyg_mtab_end )
+ FILEIO_RETURN(EINVAL);
+
+ // We have a match, call the umount function
+
+ err = m->fs->umount( m );
+
+ if( err == ENOERR )
+ {
+ m->valid = false;
+ m->name = NULL;
+ }
+
+ FILEIO_RETURN(err);
+}
+
+//==========================================================================
+// Implement filesystem locking protocol.
+
+void cyg_fs_lock( cyg_mtab_entry *mte, cyg_uint32 syncmode )
+{
+ CYG_ASSERT(mte != NULL, "Bad mount table entry");
+
+ if( syncmode & CYG_SYNCMODE_FILE_FILESYSTEM ) {
+ CYG_ASSERT(mte->fs-&cyg_fstab[0] < CYGNUM_FILEIO_FSTAB_MAX, "Bad file system");
+ FILEIO_MUTEX_LOCK( fstab_lock[mte->fs-&cyg_fstab[0]] );
+ }
+
+ if( syncmode & CYG_SYNCMODE_FILE_MOUNTPOINT ) {
+ CYG_ASSERT(mte-&cyg_mtab[0] < CYGNUM_FILEIO_MTAB_MAX, "Bad mount point");
+ FILEIO_MUTEX_LOCK( mtab_lock[mte-&cyg_mtab[0]] );
+ }
+}
+
+void cyg_fs_unlock( cyg_mtab_entry *mte, cyg_uint32 syncmode )
+{
+ CYG_ASSERT(mte != NULL, "Bad mount table entry");
+
+ if( syncmode & CYG_SYNCMODE_FILE_FILESYSTEM ) {
+ CYG_ASSERT(mte->fs-&cyg_fstab[0] < CYGNUM_FILEIO_FSTAB_MAX, "Bad file system");
+ FILEIO_MUTEX_UNLOCK( fstab_lock[mte->fs-&cyg_fstab[0]] );
+ }
+
+ if( syncmode & CYG_SYNCMODE_FILE_MOUNTPOINT ) {
+ CYG_ASSERT(mte-&cyg_mtab[0] < CYGNUM_FILEIO_MTAB_MAX, "Bad mount point");
+ FILEIO_MUTEX_UNLOCK( mtab_lock[mte-&cyg_mtab[0]] );
+ }
+}
+
+//==========================================================================
+// Search mount table for a filesystems root.
+
+__externC cyg_mtab_entry * cyg_fs_root_lookup( cyg_dir *root )
+{
+ cyg_mtab_entry *m;
+
+ for( m = &cyg_mtab[0]; m != &cyg_mtab_end; m++ )
+ {
+ if( (cyg_dir *)m->root == root )
+ {
+ return m;
+ }
+ }
+ return NULL;
+}
+
+//==========================================================================
+// Timestamp support
+// This provides access to the current time/date, expressed as a
+// time_t. It uses a number of mechanisms to do this, selecting
+// whichever is available in the current configuration.
+
+__externC time_t cyg_timestamp()
+{
+#if defined(CYGPKG_IO_WALLCLOCK)
+
+ // First, try to get the time from the wallclock device.
+
+ return (time_t) Cyg_WallClock::wallclock->get_current_time();
+
+#elif defined(CYGINT_ISO_POSIX_TIMERS)
+
+ // If POSIX is present, use the current value of the realtime
+ // clock.
+
+ struct timespec tp;
+
+ clock_gettime( CLOCK_REALTIME, &tp );
+
+ return (time_t) tp.tv_sec;
+
+#elif defined(CYGPKG_KERNEL)
+
+ // If all else fails, get the current realtime clock value and
+ // convert it to seconds ourself.
+
+ static struct Cyg_Clock::converter sec_converter;
+ static cyg_bool initialized = false;
+ cyg_tick_count ticks;
+
+ if( !initialized )
+ {
+ Cyg_Clock::real_time_clock->get_clock_to_other_converter( 1000000000, &sec_converter );
+ initialized = true;
+ }
+
+ ticks = Cyg_Clock::real_time_clock->current_value();
+
+ return (time_t) Cyg_Clock::convert( ticks, &sec_converter );
+#else
+ /* No clock support at all. */
+ return (time_t) 0;
+#endif
+
+}
+
+//==========================================================================
+// Default functions
+
+__externC int cyg_fileio_enosys() { return ENOSYS; }
+__externC int cyg_fileio_erofs() { return EROFS; }
+__externC int cyg_fileio_enoerr() { return ENOERR; }
+__externC int cyg_fileio_enotdir() { return ENOTDIR; }
+
+__externC cyg_bool cyg_fileio_seltrue (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info)
+{ return 1; }
+
+// -------------------------------------------------------------------------
+// EOF misc.cxx
diff --git a/cesar/ecos/packages/io/fileio/current/src/select.cxx b/cesar/ecos/packages/io/fileio/current/src/select.cxx
new file mode 100644
index 0000000000..03782e149d
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/select.cxx
@@ -0,0 +1,402 @@
+//==========================================================================
+//
+// select.cxx
+//
+// Fileio select() support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Nick Garnett
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-05-25
+// Purpose: Fileio select() support
+// Description: Support for select().
+//
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/io_fileio.h>
+
+#include <cyg/kernel/ktypes.h> // base kernel types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <stdarg.h> // for fcntl()
+
+#include "fio.h" // Private header
+
+#include <sys/select.h> // select header
+
+#include <cyg/kernel/sched.hxx> // scheduler definitions
+#include <cyg/kernel/thread.hxx> // thread definitions
+#include <cyg/kernel/flag.hxx> // flag definitions
+#include <cyg/kernel/clock.hxx> // clock definitions
+
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/clock.inl>
+
+//==========================================================================
+// File object locking
+
+#define LOCK_FILE( fp ) cyg_file_lock( fp )
+
+#define UNLOCK_FILE( fp ) cyg_file_unlock( fp )
+
+// Get a flag based on the thread's unique ID. Note: In a system with a large
+// number of threads, the same flag may be used by more than one thread.
+#define SELECT_WAIT_FLAG_GET() (1 << (Cyg_Thread::self()->get_unique_id() \
+ & (sizeof (Cyg_FlagValue) * NBBY - 1)))
+
+//==========================================================================
+// Local variables
+
+static volatile cyg_uint32 selwake_count = 0;
+
+// A flag is used to block a thread until data from the device is available. This
+// prevents all threads from waking up at the same time and polling for changes.
+// Each thread is allocated a flag bit via the SELECT_WAIT_FLAG_GET() macro when
+// the thread registers for selection via cyg_selrecord (). The flag is stored in
+// the driver's select info block. Only those threads specified via the flags in
+// the select info are woken up by cyg_selwakeup ().
+// If there are more than 32 threads in the system, then there is a chance that
+// cyg_selwakeup () may wake up more than one thread. Each thread then polls for
+// changes.
+static Cyg_Flag select_flag CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
+
+//==========================================================================
+// Timeval to ticks conversion support
+
+// Converters from sec and us to ticks
+static struct Cyg_Clock::converter us_converter, sec_converter;
+
+static cyg_bool converters_initialized = false;
+
+externC cyg_tick_count cyg_timeval_to_ticks( const struct timeval *tv )
+{
+ if( !converters_initialized )
+ {
+ // Create the converters we need.
+ Cyg_Clock::real_time_clock->get_other_to_clock_converter( 1000, &us_converter );
+ Cyg_Clock::real_time_clock->get_other_to_clock_converter( 1000000000, &sec_converter );
+
+ converters_initialized = true;
+ }
+
+ // Short circuit zero timeval
+ if( tv->tv_sec == 0 && tv->tv_usec == 0 )
+ {
+ return 0;
+ }
+
+ // Convert the seconds field to ticks.
+ cyg_tick_count ticks = Cyg_Clock::convert( tv->tv_sec, &sec_converter );
+
+ // Convert the nanoseconds. This will round down to nearest whole tick.
+ ticks += Cyg_Clock::convert( (cyg_tick_count)tv->tv_usec, &us_converter );
+
+ return ticks;
+}
+
+//==========================================================================
+// Select API function
+
+static int
+cyg_pselect(int nfd, fd_set *in, fd_set *out, fd_set *ex,
+ struct timeval *tv, const sigset_t *mask)
+{
+ FILEIO_ENTRY();
+
+ int error = ENOERR;
+ int fd, mode, num;
+ cyg_file *fp;
+ fd_set in_res, out_res, ex_res; // Result sets
+ fd_set *selection[3], *result[3];
+ cyg_tick_count ticks;
+ int mode_type[] = {CYG_FREAD, CYG_FWRITE, 0};
+ cyg_uint32 wake_count;
+ sigset_t oldmask;
+
+ Cyg_FlagValue myFlag = SELECT_WAIT_FLAG_GET ();
+ int maxFdIndex = __howmany(nfd, __NFDBITS); // size of fd sets
+
+ // Make sure the nfd < FD_SETSIZE, a value greater than FD_SETSIZE
+ // would break the results sets
+ if(nfd > FD_SETSIZE)
+ {
+ FILEIO_RETURN(EINVAL);
+ }
+
+ FD_ZERO(&in_res);
+ FD_ZERO(&out_res);
+ FD_ZERO(&ex_res);
+
+ // Set up sets
+ selection[0] = in; result[0] = &in_res;
+ selection[1] = out; result[1] = &out_res;
+ selection[2] = ex; result[2] = &ex_res;
+
+ // Compute end time
+ if (tv)
+ ticks = cyg_timeval_to_ticks( tv );
+ else ticks = 0;
+
+ // Scan sets for possible I/O until something found, timeout or error.
+ while (!error)
+ {
+ wake_count = selwake_count;
+
+ num = 0; // Total file descriptors "ready"
+ for (mode = 0; !error && mode < 3; mode++)
+ {
+ if (selection[mode])
+ {
+ fd_mask *fds_bits = selection[mode]->fds_bits;
+ int index, fdbase;
+ for(index = 0, fdbase = 0; !error && index < maxFdIndex; index++, fdbase += __NFDBITS)
+ {
+ fd_mask mask = fds_bits[index];
+ for(fd = fdbase; mask != 0; fd++, mask >>= 1)
+ {
+ if(mask & 1)
+ {
+ fp = cyg_fp_get( fd );
+ if( fp == NULL )
+ {
+ error = EBADF;
+ break;
+ }
+
+ if ((*fp->f_ops->fo_select)(fp, mode_type[mode], 0))
+ {
+ FD_SET(fd, result[mode]);
+ num++;
+ }
+ cyg_fp_free( fp );
+ }
+ }
+ }
+ }
+ }
+
+ if (error)
+ break;
+
+ if (num)
+ {
+ // Found something, update user's sets
+ if (in) FD_COPY( &in_res, in );
+ if (out) FD_COPY( &out_res, out );
+ if (ex) FD_COPY( &ex_res, ex );
+ CYG_FILEIO_DELIVER_SIGNALS( mask );
+ FILEIO_RETURN_VALUE(num);
+ }
+
+ Cyg_Scheduler::lock();
+
+ // Switch to the supplied signal mask. This will permit delivery
+ // of any signals that might terminate this select operation.
+
+ CYG_FILEIO_SIGMASK_SET( mask, &oldmask );
+
+ do
+ {
+
+ // We need to see if any signals have been posted while we
+ // were testing all those files. The handlers will not
+ // have run because we have ASRs inhibited but the signal
+ // will have been set pending.
+
+ if( CYG_FILEIO_SIGPENDING() )
+ {
+ // There are pending signals so we need to terminate
+ // the select operation and return EINTR. Handlers for
+ // the pending signals will be called just before we
+ // return.
+
+ error = EINTR;
+ break;
+ }
+
+ if( wake_count == selwake_count )
+ {
+ // Nothing found, see if we want to wait
+ if (tv)
+ {
+ // Special case of "poll"
+ if (ticks == 0)
+ {
+ error = EAGAIN;
+ break;
+ }
+
+ ticks += Cyg_Clock::real_time_clock->current_value();
+
+ if( !select_flag.wait (myFlag, Cyg_Flag::OR, ticks) )
+ {
+ // A non-standard wakeup, if the current time is equal to
+ // or past the timeout, return zero. Otherwise return
+ // EINTR, since we have been released.
+
+ if( Cyg_Clock::real_time_clock->current_value() >= ticks )
+ {
+ error = EAGAIN;
+ break;
+ }
+ else error = EINTR;
+ }
+
+ ticks -= Cyg_Clock::real_time_clock->current_value();
+ }
+ else
+ {
+ // Wait forever (until something happens)
+ if( !select_flag.wait (myFlag, Cyg_Flag::OR) )
+ error = EINTR;
+ }
+ }
+
+ } while(0);
+
+ CYG_FILEIO_SIGMASK_SET( &oldmask, NULL );
+
+ Cyg_Scheduler::unlock();
+
+ } // while(!error)
+
+ // If the error code is EAGAIN, this means that a timeout has
+ // happened. We return zero in that case, rather than a proper
+ // error code.
+ // If the error code is EINTR, then a signal may be pending
+ // delivery. Call back into the POSIX package to handle it.
+
+ if( error == EAGAIN )
+ FILEIO_RETURN_VALUE(0);
+ else if( error == EINTR )
+ CYG_FILEIO_DELIVER_SIGNALS( mask );
+
+ FILEIO_RETURN(error);
+}
+
+// -------------------------------------------------------------------------
+// Select API function
+
+__externC int
+select(int nfd, fd_set *in, fd_set *out, fd_set *ex, struct timeval *tv)
+{
+ return cyg_pselect(nfd, in, out, ex, tv, NULL);
+}
+
+// -------------------------------------------------------------------------
+// Pselect API function
+//
+// This is derived from the POSIX-200X specification.
+
+__externC int
+pselect(int nfd, fd_set *in, fd_set *out, fd_set *ex,
+ const struct timespec *ts, const sigset_t *sigmask)
+{
+ struct timeval tv;
+
+#ifndef CYGPKG_POSIX_SIGNALS
+ CYG_ASSERT( sigmask == NULL,
+ "pselect called with non-null sigmask without POSIX signal support"
+ );
+#endif
+
+ if (ts != NULL)
+ {
+ tv.tv_sec = ts->tv_sec;
+ tv.tv_usec = ts->tv_nsec/1000;
+ }
+
+ return cyg_pselect(nfd, in, out, ex, ts ? &tv : NULL, sigmask);
+}
+
+//==========================================================================
+// Select support functions.
+
+// -------------------------------------------------------------------------
+// cyg_selinit() is used to initialize a selinfo structure
+
+void cyg_selinit( struct CYG_SELINFO_TAG *sip )
+{
+ sip->si_info = 0;
+ sip->si_waitFlag = 0;
+}
+
+// -------------------------------------------------------------------------
+// cyg_selrecord() is called when a client device needs to register
+// the current thread for selection. Save the flag that identifies the thread.
+void cyg_selrecord( CYG_ADDRWORD info, struct CYG_SELINFO_TAG *sip )
+{
+ sip->si_info = info;
+ Cyg_Scheduler::lock();
+ sip->si_waitFlag |= SELECT_WAIT_FLAG_GET ();
+ Cyg_Scheduler::unlock();
+}
+
+// -------------------------------------------------------------------------
+// cyg_selwakeup() is called when the client device matches the select
+// criterion, and needs to wake up a thread.
+void cyg_selwakeup( struct CYG_SELINFO_TAG *sip )
+{
+ // We don't actually use the si_info field of selinfo at present.
+ Cyg_Scheduler::lock();
+
+ if( sip->si_waitFlag != 0 )
+ {
+ // If the flag is still present, this selection has not fired before.
+ // Only wake up the threads waiting on the flags specified in si_waitFlag.
+ // There is no need to wake threads that are not waiting for this data.
+ select_flag.setbits (sip->si_waitFlag);
+ sip->si_waitFlag = 0; // clear all flags
+ select_flag.maskbits (sip->si_waitFlag);
+ selwake_count++;
+ }
+ Cyg_Scheduler::unlock();
+}
+
+// -------------------------------------------------------------------------
+// EOF select.cxx
diff --git a/cesar/ecos/packages/io/fileio/current/src/socket.cxx b/cesar/ecos/packages/io/fileio/current/src/socket.cxx
new file mode 100644
index 0000000000..85f17f31c3
--- /dev/null
+++ b/cesar/ecos/packages/io/fileio/current/src/socket.cxx
@@ -0,0 +1,735 @@
+//==========================================================================
+//
+// socket.cxx
+//
+// Fileio socket operations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2000-05-25
+// Purpose: Fileio socket operations
+// Description: These are the functions that operate on sockets,
+// such as socket(), bind(), accept() etc.
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/io_fileio.h>
+
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/kernel/ktypes.h> // base kernel types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <stdarg.h> // for fcntl()
+
+#include <cyg/io/file.h> // struct iovec
+
+#include "fio.h" // Private header
+
+#include <cyg/kernel/mutex.hxx> // mutex definitions
+
+#ifdef CYGPKG_NET
+
+#include <sys/socket.h> // struct msghdr
+
+#endif
+
+//==========================================================================
+// Forward definitions
+
+static void cyg_ns_lock( cyg_nstab_entry *ns );
+static void cyg_ns_unlock( cyg_nstab_entry *ns );
+static void cyg_sock_lock( cyg_file *fp );
+static void cyg_sock_unlock( cyg_file *fp );
+
+//==========================================================================
+// Local entry/return macros
+
+#define SOCKET_ENTRY() FILEIO_ENTRY()
+
+#define SOCKET_RETURN(err) FILEIO_RETURN(err)
+
+#define SOCKET_RETURN_VALUE(val) FILEIO_RETURN_VALUE(val)
+
+//==========================================================================
+// Locking protocols
+
+#define LOCK_NS( _n ) cyg_ns_lock( _n )
+
+#define UNLOCK_NS( _n ) cyg_ns_unlock( _n )
+
+#define LOCK_SOCKET( _fp ) cyg_sock_lock( _fp )
+
+#define UNLOCK_SOCKET( _fp ) cyg_sock_unlock( _fp )
+
+//==========================================================================
+// Tables and local variables
+
+// Array of network stacks installed
+__externC cyg_nstab_entry cyg_nstab[];
+CYG_HAL_TABLE_BEGIN( cyg_nstab, nstab );
+
+// End of array marker
+__externC cyg_nstab_entry cyg_nstab_end;
+CYG_HAL_TABLE_END( cyg_nstab_end, nstab );
+
+static Cyg_Mutex nstab_lock[CYGNUM_FILEIO_NSTAB_MAX] CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);
+
+//==========================================================================
+// Initialization
+
+__externC void cyg_nstab_init()
+{
+ cyg_nstab_entry *n;
+
+ for( n = &cyg_nstab[0]; n != &cyg_nstab_end; n++ )
+ {
+ // stop if there are more than the configured maximum
+ if( n-&cyg_nstab[0] >= CYGNUM_FILEIO_NSTAB_MAX )
+ break;
+
+ if( n->init( n ) == 0 )
+ {
+ n->valid = true;
+ }
+ }
+}
+
+//==========================================================================
+// Socket API calls
+
+// -------------------------------------------------------------------------
+
+__externC int socket (int domain, int type, int protocol)
+{
+ SOCKET_ENTRY();
+
+ int err = EAFNOSUPPORT;
+ int fd;
+ cyg_file *file;
+
+ fd = cyg_fd_alloc(0);
+
+ if( fd < 0 )
+ SOCKET_RETURN(EMFILE);
+
+ file = cyg_file_alloc();
+
+ if( file == NULL )
+ {
+ cyg_fd_free(fd);
+ SOCKET_RETURN(ENFILE);
+ }
+
+ cyg_nstab_entry *n;
+
+ for( n = &cyg_nstab[0]; n != &cyg_nstab_end; n++ )
+ {
+ LOCK_NS( n );
+
+ err = n->socket( n, domain, type, protocol, file );
+
+ UNLOCK_NS( n );
+
+ if( err == 0 ) break;
+ }
+
+ if( err != 0 )
+ {
+ cyg_fd_free(fd);
+ cyg_file_free(file);
+ SOCKET_RETURN( err );
+ }
+
+ file->f_syncmode = n->syncmode;
+ file->f_mte = (cyg_mtab_entry *)n;
+
+ cyg_fd_assign( fd, file );
+
+ SOCKET_RETURN_VALUE(fd);
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC int accept (int s, struct sockaddr *sa, socklen_t *addrlen)
+{
+ SOCKET_ENTRY();
+
+ int err = 0;
+ int fd;
+ cyg_file *fp;
+ cyg_file *new_fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ fd = cyg_fd_alloc(0);
+
+ if( fd < 0 )
+ {
+ cyg_fp_free( fp );
+ SOCKET_RETURN(EMFILE);
+ }
+
+ new_fp = cyg_file_alloc();
+
+ if( new_fp == NULL )
+ {
+ cyg_fp_free( fp );
+ cyg_fd_free(fd);
+ SOCKET_RETURN(ENFILE);
+ }
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ err = ops->accept( fp, new_fp, sa, addrlen );
+
+ UNLOCK_SOCKET( fp );
+
+ }
+ else err = EBADF;
+
+ if( err != 0 )
+ {
+ cyg_fp_free( fp );
+ cyg_fd_free(fd);
+ cyg_file_free(new_fp);
+ SOCKET_RETURN( err );
+ }
+
+ new_fp->f_syncmode = fp->f_syncmode;
+ new_fp->f_mte = fp->f_mte;
+
+ cyg_fd_assign( fd, new_fp );
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN_VALUE(fd);
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC int bind (int s, const struct sockaddr *sa, unsigned int len)
+{
+ SOCKET_ENTRY();
+
+ int ret = 0;
+ cyg_file *fp;
+ struct sockaddr sa2 = *sa;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ ret = ops->bind( fp, &sa2, len );
+
+ UNLOCK_SOCKET( fp );
+
+ }
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN(ret);
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC int connect (int s, const struct sockaddr *sa, socklen_t len)
+{
+ SOCKET_ENTRY();
+
+ int ret = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ ret = ops->connect( fp, sa, len );
+
+ UNLOCK_SOCKET( fp );
+
+ }
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN(ret);
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC int getpeername (int s, struct sockaddr *sa, socklen_t *len)
+{
+ SOCKET_ENTRY();
+
+ int ret = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ ret = ops->getname( fp, sa, len, 1 );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN(ret);
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC int getsockname (int s, struct sockaddr *sa, socklen_t *len)
+{
+ SOCKET_ENTRY();
+
+ int ret = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ ret = ops->getname( fp, sa, len, 0 );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN(ret);
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen)
+{
+ SOCKET_ENTRY();
+
+ int ret = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ ret = ops->getsockopt( fp, level, optname, optval, optlen );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN(ret);
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC int listen (int s, int len)
+{
+ SOCKET_ENTRY();
+
+ int ret = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ ret = ops->listen( fp, len );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN(ret);
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC ssize_t recvmsg (int s, struct msghdr *msg, int flags)
+{
+ SOCKET_ENTRY();
+
+ ssize_t ret = 0;
+ int error = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ msg->msg_flags = flags;
+
+ error = ops->recvmsg( fp, msg, NULL, &ret );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ if( error != ENOERR )
+ SOCKET_RETURN(error);
+
+ SOCKET_RETURN_VALUE( ret );
+}
+
+// -------------------------------------------------------------------------
+
+__externC ssize_t recvfrom (int s, void *buf, size_t len, int flags,
+ struct sockaddr *from, socklen_t *fromlen)
+{
+ SOCKET_ENTRY();
+
+ struct msghdr msg;
+ struct iovec iov;
+ ssize_t ret = 0;
+ int error = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ // Set up a message header...
+ msg.msg_name = (caddr_t)from;
+ msg.msg_namelen = fromlen ? *fromlen : 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ iov.iov_base = buf;
+ iov.iov_len = len;
+ msg.msg_control = 0;
+ msg.msg_flags = flags;
+
+ LOCK_SOCKET( fp );
+
+ error = ops->recvmsg( fp, &msg, fromlen, &ret );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ if( error != ENOERR )
+ SOCKET_RETURN(error);
+
+ SOCKET_RETURN_VALUE( ret );
+
+}
+
+// -------------------------------------------------------------------------
+
+__externC ssize_t recv (int s, void *buf, size_t len, int flags)
+{
+ return recvfrom( s, buf, len, flags, NULL, NULL );
+}
+
+// -------------------------------------------------------------------------
+
+__externC ssize_t sendmsg (int s, const struct msghdr *msg, int flags)
+{
+ SOCKET_ENTRY();
+
+ ssize_t ret = 0;
+ int error = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ error = ops->sendmsg( fp, msg, flags, &ret );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ if( error != ENOERR )
+ SOCKET_RETURN(error);
+
+ SOCKET_RETURN_VALUE( ret );
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC ssize_t sendto (int s, const void *buf,
+ size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
+{
+ SOCKET_ENTRY();
+
+ ssize_t ret = 0;
+ int error = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+
+ struct msghdr msg;
+ struct iovec iov;
+
+ msg.msg_name = (caddr_t)to;
+ msg.msg_namelen = tolen;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = 0;
+ msg.msg_flags = 0;
+ iov.iov_base = (char *)buf;
+ iov.iov_len = len;
+
+ LOCK_SOCKET( fp );
+
+ error = ops->sendmsg( fp, &msg, flags, &ret );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ if( error != ENOERR )
+ SOCKET_RETURN(error);
+
+ SOCKET_RETURN_VALUE( ret );
+}
+
+// -------------------------------------------------------------------------
+
+__externC ssize_t send (int s, const void *buf, size_t len, int flags)
+{
+ return sendto( s, buf, len, flags, NULL, 0 );
+}
+
+
+// -------------------------------------------------------------------------
+
+__externC int setsockopt (int s, int level, int optname,
+ const void *optval, socklen_t optlen)
+{
+ SOCKET_ENTRY();
+
+ int ret = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ ret = ops->setsockopt( fp, level, optname, optval, optlen );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN(ret);
+}
+
+// -------------------------------------------------------------------------
+
+__externC int shutdown (int s, int how)
+{
+ SOCKET_ENTRY();
+
+ int ret = 0;
+ cyg_file *fp;
+
+ fp = cyg_fp_get( s );
+
+ if( fp == NULL )
+ FILEIO_RETURN(EBADF);
+
+ if( fp->f_type == CYG_FILE_TYPE_SOCKET )
+ {
+ cyg_sock_ops *ops = (cyg_sock_ops *)fp->f_xops;
+
+ LOCK_SOCKET( fp );
+
+ ret = ops->shutdown( fp, how );
+
+ UNLOCK_SOCKET( fp );
+ }
+
+ cyg_fp_free( fp );
+
+ SOCKET_RETURN(ret);
+}
+
+//==========================================================================
+// Locking protocol
+
+static void cyg_ns_lock( cyg_nstab_entry *ns )
+{
+ if( ns->syncmode & CYG_SYNCMODE_SOCK_NETSTACK )
+ {
+ nstab_lock[ns-&cyg_nstab[0]].lock();
+ }
+}
+
+static void cyg_ns_unlock( cyg_nstab_entry *ns )
+{
+ if( ns->syncmode & CYG_SYNCMODE_SOCK_NETSTACK )
+ {
+ nstab_lock[ns-&cyg_nstab[0]].unlock();
+ }
+}
+
+static void cyg_sock_lock( cyg_file *fp )
+{
+ cyg_nstab_entry *ns = (cyg_nstab_entry *)fp->f_mte;
+
+ if( fp->f_syncmode & CYG_SYNCMODE_SOCK_NETSTACK )
+ nstab_lock[ns-&cyg_nstab[0]].lock();
+
+ cyg_file_lock( fp, fp->f_syncmode>>CYG_SYNCMODE_SOCK_SHIFT);
+}
+
+static void cyg_sock_unlock( cyg_file *fp )
+{
+ cyg_nstab_entry *ns = (cyg_nstab_entry *)fp->f_mte;
+
+ if( fp->f_syncmode & CYG_SYNCMODE_SOCK_NETSTACK )
+ nstab_lock[ns-&cyg_nstab[0]].unlock();
+
+ cyg_file_unlock( fp, fp->f_syncmode>>CYG_SYNCMODE_SOCK_SHIFT);
+}
+
+
+// -------------------------------------------------------------------------
+// EOF socket.cxx