diff options
Diffstat (limited to '')
66 files changed, 4414 insertions, 653 deletions
diff --git a/c/src/exec/libcsupport/include/rtems/libio.h b/c/src/exec/libcsupport/include/rtems/libio.h index dcdda85aec..76a90954b0 100644 --- a/c/src/exec/libcsupport/include/rtems/libio.h +++ b/c/src/exec/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/c/src/exec/libcsupport/include/rtems/libio_.h b/c/src/exec/libcsupport/include/rtems/libio_.h new file mode 100644 index 0000000000..bb6f81f35a --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/CASES b/c/src/exec/libcsupport/src/CASES new file mode 100644 index 0000000000..4578ae5009 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/TODO b/c/src/exec/libcsupport/src/TODO new file mode 100644 index 0000000000..9d894688d9 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/__brk.c b/c/src/exec/libcsupport/src/__brk.c index 4dab22c729..24efa93adb 100644 --- a/c/src/exec/libcsupport/src/__brk.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/__gettod.c b/c/src/exec/libcsupport/src/__gettod.c index dc83c47ce4..16857da870 100644 --- a/c/src/exec/libcsupport/src/__gettod.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/__sbrk.c b/c/src/exec/libcsupport/src/__sbrk.c new file mode 100644 index 0000000000..b1d31467fd --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/__times.c b/c/src/exec/libcsupport/src/__times.c index 635bf8e062..5f7525ec5f 100644 --- a/c/src/exec/libcsupport/src/__times.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/access.c b/c/src/exec/libcsupport/src/access.c new file mode 100644 index 0000000000..a8be44a9a3 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/base_fs.c b/c/src/exec/libcsupport/src/base_fs.c new file mode 100644 index 0000000000..c8c23e5b43 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/cfgetispeed.c b/c/src/exec/libcsupport/src/cfgetispeed.c new file mode 100644 index 0000000000..61d97cb2f1 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/cfgetospeed.c b/c/src/exec/libcsupport/src/cfgetospeed.c new file mode 100644 index 0000000000..8815d436e9 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/cfsetispeed.c b/c/src/exec/libcsupport/src/cfsetispeed.c new file mode 100644 index 0000000000..37d3cd0584 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/cfsetospeed.c b/c/src/exec/libcsupport/src/cfsetospeed.c new file mode 100644 index 0000000000..f01237103b --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/chdir.c b/c/src/exec/libcsupport/src/chdir.c new file mode 100644 index 0000000000..4acbc8cfe0 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/chmod.c b/c/src/exec/libcsupport/src/chmod.c new file mode 100644 index 0000000000..fa57d50691 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/chown.c b/c/src/exec/libcsupport/src/chown.c new file mode 100644 index 0000000000..189096dcd1 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/close.c b/c/src/exec/libcsupport/src/close.c new file mode 100644 index 0000000000..94ddb45c90 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/closedir.c b/c/src/exec/libcsupport/src/closedir.c index 5edb3499e6..4d948ec95b 100644 --- a/c/src/exec/libcsupport/src/closedir.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/dup.c b/c/src/exec/libcsupport/src/dup.c new file mode 100644 index 0000000000..c17db588a7 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/dup2.c b/c/src/exec/libcsupport/src/dup2.c new file mode 100644 index 0000000000..5653425708 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/eval.c b/c/src/exec/libcsupport/src/eval.c new file mode 100644 index 0000000000..bf7dd1c126 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/fchmod.c b/c/src/exec/libcsupport/src/fchmod.c new file mode 100644 index 0000000000..a3ca4507ab --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/fcntl.c b/c/src/exec/libcsupport/src/fcntl.c new file mode 100644 index 0000000000..f6f33534ab --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/fdatasync.c b/c/src/exec/libcsupport/src/fdatasync.c new file mode 100644 index 0000000000..58a4c4e118 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/fpathconf.c b/c/src/exec/libcsupport/src/fpathconf.c new file mode 100644 index 0000000000..ea2377e15b --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/fstat.c b/c/src/exec/libcsupport/src/fstat.c new file mode 100644 index 0000000000..82d144dd2c --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/fsync.c b/c/src/exec/libcsupport/src/fsync.c new file mode 100644 index 0000000000..a5ed1e99e7 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/ftruncate.c b/c/src/exec/libcsupport/src/ftruncate.c new file mode 100644 index 0000000000..7fb2286531 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/getdents.c b/c/src/exec/libcsupport/src/getdents.c index 9b16d82409..91631843b7 100644 --- a/c/src/exec/libcsupport/src/getdents.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/hosterr.c b/c/src/exec/libcsupport/src/hosterr.c index a55e4a7e84..6c0308df3b 100644 --- a/c/src/exec/libcsupport/src/hosterr.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/ioctl.c b/c/src/exec/libcsupport/src/ioctl.c new file mode 100644 index 0000000000..0aaf0379ae --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/libio.c b/c/src/exec/libcsupport/src/libio.c index 12682c1190..e63a4626d4 100644 --- a/c/src/exec/libcsupport/src/libio.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/link.c b/c/src/exec/libcsupport/src/link.c new file mode 100644 index 0000000000..1cee54d0bf --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/lseek.c b/c/src/exec/libcsupport/src/lseek.c new file mode 100644 index 0000000000..514f8cd912 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/malloc.c b/c/src/exec/libcsupport/src/malloc.c index fac38585a7..f164e45f6c 100644 --- a/c/src/exec/libcsupport/src/malloc.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/mkdir.c b/c/src/exec/libcsupport/src/mkdir.c new file mode 100644 index 0000000000..18fc7171c7 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/mkfifo.c b/c/src/exec/libcsupport/src/mkfifo.c new file mode 100644 index 0000000000..6b3ece5650 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/mknod.c b/c/src/exec/libcsupport/src/mknod.c new file mode 100644 index 0000000000..4f83321ecd --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/mount.c b/c/src/exec/libcsupport/src/mount.c new file mode 100644 index 0000000000..fa8cebc3f9 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/newlibc.c b/c/src/exec/libcsupport/src/newlibc.c index a6acc1c8d7..bea592a46e 100644 --- a/c/src/exec/libcsupport/src/newlibc.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/no_libc.c b/c/src/exec/libcsupport/src/no_libc.c index 5a58ba761c..4bd02c4b27 100644 --- a/c/src/exec/libcsupport/src/no_libc.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/open.c b/c/src/exec/libcsupport/src/open.c new file mode 100644 index 0000000000..4cdf5acf35 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/opendir.c b/c/src/exec/libcsupport/src/opendir.c index e303eb28e5..f0e9488684 100644 --- a/c/src/exec/libcsupport/src/opendir.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/pathconf.c b/c/src/exec/libcsupport/src/pathconf.c new file mode 100644 index 0000000000..e19d1329f4 --- /dev/null +++ b/c/src/exec/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/c/src/lib/libc/_execve.c b/c/src/exec/libcsupport/src/pipe.c index d1ad365b57..35dcf627bb 100644 --- a/c/src/lib/libc/_execve.c +++ b/c/src/exec/libcsupport/src/pipe.c @@ -1,9 +1,5 @@ -#include <rtems.h> - -#if defined(RTEMS_NEWLIB) /* - * RTEMS Dummy _execveImplementation - * + * pipe() - POSIX 1003.1b 6.1.1 Create an Inter-Process Channel * * COPYRIGHT (c) 1989-1998. * On-Line Applications Research Corporation (OAR). @@ -16,16 +12,12 @@ * $Id$ */ -#include <unistd.h> #include <errno.h> -int _execve( - const char *path, - char *const argv[], - char *const environ[] +int pipe( + int filsdes[2] ) { errno = ENOSYS; return -1; } -#endif diff --git a/c/src/exec/libcsupport/src/read.c b/c/src/exec/libcsupport/src/read.c new file mode 100644 index 0000000000..150fe675ab --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/readdir.c b/c/src/exec/libcsupport/src/readdir.c index d592a62b99..f950d56171 100644 --- a/c/src/exec/libcsupport/src/readdir.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/readlink.c b/c/src/exec/libcsupport/src/readlink.c new file mode 100644 index 0000000000..22de51e88f --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/rewinddir.c b/c/src/exec/libcsupport/src/rewinddir.c index c85e6fd4d0..04313a6042 100644 --- a/c/src/exec/libcsupport/src/rewinddir.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/rmdir.c b/c/src/exec/libcsupport/src/rmdir.c new file mode 100644 index 0000000000..6c0331087f --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/scandir.c b/c/src/exec/libcsupport/src/scandir.c index 380415dd97..9ba1cb7bec 100644 --- a/c/src/exec/libcsupport/src/scandir.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/seekdir.c b/c/src/exec/libcsupport/src/seekdir.c index e591adbb9f..80802b56c6 100644 --- a/c/src/exec/libcsupport/src/seekdir.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/stat.c b/c/src/exec/libcsupport/src/stat.c new file mode 100644 index 0000000000..8ad7e61511 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/symlink.c b/c/src/exec/libcsupport/src/symlink.c new file mode 100644 index 0000000000..ca9673f51b --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/tcdrain.c b/c/src/exec/libcsupport/src/tcdrain.c index 585871cc90..c2749a90e1 100644 --- a/c/src/exec/libcsupport/src/tcdrain.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/tcgetattr.c b/c/src/exec/libcsupport/src/tcgetattr.c new file mode 100644 index 0000000000..2d3e4d7e3c --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/tcsetattr.c b/c/src/exec/libcsupport/src/tcsetattr.c new file mode 100644 index 0000000000..c0ed509a0f --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/telldir.c b/c/src/exec/libcsupport/src/telldir.c index eee8d925ec..cea6cc08cb 100644 --- a/c/src/exec/libcsupport/src/telldir.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/truncate.c b/c/src/exec/libcsupport/src/truncate.c new file mode 100644 index 0000000000..145e596654 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/umask.c b/c/src/exec/libcsupport/src/umask.c new file mode 100644 index 0000000000..35229a30a1 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/unixlibc.c b/c/src/exec/libcsupport/src/unixlibc.c index 3e757e313d..a581d95534 100644 --- a/c/src/exec/libcsupport/src/unixlibc.c +++ b/c/src/exec/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/c/src/exec/libcsupport/src/unlink.c b/c/src/exec/libcsupport/src/unlink.c new file mode 100644 index 0000000000..d4a5520bcb --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/unmount.c b/c/src/exec/libcsupport/src/unmount.c new file mode 100644 index 0000000000..f50e63ff42 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/utime.c b/c/src/exec/libcsupport/src/utime.c new file mode 100644 index 0000000000..f1a12ee1b2 --- /dev/null +++ b/c/src/exec/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/c/src/exec/libcsupport/src/write.c b/c/src/exec/libcsupport/src/write.c new file mode 100644 index 0000000000..7e0953bb90 --- /dev/null +++ b/c/src/exec/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 |