summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-11-23 19:07:58 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-11-23 19:07:58 +0000
commit07a3253de2c3f9bc2d96a351680ec72548dadd2d (patch)
treeb4f85e78927202cffe01b194c708c3dd800d8e57 /cpukit/libcsupport
parentAdded new tests in support of the file system infrastructure. (diff)
downloadrtems-07a3253de2c3f9bc2d96a351680ec72548dadd2d.tar.bz2
Added base version of file system infrastructure. This includes a major
overhaul of the RTEMS system call interface. This base file system is the "In-Memory File System" aka IMFS. The design and implementation was done by the following people: + Joel Sherrill (joel@OARcorp.com) + Jennifer Averett (jennifer@OARcorp.com) + Steve "Mr Mount" Salitasc (salitasc@OARcorp.com) + Kerwin Wade (wade@OARcorp.com) PROBLEMS ======== + It is VERY likely that merging this will break the UNIX port. This can/will be fixed. + There is likely some reentrancy/mutual exclusion needed. + Eventually, there should be a "mini-IMFS" description table to eliminate links, symlinks, etc to save memory. All you need to have "classic RTEMS" functionality is technically directories and device IO. All the rest could be left out to save memory.
Diffstat (limited to '')
-rw-r--r--cpukit/libcsupport/include/rtems/libio.h551
-rw-r--r--cpukit/libcsupport/include/rtems/libio_.h248
-rw-r--r--cpukit/libcsupport/src/CASES23
-rw-r--r--cpukit/libcsupport/src/TODO11
-rw-r--r--cpukit/libcsupport/src/__brk.c27
-rw-r--r--cpukit/libcsupport/src/__gettod.c19
-rw-r--r--cpukit/libcsupport/src/__sbrk.c29
-rw-r--r--cpukit/libcsupport/src/__times.c36
-rw-r--r--cpukit/libcsupport/src/access.c46
-rw-r--r--cpukit/libcsupport/src/base_fs.c81
-rw-r--r--cpukit/libcsupport/src/cfgetispeed.c29
-rw-r--r--cpukit/libcsupport/src/cfgetospeed.c29
-rw-r--r--cpukit/libcsupport/src/cfsetispeed.c36
-rw-r--r--cpukit/libcsupport/src/cfsetospeed.c36
-rw-r--r--cpukit/libcsupport/src/chdir.c50
-rw-r--r--cpukit/libcsupport/src/chmod.c40
-rw-r--r--cpukit/libcsupport/src/chown.c38
-rw-r--r--cpukit/libcsupport/src/close.c70
-rw-r--r--cpukit/libcsupport/src/closedir.c62
-rw-r--r--cpukit/libcsupport/src/dup.c23
-rw-r--r--cpukit/libcsupport/src/dup2.c49
-rw-r--r--cpukit/libcsupport/src/eval.c74
-rw-r--r--cpukit/libcsupport/src/fchmod.c50
-rw-r--r--cpukit/libcsupport/src/fcntl.c111
-rw-r--r--cpukit/libcsupport/src/fdatasync.c45
-rw-r--r--cpukit/libcsupport/src/fpathconf.c91
-rw-r--r--cpukit/libcsupport/src/fstat.c94
-rw-r--r--cpukit/libcsupport/src/fsync.c45
-rw-r--r--cpukit/libcsupport/src/ftruncate.c60
-rw-r--r--cpukit/libcsupport/src/getdents.c55
-rw-r--r--cpukit/libcsupport/src/hosterr.c27
-rw-r--r--cpukit/libcsupport/src/ioctl.c57
-rw-r--r--cpukit/libcsupport/src/libio.c663
-rw-r--r--cpukit/libcsupport/src/link.c60
-rw-r--r--cpukit/libcsupport/src/lseek.c93
-rw-r--r--cpukit/libcsupport/src/malloc.c14
-rw-r--r--cpukit/libcsupport/src/mkdir.c28
-rw-r--r--cpukit/libcsupport/src/mkfifo.c25
-rw-r--r--cpukit/libcsupport/src/mknod.c60
-rw-r--r--cpukit/libcsupport/src/mount.c299
-rw-r--r--cpukit/libcsupport/src/newlibc.c78
-rw-r--r--cpukit/libcsupport/src/no_libc.c20
-rw-r--r--cpukit/libcsupport/src/open.c202
-rw-r--r--cpukit/libcsupport/src/opendir.c78
-rw-r--r--cpukit/libcsupport/src/pathconf.c38
-rw-r--r--cpukit/libcsupport/src/pipe.c23
-rw-r--r--cpukit/libcsupport/src/read.c84
-rw-r--r--cpukit/libcsupport/src/readdir.c75
-rw-r--r--cpukit/libcsupport/src/readlink.c43
-rw-r--r--cpukit/libcsupport/src/rewinddir.c21
-rw-r--r--cpukit/libcsupport/src/rmdir.c56
-rw-r--r--cpukit/libcsupport/src/scandir.c148
-rw-r--r--cpukit/libcsupport/src/seekdir.c27
-rw-r--r--cpukit/libcsupport/src/stat.c79
-rw-r--r--cpukit/libcsupport/src/symlink.c34
-rw-r--r--cpukit/libcsupport/src/tcdrain.c21
-rw-r--r--cpukit/libcsupport/src/tcgetattr.c33
-rw-r--r--cpukit/libcsupport/src/tcsetattr.c38
-rw-r--r--cpukit/libcsupport/src/telldir.c28
-rw-r--r--cpukit/libcsupport/src/truncate.c41
-rw-r--r--cpukit/libcsupport/src/umask.c30
-rw-r--r--cpukit/libcsupport/src/unixlibc.c10
-rw-r--r--cpukit/libcsupport/src/unlink.c44
-rw-r--r--cpukit/libcsupport/src/unmount.c214
-rw-r--r--cpukit/libcsupport/src/utime.c35
-rw-r--r--cpukit/libcsupport/src/write.c92
66 files changed, 4434 insertions, 642 deletions
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h
index dcdda85aec..76a90954b0 100644
--- a/cpukit/libcsupport/include/rtems/libio.h
+++ b/cpukit/libcsupport/include/rtems/libio.h
@@ -1,11 +1,18 @@
/*
- * General purpose communication channel for RTEMS to allow UNIX/POSIX
- * system call behavior on top of RTEMS IO devices.
+ * System call and file system interface definition
*
- * TODO
- * stat(2)
- * unlink(2)
- * rename(2)
+ * General purpose communication channel for RTEMS to allow UNIX/POSIX
+ * system call behavior under RTEMS. Initially this supported only
+ * IO to devices but has since been enhanced to support networking
+ * and support for mounted file systems.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
@@ -15,36 +22,342 @@
#include <sys/stat.h>
-typedef unsigned32 rtems_libio_offset_t;
+/*
+ * Define data types which must be constructed using forward references.
+ */
+
+typedef struct rtems_libio_tt rtems_libio_t;
+
+struct rtems_filesystem_location_info_tt;
+typedef struct rtems_filesystem_location_info_tt
+ rtems_filesystem_location_info_t;
+
+struct rtems_filesystem_mount_table_entry_tt;
+typedef struct rtems_filesystem_mount_table_entry_tt
+ rtems_filesystem_mount_table_entry_t;
+
+/*
+ * Valid RTEMS file types.
+ */
+typedef enum {
+ RTEMS_FILESYSTEM_DIRECTORY,
+ RTEMS_FILESYSTEM_DEVICE,
+ RTEMS_FILESYSTEM_HARD_LINK,
+ RTEMS_FILESYSTEM_SYM_LINK,
+ RTEMS_FILESYSTEM_MEMORY_FILE
+} rtems_filesystem_node_types_t;
+
+/*
+ * File Handler Operations Table
+ */
+
+typedef int (*rtems_filesystem_open_t)(
+ rtems_libio_t *iop,
+ const char *pathname,
+ unsigned32 flag,
+ unsigned32 mode
+);
+
+typedef int (*rtems_filesystem_close_t)(
+ rtems_libio_t *iop
+);
+
+typedef int (*rtems_filesystem_read_t)(
+ rtems_libio_t *iop,
+ void *buffer,
+ unsigned32 count
+);
+
+typedef int (*rtems_filesystem_write_t)(
+ rtems_libio_t *iop,
+ const void *buffer,
+ unsigned32 count
+);
+
+typedef int (*rtems_filesystem_ioctl_t)(
+ rtems_libio_t *iop,
+ unsigned32 command,
+ void *buffer
+);
+
+typedef int (*rtems_filesystem_lseek_t)(
+ rtems_libio_t *iop,
+ off_t length,
+ int whence
+);
+
+typedef int (*rtems_filesystem_fstat_t)(
+ rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+typedef int (*rtems_filesystem_fchmod_t)(
+ rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
+typedef int (*rtems_filesystem_ftruncate_t)(
+ rtems_libio_t *iop,
+ off_t length
+);
+
+typedef int (*rtems_filesystem_fpathconf_t)(
+ rtems_libio_t *iop,
+ int name
+);
+
+typedef int (*rtems_filesystem_fsync_t)(
+ rtems_libio_t *iop
+);
+
+typedef int (*rtems_filesystem_fdatasync_t)(
+ rtems_libio_t *iop
+);
+
+typedef struct {
+ rtems_filesystem_open_t open;
+ rtems_filesystem_close_t close;
+ rtems_filesystem_read_t read;
+ rtems_filesystem_write_t write;
+ rtems_filesystem_ioctl_t ioctl;
+ rtems_filesystem_lseek_t lseek;
+ rtems_filesystem_fstat_t fstat;
+ rtems_filesystem_fchmod_t fchmod;
+ rtems_filesystem_ftruncate_t ftruncate;
+ rtems_filesystem_fpathconf_t fpathconf;
+ rtems_filesystem_fsync_t fsync;
+ rtems_filesystem_fdatasync_t fdatasync;
+} rtems_filesystem_file_handlers_r;
+
+/*
+ * File System Operations Table
+ */
+
+/*
+ * XXX
+ * This routine does not allocate any space and rtems_filesystem_freenode_t
+ * is not called by the generic after calling this routine.
+ * ie. node_access does not have to contain valid data when the
+ * routine returns.
+ */
+
+typedef int (*rtems_filesystem_mknod_t)(
+ const char *path, /* IN */
+ mode_t mode, /* IN */
+ dev_t dev, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+);
+
+/*
+ * rtems_filesystem_freenode_t must be called by the generic after
+ * calling this routine
+ */
+
+typedef int (*rtems_filesystem_evalpath_t)(
+ const char *pathname, /* IN */
+ int flags, /* IN */
+ rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+);
+
+typedef int (*rtems_filesystem_evalmake_t)(
+ const char *path, /* IN */
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ const char **name /* OUT */
+);
+
+typedef int (*rtems_filesystem_link_t)(
+ rtems_filesystem_location_info_t *to_loc, /* IN */
+ rtems_filesystem_location_info_t *parent_loc, /* IN */
+ const char *name /* IN */
+);
+
+typedef int (*rtems_filesystem_unlink_t)(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+typedef int (*rtems_filesystem_chown_t)(
+ rtems_filesystem_location_info_t *pathloc, /* IN */
+ uid_t owner, /* IN */
+ gid_t group /* IN */
+);
+
+typedef int (*rtems_filesystem_freenode_t)(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+typedef int (*rtems_filesystem_rmnod_t)(
+ rtems_filesystem_location_info_t *pathloc /* IN */
+);
+
+typedef int (* rtems_filesystem_mount_t ) (
+ rtems_filesystem_mount_table_entry_t *mt_entry /* in */
+);
+
+typedef int (* rtems_filesystem_fsmount_me_t )(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+typedef int (* rtems_filesystem_unmount_t ) (
+ rtems_filesystem_mount_table_entry_t *mt_entry /* in */
+);
+
+typedef int (* rtems_filesystem_fsunmount_me_t ) (
+ rtems_filesystem_mount_table_entry_t *mt_entry /* in */
+);
+
+typedef rtems_filesystem_node_types_t (* rtems_filesystem_node_type_t) (
+ rtems_filesystem_location_info_t *pathloc /* in */
+);
+
+typedef int (* rtems_filesystem_utime_t)(
+ rtems_filesystem_location_info_t *pathloc, /* IN */
+ time_t actime, /* IN */
+ time_t modtime /* IN */
+);
+
+typedef int (*rtems_filesystem_evaluate_link_t)(
+ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
+ int flags /* IN */
+);
+
+typedef int (*rtems_filesystem_symlink_t)(
+ rtems_filesystem_location_info_t *loc, /* IN */
+ const char *link_name, /* IN */
+ const char *node_name
+);
+
+typedef int (*rtems_filesystem_readlink_t)(
+ rtems_filesystem_location_info_t *loc, /* IN */
+ char *buf, /* OUT */
+ size_t bufsize
+);
+
+/*
+ * operations table that must be defined for every file system.
+ */
+
+/*
+ * File system types
+ */
+typedef struct {
+ rtems_filesystem_evalpath_t evalpath;
+ rtems_filesystem_evalmake_t evalformake;
+ rtems_filesystem_link_t link;
+ rtems_filesystem_unlink_t unlink;
+ rtems_filesystem_node_type_t node_type;
+ rtems_filesystem_mknod_t mknod;
+ rtems_filesystem_rmnod_t rmnod;
+ rtems_filesystem_chown_t chown;
+ rtems_filesystem_freenode_t freenod;
+ rtems_filesystem_mount_t mount;
+ rtems_filesystem_fsmount_me_t fsmount_me;
+ rtems_filesystem_unmount_t unmount;
+ rtems_filesystem_fsunmount_me_t fsunmount_me;
+ rtems_filesystem_utime_t utime;
+ rtems_filesystem_evaluate_link_t eval_link;
+ rtems_filesystem_symlink_t symlink;
+ rtems_filesystem_readlink_t readlink;
+} rtems_filesystem_operations_table;
+
+#define IMFS_FILE_SYSTEM IMFS_ops
+extern rtems_filesystem_operations_table IMFS_ops;
+
/*
- * An open file data structure, indexed by 'fd'
- * TODO:
- * should really have a separate per/file data structure that this
- * points to (eg: size, offset, driver, pathname should be in that)
+ * Structure used to determine a location/filesystem in the tree.
+ */
+
+struct rtems_filesystem_location_info_tt
+{
+ void *node_access;
+ rtems_filesystem_file_handlers_r *handlers;
+ rtems_filesystem_operations_table *ops;
+ rtems_filesystem_mount_table_entry_t *mt_entry;
+};
+
+/*
+ * Structure used to contain file system specific information which
+ * is required to support fpathconf().
*/
typedef struct {
- rtems_driver_name_t *driver;
- rtems_libio_offset_t size; /* size of file */
- rtems_libio_offset_t offset; /* current offset into the file */
- unsigned32 flags;
- char *pathname; /* opened pathname */
- Objects_Id sem;
- unsigned32 data0; /* private to "driver" */
- void *data1; /* ... */
-} rtems_libio_t;
+ int link_max;
+ int max_canon;
+ int max_input;
+ int name_max;
+ int path_max;
+ int pipe_buf;
+ int posix_async_io;
+ int posix_chown_restrictions;
+ int posix_no_trunc;
+ int posix_prio_io;
+ int posix_sync_io;
+ int posix_vdisable;
+} rtems_filesystem_limits_and_options_t;
+
+/*
+ * Structure for a mount table entry.
+ */
+
+struct rtems_filesystem_mount_table_entry_tt{
+ Chain_Node Node;
+ rtems_filesystem_location_info_t mt_point_node;
+ rtems_filesystem_location_info_t mt_fs_root;
+ int options;
+ void *fs_info;
+
+ rtems_filesystem_limits_and_options_t pathconf_limits_and_options;
+ /*
+ * When someone adds a mounted filesystem on a real device,
+ * this will need to be used.
+ *
+ * The best option long term for this is probably an open file descriptor.
+ */
+ char *dev;
+};
/*
- * param block for read/write
- * Note: it must include 'offset' instead of using iop's offset since
- * we can have multiple outstanding i/o's on a device.
+ * Valid RTEMS file systems options
+ */
+
+typedef enum
+{
+ RTEMS_FILESYSTEM_READ_ONLY,
+ RTEMS_FILESYSTEM_READ_WRITE_ONLY,
+ RTEMS_FILESYSTEM_BAD_OPTIONS
+} rtems_filesystem_options_t;
+
+
+/*
+ * An open file data structure, indexed by 'fd'
+ * TODO:
+ * should really have a separate per/file data structure that this
+ * points to (eg: size, offset, driver, pathname should be in that)
+ */
+
+struct rtems_libio_tt {
+ rtems_driver_name_t *driver;
+ off_t size; /* size of file */
+ off_t offset; /* current offset into file */
+ unsigned32 flags;
+ rtems_filesystem_location_info_t pathinfo;
+ Objects_Id sem;
+ unsigned32 data0; /* private to "driver" */
+ void *data1; /* ... */
+ void *file_info; /* used by file handlers */
+ rtems_filesystem_file_handlers_r *handlers; /* type specific handlers */
+};
+
+/*
+ * param block for read/write
+ * Note: it must include 'offset' instead of using iop's offset since
+ * we can have multiple outstanding i/o's on a device.
*/
typedef struct {
rtems_libio_t *iop;
- rtems_libio_offset_t offset;
+ off_t offset;
unsigned8 *buffer;
unsigned32 count;
unsigned32 flags;
@@ -52,7 +365,7 @@ typedef struct {
} rtems_libio_rw_args_t;
/*
- * param block for open/close
+ * param block for open/close
*/
typedef struct {
@@ -62,7 +375,7 @@ typedef struct {
} rtems_libio_open_close_args_t;
/*
- * param block for ioctl
+ * param block for ioctl
*/
typedef struct {
@@ -72,9 +385,8 @@ typedef struct {
unsigned32 ioctl_return;
} rtems_libio_ioctl_args_t;
-
/*
- * Values for 'flag'
+ * Values for 'flag'
*/
#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */
@@ -84,33 +396,72 @@ typedef struct {
#define LIBIO_FLAGS_OPEN 0x0100 /* device is open */
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */
+#define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
-void rtems_libio_init(void);
-int __rtems_open(const char *pathname, unsigned32 flag, unsigned32 mode);
-int __rtems_close(int fd);
-int __rtems_read(int fd, void *buffer, unsigned32 count);
-int __rtems_write(int fd, const void *buffer, unsigned32 count);
-int __rtems_ioctl(int fd, unsigned32 command, void *buffer);
-int __rtems_lseek(int fd, rtems_libio_offset_t offset, int whence);
-int __rtems_fstat(int _fd, struct stat* _sbuf);
+void rtems_libio_init(void);
/*
- * External I/O handlers
+ * External I/O handlers
*/
+
+typedef int (*rtems_libio_open_t)(
+ const char *pathname,
+ unsigned32 flag,
+ unsigned32 mode
+);
+
+typedef int (*rtems_libio_close_t)(
+ int fd
+);
+
+typedef int (*rtems_libio_read_t)(
+ int fd,
+ void *buffer,
+ unsigned32 count
+);
+
+typedef int (*rtems_libio_write_t)(
+ int fd,
+ const void *buffer,
+ unsigned32 count
+);
+
+typedef int (*rtems_libio_ioctl_t)(
+ int fd,
+ unsigned32 command,
+ void *buffer
+);
+
+typedef int (*rtems_libio_lseek_t)(
+ int fd,
+ off_t offset,
+ int whence
+);
+
typedef struct {
- int (*open)(const char *pathname, unsigned32 flag, unsigned32 mode);
- int (*close)(int fd);
- int (*read)(int fd, void *buffer, unsigned32 count);
- int (*write)(int fd, const void *buffer, unsigned32 count);
- int (*ioctl)(int fd, unsigned32 command, void *buffer);
- int (*lseek)(int fd, rtems_libio_offset_t offset, int whence);
+ rtems_libio_open_t open;
+ rtems_libio_close_t close;
+ rtems_libio_read_t read;
+ rtems_libio_write_t write;
+ rtems_libio_ioctl_t ioctl;
+ rtems_libio_lseek_t lseek;
} rtems_libio_handler_t;
-void rtems_register_libio_handler(int handler_flag,
- const rtems_libio_handler_t *handler);
+/*
+ * Register a set of external handlers
+ */
+
+void rtems_register_libio_handler(
+ int handler_flag,
+ const rtems_libio_handler_t *handler
+);
+
+/*
+ * Macros to assist in management of external IO handlers.
+ */
#define RTEMS_FILE_DESCRIPTOR_TYPE_FILE 0x0000
#define RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET 0x1000
@@ -128,39 +479,117 @@ void rtems_register_libio_handler(int handler_flag,
#define RTEMS_IO_TCDRAIN 3
/*
+ * The following macros are used to build up the permissions sets
+ * used to check permissions. These are similar in style to the
+ * mode_t bits and should stay compatible with them.
+ */
+
+#define RTEMS_LIBIO_PERMS_READ S_IROTH
+#define RTEMS_LIBIO_PERMS_WRITE S_IWOTH
+#define RTEMS_LIBIO_PERMS_RDWR (S_IROTH|S_IWOTH)
+#define RTEMS_LIBIO_PERMS_EXEC S_IXOTH
+#define RTEMS_LIBIO_PERMS_SEARCH RTEMS_LIBIO_PERMS_EXEC
+#define RTEMS_LIBIO_PERMS_RWX S_IRWXO
+
+/*
+ * Macros
+ */
+
+#define rtems_filesystem_make_dev_t( _major, _minor ) \
+ ((((dev_t)(_major)) << 32) | (dev_t)(_minor))
+
+#define rtems_filesystem_split_dev_t( _dev, _major, _minor ) \
+ do { \
+ (_major) = (rtems_device_major_number) ((_dev) >> 32); \
+ (_minor) = (rtems_device_minor_number) ((_dev) & 0xFFFFFFFF); \
+ } while(0)
+
+/*
+ * Verifies that the permission flag is valid.
+ */
+#define rtems_libio_is_valid_perms( _perm ) \
+ (~ ((~RTEMS_LIBIO_PERMS_RWX) & _perm ))
+
+
+/*
+ * Prototypes for filesystem
+ */
+
+void rtems_filesystem_initialize( void );
+
+
+/*
* Callbacks from TERMIOS routines to device-dependent code
*/
+
#include <termios.h>
+
typedef struct rtems_termios_callbacks {
- int (*firstOpen)(int major, int minor, void *arg);
- int (*lastClose)(int major, int minor, void *arg);
- int (*pollRead)(int minor);
- int (*write)(int minor, const char *buf, int len);
- int (*setAttributes)(int minor, const struct termios *t);
- int (*stopRemoteTx)(int minor);
- int (*startRemoteTx)(int minor);
- int outputUsesInterrupts;
+ int (*firstOpen)(int major, int minor, void *arg);
+ int (*lastClose)(int major, int minor, void *arg);
+ int (*pollRead)(int minor);
+ int (*write)(int minor, const char *buf, int len);
+ int (*setAttributes)(int minor, const struct termios *t);
+ int (*stopRemoteTx)(int minor);
+ int (*startRemoteTx)(int minor);
+ int outputUsesInterrupts;
} rtems_termios_callbacks;
/*
- * Device-independent TERMIOS routines
+ * Device-independent TERMIOS routines
*/
+
void rtems_termios_initialize (void);
+
rtems_status_code rtems_termios_open (
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg,
const rtems_termios_callbacks *callbacks
- );
-rtems_status_code rtems_termios_close (void *arg);
-rtems_status_code rtems_termios_read (void *arg);
-rtems_status_code rtems_termios_write (void *arg);
-rtems_status_code rtems_termios_ioctl (void *arg);
-int rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len);
-int rtems_termios_dequeue_characters (void *ttyp, int len);
+);
+
+rtems_status_code rtems_termios_close(
+ void *arg
+);
+
+rtems_status_code rtems_termios_read(
+ void *arg
+);
+
+rtems_status_code rtems_termios_write(
+ void *arg
+);
+
+rtems_status_code rtems_termios_ioctl(
+ void *arg
+);
+
+int rtems_termios_enqueue_raw_characters(
+ void *ttyp,
+ char *buf,
+ int len
+);
+
+int rtems_termios_dequeue_characters(
+ void *ttyp,
+ int len
+);
+
void rtems_termios_reserve_resources(
rtems_configuration_table *configuration,
rtems_unsigned32 number_of_devices
);
+int unmount(
+ const char *mount_path
+);
+
+int mount(
+ rtems_filesystem_mount_table_entry_t **mt_entry,
+ rtems_filesystem_operations_table *fs_ops,
+ char *fsoptions,
+ char *device,
+ char *mount_point
+);
+
#endif /* _RTEMS_LIBIO_H */
diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
new file mode 100644
index 0000000000..bb6f81f35a
--- /dev/null
+++ b/cpukit/libcsupport/include/rtems/libio_.h
@@ -0,0 +1,248 @@
+/*
+ * Libio Internal Information
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef __LIBIO__h
+#define __LIBIO__h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <rtems/assoc.h> /* assoc.h not included by rtems.h */
+#include <rtems/libio.h>
+
+#include <stdio.h> /* O_RDONLY, et.al. */
+#include <fcntl.h> /* O_RDONLY, et.al. */
+#include <assert.h>
+#include <stdarg.h>
+
+#if ! defined(O_NDELAY)
+# if defined(solaris2)
+# define O_NDELAY O_NONBLOCK
+# elif defined(RTEMS_NEWLIB)
+# define O_NDELAY _FNBIO
+# endif
+#endif
+
+#include <errno.h>
+#include <string.h> /* strcmp */
+#include <unistd.h>
+#include <stdlib.h> /* calloc() */
+
+#include "libio.h" /* libio.h not pulled in by rtems */
+
+
+/*
+ * Semaphore to protect the io table
+ */
+
+#define RTEMS_LIBIO_SEM rtems_build_name('L', 'B', 'I', 'O')
+#define RTEMS_LIBIO_IOP_SEM(n) rtems_build_name('L', 'B', 'I', n)
+
+extern rtems_id rtems_libio_semaphore;
+
+/*
+ * File descriptor Table Information
+ */
+
+extern unsigned32 rtems_libio_number_iops;
+extern rtems_libio_t *rtems_libio_iops;
+extern rtems_libio_t *rtems_libio_last_iop;
+
+/*
+ * External I/O Handlers Table
+ *
+ * Space for all possible handlers is preallocated
+ * to speed up dispatch to external handlers.
+ */
+
+extern rtems_libio_handler_t rtems_libio_handlers[15];
+
+/*
+ * Default mode for all files.
+ */
+
+extern mode_t rtems_filesystem_umask;
+
+/*
+ * set_errno_and_return_minus_one
+ *
+ * Macro to ease common way to return an error.
+ */
+
+#ifndef set_errno_and_return_minus_one
+#define set_errno_and_return_minus_one( _error ) \
+ do { errno = (_error); return -1; } while(0)
+#endif
+
+/*
+ * rtems_libio_iop
+ *
+ * Macro to return the file descriptor pointer.
+ */
+
+#define rtems_libio_iop(_fd) \
+ ((((unsigned32)(_fd)) < rtems_libio_number_iops) ? \
+ &rtems_libio_iops[_fd] : 0)
+
+/*
+ * rtems_libio_check_fd
+ *
+ * Macro to check if a file descriptor number is valid.
+ */
+
+#define rtems_libio_check_fd(_fd) \
+ do { \
+ if ((unsigned32) (_fd) >= rtems_libio_number_iops) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ } while (0)
+
+/*
+ * rtems_libio_check_fd
+ *
+ * Macro to check if a buffer pointer is valid.
+ */
+
+#define rtems_libio_check_buffer(_buffer) \
+ do { \
+ if ((_buffer) == 0) { \
+ errno = EINVAL; \
+ return -1; \
+ } \
+ } while (0)
+
+/*
+ * rtems_libio_check_count
+ *
+ * Macro to check if a count or length is valid.
+ */
+
+#define rtems_libio_check_count(_count) \
+ do { \
+ if ((_count) == 0) { \
+ return 0; \
+ } \
+ } while (0)
+
+/*
+ * rtems_libio_check_permissions
+ *
+ * Macro to check if a file descriptor is open for this operation.
+ */
+
+#define rtems_libio_check_permissions(_iop, _flag) \
+ do { \
+ if (((_iop)->flags & (_flag)) == 0) { \
+ set_errno_and_return_minus_one( EINVAL ); \
+ return -1; \
+ } \
+ } while (0)
+
+/*
+ * rtems_filesystem_is_separator
+ *
+ * Macro to determine if a character is a path name separator.
+ *
+ * NOTE: This macro handles MS-DOS and UNIX style names.
+ */
+
+#define rtems_filesystem_is_separator( _ch ) \
+ ( ((_ch) == '/') || ((_ch) == '\\') || ((_ch) == '\0'))
+
+/*
+ * rtems_filesystem_get_start_loc
+ *
+ * Macro to determine if path is absolute or relative.
+ */
+
+#define rtems_filesystem_get_start_loc( _path, _index, _loc ) \
+ do { \
+ if ( rtems_filesystem_is_separator( (_path)[ 0 ] ) ) { \
+ *(_loc) = rtems_filesystem_root; \
+ *(_index) = 1; \
+ } else { \
+ *(_loc) = rtems_filesystem_current; \
+ *(_index) = 0; \
+ } \
+ } while (0)
+
+#define rtems_filesystem_get_sym_start_loc( _path, _index, _loc ) \
+ do { \
+ if ( rtems_filesystem_is_separator( (_path)[ 0 ] ) ) { \
+ *(_loc) = rtems_filesystem_root; \
+ *(_index) = 1; \
+ } else { \
+ *(_index) = 0; \
+ } \
+ } while (0)
+
+
+/*
+ * External structures
+ */
+
+extern rtems_filesystem_location_info_t rtems_filesystem_current;
+extern rtems_filesystem_location_info_t rtems_filesystem_root;
+extern nlink_t rtems_filesystem_link_counts;
+
+
+/*
+ * File Descriptor Routine Prototypes
+ */
+
+rtems_libio_t *rtems_libio_allocate(void);
+
+unsigned32 rtems_libio_fcntl_flags(
+ unsigned32 fcntl_flags
+);
+
+void rtems_libio_free(
+ rtems_libio_t *iop
+);
+
+int rtems_libio_is_open_files_in_fs(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+int rtems_libio_is_file_open(
+ void *node_access
+);
+
+/*
+ * File System Routine Prototypes
+ */
+
+int rtems_filesystem_evaluate_path(
+ const char *pathname,
+ int flags,
+ rtems_filesystem_location_info_t *pathloc,
+ int follow_link
+);
+
+void rtems_filesystem_initialize();
+
+int init_fs_mount_table();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
+
+
diff --git a/cpukit/libcsupport/src/CASES b/cpukit/libcsupport/src/CASES
new file mode 100644
index 0000000000..4578ae5009
--- /dev/null
+++ b/cpukit/libcsupport/src/CASES
@@ -0,0 +1,23 @@
+#
+# $Id$
+#
+
+This is a list of cases to consider when implementing a file system:
+
+
++ Given a tree of this form:
+
+ a ----- b
+ /
+ c
+
+ Where a and b are directories and c is a link to directory b. Consider
+ this sequence:
+
+ - rmdir a/b
+ - mknod c/b/x
+ - unlink c
+
+
+
+
diff --git a/cpukit/libcsupport/src/TODO b/cpukit/libcsupport/src/TODO
new file mode 100644
index 0000000000..9d894688d9
--- /dev/null
+++ b/cpukit/libcsupport/src/TODO
@@ -0,0 +1,11 @@
+#
+# $Id$
+#
+
++ newlib 1.8.0 has the wrong prototype for at least read() and write().
+
++ There should be a "eat it" stub for all system calls which are
+ available to make filling out an operations table easier.
+ See device_lseek() for an example of where this would be nice.
+
++ Fix strerror() so it prints all error numbers.
diff --git a/cpukit/libcsupport/src/__brk.c b/cpukit/libcsupport/src/__brk.c
index 4dab22c729..24efa93adb 100644
--- a/cpukit/libcsupport/src/__brk.c
+++ b/cpukit/libcsupport/src/__brk.c
@@ -1,10 +1,7 @@
-#if !defined(RTEMS_UNIX)
-
/*
- * RTEMS "Broken" __brk/__sbrk Implementation
- *
- * NOTE: sbrk is BSP provided.
+ * RTEMS "Broken" __brk Implementation
*
+ * NOTE: sbrk() is provided by each BSP.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
@@ -18,27 +15,15 @@
*/
#include <rtems.h>
+#if !defined(RTEMS_UNIX)
-#include <signal.h>
#include <errno.h>
-#include <sys/types.h>
-#ifdef RTEMS_NEWLIB
-#include <reent.h>
-#endif
-#include <unistd.h>
-
-/* we use RTEMS for memory management. We don't need sbrk */
-void * __sbrk(int incr)
-{
- errno = EINVAL;
- return (void *)0;
-}
-
-int __brk( const void *endds )
+int __brk(
+ const void *endds
+)
{
errno = EINVAL;
return -1;
}
-
#endif
diff --git a/cpukit/libcsupport/src/__gettod.c b/cpukit/libcsupport/src/__gettod.c
index dc83c47ce4..16857da870 100644
--- a/cpukit/libcsupport/src/__gettod.c
+++ b/cpukit/libcsupport/src/__gettod.c
@@ -1,11 +1,5 @@
-#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
-
-#include <rtems.h>
-
-#if !defined(RTEMS_UNIX)
/*
- * RTEMS gettimeofday Implementation
- *
+ * gettimeofday() - SVR4 and BSD4.3 extension required by Newlib
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
@@ -18,6 +12,11 @@
* $Id$
*/
+#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
+
+#include <rtems.h>
+
+#if !defined(RTEMS_UNIX)
#ifdef RTEMS_NEWLIB
#include <sys/reent.h>
#endif
@@ -61,7 +60,7 @@ int gettimeofday(
*
* NOTE: XXX this routine should really be in the executive proper.
*/
-
+
rtems_interrupt_disable(level);
seconds = _TOD_Seconds_since_epoch;
microseconds = _TOD_Current.ticks;
@@ -86,7 +85,7 @@ int gettimeofday(
return 0;
}
-#if defined(RTEMS_NEWLIB)
+#if defined(RTEMS_NEWLIB)
/*
* "Reentrant" version
@@ -102,7 +101,7 @@ int _gettimeofday_r(
}
/*
- * "System call" version
+ * "System call" version
*/
int _gettimeofday(
diff --git a/cpukit/libcsupport/src/__sbrk.c b/cpukit/libcsupport/src/__sbrk.c
new file mode 100644
index 0000000000..b1d31467fd
--- /dev/null
+++ b/cpukit/libcsupport/src/__sbrk.c
@@ -0,0 +1,29 @@
+/*
+ * RTEMS "Broken" __sbrk Implementation
+ *
+ * NOTE: sbrk is provided by the BSP.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#if !defined(RTEMS_UNIX)
+
+#include <errno.h>
+
+void * __sbrk(
+ int incr
+)
+{
+ errno = EINVAL;
+ return (void *)0;
+}
+#endif
diff --git a/cpukit/libcsupport/src/__times.c b/cpukit/libcsupport/src/__times.c
index 635bf8e062..5f7525ec5f 100644
--- a/cpukit/libcsupport/src/__times.c
+++ b/cpukit/libcsupport/src/__times.c
@@ -1,6 +1,5 @@
/*
- * RTEMS _times Implementation
- *
+ * times() - POSIX 1003.1b 4.5.2 - Get Process Times
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
@@ -25,8 +24,8 @@ clock_t _times(
struct tms *ptms
)
{
- rtems_status_code status;
- rtems_interval ticks_since_boot;
+ rtems_status_code status;
+ rtems_interval ticks;
if ( !ptms ) {
errno = EFAULT;
@@ -34,21 +33,19 @@ clock_t _times(
}
/* "POSIX" does not seem to allow for not having a TOD */
- status = rtems_clock_get(
- RTEMS_CLOCK_GET_TICKS_SINCE_BOOT,
- &ticks_since_boot
- );
+ status = rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &ticks );
if ( status != RTEMS_SUCCESSFUL ) {
assert( 0 );
return -1;
}
/*
- * RTEMS has no notion of system versus user time and does
- * not (as of 3.2.0) keep track of CPU usage on a per task basis.
+ * RTEMS has no notion of system versus user time and although
+ * a way to keep track of per task CPU usage was added since
+ * 3.6.0, this routine does not utilize it yet.
*/
- ptms->tms_utime = ticks_since_boot;
+ ptms->tms_utime = ticks;
ptms->tms_stime = 0;
ptms->tms_cutime = 0;
ptms->tms_cstime = 0;
@@ -56,6 +53,12 @@ clock_t _times(
return 0;
}
+/*
+ * times()
+ *
+ * times() system call wrapper for _times() above.
+ */
+
clock_t times(
struct tms *ptms
)
@@ -63,12 +66,21 @@ clock_t times(
return _times( ptms );
}
+/*
+ * _times_r
+ *
+ * This is the Newlib dependent reentrant version of times().
+ */
+
#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
clock_t _times_r(
struct _reent *ptr,
struct tms *ptms
)
{
- return _times(ptms);
+ return _times( ptms );
}
#endif
diff --git a/cpukit/libcsupport/src/access.c b/cpukit/libcsupport/src/access.c
new file mode 100644
index 0000000000..a8be44a9a3
--- /dev/null
+++ b/cpukit/libcsupport/src/access.c
@@ -0,0 +1,46 @@
+/*
+ * access() - POSIX 1003.1b 5.6.3 - File Accessibility
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+int access(
+ const char *path,
+ int amode
+)
+{
+ struct stat statbuf;
+
+ if ( stat(path, &statbuf) )
+ return -1;
+
+ if ( amode & R_OK ) {
+ if (!( statbuf.st_mode & S_IREAD ))
+ return -1;
+ }
+
+ if ( amode & W_OK ) {
+ if ( !( statbuf.st_mode & S_IWRITE ) )
+ return -1;
+ }
+
+ if ( amode & X_OK ) {
+ if ( !( statbuf.st_mode & S_IEXEC ) )
+ return -1;
+ }
+
+ return 0;
+}
+
diff --git a/cpukit/libcsupport/src/base_fs.c b/cpukit/libcsupport/src/base_fs.c
new file mode 100644
index 0000000000..c8c23e5b43
--- /dev/null
+++ b/cpukit/libcsupport/src/base_fs.c
@@ -0,0 +1,81 @@
+/*
+ * Base file system initialization
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include "imfs.h"
+#include "libio_.h"
+
+/*
+ * Global information for the base file system.
+ */
+
+rtems_filesystem_location_info_t rtems_filesystem_current;
+rtems_filesystem_location_info_t rtems_filesystem_root;
+nlink_t rtems_filesystem_link_counts;
+
+/*
+ * Default mode for created files.
+ */
+
+mode_t rtems_filesystem_umask;
+
+/*
+ * rtems_filesystem_initialize
+ *
+ * Initialize the foundation of the file system with one instantiation
+ * of the IMFS with a single "/dev" directory in it.
+ */
+
+void rtems_filesystem_initialize( void )
+{
+ int status;
+ rtems_filesystem_mount_table_entry_t *first_entry;
+
+ /*
+ * Set the default umask to "022".
+ */
+
+ rtems_filesystem_umask = S_IWOTH | S_IROTH;
+
+ init_fs_mount_table();
+
+ status = mount(
+ &first_entry,
+ &IMFS_ops,
+ "RW",
+ NULL,
+ NULL );
+ if( status == -1 ){
+ rtems_fatal_error_occurred( 0xABCD0002 );
+ }
+
+ rtems_filesystem_link_counts = 0;
+
+ rtems_filesystem_root = first_entry->mt_fs_root;
+
+ rtems_filesystem_current = rtems_filesystem_root;
+
+ /*
+ * Traditionally RTEMS devices are under "/dev" so install this directory.
+ *
+ * If the mkdir() fails, we can't print anything so just fatal error.
+ *
+ * NOTE: UNIX root is 755 and owned by root/root (0/0).
+ */
+
+ status = mkdir( "/dev", S_IRWXU | S_IRWXG | S_IRWXO );
+ if ( status != 0 )
+ rtems_fatal_error_occurred( 0xABCD0003 );
+}
diff --git a/cpukit/libcsupport/src/cfgetispeed.c b/cpukit/libcsupport/src/cfgetispeed.c
new file mode 100644
index 0000000000..61d97cb2f1
--- /dev/null
+++ b/cpukit/libcsupport/src/cfgetispeed.c
@@ -0,0 +1,29 @@
+/*
+ * cfgetispeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+speed_t cfgetispeed(
+ const struct termios *tp
+)
+{
+ return (tp->c_cflag / (CIBAUD / CBAUD)) & CBAUD;
+}
+#endif
diff --git a/cpukit/libcsupport/src/cfgetospeed.c b/cpukit/libcsupport/src/cfgetospeed.c
new file mode 100644
index 0000000000..8815d436e9
--- /dev/null
+++ b/cpukit/libcsupport/src/cfgetospeed.c
@@ -0,0 +1,29 @@
+/*
+ * cfgetospeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+speed_t cfgetospeed(
+ const struct termios *tp
+)
+{
+ return tp->c_cflag & CBAUD;
+}
+#endif
diff --git a/cpukit/libcsupport/src/cfsetispeed.c b/cpukit/libcsupport/src/cfsetispeed.c
new file mode 100644
index 0000000000..37d3cd0584
--- /dev/null
+++ b/cpukit/libcsupport/src/cfsetispeed.c
@@ -0,0 +1,36 @@
+/*
+ * cfsetispeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+#include "libio_.h"
+
+int cfsetispeed(
+ struct termios *tp,
+ speed_t speed
+)
+{
+ if ( speed & ~CBAUD )
+ set_errno_and_return_minus_one( EINVAL );
+
+ tp->c_cflag = (tp->c_cflag & ~CIBAUD) | (speed * (CIBAUD / CBAUD));
+ return 0;
+}
+#endif
diff --git a/cpukit/libcsupport/src/cfsetospeed.c b/cpukit/libcsupport/src/cfsetospeed.c
new file mode 100644
index 0000000000..f01237103b
--- /dev/null
+++ b/cpukit/libcsupport/src/cfsetospeed.c
@@ -0,0 +1,36 @@
+/*
+ * cfsetospeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+
+#include "libio_.h"
+
+int cfsetospeed(
+ struct termios *tp,
+ speed_t speed
+)
+{
+ if ( speed & ~CBAUD )
+ set_errno_and_return_minus_one( EINVAL );
+
+ tp->c_cflag = (tp->c_cflag & ~CBAUD) | speed;
+ return 0;
+}
+#endif
diff --git a/cpukit/libcsupport/src/chdir.c b/cpukit/libcsupport/src/chdir.c
new file mode 100644
index 0000000000..4acbc8cfe0
--- /dev/null
+++ b/cpukit/libcsupport/src/chdir.c
@@ -0,0 +1,50 @@
+/*
+ * chdir() - POSIX 1003.1b - 5.2.1 - Change Current Working Directory
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "libio_.h"
+
+int chdir(
+ const char *pathname
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ /*
+ * Get the node where we wish to go.
+ */
+
+ result = rtems_filesystem_evaluate_path( pathname, 0, &loc, TRUE );
+ if ( result != 0 )
+ return -1;
+
+ /*
+ * Verify you can change directory into this node.
+ */
+
+ if ( !loc.ops->node_type )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( (*loc.ops->node_type)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY )
+ set_errno_and_return_minus_one( ENOTDIR );
+
+ rtems_filesystem_current = loc;
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/chmod.c b/cpukit/libcsupport/src/chmod.c
new file mode 100644
index 0000000000..fa57d50691
--- /dev/null
+++ b/cpukit/libcsupport/src/chmod.c
@@ -0,0 +1,40 @@
+/*
+ * chmod() - POSIX 1003.1b 5.6.4 - Change File Modes
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "libio_.h"
+
+int chmod(
+ const char *path,
+ mode_t mode
+)
+{
+ int status;
+ rtems_filesystem_location_info_t loc;
+
+ status = rtems_filesystem_evaluate_path( path, 0, &loc, TRUE );
+ if ( status != 0 )
+ return -1;
+
+ if ( !loc.handlers->fchmod )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*loc.handlers->fchmod)( &loc, mode );
+}
diff --git a/cpukit/libcsupport/src/chown.c b/cpukit/libcsupport/src/chown.c
new file mode 100644
index 0000000000..189096dcd1
--- /dev/null
+++ b/cpukit/libcsupport/src/chown.c
@@ -0,0 +1,38 @@
+/*
+ * chown() - POSIX 1003.1b 5.6.5 - Change Owner and Group of a File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+
+#include "libio_.h"
+
+int chown(
+ const char *path,
+ uid_t owner,
+ gid_t group
+)
+{
+ rtems_filesystem_location_info_t temp_loc;
+
+ if ( rtems_filesystem_evaluate_path( path, 0x00, &temp_loc, TRUE ) )
+ return -1;
+
+ if ( !temp_loc.ops->chown )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*temp_loc.ops->chown)( &temp_loc, owner, group );
+}
diff --git a/cpukit/libcsupport/src/close.c b/cpukit/libcsupport/src/close.c
new file mode 100644
index 0000000000..94ddb45c90
--- /dev/null
+++ b/cpukit/libcsupport/src/close.c
@@ -0,0 +1,70 @@
+/*
+ * close() - POSIX 1003.1b 6.3.1 - Close a File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include "libio_.h"
+
+int close(
+ int fd
+)
+{
+ rtems_libio_t *iop;
+ rtems_status_code rc;
+ int status;
+
+ if ( rtems_file_descriptor_type( fd ) ) {
+ int (*fp)(int fd);
+
+ fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].close;
+ if ( fp == NULL )
+ set_errno_and_return_minus_one( EBADF );
+ status = (*fp)( fd );
+ return status;
+ }
+ iop = rtems_libio_iop(fd);
+ rtems_libio_check_fd(fd);
+
+ if ( !iop->handlers )
+ set_errno_and_return_minus_one( EBADF );
+
+ if ( !iop->handlers->close )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ rc = (*iop->handlers->close)( iop );
+
+ rtems_libio_free( iop );
+
+ if (rc != RTEMS_SUCCESSFUL)
+ set_errno_and_return_minus_one( rc );
+
+ return rc;
+}
+
+/*
+ * _close_r
+ *
+ * This is the Newlib dependent reentrant version of close().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _close_r(
+ struct _reent *ptr,
+ int fd
+)
+{
+ return close( fd );
+}
+#endif
diff --git a/cpukit/libcsupport/src/closedir.c b/cpukit/libcsupport/src/closedir.c
index 5edb3499e6..4d948ec95b 100644
--- a/cpukit/libcsupport/src/closedir.c
+++ b/cpukit/libcsupport/src/closedir.c
@@ -1,9 +1,44 @@
/*
* closedir() - POSIX 1003.1b - XXX
*
- * $Id$
+ * This was copied from Newlib 1.8.0.
+ *
+ *
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)closedir.c 5.9 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <dirent.h>
@@ -11,10 +46,25 @@
#include <unistd.h>
#include <errno.h>
-int closedir(
- register DIR *dirp
-)
+
+#include "libio_.h"
+
+/*
+ * close a directory.
+ */
+int
+closedir(dirp)
+ register DIR *dirp;
{
- errno = ENOSYS;
- return -1;
+ int fd;
+
+ if ( !dirp )
+ set_errno_and_return_minus_one( EBADF );
+
+ fd = dirp->dd_fd;
+ dirp->dd_fd = -1;
+ dirp->dd_loc = 0;
+ (void)free((void *)dirp->dd_buf);
+ (void)free((void *)dirp);
+ return(close(fd));
}
diff --git a/cpukit/libcsupport/src/dup.c b/cpukit/libcsupport/src/dup.c
new file mode 100644
index 0000000000..c17db588a7
--- /dev/null
+++ b/cpukit/libcsupport/src/dup.c
@@ -0,0 +1,23 @@
+/*
+ * dup() - POSIX 1003.1b 6.2.1 Duplicate an Open File Descriptor
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+
+int dup(
+ int fildes
+)
+{
+ return fcntl( fildes, F_DUPFD, 0 );
+}
diff --git a/cpukit/libcsupport/src/dup2.c b/cpukit/libcsupport/src/dup2.c
new file mode 100644
index 0000000000..5653425708
--- /dev/null
+++ b/cpukit/libcsupport/src/dup2.c
@@ -0,0 +1,49 @@
+/*
+ * dup2() - POSIX 1003.1b 6.2.1 Duplicate an Open File Descriptor
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "libio_.h"
+
+int dup2(
+ int fildes,
+ int fildes2
+)
+{
+ int status;
+ struct stat buf;
+
+ /*
+ * If fildes is not valid, then fildes2 should not be closed.
+ */
+
+ status = fstat( fildes, &buf );
+ if ( status == -1 )
+ return -1;
+
+ /*
+ * If fildes2 is not valid, then we should not do anything either.
+ */
+
+ status = fstat( fildes2, &buf );
+ if ( status == -1 )
+ return -1;
+
+ /*
+ * This fcntl handles everything else.
+ */
+
+ return fcntl( fildes, F_DUPFD, fildes2 );
+}
diff --git a/cpukit/libcsupport/src/eval.c b/cpukit/libcsupport/src/eval.c
new file mode 100644
index 0000000000..bf7dd1c126
--- /dev/null
+++ b/cpukit/libcsupport/src/eval.c
@@ -0,0 +1,74 @@
+/*
+ * rtems_filesystem_evaluate_path()
+ *
+ * Routine to seed the evaluate path routine.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "libio_.h"
+
+int rtems_filesystem_evaluate_path(
+ const char *pathname,
+ int flags,
+ rtems_filesystem_location_info_t *pathloc,
+ int follow_link
+)
+{
+ int i;
+ int result;
+ rtems_filesystem_node_types_t type;
+
+ /*
+ * Verify Input parameters.
+ */
+
+ if ( !pathname )
+ set_errno_and_return_minus_one( EFAULT );
+
+ if ( !pathloc )
+ set_errno_and_return_minus_one( EIO ); /* should never happen */
+
+ /*
+ * Evaluate the path using the optable evalpath.
+ */
+
+ rtems_filesystem_get_start_loc( pathname, &i, pathloc );
+
+ result = (*pathloc->ops->evalpath)( &pathname[i], flags, pathloc );
+
+ /*
+ * Get the Node type and determine if you need to follow the link or
+ * not.
+ */
+
+ if ( follow_link ) {
+
+ if ( !pathloc->ops->node_type )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ type = (*pathloc->ops->node_type)( pathloc );
+
+ if ( ( type == RTEMS_FILESYSTEM_HARD_LINK ) ||
+ ( type == RTEMS_FILESYSTEM_SYM_LINK ) ) {
+
+ if ( !pathloc->ops->eval_link )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ result = (*pathloc->ops->eval_link)( pathloc, flags );
+
+ }
+ }
+
+ return result;
+}
+
diff --git a/cpukit/libcsupport/src/fchmod.c b/cpukit/libcsupport/src/fchmod.c
new file mode 100644
index 0000000000..a3ca4507ab
--- /dev/null
+++ b/cpukit/libcsupport/src/fchmod.c
@@ -0,0 +1,50 @@
+/*
+ * fchmod() - POSIX 1003.1b 5.6.4 - Change File Modes
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include "libio_.h"
+
+int fchmod(
+ int fd,
+ mode_t mode
+)
+{
+ rtems_libio_t *iop;
+
+ /*
+ * If this is not a file system based entity, it is an error.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) )
+ set_errno_and_return_minus_one( EBADF );
+
+ /*
+ * Now process the fchmod().
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ if ( !iop->handlers->fchmod )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->pathinfo.handlers->fchmod)( &iop->pathinfo, mode );
+}
+
diff --git a/cpukit/libcsupport/src/fcntl.c b/cpukit/libcsupport/src/fcntl.c
new file mode 100644
index 0000000000..f6f33534ab
--- /dev/null
+++ b/cpukit/libcsupport/src/fcntl.c
@@ -0,0 +1,111 @@
+/*
+ * fcntl() - POSIX 1003.1b 6.5.2 - File Control
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include "libio_.h"
+
+int fcntl(
+ int fd,
+ int cmd,
+ ...
+)
+{
+ va_list ap;
+ rtems_libio_t *iop;
+
+ va_start( ap, cmd );
+
+ /*
+ * If this is not a file system based entity, it is an error.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) )
+ set_errno_and_return_minus_one( EBADF );
+
+ /*
+ * Now process the fcntl().
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+
+ /*
+ * This switch should contain all the cases from POSIX.
+ */
+
+ switch ( cmd ) {
+ case F_DUPFD: /* dup */
+ /*
+ * This is how it appears that this case should work:
+ *
+ * filedes2 = va_arg( ap, int )
+ * if filedes2 is 0
+ * duplicate fd into a new descriptor
+ * else
+ * duplicate fd into specified descriptor after error checking it
+ *
+ * See dup2() in case we can eliminate stuff in there.
+ */
+ return -1;
+
+ case F_GETFD: /* get f_flags */
+ if ( iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC )
+ return 1;
+ return 0;
+
+ case F_SETFD: /* set f_flags */
+ /*
+ * Interpret the third argument as the "close on exec()" flag.
+ * If this argument is 1, then the file descriptor is to be closed
+ * if a new process is exec()'ed. Since RTEMS does not support
+ * processes, then we can ignore this one except to make
+ * F_GETFD work.
+ */
+
+ if ( va_arg( ap, int ) )
+ iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
+ else
+ iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
+ return 0;
+
+ case F_GETFL: /* more flags (cloexec) */
+ return -1;
+
+ case F_SETFL:
+ return -1;
+
+ case F_GETLK:
+ return -1;
+
+ case F_SETLK:
+ return -1;
+
+ case F_SETLKW:
+ return -1;
+
+ case F_SETOWN: /* for sockets. */
+ return -1;
+
+ case F_GETOWN: /* for sockets. */
+ return -1;
+
+ default:
+ break;
+ }
+ return -1;
+}
diff --git a/cpukit/libcsupport/src/fdatasync.c b/cpukit/libcsupport/src/fdatasync.c
new file mode 100644
index 0000000000..58a4c4e118
--- /dev/null
+++ b/cpukit/libcsupport/src/fdatasync.c
@@ -0,0 +1,45 @@
+/*
+ * fdatasync() - POSIX 1003.1b 6.6.2 - Synchronize the Data of a File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+
+#include "libio_.h"
+
+int fdatasync(
+ int fd
+)
+{
+ rtems_libio_t *iop;
+
+ /*
+ * If this file descriptor is mapped to an external set of handlers,
+ * then pass the request on to them.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) )
+ set_errno_and_return_minus_one( EBADF );
+
+ /*
+ * Now process the fdatasync().
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ if ( !iop->handlers->fdatasync )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->fdatasync)( iop );
+}
diff --git a/cpukit/libcsupport/src/fpathconf.c b/cpukit/libcsupport/src/fpathconf.c
new file mode 100644
index 0000000000..ea2377e15b
--- /dev/null
+++ b/cpukit/libcsupport/src/fpathconf.c
@@ -0,0 +1,91 @@
+/*
+ * fpathconf() - POSIX 1003.1b - 5.7.1 - Configurable Pathname Varables
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include "libio_.h"
+
+#include <unistd.h>
+#include <errno.h>
+
+long fpathconf(
+ int fd,
+ int name
+)
+{
+ long return_value;
+ rtems_libio_t *iop;
+ rtems_filesystem_limits_and_options_t *the_limits;
+
+ /*
+ * If this file descriptor is mapped to an external set of handlers,
+ * then it is an error since fpathconf() is not included in the
+ * set.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) )
+ set_errno_and_return_minus_one( EBADF );
+
+ /*
+ * Now process the information request.
+ */
+
+ iop = rtems_libio_iop(fd);
+ rtems_libio_check_fd(fd);
+ rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
+
+ the_limits = &iop->pathinfo.mt_entry->pathconf_limits_and_options;
+
+ switch ( name ) {
+ case _PC_LINK_MAX:
+ return_value = the_limits->link_max;
+ break;
+ case _PC_MAX_CANON:
+ return_value = the_limits->max_canon;
+ break;
+ case _PC_MAX_INPUT:
+ return_value = the_limits->max_input;
+ break;
+ case _PC_NAME_MAX:
+ return_value = the_limits->name_max;
+ break;
+ case _PC_PATH_MAX:
+ return_value = the_limits->path_max;
+ break;
+ case _PC_PIPE_BUF:
+ return_value = the_limits->pipe_buf;
+ break;
+ case _PC_CHOWN_RESTRICTED:
+ return_value = the_limits->posix_chown_restrictions;
+ break;
+ case _PC_NO_TRUNC:
+ return_value = the_limits->posix_no_trunc;
+ break;
+ case _PC_VDISABLE:
+ return_value = the_limits->posix_vdisable;
+ break;
+ case _PC_ASYNC_IO:
+ return_value = the_limits->posix_async_io;
+ break;
+ case _PC_PRIO_IO:
+ return_value = the_limits->posix_prio_io;
+ break;
+ case _PC_SYNC_IO:
+ return_value = the_limits->posix_sync_io;
+ break;
+ default:
+ set_errno_and_return_minus_one( EINVAL );
+ break;
+ }
+
+ return return_value;
+}
diff --git a/cpukit/libcsupport/src/fstat.c b/cpukit/libcsupport/src/fstat.c
new file mode 100644
index 0000000000..82d144dd2c
--- /dev/null
+++ b/cpukit/libcsupport/src/fstat.c
@@ -0,0 +1,94 @@
+/*
+ * fstat() - POSIX 1003.1b 5.6.2 - Get File Status
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "libio_.h"
+
+int fstat(
+ int fd,
+ struct stat *sbuf
+)
+{
+ rtems_libio_t *iop;
+
+ /*
+ * Check to see if we were passed a valid pointer.
+ */
+
+ if ( !sbuf )
+ set_errno_and_return_minus_one( EFAULT );
+
+ /*
+ * Zero out the stat structure so the various support
+ * versions of stat don't have to.
+ */
+
+ memset( sbuf, 0, sizeof(struct stat) );
+
+ /*
+ * If this file descriptor is mapped to an external set of handlers,
+ * then pass the request on to them.
+ */
+
+ if (rtems_file_descriptor_type(fd)) {
+ switch (rtems_file_descriptor_type (fd)) {
+ case RTEMS_FILE_DESCRIPTOR_TYPE_FILE:
+ break;
+
+ case RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET:
+#if !defined(__GO32__)
+ sbuf->st_mode = S_IFSOCK;
+ break;
+#endif
+
+ default:
+ set_errno_and_return_minus_one( EBADF );
+ }
+ }
+
+ /*
+ * Now process the stat() request.
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+
+ if ( !iop->handlers->fstat )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->fstat)( &iop->pathinfo, sbuf );
+}
+
+/*
+ * _fstat_r
+ *
+ * This is the Newlib dependent reentrant version of fstat().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _fstat_r(
+ struct _reent *ptr,
+ int fd,
+ struct stat *buf
+)
+{
+ return fstat( fd, buf );
+}
+#endif
diff --git a/cpukit/libcsupport/src/fsync.c b/cpukit/libcsupport/src/fsync.c
new file mode 100644
index 0000000000..a5ed1e99e7
--- /dev/null
+++ b/cpukit/libcsupport/src/fsync.c
@@ -0,0 +1,45 @@
+/*
+ * fsync() - POSIX 1003.1b 6.6.1 - Synchronize the State of a File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+
+#include "libio_.h"
+
+int fsync(
+ int fd
+)
+{
+ rtems_libio_t *iop;
+
+ /*
+ * If this file descriptor is mapped to an external set of handlers,
+ * then pass the request on to them.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) )
+ set_errno_and_return_minus_one( EBADF );
+
+ /*
+ * Now process the fsync().
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ if ( !iop->handlers->fsync )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->fsync)( iop );
+}
diff --git a/cpukit/libcsupport/src/ftruncate.c b/cpukit/libcsupport/src/ftruncate.c
new file mode 100644
index 0000000000..7fb2286531
--- /dev/null
+++ b/cpukit/libcsupport/src/ftruncate.c
@@ -0,0 +1,60 @@
+/*
+ * ftruncate() - Truncate a File to the Specified Length
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "libio_.h"
+
+int ftruncate(
+ int fd,
+ off_t length
+)
+{
+ rtems_libio_t *iop;
+ rtems_filesystem_location_info_t loc;
+
+ /*
+ * If this is not a file system based entity, it is an error.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) )
+ set_errno_and_return_minus_one( EBADF );
+
+ /*
+ * Now process the ftruncate() request.
+ */
+
+ iop = rtems_libio_iop( fd );
+
+ /*
+ * Make sure we are not working on a directory
+ */
+
+ loc = iop->pathinfo;
+ if ( !loc.ops->node_type )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( (*loc.ops->node_type)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY )
+ set_errno_and_return_minus_one( EISDIR );
+
+ rtems_libio_check_fd( fd );
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ if ( !iop->handlers->ftruncate )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->ftruncate)( iop, length );
+}
+
diff --git a/cpukit/libcsupport/src/getdents.c b/cpukit/libcsupport/src/getdents.c
index 9b16d82409..91631843b7 100644
--- a/cpukit/libcsupport/src/getdents.c
+++ b/cpukit/libcsupport/src/getdents.c
@@ -1,14 +1,59 @@
/*
- * Just enough to make newlib return an error.
+ * getdents() - Get Directory Entries
+ *
+ * SVR4 and SVID extension required by Newlib readdir() family.
+ *
+ * This routine will dd_len / (sizeof dirent) directory entries relative to
+ * the current directory position index. These entries will be placed in
+ * character array pointed to by -dd_buf-
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
+#include <errno.h>
+
+#include "libio_.h"
+
int getdents(
- int fd,
- void *buf,
- int len
+ int dd_fd,
+ char *dd_buf,
+ int dd_len
)
{
- return -1;
+ rtems_libio_t *iop;
+ rtems_filesystem_location_info_t loc;
+
+ /*
+ * Get the file control block structure associated with the file descriptor
+ */
+
+ iop = rtems_libio_iop( dd_fd );
+
+ /*
+ * Make sure we are working on a directory
+ */
+ loc = iop->pathinfo;
+ if ( !loc.ops->node_type )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( (*loc.ops->node_type)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY )
+ set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * Return the number of bytes that were actually transfered as a result
+ * of the read attempt.
+ */
+
+ if ( !iop->handlers->read )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->read)( iop, dd_buf, dd_len );
}
diff --git a/cpukit/libcsupport/src/hosterr.c b/cpukit/libcsupport/src/hosterr.c
index a55e4a7e84..6c0308df3b 100644
--- a/cpukit/libcsupport/src/hosterr.c
+++ b/cpukit/libcsupport/src/hosterr.c
@@ -13,31 +13,36 @@
*/
#include <rtems.h>
+#if defined(RTEMS_UNIX)
#include <errno.h>
-int host_errno(void);
+int host_errno( void );
/*
- * copy host errno, if any to thread aware errno, if any
+ * fix_syscall_errno
+ *
+ * copy host errno, if any to thread aware errno, if any
*/
-void fix_syscall_errno(void)
+void fix_syscall_errno( void )
{
- errno = host_errno();
+ errno = host_errno();
}
/*
- * Get the host system errno, if any
- * When using newlib (or possibly other libc's) on top of UNIX
- * the errno returned by system calls may be unavailable due
- * to trickery of making errno thread aware.
- * This provides a kludge of getting at it.
+ * host_errno
+ *
+ * Get the host system errno, if any
+ * When using newlib (or possibly other libc's) on top of UNIX
+ * the errno returned by system calls may be unavailable due
+ * to trickery of making errno thread aware.
+ * This provides a kludge of getting at it.
*/
#undef errno
extern int errno;
int host_errno(void)
{
- return errno;
+ return errno;
}
-
+#endif
diff --git a/cpukit/libcsupport/src/ioctl.c b/cpukit/libcsupport/src/ioctl.c
new file mode 100644
index 0000000000..0aaf0379ae
--- /dev/null
+++ b/cpukit/libcsupport/src/ioctl.c
@@ -0,0 +1,57 @@
+/*
+ * ioctl() system call
+ *
+ * This routine is not defined in the POSIX 1003.1b standard but is
+ * commonly supported on most UNIX and POSIX systems.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include "libio_.h"
+
+int ioctl(
+ int fd,
+ unsigned32 command,
+ void * buffer
+)
+{
+ rtems_status_code rc;
+ rtems_libio_t *iop;
+
+ /*
+ * If this file descriptor is mapped to an external set of handlers,
+ * then pass the request on to them.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) ) {
+ rtems_libio_ioctl_t fp;
+
+ fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].ioctl;
+ if ( fp == NULL )
+ set_errno_and_return_minus_one( EBADF );
+
+ return (*fp)( fd, command, buffer );
+ }
+
+ /*
+ * Now process the ioctl().
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+
+ if ( !iop->handlers->ioctl )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ rc = (*iop->handlers->ioctl)( iop, command, buffer );
+
+ return rc;
+}
diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c
index 12682c1190..e63a4626d4 100644
--- a/cpukit/libcsupport/src/libio.c
+++ b/cpukit/libcsupport/src/libio.c
@@ -1,524 +1,295 @@
/*
- * Provide UNIX/POSIX-like io system calls for RTEMS using the
- * RTEMS IO manager
+ * This file contains the support infrastructure used to manage the
+ * table of integer style file descriptors used by the low level
+ * POSIX system calls like open(), read, fstat(), etc.
+ *
+ * This provides the foundation for POSIX compliant IO system calls
+ * for RTEMS.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
-#include <rtems.h>
-#include <rtems/assoc.h> /* assoc.h not included by rtems.h */
-
-#include <stdio.h> /* O_RDONLY, et.al. */
-#include <fcntl.h> /* O_RDONLY, et.al. */
-#include <assert.h>
-
-#if ! defined(O_NDELAY)
-# if defined(solaris2)
-# define O_NDELAY O_NONBLOCK
-# elif defined(RTEMS_NEWLIB)
-# define O_NDELAY _FNBIO
-# endif
-#endif
-
-
-#include <errno.h>
-#include <string.h> /* strcmp */
-#include <unistd.h>
-#include <stdlib.h> /* calloc() */
-
-#include "libio.h" /* libio.h not pulled in by rtems */
+#include "libio_.h" /* libio_.h pulls in rtems */
/*
- * Semaphore to protect the io table
+ * Global variables used to manage the File Descriptor Table.
+ * IOP = IO Pointer.
*/
-Objects_Id rtems_libio_semaphore;
-
-#define RTEMS_LIBIO_SEM rtems_build_name('L', 'B', 'I', 'O')
-#define RTEMS_LIBIO_IOP_SEM(n) rtems_build_name('L', 'B', 'I', n)
-
-extern unsigned32 rtems_libio_number_iops;
-rtems_libio_t *rtems_libio_iops;
-rtems_libio_t *rtems_libio_last_iop;
-
-#define rtems_libio_iop(fd) ((((unsigned32)(fd)) < rtems_libio_number_iops) ? \
- &rtems_libio_iops[fd] : 0)
-
-#define rtems_libio_check_fd(fd) \
- do { \
- if ((unsigned32) (fd) >= rtems_libio_number_iops) \
- { \
- errno = EBADF; \
- return -1; \
- } \
- } while (0)
-
-#define rtems_libio_check_buffer(buffer) \
- do { \
- if ((buffer) == 0) \
- { \
- errno = EINVAL; \
- return -1; \
- } \
- } while (0)
-
-#define rtems_libio_check_count(count) \
- do { \
- if ((count) == 0) \
- { \
- return 0; \
- } \
- } while (0)
-
-#define rtems_libio_check_permissions(iop, flag) \
- do { \
- if (((iop)->flags & (flag)) == 0) \
- { \
- errno = EINVAL; \
- return -1; \
- } \
- } while (0)
+rtems_id rtems_libio_semaphore;
+rtems_libio_t *rtems_libio_iops;
+rtems_libio_t *rtems_libio_last_iop;
+rtems_libio_handler_t rtems_libio_handlers[15];
/*
- * External I/O handlers
- *
- * Space for all possible handlers is preallocated
- * to speed up dispatch to external handlers.
+ * rtems_register_libio_handler
+ *
+ * This function registers an external IO handler set. This lets
+ * other subsystems have their own versions of many of the system
+ * calls. For example, the networking code registers handlers which
+ * map the system calls for read() and write() to socket calls.
+ *
*/
-static rtems_libio_handler_t handlers[15];
-
-void
-rtems_register_libio_handler(
- int handler_flag,
- const rtems_libio_handler_t *handler
+void rtems_register_libio_handler(
+ int handler_flag,
+ const rtems_libio_handler_t *handler
)
{
- int handler_index = rtems_file_descriptor_type_index(handler_flag);
+ int handler_index = rtems_file_descriptor_type_index( handler_flag );
+
if ((handler_index < 0) || (handler_index >= 15))
rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
- handlers[handler_index] = *handler;
-}
-
-/*
- * Called by bsp startup code to init the libio area.
- */
-void
-rtems_libio_init(void)
-{
- rtems_status_code rc;
-
- if (rtems_libio_number_iops > 0)
- {
- rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
- sizeof(rtems_libio_t));
- if (rtems_libio_iops == NULL)
- rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
-
- rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1);
- }
-
- rc = rtems_semaphore_create(
- RTEMS_LIBIO_SEM,
- 1,
- RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
- RTEMS_NO_PRIORITY,
- &rtems_libio_semaphore
- );
- if (rc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred(rc);
+ rtems_libio_handlers[handler_index] = *handler;
}
/*
- * Convert RTEMS status to a UNIX errno
+ * rtems_libio_init
+ *
+ * Called by BSP startup code to initialize the libio subsystem.
*/
-rtems_assoc_t errno_assoc[] = {
- { "OK", RTEMS_SUCCESSFUL, 0 },
- { "BUSY", RTEMS_RESOURCE_IN_USE, EBUSY },
- { "INVALID NAME", RTEMS_INVALID_NAME, EINVAL },
- { "NOT IMPLEMENTED", RTEMS_NOT_IMPLEMENTED, ENOSYS },
- { "TIMEOUT", RTEMS_TIMEOUT, ETIMEDOUT },
- { "NO MEMORY", RTEMS_NO_MEMORY, ENOMEM },
- { "NO DEVICE", RTEMS_UNSATISFIED, ENODEV },
- { "INVALID NUMBER", RTEMS_INVALID_NUMBER, EBADF},
- { "NOT RESOURCE OWNER", RTEMS_NOT_OWNER_OF_RESOURCE, EPERM},
- { "IO ERROR", RTEMS_IO_ERROR, EIO},
- { 0, 0, 0 },
-};
-
-static unsigned32
-rtems_libio_errno(rtems_status_code code)
+void rtems_libio_init( void )
{
- int rc;
-
- if ((rc = rtems_assoc_remote_by_local(errno_assoc, (unsigned32) code)))
- {
- errno = rc;
- return -1;
- }
- return -1;
+ rtems_status_code rc;
+
+ /*
+ * Allocate memory for the IOP Table
+ */
+
+ if ( rtems_libio_number_iops > 0 ) {
+ rtems_libio_iops =
+ (rtems_libio_t *) calloc(rtems_libio_number_iops, sizeof(rtems_libio_t));
+
+ if (rtems_libio_iops == NULL)
+ rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
+
+ rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1);
+ }
+
+ /*
+ * Create the binary semaphore used to provide mutual exclusion
+ * on the IOP Table.
+ */
+
+ rc = rtems_semaphore_create(
+ RTEMS_LIBIO_SEM,
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &rtems_libio_semaphore
+ );
+ if ( rc != RTEMS_SUCCESSFUL )
+ rtems_fatal_error_occurred( rc );
+
+ /*
+ * Initialize the base file system infrastructure.
+ */
+
+ rtems_filesystem_initialize();
}
/*
- * Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
+ * rtems_libio_fcntl_flags
+ *
+ * Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
*/
rtems_assoc_t access_modes_assoc[] = {
- { "READ", LIBIO_FLAGS_READ, O_RDONLY },
- { "WRITE", LIBIO_FLAGS_WRITE, O_WRONLY },
- { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
- { 0, 0, 0 },
+ { "READ", LIBIO_FLAGS_READ, O_RDONLY },
+ { "WRITE", LIBIO_FLAGS_WRITE, O_WRONLY },
+ { "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
+ { 0, 0, 0 },
};
rtems_assoc_t status_flags_assoc[] = {
- { "NO DELAY", LIBIO_FLAGS_NO_DELAY, O_NDELAY },
- { "APPEND", LIBIO_FLAGS_APPEND, O_APPEND },
- { "CREATE", LIBIO_FLAGS_CREATE, O_CREAT },
- { 0, 0, 0 },
+ { "NO DELAY", LIBIO_FLAGS_NO_DELAY, O_NDELAY },
+ { "APPEND", LIBIO_FLAGS_APPEND, O_APPEND },
+ { "CREATE", LIBIO_FLAGS_CREATE, O_CREAT },
+ { 0, 0, 0 },
};
-static unsigned32
-rtems_libio_fcntl_flags(unsigned32 fcntl_flags)
+unsigned32 rtems_libio_fcntl_flags(
+ unsigned32 fcntl_flags
+)
{
- unsigned32 flags = 0;
- unsigned32 access_modes;
+ unsigned32 flags = 0;
+ unsigned32 access_modes;
- /*
- * Access mode is a small integer
- */
-
- access_modes = fcntl_flags & O_ACCMODE;
- fcntl_flags &= ~O_ACCMODE;
- flags = rtems_assoc_local_by_remote(access_modes_assoc, access_modes);
+ /*
+ * Access mode is a small integer
+ */
+
+ access_modes = fcntl_flags & O_ACCMODE;
+ fcntl_flags &= ~O_ACCMODE;
+ flags = rtems_assoc_local_by_remote( access_modes_assoc, access_modes );
- /*
- * Everything else is single bits
- */
+ /*
+ * Everything else is single bits
+ */
- flags |= rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
- return flags;
+ flags |=
+ rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
+ return flags;
}
+/*
+ * rtems_libio_allocate
+ *
+ * This routine searches the IOP Table for an unused entry. If it
+ * finds one, it returns it. Otherwise, it returns NULL.
+ */
-static rtems_libio_t *
-rtems_libio_allocate(void)
+rtems_libio_t *rtems_libio_allocate( void )
{
- rtems_libio_t *iop;
- rtems_status_code rc;
-
- rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
-
- for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++)
- if ((iop->flags & LIBIO_FLAGS_OPEN) == 0)
- {
- /*
- * Got one; create a semaphore for it
- */
-
- rc = rtems_semaphore_create(
- RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
- 1,
- RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
- RTEMS_NO_PRIORITY,
- &iop->sem
- );
- if (rc != RTEMS_SUCCESSFUL)
- goto failed;
-
- iop->flags = LIBIO_FLAGS_OPEN;
- goto done;
- }
+ rtems_libio_t *iop;
+ rtems_status_code rc;
+
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+
+ for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++)
+ if ((iop->flags & LIBIO_FLAGS_OPEN) == 0) {
+ /*
+ * Got an IOP -- create a semaphore for it.
+ */
+
+ rc = rtems_semaphore_create(
+ RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
+ RTEMS_NO_PRIORITY,
+ &iop->sem
+ );
+ if ( rc != RTEMS_SUCCESSFUL )
+ goto failed;
+ iop->flags = LIBIO_FLAGS_OPEN;
+ goto done;
+ }
+
failed:
- iop = 0;
-
+ iop = 0;
+
done:
- rtems_semaphore_release(rtems_libio_semaphore);
- return iop;
+ rtems_semaphore_release( rtems_libio_semaphore );
+ return iop;
}
-static void
-rtems_libio_free(rtems_libio_t *iop)
-{
- rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
-
- if (iop->sem)
- rtems_semaphore_delete(iop->sem);
- (void) memset(iop, 0, sizeof(*iop));
-
- rtems_semaphore_release(rtems_libio_semaphore);
-}
+/*
+ * rtems_libio_free
+ *
+ * This routine frees the resources associated with an IOP (file descriptor)
+ * and clears the slot in the IOP Table.
+ */
-int
-__rtems_open(
- const char *pathname,
- unsigned32 flag,
- unsigned32 mode)
+void rtems_libio_free(
+ rtems_libio_t *iop
+)
{
- rtems_status_code rc;
- rtems_libio_t *iop = 0;
- rtems_driver_name_t *np;
- rtems_libio_open_close_args_t args;
-
- /*
- * Additional external I/O handlers would be supported by
- * adding code to pick apart the pathname appropriately.
- * The networking code does not require changes here since
- * network file descriptors are obtained using socket(), not
- * open().
- */
-
- if ((rc = rtems_io_lookup_name(pathname, &np)) != RTEMS_SUCCESSFUL)
- goto done;
-
- iop = rtems_libio_allocate();
- if (iop == 0)
- {
- rc = RTEMS_TOO_MANY;
- goto done;
- }
-
- iop->driver = np;
- iop->pathname = (char *) pathname;
- iop->flags |= rtems_libio_fcntl_flags(flag);
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
- args.iop = iop;
- args.flags = iop->flags;
- args.mode = mode;
+ if (iop->sem)
+ rtems_semaphore_delete(iop->sem);
- rc = rtems_io_open(np->major, np->minor, (void *) &args);
-
-done:
-
- if (rc != RTEMS_SUCCESSFUL)
- {
- if (iop)
- rtems_libio_free(iop);
- return rtems_libio_errno(rc);
- }
-
- return iop - rtems_libio_iops;
-}
-
-int
-__rtems_close(
- int fd
- )
-{
- rtems_status_code rc;
- rtems_driver_name_t *np;
- rtems_libio_t *iop;
- rtems_libio_open_close_args_t args;
- int status;
-
- if (rtems_file_descriptor_type(fd)) {
- int (*fp)(int fd);
-
- fp = handlers[rtems_file_descriptor_type_index(fd)].close;
- if (fp == NULL) {
- errno = EBADF;
- return -1;
- }
- status = (*fp)(fd);
- return status;
- }
- iop = rtems_libio_iop(fd);
- rtems_libio_check_fd(fd);
+ (void) memset(iop, 0, sizeof(*iop));
- np = iop->driver;
-
- args.iop = iop;
- args.flags = 0;
- args.mode = 0;
-
- rc = rtems_io_close(np->major, np->minor, (void *) &args);
+ rtems_semaphore_release( rtems_libio_semaphore );
+}
- rtems_libio_free(iop);
+/*
+ * rtems_libio_is_open_files_in_fs
+ *
+ * This routine scans the entire file descriptor table to determine if the
+ * are any active file descriptors that refer to the atleast one node in the
+ * file system that we are trying to dismount.
+ *
+ * If there is at least one node in the file system referenced by the mount
+ * table entry a 1 is returned, otherwise a 0 is returned.
+ */
- if (rc != RTEMS_SUCCESSFUL)
- return rtems_libio_errno(rc);
- return 0;
-}
-
-int
-__rtems_read(
- int fd,
- void * buffer,
- unsigned32 count
- )
+int rtems_libio_is_open_files_in_fs(
+ rtems_filesystem_mount_table_entry_t * fs_mt_entry
+)
{
- rtems_status_code rc;
- rtems_driver_name_t *np;
- rtems_libio_t *iop;
- rtems_libio_rw_args_t args;
-
- if (rtems_file_descriptor_type(fd)) {
- int (*fp)(int fd, void *buffer, unsigned32 count);
-
- fp = handlers[rtems_file_descriptor_type_index(fd)].read;
- if (fp == NULL) {
- errno = EBADF;
- return -1;
- }
- return (*fp)(fd, buffer, count);
- }
- iop = rtems_libio_iop(fd);
- rtems_libio_check_fd(fd);
- rtems_libio_check_buffer(buffer);
- rtems_libio_check_count(count);
- rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
+ rtems_libio_t *iop;
+ int result = 0;
- np = iop->driver;
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
- args.iop = iop;
- args.offset = iop->offset;
- args.buffer = buffer;
- args.count = count;
- args.flags = iop->flags;
- args.bytes_moved = 0;
+ /*
+ * Look for any active file descriptor entry.
+ */
- rc = rtems_io_read(np->major, np->minor, (void *) &args);
+ for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) {
- iop->offset += args.bytes_moved;
+ if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
- if (rc != RTEMS_SUCCESSFUL)
- return rtems_libio_errno(rc);
+ /*
+ * Check if this node is under the file system that we
+ * are trying to dismount.
+ */
- return args.bytes_moved;
-}
-
-int
-__rtems_write(
- int fd,
- const void *buffer,
- unsigned32 count
- )
-{
- rtems_status_code rc;
- rtems_driver_name_t *np;
- rtems_libio_t *iop;
- rtems_libio_rw_args_t args;
-
- if (rtems_file_descriptor_type(fd)) {
- int (*fp)(int fd, const void *buffer, unsigned32 count);
-
- fp = handlers[rtems_file_descriptor_type_index(fd)].write;
- if (fp == NULL) {
- errno = EBADF;
- return -1;
- }
- return (*fp)(fd, buffer, count);
+ if ( iop->pathinfo.mt_entry == fs_mt_entry ) {
+ result = 1;
+ break;
+ }
}
- iop = rtems_libio_iop(fd);
- rtems_libio_check_fd(fd);
- rtems_libio_check_buffer(buffer);
- rtems_libio_check_count(count);
- rtems_libio_check_permissions(iop, LIBIO_FLAGS_WRITE);
-
- np = iop->driver;
-
- args.iop = iop;
- args.offset = iop->offset;
- args.buffer = (void *) buffer;
- args.count = count;
- args.flags = iop->flags;
- args.bytes_moved = 0;
-
- rc = rtems_io_write(np->major, np->minor, (void *) &args);
+ }
- iop->offset += args.bytes_moved;
+ rtems_semaphore_release( rtems_libio_semaphore );
- if (rc != RTEMS_SUCCESSFUL)
- return rtems_libio_errno(rc);
-
- return args.bytes_moved;
+ return result;
}
-int
-__rtems_ioctl(
- int fd,
- unsigned32 command,
- void * buffer)
-{
- rtems_status_code rc;
- rtems_driver_name_t *np;
- rtems_libio_t *iop;
- rtems_libio_ioctl_args_t args;
-
- if (rtems_file_descriptor_type(fd)) {
- int (*fp)(int fd, unsigned32 command, void *buffer);
-
- fp = handlers[rtems_file_descriptor_type_index(fd)].ioctl;
- if (fp == NULL) {
- errno = EBADF;
- return -1;
- }
- return (*fp)(fd, command, buffer);
- }
- iop = rtems_libio_iop(fd);
- rtems_libio_check_fd(fd);
+/*
+ * rtems_libio_is_file_open
+ *
+ * This routine scans the entire file descriptor table to determine if the
+ * given file refers to an active file descriptor.
+ *
+ * If the given file is open a 1 is returned, otherwise a 0 is returned.
+ */
- np = iop->driver;
+int rtems_libio_is_file_open(
+ void *node_access
+)
+{
+ rtems_libio_t *iop;
+ int result=0;
- args.iop = iop;
- args.command = command;
- args.buffer = buffer;
+ rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
- rc = rtems_io_control(np->major, np->minor, (void *) &args);
+ /*
+ * Look for any active file descriptor entry.
+ */
- if (rc != RTEMS_SUCCESSFUL)
- return rtems_libio_errno(rc);
+ for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) {
- return args.ioctl_return;
-}
-
-/*
- * internal only??
- */
+ if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) {
+ /*
+ * Check if this node is under the file system that we
+ * are trying to dismount.
+ */
-int
-__rtems_lseek(
- int fd,
- rtems_libio_offset_t offset,
- int whence
- )
-{
- rtems_libio_t *iop;
+ if ( iop->pathinfo.node_access == node_access ) {
+ result = 1;
+ break;
+ }
+ }
+ }
- if (rtems_file_descriptor_type(fd)) {
- int (*fp)(int fd, rtems_libio_offset_t offset, int whence);
+ rtems_semaphore_release( rtems_libio_semaphore );
- fp = handlers[rtems_file_descriptor_type_index(fd)].lseek;
- if (fp == NULL) {
- errno = EBADF;
- return -1;
- }
- return (*fp)(fd, offset, whence);
- }
- iop = rtems_libio_iop(fd);
- rtems_libio_check_fd(fd);
-
- switch (whence)
- {
- case SEEK_SET:
- iop->offset = offset;
- break;
-
- case SEEK_CUR:
- iop->offset += offset;
- break;
-
- case SEEK_END:
- iop->offset = iop->size - offset;
- break;
-
- default:
- errno = EINVAL;
- return -1;
- }
- return 0;
+ return result;
}
diff --git a/cpukit/libcsupport/src/link.c b/cpukit/libcsupport/src/link.c
new file mode 100644
index 0000000000..1cee54d0bf
--- /dev/null
+++ b/cpukit/libcsupport/src/link.c
@@ -0,0 +1,60 @@
+/*
+ * link() - POSIX 1003.1b - 5.3.4 - Create a new link
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <errno.h>
+
+#include "libio_.h"
+
+int link(
+ const char *existing,
+ const char *new
+)
+{
+ rtems_filesystem_location_info_t existing_loc;
+ rtems_filesystem_location_info_t parent_loc;
+ int i;
+ int result;
+ const char *name_start;
+
+ /*
+ * Get the node we are linking to.
+ */
+ result = rtems_filesystem_evaluate_path( existing, 0, &existing_loc, TRUE );
+ if ( result != 0 )
+ return -1;
+
+ /*
+ * Get the parent of the node we are creating.
+ */
+
+ rtems_filesystem_get_start_loc( new, &i, &parent_loc );
+ result = (*parent_loc.ops->evalformake)( &new[i], &parent_loc, &name_start );
+ if ( result != 0 )
+ set_errno_and_return_minus_one( result );
+
+ /*
+ * Check to see if the caller is trying to link across file system
+ * boundaries.
+ */
+
+ if ( parent_loc.mt_entry != existing_loc.mt_entry )
+ set_errno_and_return_minus_one( EXDEV );
+
+ if ( !parent_loc.ops->link )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*parent_loc.ops->link)( &existing_loc, &parent_loc, name_start );
+}
diff --git a/cpukit/libcsupport/src/lseek.c b/cpukit/libcsupport/src/lseek.c
new file mode 100644
index 0000000000..514f8cd912
--- /dev/null
+++ b/cpukit/libcsupport/src/lseek.c
@@ -0,0 +1,93 @@
+/*
+ * lseek() - POSIX 1003.1b 6.5.3 - Reposition Read/Write File Offset
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+
+#include "libio_.h"
+
+off_t lseek(
+ int fd,
+ off_t offset,
+ int whence
+)
+{
+ rtems_libio_t *iop;
+
+ /*
+ * If this file descriptor is mapped to an external set of handlers,
+ * then pass the request on to them.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) ) {
+ rtems_libio_lseek_t fp;
+
+ fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].lseek;
+ if ( fp == NULL )
+ set_errno_and_return_minus_one( EBADF );
+
+ return (*fp)( fd, offset, whence );
+ }
+
+ /*
+ * Now process the lseek().
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+
+ switch ( whence ) {
+ case SEEK_SET:
+ iop->offset = offset;
+ break;
+
+ case SEEK_CUR:
+ iop->offset += offset;
+ break;
+
+ case SEEK_END:
+ iop->offset = iop->size - offset;
+ break;
+
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ( !iop->handlers->lseek )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*iop->handlers->lseek)( iop, offset, whence );
+}
+
+/*
+ * _lseek_r
+ *
+ * This is the Newlib dependent reentrant version of lseek().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+off_t _lseek_r(
+ struct _reent *ptr,
+ int fd,
+ off_t offset,
+ int whence
+)
+{
+ return lseek( fd, offset, whence );
+}
+#endif
+
diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c
index fac38585a7..f164e45f6c 100644
--- a/cpukit/libcsupport/src/malloc.c
+++ b/cpukit/libcsupport/src/malloc.c
@@ -135,7 +135,7 @@ void RTEMS_Malloc_Initialize(
#ifdef MALLOC_STATS
/* zero all the stats */
- (void) memset(&rtems_malloc_stats, 0, sizeof(rtems_malloc_stats));
+ (void) memset( &rtems_malloc_stats, 0, sizeof(rtems_malloc_stats) );
#endif
MSBUMP(space_available, length);
@@ -220,9 +220,11 @@ void *malloc(
{
unsigned32 actual_size;
unsigned32 current_depth;
- status = rtems_region_get_segment_size(RTEMS_Malloc_Heap, return_this, &actual_size);
+ status = rtems_region_get_segment_size(
+ RTEMS_Malloc_Heap, return_this, &actual_size);
MSBUMP(lifetime_allocated, actual_size);
- current_depth = rtems_malloc_stats.lifetime_allocated - rtems_malloc_stats.lifetime_freed;
+ current_depth = rtems_malloc_stats.lifetime_allocated -
+ rtems_malloc_stats.lifetime_freed;
if (current_depth > rtems_malloc_stats.max_depth)
rtems_malloc_stats.max_depth = current_depth;
}
@@ -335,10 +337,12 @@ void free(
void malloc_dump(void)
{
- unsigned32 allocated = rtems_malloc_stats.lifetime_allocated - rtems_malloc_stats.lifetime_freed;
+ unsigned32 allocated = rtems_malloc_stats.lifetime_allocated -
+ rtems_malloc_stats.lifetime_freed;
printf("Malloc stats\n");
- printf(" avail:%uk allocated:%uk (%d%%) max:%uk (%d%%) lifetime:%Luk freed:%Luk\n",
+ printf(" avail:%uk allocated:%uk (%d%%) "
+ "max:%uk (%d%%) lifetime:%Luk freed:%Luk\n",
(unsigned int) rtems_malloc_stats.space_available / 1024,
(unsigned int) allocated / 1024,
/* avoid float! */
diff --git a/cpukit/libcsupport/src/mkdir.c b/cpukit/libcsupport/src/mkdir.c
new file mode 100644
index 0000000000..18fc7171c7
--- /dev/null
+++ b/cpukit/libcsupport/src/mkdir.c
@@ -0,0 +1,28 @@
+/*
+ * mkdir() - POSIX 1003.1b 5.4.1 - Make a Directory
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+int mkdir(
+ const char *pathname,
+ mode_t mode
+)
+{
+ return mknod( pathname, mode | S_IFDIR, 0LL);
+}
+
diff --git a/cpukit/libcsupport/src/mkfifo.c b/cpukit/libcsupport/src/mkfifo.c
new file mode 100644
index 0000000000..6b3ece5650
--- /dev/null
+++ b/cpukit/libcsupport/src/mkfifo.c
@@ -0,0 +1,25 @@
+/*
+ * mkfifo() - POSIX 1003.1b 5.4.1 - Make a FIFO Special File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+int mkfifo(
+ const char *path,
+ mode_t mode
+)
+{
+ return mknod( path, mode | S_IFIFO, 0LL );
+}
diff --git a/cpukit/libcsupport/src/mknod.c b/cpukit/libcsupport/src/mknod.c
new file mode 100644
index 0000000000..4f83321ecd
--- /dev/null
+++ b/cpukit/libcsupport/src/mknod.c
@@ -0,0 +1,60 @@
+/*
+ * mknod()
+ *
+ * This routine is not defined in the POSIX 1003.1b standard but is
+ * commonly supported on most UNIX and POSIX systems. It is the
+ * foundation for creating file system objects.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "libio_.h"
+
+int mknod(
+ const char *pathname,
+ mode_t mode,
+ dev_t dev
+)
+{
+ rtems_filesystem_location_info_t temp_loc;
+ int i;
+ const char *name_start;
+ int result;
+
+ if ( !(mode & (S_IFREG|S_IFCHR|S_IFBLK|S_IFIFO) ) )
+ set_errno_and_return_minus_one( EINVAL );
+
+ if ( S_ISFIFO(mode) )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ rtems_filesystem_get_start_loc( pathname, &i, &temp_loc );
+
+ result = (*temp_loc.ops->evalformake)(
+ &pathname[i],
+ &temp_loc,
+ &name_start
+ );
+ if ( result != 0 )
+ return -1;
+
+ if ( !temp_loc.ops->mknod )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*temp_loc.ops->mknod)( name_start, mode, dev, &temp_loc );
+}
diff --git a/cpukit/libcsupport/src/mount.c b/cpukit/libcsupport/src/mount.c
new file mode 100644
index 0000000000..fa8cebc3f9
--- /dev/null
+++ b/cpukit/libcsupport/src/mount.c
@@ -0,0 +1,299 @@
+/*
+ * mount()
+ *
+ * XXX
+ *
+ * XXX make sure no required ops are NULL
+ * XXX make sure no optional ops you are using are NULL
+ * XXX unmount should be required.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <chain.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "libio_.h"
+
+Chain_Control rtems_filesystem_mount_table_control;
+
+
+rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS = {
+ 5, /* link_max */
+ 6, /* max_canon */
+ 7, /* max_input */
+ 255, /* name_max */
+ 255, /* path_max */
+ 2, /* pipe_buf */
+ 1, /* posix_async_io */
+ 2, /* posix_chown_restrictions */
+ 3, /* posix_no_trunc */
+ 4, /* posix_prio_io */
+ 5, /* posix_sync_io */
+ 6 /* posix_vdisable */
+};
+
+/*
+ * XXX
+ */
+
+int search_mt_for_mount_point(
+ rtems_filesystem_location_info_t *location_of_mount_point
+);
+
+
+rtems_filesystem_options_t get_file_system_options(
+ char *fsoptions
+);
+
+int init_fs_mount_table( void );
+
+
+/*
+ * XXX
+ */
+
+#define FOUND 0
+#define NOT_FOUND -1
+
+/*
+ * mount
+ *
+ * This routine will attempt to mount a new file system at the specified
+ * mount point. A series of tests will be run to determine if any of the
+ * following reasons exist to prevent the mount operation:
+ *
+ * 1) The file system type or options are not valid
+ * 2) No new file system root node is specified
+ * 3) The selected file system has already been mounted
+ * 4) The mount point exists with the proper permissions to allow mounting
+ * 5) The selected mount point already has a file system mounted to it
+ *
+ */
+
+int mount(
+ rtems_filesystem_mount_table_entry_t **mt_entry,
+ rtems_filesystem_operations_table *fs_ops,
+ char *fsoptions,
+ char *device,
+ char *mount_point
+)
+{
+ rtems_filesystem_location_info_t temp_loc;
+ rtems_filesystem_options_t options;
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry;
+
+/* XXX add code to check for required operations */
+
+ /*
+ * Are the file system options valid?
+ */
+
+ options = get_file_system_options( fsoptions );
+ if ( options == RTEMS_FILESYSTEM_BAD_OPTIONS ){
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Is the file system type valid?
+ */
+
+ if ( fs_ops == NULL ){
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Allocate a mount table entry
+ */
+
+ temp_mt_entry = malloc( sizeof(rtems_filesystem_mount_table_entry_t) );
+
+ temp_mt_entry->mt_fs_root.mt_entry = temp_mt_entry;
+ temp_mt_entry->options = options;
+ if( device )
+ sprintf( temp_mt_entry->dev, "%s", device );
+ else
+ temp_mt_entry->dev = 0;
+
+ /*
+ * The mount_point should be a directory with read/write/execute
+ * permissions in the existing tree.
+ */
+
+ if ( mount_point ) {
+ if ( rtems_filesystem_evaluate_path(
+ mount_point,
+ RTEMS_LIBIO_PERMS_RWX,
+ &temp_loc ,
+ TRUE ) == -1 )
+ goto cleanup_and_bail;
+
+ /*
+ * Test to see if it is a directory
+ */
+
+ if ( temp_loc.ops->node_type( &temp_loc ) != RTEMS_FILESYSTEM_DIRECTORY ){
+ errno = ENOTDIR;
+ goto cleanup_and_bail;
+ }
+
+ /*
+ * You can only mount one file system onto a single mount point.
+ */
+
+ if ( search_mt_for_mount_point( &temp_loc ) == FOUND ){
+ errno = EBUSY;
+ goto cleanup_and_bail;
+ }
+
+ /*
+ * This must be a good mount point, so move the location information
+ * into the allocated mount entry
+ */
+
+ temp_mt_entry->mt_point_node.node_access = temp_loc.node_access;
+ temp_mt_entry->mt_point_node.handlers = temp_loc.handlers;
+ temp_mt_entry->mt_point_node.ops = temp_loc.ops;
+ temp_mt_entry->mt_point_node.mt_entry = temp_loc.mt_entry;
+
+ /*
+ * This link to the parent is only done when we are dealing with system
+ * below the base file system
+ */
+
+ if ( !temp_loc.ops->mount ){
+ errno = ENOTSUP;
+ goto cleanup_and_bail;
+ }
+
+ if ( temp_loc.ops->mount( temp_mt_entry ) ) {
+ goto cleanup_and_bail;
+ }
+ }
+ else {
+
+ /*
+ * This is a mount of the base file system --> The
+ * mt_point_node.node_access will be set to null to indicate that this
+ * is the root of the entire file system.
+ */
+
+ temp_mt_entry->mt_fs_root.node_access = NULL;
+ temp_mt_entry->mt_fs_root.handlers = NULL;
+ temp_mt_entry->mt_fs_root.ops = NULL;
+
+ temp_mt_entry->mt_point_node.node_access = NULL;
+ temp_mt_entry->mt_point_node.handlers = NULL;
+ temp_mt_entry->mt_point_node.ops = NULL;
+ temp_mt_entry->mt_point_node.mt_entry = NULL;
+ }
+
+ if ( !fs_ops->fsmount_me ){
+ errno = ENOTSUP;
+ goto cleanup_and_bail;
+ }
+
+ if ( fs_ops->fsmount_me( temp_mt_entry ) )
+ goto cleanup_and_bail;
+
+ /*
+ * Add the mount table entry to the mount table chain
+ */
+
+ Chain_Append( &rtems_filesystem_mount_table_control, &temp_mt_entry->Node );
+
+ *mt_entry = temp_mt_entry;
+ return 0;
+
+cleanup_and_bail:
+
+ free( temp_mt_entry );
+ return -1;
+}
+
+
+
+/*
+ * init_fs_mount_table
+ *
+ * This routine will initialize the chain control element that manages the
+ * mount table chain.
+ */
+
+int init_fs_mount_table()
+{
+ Chain_Initialize_empty ( &rtems_filesystem_mount_table_control );
+ return 0;
+}
+
+/*
+ * get_file_system_options
+ *
+ * This routine will determine is the text string that represents the options
+ * that are to be used to mount the file system are actually valid. If the
+ * options are valid the appropriate file system options type will be returned
+ * to the calling routine.
+ */
+
+rtems_filesystem_options_t get_file_system_options(
+ char *fsoptions
+)
+{
+ if ( strcmp( "RO", strupr( fsoptions ) ) == 0 )
+ return RTEMS_FILESYSTEM_READ_ONLY;
+ if ( strcmp( "RW", strupr( fsoptions ) ) == 0 )
+ return RTEMS_FILESYSTEM_READ_WRITE_ONLY;
+ else
+ return RTEMS_FILESYSTEM_BAD_OPTIONS;
+}
+
+
+
+/*
+ * search_mt_for_mount_point
+ *
+ * This routine will run through the entries that currently exist in the
+ * mount table chain. For each entry in the mount table chain it will
+ * compare the mount tables mt_point_node to the node describing the selected
+ * mount point.. If any of the mount table file system mount point nodes
+ * match the new file system selected mount point node, we are attempting
+ * to mount the new file system onto a node that already has a file system
+ * mounted to it. This is not a permitted operation.
+ */
+
+int search_mt_for_mount_point(
+ rtems_filesystem_location_info_t *location_of_mount_point
+)
+{
+ Chain_Node *the_node;
+ rtems_filesystem_mount_table_entry_t *the_mount_entry;
+
+ for ( the_node = rtems_filesystem_mount_table_control.first;
+ !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
+ the_node = the_node->next ) {
+
+ the_mount_entry = (rtems_filesystem_mount_table_entry_t *) the_node;
+ if ( the_mount_entry->mt_point_node.node_access ==
+ location_of_mount_point->node_access )
+ return FOUND;
+ }
+ return NOT_FOUND;
+}
+
diff --git a/cpukit/libcsupport/src/newlibc.c b/cpukit/libcsupport/src/newlibc.c
index a6acc1c8d7..bea592a46e 100644
--- a/cpukit/libcsupport/src/newlibc.c
+++ b/cpukit/libcsupport/src/newlibc.c
@@ -1,21 +1,14 @@
-
/*
+ * Implementation of hooks for the CYGNUS newlib libc
+ * These hooks set things up so that:
+ * + '_REENT' is switched at task switch time.
+ *
* COPYRIGHT (c) 1994 by Division Incorporated
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
- * Description:
- * Implementation of hooks for the CYGNUS newlib libc
- * These hooks set things up so that:
- * '_REENT' is switched at task switch time.
- *
- *
- * TODO:
- *
- * NOTE:
- *
* $Id$
*
*/
@@ -47,7 +40,21 @@
#include <stdio.h>
#endif
-#include "internal.h"
+/*
+ * Private routines
+ */
+
+void MY_task_set_note(
+ rtems_tcb *tcb,
+ rtems_unsigned32 notepad,
+ rtems_unsigned32 note
+);
+
+rtems_unsigned32 MY_task_get_note(
+ rtems_tcb *tcb,
+ rtems_unsigned32 notepad
+);
+
#define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST
@@ -304,7 +311,7 @@ libc_init(int reentrant)
rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'),
&libc_extension, &extension_id);
if (rc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred(rc);
+ rtems_fatal_error_occurred( rc );
libc_reentrant = reentrant;
}
@@ -353,11 +360,14 @@ int get_errno()
/* #if !defined(RTEMS_UNIX) && !defined(__GO32__) && !defined(_AM29K) */
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
+#if !defined(pc386)
void _exit(int status)
{
libc_wrapup(); /* Why? XXX */
rtems_shutdown_executive(status);
}
+#endif
+
#else
void exit(int status)
@@ -426,4 +436,46 @@ unsigned int sleep(
#endif
+/*
+ * Newlib Interface Support
+ *
+ * Routines to Access Internal RTEMS Resources without violating
+ * kernel visibility.
+ *
+ */
+
+void MY_task_set_note(
+ Thread_Control *the_thread,
+ unsigned32 notepad,
+ unsigned32 note
+)
+{
+ RTEMS_API_Control *api;
+
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+
+ if ( api )
+ api->Notepads[ notepad ] = note;
+}
+
+
+unsigned32 MY_task_get_note(
+ Thread_Control *the_thread,
+ unsigned32 notepad
+)
+{
+ RTEMS_API_Control *api;
+
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+
+ return api->Notepads[ notepad ];
+}
+
+void *MY_CPU_Context_FP_start(
+ void *base,
+ unsigned32 offset
+)
+{
+ return _CPU_Context_Fp_start( base, offset );
+}
#endif
diff --git a/cpukit/libcsupport/src/no_libc.c b/cpukit/libcsupport/src/no_libc.c
index 5a58ba761c..4bd02c4b27 100644
--- a/cpukit/libcsupport/src/no_libc.c
+++ b/cpukit/libcsupport/src/no_libc.c
@@ -1,6 +1,4 @@
-
-/* no_libc.h
- *
+/*
* This file contains stubs for the reentrancy hooks when
* an unknown C library is used.
*
@@ -17,15 +15,15 @@
#include <rtems.h>
-#if !defined(RTEMS_NEWLIB) && !defined(RTEMS_UNIX)
+#if !defined(RTEMS_NEWLIB) && !defined(RTEMS_UNIX)
#include "libcsupport.h"
-#include "internal.h"
#include <stdlib.h> /* for free() */
-void
-libc_init(int reentrant)
+void libc_init(
+ int reentrant
+)
{
}
@@ -34,11 +32,15 @@ void libc_suspend_main(void)
}
-void libc_global_exit(rtems_unsigned32 code)
+void libc_global_exit(
+ rtems_unsigned32 code
+)
{
}
-void _exit(int status)
+void _exit(
+ int status
+)
{
}
diff --git a/cpukit/libcsupport/src/open.c b/cpukit/libcsupport/src/open.c
new file mode 100644
index 0000000000..4cdf5acf35
--- /dev/null
+++ b/cpukit/libcsupport/src/open.c
@@ -0,0 +1,202 @@
+/*
+ * open() - POSIX 1003.1 5.3.1 - Open a File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include "libio_.h"
+
+#include <unistd.h>
+
+/*
+ * Returns file descriptor on success or -1 and errno set to one of the
+ * following:
+ *
+ * EACCESS - Seach permission is denied on a component of the path prefix,
+ * or the file exists and the permissions specified by the
+ * flags are denied, or the file does not exist and write
+ * permission is denied for the parent directory of the file
+ * to be created, or O_TRUNC is specified and write permission
+ * is denied.
+ * EEXIST - O_CREAT and O_EXCL are set and the named file exists.
+ * EINTR - The open( operation was interrupted by a signal.
+ * EINVAL - This implementation does not support synchronized IO for this
+ * file.
+ * EISDIR - The named file is a directory and the flags argument
+ * specified write or read/write access.
+ * EMFILE - Too many file descriptors are in used by this process.
+ * ENAMETOOLONG -
+ * The length of the path exceeds PATH_MAX or a pathname
+ * component is longer than NAME_MAX while POSIX_NO_TRUNC
+ * is in effect.
+ * ENFILE - Too many files are open in the system.
+ * ENOENT - O_CREAT is not set and and the anmed file does not exist,
+ * or O_CREAT is set and eitehr the path prefix does not exist
+ * or the path argument points to an empty string.
+ * ENOSPC - The directory or file system that would contain the new file
+ * cannot be extended.
+ * ENOTDIR - A component of the path prefix is not a directory.
+ * ENXIO - O_NONBLOCK is set, the named file is a FIFO, O_WRONLY is
+ * set, and no process has the file open for reading.
+ * EROFS - The named file resides on a read-only file system and either
+ * O_WRONLY, O_RDWR, O_CREAT (if the file does not exist), or
+ * O_TRUNC is set in the flags argument.
+ */
+
+int open(
+ const char *pathname,
+ int flags,
+ ...
+)
+{
+ va_list ap;
+ int mode;
+ int rc;
+ rtems_libio_t *iop = 0;
+ int status;
+ rtems_filesystem_location_info_t temp_loc;
+ int eval_flags;
+
+
+ /*
+ * Set the Evaluation flags
+ */
+
+ eval_flags = 0;
+ status = flags + 1;
+ if ( ( status & _FREAD ) == _FREAD )
+ eval_flags |= RTEMS_LIBIO_PERMS_READ;
+ if ( ( status & _FWRITE ) == _FWRITE )
+ eval_flags |= RTEMS_LIBIO_PERMS_WRITE;
+
+
+ va_start(ap, flags);
+
+ mode = va_arg( ap, int );
+
+ /*
+ * NOTE: This comment is OBSOLETE. The proper way to do this now
+ * would be to support a magic mounted file system.
+ *
+ * Additional external I/O handlers would be supported by adding
+ * code to pick apart the pathname appropriately. The networking
+ * code does not require changes here since network file
+ * descriptors are obtained using socket(), not open().
+ */
+
+ /* allocate a file control block */
+ iop = rtems_libio_allocate();
+ if ( iop == 0 ) {
+ rc = ENFILE;
+ goto done;
+ }
+
+ /*
+ * See if the file exists.
+ */
+
+
+ status = rtems_filesystem_evaluate_path( pathname, eval_flags, &temp_loc, TRUE );
+
+ if ( status == -1 ) {
+ if ( errno != ENOENT ) {
+ rc = errno;
+ goto done;
+ }
+
+ /* If the file does not exist and we are not trying to create it--> error */
+ if ( !(flags & O_CREAT) ) {
+ rc = ENOENT;
+ goto done;
+ }
+
+ /* Create the node for the new regular file */
+ rc = mknod( pathname, S_IFREG | mode, 0LL );
+ if ( rc ) {
+ rc = errno;
+ goto done;
+ }
+
+ /* Sanity check to see if the file name exists after the mknod() */
+ status = rtems_filesystem_evaluate_path( pathname, 0x0, &temp_loc, TRUE );
+ if ( status != 0 ) { /* The file did not exist */
+ rc = EACCES;
+ goto done;
+ }
+
+ } else if ((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT)) {
+ /* We were trying to create a file that already exists */
+ rc = EEXIST;
+ goto done;
+ }
+
+ /*
+ * Fill in the file control block based on the temp_loc structure
+ * returned by successful path evaluation.
+ */
+
+ iop->handlers = temp_loc.handlers;
+ iop->file_info = temp_loc.node_access;
+ iop->flags |= rtems_libio_fcntl_flags( flags );
+ iop->pathinfo = temp_loc;
+
+ if ( !iop->handlers->open ) {
+ rc = ENOTSUP;
+ goto done;
+ }
+
+ rc = (*iop->handlers->open)( iop, pathname, flags, mode );
+ if ( rc )
+ goto done;
+
+ /*
+ * Optionally truncate the file.
+ */
+
+ if ( (flags & O_TRUNC) == O_TRUNC ) {
+ rc = ftruncate( iop - rtems_libio_iops, 0 );
+ }
+
+ /*
+ * Single exit and clean up path.
+ */
+
+done:
+ va_end(ap);
+
+ if ( rc ) {
+ if ( iop )
+ rtems_libio_free( iop );
+ set_errno_and_return_minus_one( rc );
+ }
+ return iop - rtems_libio_iops;
+}
+
+/*
+ * _open_r
+ *
+ * This is the Newlib dependent reentrant version of open().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _open_r(
+ struct _reent *ptr,
+ const char *buf,
+ int flags,
+ int mode
+)
+{
+ return open( buf, flags, mode );
+}
+#endif
diff --git a/cpukit/libcsupport/src/opendir.c b/cpukit/libcsupport/src/opendir.c
index e303eb28e5..f0e9488684 100644
--- a/cpukit/libcsupport/src/opendir.c
+++ b/cpukit/libcsupport/src/opendir.c
@@ -1,17 +1,85 @@
/*
* opendir() - POSIX 1003.1b - XXX
*
- * $Id$
+ * This was copied from Newlib 1.8.0.
+ *
+ *
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)opendir.c 5.11 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
#include <dirent.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
-DIR *opendir(
- const char *name
-)
+/*
+ * open a directory.
+ */
+DIR *
+opendir(name)
+ const char *name;
{
- return NULL;
+ register DIR *dirp;
+ register int fd;
+
+ if ((fd = open(name, 0)) == -1)
+ return NULL;
+ if (fcntl(fd, F_SETFD, 1) == -1 ||
+ (dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
+ close (fd);
+ return NULL;
+ }
+ /*
+ * If CLSIZE is an exact multiple of DIRBLKSIZ, use a CLSIZE
+ * buffer that it cluster boundary aligned.
+ * Hopefully this can be a big win someday by allowing page trades
+ * to user space to be done by getdirentries()
+ */
+ dirp->dd_buf = malloc (512);
+ dirp->dd_len = 512;
+
+ if (dirp->dd_buf == NULL) {
+ close (fd);
+ return NULL;
+ }
+ dirp->dd_fd = fd;
+ dirp->dd_loc = 0;
+ dirp->dd_seek = 0;
+ /*
+ * Set up seek point for rewinddir.
+ */
+ return dirp;
}
diff --git a/cpukit/libcsupport/src/pathconf.c b/cpukit/libcsupport/src/pathconf.c
new file mode 100644
index 0000000000..e19d1329f4
--- /dev/null
+++ b/cpukit/libcsupport/src/pathconf.c
@@ -0,0 +1,38 @@
+/*
+ * pathconf() - POSIX 1003.1b - 5.7.1 - Configurable Pathname Varables
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+long pathconf(
+ const char *path,
+ int name
+)
+{
+ int status;
+ int fd;
+
+ fd = open( path, O_RDONLY );
+ if ( fd == -1 )
+ return -1;
+
+ status = fpathconf( fd, name );
+
+ (void) close( fd );
+
+ return status;
+}
diff --git a/cpukit/libcsupport/src/pipe.c b/cpukit/libcsupport/src/pipe.c
new file mode 100644
index 0000000000..35dcf627bb
--- /dev/null
+++ b/cpukit/libcsupport/src/pipe.c
@@ -0,0 +1,23 @@
+/*
+ * pipe() - POSIX 1003.1b 6.1.1 Create an Inter-Process Channel
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <errno.h>
+
+int pipe(
+ int filsdes[2]
+)
+{
+ errno = ENOSYS;
+ return -1;
+}
diff --git a/cpukit/libcsupport/src/read.c b/cpukit/libcsupport/src/read.c
new file mode 100644
index 0000000000..150fe675ab
--- /dev/null
+++ b/cpukit/libcsupport/src/read.c
@@ -0,0 +1,84 @@
+/*
+ * read() - POSIX 1003.1b 6.4.1 - Read From a File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include "libio_.h"
+
+/* XXX newlib has the prototype for this wrong. It will be a bit painful */
+/* XXX to fix so we are choosing to delay fixing this. */
+
+int read(
+ int fd,
+ void *buffer,
+ unsigned32 count
+)
+{
+ int rc; /* XXX change to a size_t when prototype is fixed */
+ rtems_libio_t *iop;
+
+ /*
+ * If this file descriptor is mapped to an external set of handlers,
+ * then pass the request on to them.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) ) {
+ rtems_libio_read_t fp;
+
+ fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].read;
+ if ( fp == NULL )
+ set_errno_and_return_minus_one( EBADF );
+
+ return (*fp)( fd, buffer, count );
+ }
+
+ /*
+ * Now process the read().
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+ rtems_libio_check_buffer( buffer );
+ rtems_libio_check_count( count );
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ );
+
+ if ( !iop->handlers->read )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ rc = (*iop->handlers->read)( iop, buffer, count );
+
+ if ( rc > 0 )
+ iop->offset += rc;
+
+ return rc;
+}
+
+/*
+ * _read_r
+ *
+ * This is the Newlib dependent reentrant version of read().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+_ssize_t _read_r(
+ struct _reent *ptr,
+ int fd,
+ void *buf,
+ size_t nbytes
+)
+{
+ return read( fd, buf, nbytes );
+}
+#endif
diff --git a/cpukit/libcsupport/src/readdir.c b/cpukit/libcsupport/src/readdir.c
index d592a62b99..f950d56171 100644
--- a/cpukit/libcsupport/src/readdir.c
+++ b/cpukit/libcsupport/src/readdir.c
@@ -1,14 +1,77 @@
/*
* readdir() - POSIX 1003.1b - XXX
*
- * $Id$
+ * This was copied from Newlib 1.8.0.
+ *
+ *
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)readdir.c 5.7 (Berkeley) 6/1/90";
+#endif /* LIBC_SCCS and not lint */
+
#include <dirent.h>
-struct dirent *readdir(
- register DIR *dirp
-)
-{
- return NULL;
+/*
+ * get next entry in a directory.
+ */
+struct dirent *
+readdir(dirp)
+register DIR *dirp; {
+ register struct dirent *dp;
+
+ for (;;) {
+ if (dirp->dd_loc == 0) {
+ dirp->dd_size = getdents (dirp->dd_fd,
+ dirp->dd_buf,
+ dirp->dd_len);
+
+ if (dirp->dd_size <= 0)
+ return NULL;
+ }
+ if (dirp->dd_loc >= dirp->dd_size) {
+ dirp->dd_loc = 0;
+ continue;
+ }
+ dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
+ if ((int)dp & 03) /* bogus pointer check */
+ return NULL;
+ if (dp->d_reclen <= 0 ||
+ dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
+ return NULL;
+ dirp->dd_loc += dp->d_reclen;
+ if (dp->d_ino == 0)
+ continue;
+ return (dp);
+ }
}
diff --git a/cpukit/libcsupport/src/readlink.c b/cpukit/libcsupport/src/readlink.c
new file mode 100644
index 0000000000..22de51e88f
--- /dev/null
+++ b/cpukit/libcsupport/src/readlink.c
@@ -0,0 +1,43 @@
+/*
+ * readlink() - POSIX 1003.1b - X.X.X - XXX
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include "libio_.h"
+
+int readlink(
+ const char *pathname,
+ char *buf,
+ int bufsize
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ result = rtems_filesystem_evaluate_path( pathname, 0, &loc, FALSE );
+ if ( result != 0 )
+ return -1;
+
+ if (!buf)
+ set_errno_and_return_minus_one( EFAULT );
+
+ if ( !loc.ops->node_type )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( (*loc.ops->node_type)( &loc ) != RTEMS_FILESYSTEM_SYM_LINK )
+ set_errno_and_return_minus_one( EINVAL );
+
+ if ( !loc.ops->readlink )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*loc.ops->readlink)( &loc, buf, bufsize );
+}
diff --git a/cpukit/libcsupport/src/rewinddir.c b/cpukit/libcsupport/src/rewinddir.c
index c85e6fd4d0..04313a6042 100644
--- a/cpukit/libcsupport/src/rewinddir.c
+++ b/cpukit/libcsupport/src/rewinddir.c
@@ -1,7 +1,14 @@
/*
* rewinddir() - POSIX 1003.1b - XXX
*
- * $Id$
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
*/
#include <sys/types.h>
@@ -15,6 +22,14 @@ void rewinddir(
DIR *dirp
)
{
- errno = ENOSYS;
- return -1;
+ off_t status;
+
+ status = lseek( dirp->dd_fd, 0, SEEK_SET );
+
+ if( status == -1 )
+ return;
+
+ dirp->dd_loc = 0;
+
+
}
diff --git a/cpukit/libcsupport/src/rmdir.c b/cpukit/libcsupport/src/rmdir.c
new file mode 100644
index 0000000000..6c0331087f
--- /dev/null
+++ b/cpukit/libcsupport/src/rmdir.c
@@ -0,0 +1,56 @@
+/*
+ * rmdir() - POSIX 1003.1b - 5.2.2 - Remove a Directory
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "libio_.h"
+
+int rmdir(
+ const char *pathname
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ /*
+ * Get the node where we wish to go.
+ */
+
+ result = rtems_filesystem_evaluate_path( pathname, 0, &loc, FALSE );
+ if ( result != 0 )
+ return -1;
+
+ /*
+ * Verify you can remove this node as a directory.
+ */
+
+ if ( !loc.ops->node_type )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( (*loc.ops->node_type)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY )
+ set_errno_and_return_minus_one( ENOTDIR );
+
+ /*
+ * Use the filesystems rmnod to remove the node.
+ */
+
+ if ( !loc.ops->rmnod )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*loc.ops->rmnod)( &loc );
+}
diff --git a/cpukit/libcsupport/src/scandir.c b/cpukit/libcsupport/src/scandir.c
index 380415dd97..9ba1cb7bec 100644
--- a/cpukit/libcsupport/src/scandir.c
+++ b/cpukit/libcsupport/src/scandir.c
@@ -1,7 +1,50 @@
/*
* scandir() - POSIX 1003.1b - XXX
*
- * $Id$
+ * This was copied from Newlib 1.8.0.
+ *
+ *
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)scandir.c 5.10 (Berkeley) 2/23/91";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Scan the directory dirname calling select to make a list of selected
+ * directory entries then sort using qsort and compare routine dcomp.
+ * Returns the number of entries and a pointer to a list of pointers to
+ * struct dirent (through namelist). Returns -1 if there were any errors.
*/
#include <sys/types.h>
@@ -9,15 +52,98 @@
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
-#include <errno.h>
-
-int scandir(
- const char *dirname,
- struct dirent ***namelist,
- int (*select)(struct dirent *),
- int (*dcomp)(const void *, const void *)
-)
+
+/*
+ * The DIRSIZ macro gives the minimum record length which will hold
+ * the directory entry. This requires the amount of space in struct dirent
+ * without the d_name field, plus enough space for the name with a terminating
+ * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ */
+#undef DIRSIZ
+/*
+#define DIRSIZ(dp) \
+ ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+*/
+
+#define DIRSIZ(dp) \
+ ((sizeof (struct dirent) - (NAME_MAX+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+
+#ifndef __P
+#define __P(args) ()
+#endif
+
+int
+scandir(dirname, namelist, select, dcomp)
+ const char *dirname;
+ struct dirent ***namelist;
+ int (*select) __P((struct dirent *));
+ int (*dcomp) __P((const void *, const void *));
+{
+ register struct dirent *d, *p, **names;
+ register size_t nitems;
+ struct stat stb;
+ long arraysz;
+ DIR *dirp;
+
+ if ((dirp = opendir(dirname)) == NULL)
+ return(-1);
+ if (fstat(dirp->dd_fd, &stb) < 0)
+ return(-1);
+
+ /*
+ * estimate the array size by taking the size of the directory file
+ * and dividing it by a multiple of the minimum size entry.
+ */
+ arraysz = (stb.st_size / 24);
+ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
+ if (names == NULL)
+ return(-1);
+
+ nitems = 0;
+ while ((d = readdir(dirp)) != NULL) {
+ if (select != NULL && !(*select)(d))
+ continue; /* just selected names */
+ /*
+ * Make a minimum size copy of the data
+ */
+ p = (struct dirent *)malloc(DIRSIZ(d));
+ if (p == NULL)
+ return(-1);
+ p->d_ino = d->d_ino;
+ p->d_reclen = d->d_reclen;
+ p->d_namlen = d->d_namlen;
+ bcopy(d->d_name, p->d_name, p->d_namlen + 1);
+ /*
+ * Check to make sure the array has space left and
+ * realloc the maximum size.
+ */
+ if (++nitems >= arraysz) {
+ if (fstat(dirp->dd_fd, &stb) < 0)
+ return(-1); /* just might have grown */
+ arraysz = stb.st_size / 12;
+ names = (struct dirent **)realloc((char *)names,
+ arraysz * sizeof(struct dirent *));
+ if (names == NULL)
+ return(-1);
+ }
+ names[nitems-1] = p;
+ }
+ closedir(dirp);
+ if (nitems && dcomp != NULL){
+ qsort(names, nitems, sizeof(struct dirent *), dcomp);
+ }
+ *namelist = names;
+ return(nitems);
+}
+
+/*
+ * Alphabetic order comparison routine for those who want it.
+ */
+int
+alphasort(d1, d2)
+ const void *d1;
+ const void *d2;
{
- errno = ENOSYS;
- return -1;
+ return(strcmp((*(struct dirent **)d1)->d_name,
+ (*(struct dirent **)d2)->d_name));
}
diff --git a/cpukit/libcsupport/src/seekdir.c b/cpukit/libcsupport/src/seekdir.c
index e591adbb9f..80802b56c6 100644
--- a/cpukit/libcsupport/src/seekdir.c
+++ b/cpukit/libcsupport/src/seekdir.c
@@ -1,7 +1,14 @@
/*
* seekdir() - POSIX 1003.1b - XXX
*
- * $Id$
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
*/
#include <sys/param.h>
@@ -12,10 +19,20 @@
#include <errno.h>
void seekdir(
- DIR *dirp,
- long loc
+ DIR *dirp,
+ long loc
)
{
- errno = ENOSYS;
- return -1;
+ off_t status;
+
+ status = lseek( dirp->dd_fd, loc, SEEK_SET );
+
+ /*
+ * This is not a nice way to error out, but we have no choice here.
+ */
+ if( status == -1 )
+ return;
+
+ dirp->dd_loc = 0;
+
}
diff --git a/cpukit/libcsupport/src/stat.c b/cpukit/libcsupport/src/stat.c
new file mode 100644
index 0000000000..8ad7e61511
--- /dev/null
+++ b/cpukit/libcsupport/src/stat.c
@@ -0,0 +1,79 @@
+/*
+ * stat() - POSIX 1003.1b 5.6.2 - Get File Status
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+
+#if !defined(RTEMS_UNIX)
+
+#include <rtems/libio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "libio_.h"
+
+int stat(
+ const char *path,
+ struct stat *buf
+)
+{
+ int status;
+ rtems_filesystem_location_info_t loc;
+
+ /*
+ * Check to see if we were passed a valid pointer.
+ */
+
+ if ( !buf )
+ set_errno_and_return_minus_one( EFAULT );
+
+ status = rtems_filesystem_evaluate_path( path, 0, &loc, TRUE );
+ if ( status != 0 )
+ return -1;
+
+ if ( !loc.handlers->fstat )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ /*
+ * Zero out the stat structure so the various support
+ * versions of stat don't have to.
+ */
+
+ memset( buf, 0, sizeof(struct stat) );
+
+ return (*loc.handlers->fstat)( &loc, buf );
+}
+#endif
+
+/*
+ * _stat_r
+ *
+ * This is the Newlib dependent reentrant version of stat().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+int _stat_r(
+ struct _reent *ptr,
+ const char *path,
+ struct stat *buf
+)
+{
+ return stat( path, buf );
+}
+#endif
diff --git a/cpukit/libcsupport/src/symlink.c b/cpukit/libcsupport/src/symlink.c
new file mode 100644
index 0000000000..ca9673f51b
--- /dev/null
+++ b/cpukit/libcsupport/src/symlink.c
@@ -0,0 +1,34 @@
+/*
+ * symlink() - POSIX 1003.1b - X.X.X - XXX
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include "libio_.h"
+
+int symlink(
+ const char *actualpath,
+ const char *sympath
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int i;
+ const char *name_start;
+ int result;
+
+ rtems_filesystem_get_start_loc( sympath, &i, &loc );
+ result = (*loc.ops->evalformake)( &sympath[i], &loc, &name_start );
+ if ( result != 0 )
+ return -1;
+
+ return (*loc.ops->symlink)( &loc, actualpath, name_start);
+}
+
diff --git a/cpukit/libcsupport/src/tcdrain.c b/cpukit/libcsupport/src/tcdrain.c
index 585871cc90..c2749a90e1 100644
--- a/cpukit/libcsupport/src/tcdrain.c
+++ b/cpukit/libcsupport/src/tcdrain.c
@@ -1,9 +1,15 @@
/*
- * This file contains the RTEMS implementation of the POSIX API
- * routines tcdrain.
+ * tcdrain() - POSIX 1003.1b 7.2.2 - Line Control Functions
*
- * $Id$
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
*
+ * $Id$
*/
#include <rtems.h>
@@ -13,14 +19,15 @@
#include <sys/stat.h>
#include <errno.h>
#include <termios.h>
+#include <sys/ioctl.h>
-#include "internal.h"
#include "libio.h"
-int
-tcdrain(int fd)
+int tcdrain(
+ int fd
+)
{
- return __rtems_ioctl(fd,RTEMS_IO_TCDRAIN,0);
+ return ioctl( fd, RTEMS_IO_TCDRAIN, 0 );
}
#endif
diff --git a/cpukit/libcsupport/src/tcgetattr.c b/cpukit/libcsupport/src/tcgetattr.c
new file mode 100644
index 0000000000..2d3e4d7e3c
--- /dev/null
+++ b/cpukit/libcsupport/src/tcgetattr.c
@@ -0,0 +1,33 @@
+/*
+ * tcgetattr() - POSIX 1003.1b 7.2.1 - Get and Set State
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include "libio.h"
+
+int tcgetattr(
+ int fd,
+ struct termios *tp
+)
+{
+ return ioctl( fd, RTEMS_IO_GET_ATTRIBUTES, tp );
+}
+#endif
diff --git a/cpukit/libcsupport/src/tcsetattr.c b/cpukit/libcsupport/src/tcsetattr.c
new file mode 100644
index 0000000000..c0ed509a0f
--- /dev/null
+++ b/cpukit/libcsupport/src/tcsetattr.c
@@ -0,0 +1,38 @@
+/*
+ * tcsetattr() - POSIX 1003.1b 7.2.1 - Get and Set State
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#if defined(RTEMS_NEWLIB)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include "libio.h"
+#include "libio_.h"
+
+int tcsetattr(
+ int fd,
+ int opt,
+ struct termios *tp
+)
+{
+ if ( opt != TCSANOW )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return ioctl( fd, RTEMS_IO_SET_ATTRIBUTES, tp );
+}
+#endif
diff --git a/cpukit/libcsupport/src/telldir.c b/cpukit/libcsupport/src/telldir.c
index eee8d925ec..cea6cc08cb 100644
--- a/cpukit/libcsupport/src/telldir.c
+++ b/cpukit/libcsupport/src/telldir.c
@@ -1,7 +1,14 @@
/*
* telldir() - XXX
*
- * $Id$
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
*/
#include <sys/param.h>
@@ -9,15 +16,24 @@
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
-#include <errno.h>
-#include <rtems.h>
-#include "libio.h"
+#include "libio_.h"
+
long telldir(
DIR *dirp
)
{
- errno = ENOSYS;
- return -1;
+ rtems_libio_t *iop;
+
+ /*
+ * Get the file control block structure associated with the file descriptor
+ */
+
+ iop = rtems_libio_iop( dirp->dd_fd );
+
+ if (iop == NULL)
+ assert(0);
+
+ return (long)( iop->offset );
}
diff --git a/cpukit/libcsupport/src/truncate.c b/cpukit/libcsupport/src/truncate.c
new file mode 100644
index 0000000000..145e596654
--- /dev/null
+++ b/cpukit/libcsupport/src/truncate.c
@@ -0,0 +1,41 @@
+/*
+ * truncate() - Truncate a File to the Specified Length
+ *
+ * This routine is not defined in the POSIX 1003.1b standard but is
+ * commonly supported on most UNIX and POSIX systems. It is provided
+ * for compatibility.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+int truncate(
+ const char *path,
+ off_t length
+)
+{
+ int status;
+ int fd;
+
+ fd = open( path, O_WRONLY );
+ if ( fd == -1 )
+ return -1;
+
+ status = ftruncate( fd, length );
+
+ (void) close( fd );
+
+ return status;
+}
+
diff --git a/cpukit/libcsupport/src/umask.c b/cpukit/libcsupport/src/umask.c
new file mode 100644
index 0000000000..35229a30a1
--- /dev/null
+++ b/cpukit/libcsupport/src/umask.c
@@ -0,0 +1,30 @@
+/*
+ * umask() - POSIX 1003.1b 5.3.3 - Set File Creation Mask
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "libio_.h"
+
+mode_t umask(
+ mode_t cmask
+)
+{
+ mode_t old_mask;
+
+ old_mask = rtems_filesystem_umask;
+ rtems_filesystem_umask = cmask;
+
+ return old_mask;
+}
diff --git a/cpukit/libcsupport/src/unixlibc.c b/cpukit/libcsupport/src/unixlibc.c
index 3e757e313d..a581d95534 100644
--- a/cpukit/libcsupport/src/unixlibc.c
+++ b/cpukit/libcsupport/src/unixlibc.c
@@ -1,5 +1,15 @@
/*
* $Id$
+ * UNIX Port C Library Support
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
*/
#include <rtems.h>
diff --git a/cpukit/libcsupport/src/unlink.c b/cpukit/libcsupport/src/unlink.c
new file mode 100644
index 0000000000..d4a5520bcb
--- /dev/null
+++ b/cpukit/libcsupport/src/unlink.c
@@ -0,0 +1,44 @@
+/*
+ * unlink() - POSIX 1003.1b - 5.5.1 - Remove an existing link
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <errno.h>
+
+#include "libio_.h"
+
+int unlink(
+ const char *path
+)
+{
+ rtems_filesystem_location_info_t loc;
+ int result;
+
+ /*
+ * Get the node to be unlinked.
+ */
+
+ result = rtems_filesystem_evaluate_path( path, 0, &loc, FALSE );
+ if ( result != 0 )
+ return -1;
+
+ if ( !loc.ops->node_type )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ if ( (*loc.ops->node_type)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY )
+ set_errno_and_return_minus_one( EISDIR );
+
+ if ( !loc.ops->unlink )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*loc.ops->unlink)( &loc );
+}
diff --git a/cpukit/libcsupport/src/unmount.c b/cpukit/libcsupport/src/unmount.c
new file mode 100644
index 0000000000..f50e63ff42
--- /dev/null
+++ b/cpukit/libcsupport/src/unmount.c
@@ -0,0 +1,214 @@
+/*
+ * unmount() - Unmount a File System
+ *
+ * This routine is not defined in the POSIX 1003.1b standard but
+ * in some form is supported on most UNIX and POSIX systems. This
+ * routine is necessary to mount instantiations of a file system
+ * into the file system name space.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <chain.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "imfs.h"
+#include "libio_.h"
+
+/*
+ * Data structures and routines private to mount/unmount pair.
+ */
+
+extern Chain_Control rtems_filesystem_mount_table_control;
+extern rtems_filesystem_location_info_t rtems_filesystem_current;
+
+int search_mt_for_mount_point(
+ rtems_filesystem_location_info_t *location_of_mount_point
+);
+
+
+int file_systems_below_this_mountpoint(
+ const char *mount_path,
+ rtems_filesystem_location_info_t *temp_loc,
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry
+);
+
+/*
+ * unmount
+ *
+ * This routine will attempt to unmount the file system that has been
+ * is mounted a mount_path. If the operation is successful, 0 will
+ * be returned to the calling routine. Otherwise, 1 will be returned.
+ */
+
+int unmount(
+ const char *mount_path
+)
+{
+ int status;
+ rtems_filesystem_location_info_t temp_loc;
+ rtems_filesystem_mount_table_entry_t temp_mt_entry;
+ int result;
+
+ /*
+ * Are there any file systems below the mount_path specified
+ */
+
+ status = file_systems_below_this_mountpoint(
+ mount_path,
+ &temp_loc,
+ &temp_mt_entry
+ );
+
+ if ( status != 0 )
+ return -1;
+
+ /*
+ * Is the current node reference pointing to a node in the file system
+ * we are attempting to unmount ?
+ */
+
+ if ( rtems_filesystem_current.mt_entry == temp_loc.mt_entry )
+ set_errno_and_return_minus_one( EBUSY );
+
+ /*
+ * Run the file descriptor table to determine if there are any file
+ * descriptors that are currently active and reference nodes in the
+ * file system that we are trying to unmount
+ */
+
+ if ( rtems_libio_is_open_files_in_fs( temp_loc.mt_entry ) == 1 )
+ set_errno_and_return_minus_one( EBUSY );
+
+ /*
+ * Allow the file system being mounted on to do its cleanup.
+ * XXX - Did I change these correctly ??? It looks like either I did
+ * XXX this backwards or the IMFS_unmount and IMFS_fsumount are swaped.
+ * XXX Add to the mt_point_node unmount to set the mt_entry back to null
+ * XXX I will step off in space when evaluating past the end of the node.
+ */
+
+ if ( ( temp_mt_entry.mt_point_node.ops->unmount )( temp_loc.mt_entry ) != 0 )
+ return -1;
+
+ /*
+ * Run the unmount function for the subordinate file system.
+ */
+
+ if ( ( temp_mt_entry.mt_fs_root.ops->fsunmount_me )( temp_loc.mt_entry ) != 0 )
+ return -1;
+
+ /*
+ * Allow the file system to clean up.
+ */
+
+ result = (*temp_loc.ops->fsunmount_me)( temp_loc.mt_entry );
+
+ /*
+ * Extract the mount table entry from the chain
+ */
+
+ Chain_Extract( ( Chain_Node * ) temp_loc.mt_entry );
+
+ /*
+ * Free the memory associated with the extracted mount table entry.
+ */
+
+ free( temp_loc.mt_entry );
+
+ return result;
+
+}
+
+
+/*
+ * file_systems_below_this_mountpoint
+ *
+ * This routine will run through the entries that currently exist in the
+ * mount table chain. For each entry in the mount table chain it will
+ * compare the mount tables mt_fs_root to the new_fs_root_node. If any of the
+ * mount table file system root nodes matches the new file system root node
+ * this indicates that we are trying to mount a file system that has already
+ * been mounted. This is not a permitted operation. temp_loc is set to
+ * the root node of the file system being unmounted.
+ */
+
+int file_systems_below_this_mountpoint(
+ const char *mount_path,
+ rtems_filesystem_location_info_t *temp_loc,
+ rtems_filesystem_mount_table_entry_t *temp_mt_entry
+)
+{
+ Chain_Node *the_node;
+ rtems_filesystem_mount_table_entry_t *the_mount_entry;
+ rtems_filesystem_mount_table_entry_t *current_fs_mt_entry;
+
+ /*
+ * Is the mount_path even a valid node name in the existing tree?
+ */
+
+ if ( rtems_filesystem_evaluate_path( mount_path, 0x0, temp_loc, TRUE ) )
+ return -1;
+
+ /*
+ * Look for the node defined in temp_loc as a mount point in the
+ * mount table chain.
+ */
+
+ for ( the_node = rtems_filesystem_mount_table_control.first;
+ !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
+ the_node = the_node->next ) {
+
+ the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
+ if (the_mount_entry->mt_point_node.node_access ==
+ temp_loc->node_access ) {
+ current_fs_mt_entry = the_mount_entry;
+ *temp_loc = current_fs_mt_entry->mt_fs_root;
+ goto after_real_mount_point_found;
+ }
+ }
+ set_errno_and_return_minus_one( EACCES );
+
+
+after_real_mount_point_found:
+
+ for ( the_node = rtems_filesystem_mount_table_control.first;
+ !Chain_Is_tail( &rtems_filesystem_mount_table_control, the_node );
+ the_node = the_node->next ) {
+
+ the_mount_entry = ( rtems_filesystem_mount_table_entry_t * )the_node;
+
+ /*
+ * Exclude the current file systems mount table entry from the test
+ */
+
+ if ( current_fs_mt_entry != the_mount_entry ) {
+ if ( the_mount_entry->mt_point_node.mt_entry == current_fs_mt_entry ) {
+
+ /*
+ * There is at least one fs below the fs on the mount_path.
+ */
+ set_errno_and_return_minus_one( EBUSY );
+ }
+ }
+ }
+
+ *temp_mt_entry = *current_fs_mt_entry;
+
+ return 0;
+}
diff --git a/cpukit/libcsupport/src/utime.c b/cpukit/libcsupport/src/utime.c
new file mode 100644
index 0000000000..f1a12ee1b2
--- /dev/null
+++ b/cpukit/libcsupport/src/utime.c
@@ -0,0 +1,35 @@
+/*
+ * utime() - POSIX 1003.1b 5.5.6 - Set File Access and Modification Times
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <utime.h>
+#include <errno.h>
+
+#include "libio_.h"
+
+int utime(
+ const char *path,
+ const struct utimbuf *times
+)
+{
+ rtems_filesystem_location_info_t temp_loc;
+
+ if ( rtems_filesystem_evaluate_path( path, 0x00, &temp_loc, TRUE ) )
+ return -1;
+
+ if ( !temp_loc.ops->utime )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ return (*temp_loc.ops->utime)( &temp_loc, times->actime, times->modtime );
+}
diff --git a/cpukit/libcsupport/src/write.c b/cpukit/libcsupport/src/write.c
new file mode 100644
index 0000000000..7e0953bb90
--- /dev/null
+++ b/cpukit/libcsupport/src/write.c
@@ -0,0 +1,92 @@
+/*
+ * write() - POSIX 1003.1b 6.4.2 - Write to a File
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include "libio_.h"
+
+
+/*
+ * write
+ *
+ * This routine writes count bytes from from buffer pointed to by buffer
+ * to the file associated with the open file descriptor, fildes.
+ */
+
+/* XXX newlib has the prototype for this wrong. It will be a bit painful */
+/* XXX to fix so we are choosing to delay fixing this. */
+
+int write( /* XXX this should return a ssize_t */
+ int fd,
+ const void *buffer,
+ unsigned32 count /* XXX this should be a size_t */
+)
+{
+ rtems_status_code rc;
+ rtems_libio_t *iop;
+
+ /*
+ * If this file descriptor is mapped to an external set of handlers,
+ * then pass the request on to them.
+ */
+
+ if ( rtems_file_descriptor_type( fd ) ) {
+ rtems_libio_write_t fp;
+
+ fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].write;
+ if ( fp == NULL )
+ set_errno_and_return_minus_one( EBADF );
+
+ return (*fp)( fd, buffer, count );
+ }
+
+ /*
+ * Now process the write() request.
+ */
+
+ iop = rtems_libio_iop( fd );
+ rtems_libio_check_fd( fd );
+ rtems_libio_check_buffer( buffer );
+ rtems_libio_check_count( count );
+ rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
+
+ if ( !iop->handlers->write )
+ set_errno_and_return_minus_one( ENOTSUP );
+
+ rc = (*iop->handlers->write)( iop, buffer, count );
+
+ if ( rc > 0 )
+ iop->offset += rc;
+
+ return rc;
+}
+
+/*
+ * _write_r
+ *
+ * This is the Newlib dependent reentrant version of write().
+ */
+
+#if defined(RTEMS_NEWLIB)
+
+#include <reent.h>
+
+long _write_r(
+ struct _reent *ptr,
+ int fd,
+ const void *buf,
+ size_t nbytes
+)
+{
+ return write( fd, buf, nbytes );
+}
+#endif