diff options
Diffstat (limited to 'cpukit/libcsupport')
206 files changed, 17536 insertions, 0 deletions
diff --git a/cpukit/libcsupport/.cvsignore b/cpukit/libcsupport/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/cpukit/libcsupport/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am new file mode 100644 index 0000000000..95eee5bd77 --- /dev/null +++ b/cpukit/libcsupport/Makefile.am @@ -0,0 +1,133 @@ +## +## $Id$ +## + +include $(top_srcdir)/automake/multilib.am +include $(top_srcdir)/automake/compile.am + +noinst_LIBRARIES = libcsupport.a +libcsupport_a_CPPFLAGS = $(AM_CPPFLAGS) + +include_rtemsdir = $(includedir)/rtems +include_rtems_HEADERS = include/console.h include/clockdrv.h \ + include/rtems/framebuffer.h include/iosupp.h include/ringbuf.h \ + include/rtc.h include/spurious.h include/timerdrv.h include/vmeintr.h + +## motorola + +include_rtems_motoroladir = $(includedir)/rtems/motorola + +include_rtems_motorola_HEADERS = include/motorola/mc68230.h \ + include/motorola/mc68681.h + +## rtems +include_rtems_HEADERS += include/rtems/assoc.h include/rtems/error.h \ + include/rtems/libcsupport.h include/rtems/libio.h include/rtems/libio_.h \ + include/rtems/malloc.h include/rtems/termiostypes.h \ + include/rtems/gxx_wrappers.h + +## zilog + +include_rtems_zilogdir = $(includedir)/rtems/zilog + +include_rtems_zilog_HEADERS = include/zilog/z8036.h include/zilog/z8530.h \ + include/zilog/z8536.h + +## General stuff +ERROR_C_FILES = src/error.c src/__assert.c + +ASSOCIATION_C_FILES = src/assoclocalbyname.c \ + src/assoclocalbyremotebitfield.c src/assoclocalbyremote.c \ + src/assocnamebad.c src/assocnamebylocalbitfield.c \ + src/assocnamebylocal.c src/assocnamebyremotebitfield.c \ + src/assocnamebyremote.c src/assocptrbylocal.c src/assocptrbyname.c \ + src/assocptrbyremote.c src/assocremotebylocalbitfield.c \ + src/assocremotebylocal.c src/assocremotebyname.c + +BASE_FS_C_FILES = src/base_fs.c src/mount.c src/unmount.c src/libio.c \ + src/mount-mgr.c src/mount-mktgt.c src/libio_init.c \ + src/eval.c src/privateenv.c \ + src/open_dev_console.c src/__usrenv.c src/rtems_mkdir.c + +if LIBNETWORKING +BASE_FS_C_FILES += src/libio_sockets.c +endif + +TERMIOS_C_FILES = src/cfgetispeed.c src/cfgetospeed.c src/cfsetispeed.c \ + src/cfsetospeed.c src/tcgetattr.c src/tcsetattr.c src/tcdrain.c \ + src/tcflow.c src/tcflush.c src/tcgetpgrp.c src/tcsendbreak.c \ + src/tcsetpgrp.c src/termios.c src/termiosinitialize.c \ + src/termios_baud2index.c src/termios_baud2num.c src/termios_num2baud.c \ + src/termios_setinitialbaud.c src/termios_baudtable.c + +SYSTEM_CALL_C_FILES = src/open.c src/close.c src/read.c src/write.c \ + src/write_r.c \ + src/lseek.c src/ioctl.c src/mkdir.c src/mknod.c src/mkfifo.c src/rmdir.c \ + src/chdir.c src/chmod.c src/fchdir.c src/fchmod.c src/fchown.c src/chown.c \ + src/link.c src/unlink.c src/umask.c src/ftruncate.c src/utime.c src/fstat.c \ + src/fcntl.c src/fpathconf.c src/getdents.c src/fsync.c src/fdatasync.c \ + src/pipe.c src/dup.c src/dup2.c src/symlink.c src/readlink.c \ + src/chroot.c src/sync.c src/_rename_r.c src/statvfs.c src/utimes.c src/lchown.c + +## Until sys/uio.h is moved to libcsupport, we have to have networking +## enabled to compile these. Hopefully this is a temporary situation. +if NEWLIB +SYSTEM_CALL_C_FILES += src/readv.c src/writev.c +endif + +DIRECTORY_SCAN_C_FILES = +## Newlib SHOULD have provided this one +DIRECTORY_SCAN_C_FILES += src/readdir_r.c +## Comment out when using these from newlib's unix directory +DIRECTORY_SCAN_C_FILES += src/getcwd.c + +ID_C_FILES = src/getegid.c src/geteuid.c src/getgid.c src/getgroups.c \ + src/getlogin.c src/getpgrp.c src/getpid.c src/getppid.c src/getuid.c \ + src/seteuid.c src/setgid.c src/setuid.c src/seteuid.c src/setpgid.c \ + src/setsid.c + +MALLOC_C_FILES = src/malloc_initialize.c src/calloc.c src/malloc.c \ + src/realloc.c src/_calloc_r.c src/_malloc_r.c \ + src/free.c src/freenode.c src/_free_r.c \ + src/_realloc_r.c src/mallocfreespace.c \ + src/mallocgetheapptr.c src/mallocsetheapptr.c \ + src/mallocinfo.c src/malloc_walk.c src/malloc_get_statistics.c \ + src/malloc_report_statistics.c src/malloc_report_statistics_plugin.c \ + src/malloc_statistics_helpers.c src/posix_memalign.c \ + src/rtems_memalign.c src/malloc_deferred.c src/malloc_sbrk_helpers.c \ + src/malloc_dirtier.c src/malloc_p.h src/rtems_malloc.c \ + src/rtems_heap_extend.c + +PASSWORD_GROUP_C_FILES = src/getpwent.c + +TERMINAL_IDENTIFICATION_C_FILES = src/ctermid.c +## 20 Nov 2008: Now using these from newlib's posix directory +TERMINAL_IDENTIFICATION_C_FILES += src/isatty.c src/isatty_r.c +## Comment out when using these from newlib's unix directory +TERMINAL_IDENTIFICATION_C_FILES += src/ttyname.c + +LIBC_GLUE_C_FILES = src/__getpid.c src/__gettod.c src/__times.c \ + src/truncate.c src/access.c src/stat.c src/lstat.c src/pathconf.c \ + src/newlibc_reent.c src/newlibc_init.c src/newlibc_exit.c \ + src/kill_noposix.c src/utsname.c + +BSD_LIBC_C_FILES = src/strlcpy.c src/strlcat.c src/issetugid.c + +libcsupport_a_SOURCES = src/gxx_wrappers.c src/getchark.c src/printk.c \ + src/printk_plugin.c src/putk.c src/vprintk.c \ + src/sup_fs_is_separator.c src/sup_fs_get_start_loc.c \ + src/sup_fs_get_sym_start_loc.c \ + $(BSD_LIBC_C_FILES) $(BASE_FS_C_FILES) $(MALLOC_C_FILES) \ + $(ERROR_C_FILES) $(ASSOCIATION_C_FILES) + +libcsupport_a_SOURCES += $(LIBC_GLUE_C_FILES) $(PASSWORD_GROUP_C_FILES) \ + $(TERMINAL_IDENTIFICATION_C_FILES) $(SYSTEM_CALL_C_FILES) \ + $(DIRECTORY_SCAN_C_FILES) $(ID_C_FILES) src/envlock.c \ + $(TERMIOS_C_FILES) src/getpagesize.c src/getrusage.c + +libcsupport_a_SOURCES += src/flockfile.c src/funlockfile.c src/ftrylockfile.c + +EXTRA_DIST = src/TODO src/CASES src/README + +include $(srcdir)/preinstall.am +include $(top_srcdir)/automake/local.am diff --git a/cpukit/libcsupport/include/clockdrv.h b/cpukit/libcsupport/include/clockdrv.h new file mode 100644 index 0000000000..d0eb55e9f6 --- /dev/null +++ b/cpukit/libcsupport/include/clockdrv.h @@ -0,0 +1,52 @@ +/** + * @file rtems/clockdrv.h + */ + +/* clock.h + * + * This file describes the Clock Driver for all boards. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_CLOCKDRV_H +#define _RTEMS_CLOCKDRV_H + +#include <rtems/io.h> /* rtems_device_driver */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* variables */ + +extern volatile uint32_t Clock_driver_ticks; +extern rtems_device_major_number rtems_clock_major; +extern rtems_device_minor_number rtems_clock_minor; + +/* default clock driver entry */ + +#define CLOCK_DRIVER_TABLE_ENTRY \ + { Clock_initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver Clock_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +void Clock_exit(void); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/console.h b/cpukit/libcsupport/include/console.h new file mode 100644 index 0000000000..0a2d258887 --- /dev/null +++ b/cpukit/libcsupport/include/console.h @@ -0,0 +1,162 @@ +/** + * @file rtems/console.h + */ + +/* console.h + * + * This file describes the Console Device Driver for all boards. + * This driver provides support for the standard C Library. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_CONSOLE_H +#define _RTEMS_CONSOLE_H + +#include <rtems/io.h> /* rtems_device_driver */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This macro defines the standard name for the console device + * that is available to applications. + */ +#define CONSOLE_DEVICE_NAME "/dev/console" + +/** + * This macro defines the standard device driver table entry for + * a console device driver. + */ +#define CONSOLE_DRIVER_TABLE_ENTRY \ + { console_initialize, console_open, console_close, \ + console_read, console_write, console_control } + +/** + * @brief Console Initialization Entry Point + * + * This method initializes the console device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device driver is successfully initialized. + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Console Open Entry Point + * + * This method opens a specific device supported by the + * console device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device driver is successfully opened. + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Console Close Entry Point + * + * This method closes a specific device supported by the + * console device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device is successfully closed. + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Console Read Entry Point + * + * This method reads from a specific device supported by the + * console device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device is successfully read from. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Console Write Entry Point + * + * This method writes to a specific device supported by the + * console device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device is successfully written. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Console IO Control Entry Point + * + * This method performs an IO Control operation on a + * specific device supported by the console device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device driver IO control operation is + * successfully performed. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/iosupp.h b/cpukit/libcsupport/include/iosupp.h new file mode 100644 index 0000000000..cd2ff02e06 --- /dev/null +++ b/cpukit/libcsupport/include/iosupp.h @@ -0,0 +1,46 @@ +/** + * @file rtems/iosupp.h + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_IOSUPP_H +#define _RTEMS_IOSUPP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* character constants */ + +#define BS 0x08 /* backspace */ +#define LF 0x0a /* line feed */ +#define CR 0x0d /* carriage return */ +#define XON 0x11 /* control-Q */ +#define XOFF 0x13 /* control-S */ + +/* structures */ + +#ifdef IOSUPP_INIT +#define IOSUPP_EXTERN +#else +#undef IOSUPP_EXTERN +#define IOSUPP_EXTERN extern +#endif + +/* functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/include/motorola/mc68230.h b/cpukit/libcsupport/include/motorola/mc68230.h new file mode 100644 index 0000000000..d993a150fd --- /dev/null +++ b/cpukit/libcsupport/include/motorola/mc68230.h @@ -0,0 +1,74 @@ +/** + * @file rtems/motorola/mc68230.h + */ + +/* + * mc68230.h -- Low level support code for the Motorola 68230 Parallel + * Interface/Timer (PIT) + * + * Modified by Doug McBride, Colorado Space Grant College + * + * Format taken partly from RTEMS code and mostly from Motorola IDP user's + * manual. RTEMS copyright information below. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_MOTOROLA_MC68230_H +#define _RTEMS_MOTOROLA_MC68230_H + +/* Some Motorola IDP User manual defines: */ +#define MC68230_PIT_ADDR 0x00c01003 /* base address of the PIT */ +#define MC68230_REGOFF 0x04 /* Difference between addresses */ +#define MC68230_VECT 64 +#define MC68230_H1VECT 0x00 +#define MC68230_H2VECT 0x01 +#define MC68230_H3VECT 0x02 +#define MC68230_H4VECT 0x03 + +/* + * mc68230 register offsets + */ +#define MC68230_PGCR 0x00 +#define MC68230_PSRR 1*MC68230_REGOFF +#define MC68230_PADDR 2*MC68230_REGOFF +#define MC68230_PBDDR 3*MC68230_REGOFF +#define MC68230_PCDDR 4*MC68230_REGOFF +#define MC68230_PIVR 5*MC68230_REGOFF +#define MC68230_PACR 6*MC68230_REGOFF +#define MC68230_PBCR 7*MC68230_REGOFF +#define MC68230_PADR 8*MC68230_REGOFF +#define MC68230_PBDR 9*MC68230_REGOFF +#define MC68230_PAAR 10*MC68230_REGOFF +#define MC68230_PBAR 11*MC68230_REGOFF +#define MC68230_PCDR 12*MC68230_REGOFF +#define MC68230_PITSR 13*MC68230_REGOFF +#define MC68230_TCR 16*MC68230_REGOFF +#define MC68230_TIVR 17*MC68230_REGOFF +#define MC68230_CPRH 19*MC68230_REGOFF +#define MC68230_CPRM 20*MC68230_REGOFF +#define MC68230_CPRL 21*MC68230_REGOFF +#define MC68230_CNTRH 23*MC68230_REGOFF +#define MC68230_CNTRM 24*MC68230_REGOFF +#define MC68230_CNTRL 25*MC68230_REGOFF +#define MC68230_TSR 26*MC68230_REGOFF + +/* Some RTEMS style defines: */ +#ifndef MC68230_VOL8 +#define MC68230_VOL8( ptr ) ((volatile uint8_t *)(ptr)) +#endif + +#define MC68230_WRITE( reg, data ) \ + *(MC68230_VOL8(MC68230_PIT_ADDR+reg)) = (data) + +#define MC68230_READ( reg, data ) \ + (data) = *(MC68230_VOL8(MC68230_PIT_ADDR+reg)) + +#endif diff --git a/cpukit/libcsupport/include/motorola/mc68681.h b/cpukit/libcsupport/include/motorola/mc68681.h new file mode 100644 index 0000000000..7b2f566da3 --- /dev/null +++ b/cpukit/libcsupport/include/motorola/mc68681.h @@ -0,0 +1,309 @@ +/** + * @file rtems/motorola/mc68681.h + * + * + * mc68681-duart.h -- Low level support code for the Motorola mc68681 + * DUART. + */ + +/* + * + * Originally written by rob@cygnus.com (Rob Savoye) for the libgloss + * IDP support. + * + * $Id$ + */ + +#ifndef _RTEMS_MOTOROLA_MC68681_H +#define _RTEMS_MOTOROLA_MC68681_H + +/* + * In the dark ages when this controller was designed, it was actually + * possible to access data on unaligned byte boundaries with no penalty. + * Now we find this chip in configurations in which the registers are + * at 16-bit, 32-bit, and 64-bit boundaries at the whim of the board + * designer. If the registers are not at byte addresses, then + * set this multiplier before including this file to correct the offsets. + */ + +#ifndef MC68681_OFFSET_MULTIPLIER +#define MC68681_OFFSET_MULTIPLIER 1 +#endif + +#define __MC68681_REG(_R) ((_R) * MC68681_OFFSET_MULTIPLIER) + +/* + * mc68681 register offsets Read/Write Addresses + */ +#define MC68681_MODE_REG_1A __MC68681_REG(0) /* MR1A-MR Prior to Read */ +#define MC68681_MODE_REG_2A __MC68681_REG(0) /* MR2A-MR After Read */ + +#define MC68681_COUNT_MODE_CURRENT_MSB __MC68681_REG(6) /* CTU */ +#define MC68681_COUNTER_TIMER_UPPER_REG __MC68681_REG(6) /* CTU */ +#define MC68681_COUNT_MODE_CURRENT_LSB __MC68681_REG(7) /* CTL */ +#define MC68681_COUNTER_TIMER_LOWER_REG __MC68681_REG(7) /* CTL */ +#define MC68681_INTERRUPT_VECTOR_REG __MC68681_REG(12) /* IVR */ + +#define MC68681_MODE_REG_1B __MC68681_REG(8) /* MR1B-MR Prior to Read */ +#define MC68681_MODE_REG_2B __MC68681_REG(8) /* MR2BA-MR After Read */ + +/* + * mc68681 register offsets Read Only Addresses + */ +#define MC68681_STATUS_REG_A __MC68681_REG(1) /* SRA */ +#define MC68681_MASK_ISR_REG __MC68681_REG(2) /* MISR */ +#define MC68681_RECEIVE_BUFFER_A __MC68681_REG(3) /* RHRA */ +#define MC68681_INPUT_PORT_CHANGE_REG __MC68681_REG(4) /* IPCR */ +#define MC68681_INTERRUPT_STATUS_REG __MC68681_REG(5) /* ISR */ +#define MC68681_STATUS_REG_B __MC68681_REG(9) /* SRB */ +#define MC68681_RECEIVE_BUFFER_B __MC68681_REG(11) /* RHRB */ +#define MC68681_INPUT_PORT __MC68681_REG(13) /* IP */ +#define MC68681_START_COUNT_CMD __MC68681_REG(14) /* SCC */ +#define MC68681_STOP_COUNT_CMD __MC68681_REG(15) /* STC */ + +/* + * mc68681 register offsets Write Only Addresses + */ +#define MC68681_CLOCK_SELECT_REG_A __MC68681_REG(1) /* CSRA */ +#define MC68681_COMMAND_REG_A __MC68681_REG(2) /* CRA */ +#define MC68681_TRANSMIT_BUFFER_A __MC68681_REG(3) /* THRA */ +#define MC68681_AUX_CTRL_REG __MC68681_REG(4) /* ACR */ +#define MC68681_INTERRUPT_MASK_REG __MC68681_REG(5) /* IMR */ +#define MC68681_CLOCK_SELECT_REG_B __MC68681_REG(9) /* CSRB */ +#define MC68681_COMMAND_REG_B __MC68681_REG(10) /* CRB */ +#define MC68681_TRANSMIT_BUFFER_B __MC68681_REG(11) /* THRB */ +#define MC68681_OUTPUT_PORT_CONFIG_REG __MC68681_REG(13) /* OPCR */ +#define MC68681_OUTPUT_PORT_SET_REG __MC68681_REG(14) /* SOPBC */ +#define MC68681_OUTPUT_PORT_RESET_BITS __MC68681_REG(15) /* COPBC */ + + +#ifndef MC6681_VOL +#define MC6681_VOL( ptr ) ((volatile unsigned char *)(ptr)) +#endif + +#define MC68681_WRITE( _base, _reg, _data ) \ + *((volatile unsigned char *)_base+_reg) = (_data) + +#define MC68681_READ( _base, _reg ) \ + *(((volatile unsigned char *)_base+_reg)) + + + +#define MC68681_CLEAR 0x00 + +#define MC68681_PORT_A 0 +#define MC68681_PORT_B 1 + +/* + * DUART Command Register Definitions: + * + * MC68681_COMMAND_REG_A,MC68681_COMMAND_REG_B + */ +#define MC68681_MODE_REG_ENABLE_RX 0x01 +#define MC68681_MODE_REG_DISABLE_RX 0x02 +#define MC68681_MODE_REG_ENABLE_TX 0x04 +#define MC68681_MODE_REG_DISABLE_TX 0x08 +#define MC68681_MODE_REG_RESET_MR_PTR 0x10 +#define MC68681_MODE_REG_RESET_RX 0x20 +#define MC68681_MODE_REG_RESET_TX 0x30 +#define MC68681_MODE_REG_RESET_ERROR 0x40 +#define MC68681_MODE_REG_RESET_BREAK 0x50 +#define MC68681_MODE_REG_START_BREAK 0x60 +#define MC68681_MODE_REG_STOP_BREAK 0x70 +#define MC68681_MODE_REG_SET_RX_BRG 0x80 +#define MC68681_MODE_REG_CLEAR_RX_BRG 0x90 +#define MC68681_MODE_REG_SET_TX_BRG 0xa0 +#define MC68681_MODE_REG_CLEAR_TX_BRG 0xb0 +#define MC68681_MODE_REG_SET_STANDBY 0xc0 +#define MC68681_MODE_REG_SET_ACTIVE 0xd0 + +/* + * Mode Register Definitions + * + * MC68681_MODE_REG_1A + * MC68681_MODE_REG_1B + */ +#define MC68681_5BIT_CHARS 0x00 +#define MC68681_6BIT_CHARS 0x01 +#define MC68681_7BIT_CHARS 0x02 +#define MC68681_8BIT_CHARS 0x03 + +#define MC68681_ODD_PARITY 0x00 +#define MC68681_EVEN_PARITY 0x04 + +#define MC68681_WITH_PARITY 0x00 +#define MC68681_FORCE_PARITY 0x08 +#define MC68681_NO_PARITY 0x10 +#define MC68681_MULTI_DROP 0x18 + +#define MC68681_ERR_MODE_CHAR 0x00 +#define MC68681_ERR_MODE_BLOCK 0x20 + +#define MC68681_RX_INTR_RX_READY 0x00 +#define MC68681_RX_INTR_FFULL 0x40 + +#define MC68681_NO_RX_RTS_CTL 0x00 +#define MC68681_RX_RTS_CTRL 0x80 + + +/* + * Mode Register Definitions + * + * MC68681_MODE_REG_2A + * MC68681_MODE_REG_2B + */ +#define MC68681_STOP_BIT_LENGTH__563 0x00 +#define MC68681_STOP_BIT_LENGTH__625 0x01 +#define MC68681_STOP_BIT_LENGTH__688 0x02 +#define MC68681_STOP_BIT_LENGTH__75 0x03 +#define MC68681_STOP_BIT_LENGTH__813 0x04 +#define MC68681_STOP_BIT_LENGTH__875 0x05 +#define MC68681_STOP_BIT_LENGTH__938 0x06 +#define MC68681_STOP_BIT_LENGTH_1 0x07 +#define MC68681_STOP_BIT_LENGTH_1_563 0x08 +#define MC68681_STOP_BIT_LENGTH_1_625 0x09 +#define MC68681_STOP_BIT_LENGTH_1_688 0x0a +#define MC68681_STOP_BIT_LENGTH_1_75 0x0b +#define MC68681_STOP_BIT_LENGTH_1_813 0x0c +#define MC68681_STOP_BIT_LENGTH_1_875 0x0d +#define MC68681_STOP_BIT_LENGTH_1_938 0x0e +#define MC68681_STOP_BIT_LENGTH_2 0x0f + +#define MC68681_CTS_ENABLE_TX 0x10 +#define MC68681_TX_RTS_CTRL 0x20 + +#define MC68681_CHANNEL_MODE_NORMAL 0x00 +#define MC68681_CHANNEL_MODE_ECHO 0x40 +#define MC68681_CHANNEL_MODE_LOCAL_LOOP 0x80 +#define MC68681_CHANNEL_MODE_REMOTE_LOOP 0xc0 + +/* + * Status Register Definitions + * + * MC68681_STATUS_REG_A, MC68681_STATUS_REG_B + */ +#define MC68681_RX_READY 0x01 +#define MC68681_FFULL 0x02 +#define MC68681_TX_READY 0x04 +#define MC68681_TX_EMPTY 0x08 +#define MC68681_OVERRUN_ERROR 0x10 +#define MC68681_PARITY_ERROR 0x20 +#define MC68681_FRAMING_ERROR 0x40 +#define MC68681_RECEIVED_BREAK 0x80 + + +/* + * Interupt Status Register Definitions. + * + * MC68681_INTERRUPT_STATUS_REG + */ + + +/* + * Interupt Mask Register Definitions + * + * MC68681_INTERRUPT_MASK_REG + */ +#define MC68681_IR_TX_READY_A 0x01 +#define MC68681_IR_RX_READY_A 0x02 +#define MC68681_IR_BREAK_A 0x04 +#define MC68681_IR_COUNTER_READY 0x08 +#define MC68681_IR_TX_READY_B 0x10 +#define MC68681_IR_RX_READY_B 0x20 +#define MC68681_IR_BREAK_B 0x40 +#define MC68681_IR_INPUT_PORT_CHANGE 0x80 + +/* + * Status Register Definitions. + * + * MC68681_STATUS_REG_A,MC68681_STATUS_REG_B + */ +#define MC68681_STATUS_RXRDY 0x01 +#define MC68681_STATUS_FFULL 0x02 +#define MC68681_STATUS_TXRDY 0x04 +#define MC68681_STATUS_TXEMT 0x08 +#define MC68681_STATUS_OVERRUN_ERROR 0x10 +#define MC68681_STATUS_PARITY_ERROR 0x20 +#define MC68681_STATUS_FRAMING_ERROR 0x40 +#define MC68681_STATUS_RECEIVED_BREAK 0x80 + +/* + * Definitions for the Interrupt Vector Register: + * + * MC68681_INTERRUPT_VECTOR_REG + */ +#define MC68681_INTERRUPT_VECTOR_INIT 0x0f + +/* + * Definitions for the Auxiliary Control Register + * + * MC68681_AUX_CTRL_REG + */ +#define MC68681_AUX_BRG_SET1 0x00 +#define MC68681_AUX_BRG_SET2 0x80 + + +/* + * The following Baud rates assume the X1 clock pin is driven with a + * 3.6864 MHz signal. If a different frequency is used the DUART channel + * is running at the follwoing baud rate: + * ((Table Baud Rate)*frequency)/3.6864 MHz + */ + +/* + * Definitions for the Clock Select Register: + * + * MC68681_CLOCK_SELECT_REG_A,MC68681_CLOCK_SELECT_REG_A + * + * Note: ACR[7] is the MSB of the Auxiliary Control register + * X is the extend bit. + * CRA - 0x08 Set Rx BRG Select Extend Bit (X=1) + * CRA - 0x09 Clear Rx BRG Select Extend Bit (X=0) + * CRB - 0x0a Set Tx BRG Select Extend Bit (X=1) + * CRB - 0x0b Clear Tx BRG Select Extend Bit (x=1) + */ +#define MC68681_BAUD_RATE_MASK_50 0x00 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_75 0x00 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_110 0x01 +#define MC68681_BAUD_RATE_MASK_134_5 0x02 +#define MC68681_BAUD_RATE_MASK_150 0x03 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_200 0x03 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_300 0x04 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_600 0x05 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_1050 0x07 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_1200 0x06 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_1800 0x0a /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_2400 0x08 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_3600 0x04 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_4800 0x09 +#define MC68681_BAUD_RATE_MASK_7200 0x0a /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_9600 0xbb + +#define MC68681_BAUD_RATE_MASK_14_4K 0x05 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_19_2K 0xcc /* ACR[7]=1,X=0 */ + /* ARC[7]=0,X=1 */ +#define MC68681_BAUD_RATE_MASK_28_8K 0x06 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_38_4K 0xcc /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_57_6K 0x07 /* ACR[7]=0,X=0 */ + /* ARC[7]=1,X=1 */ +#define MC68681_BAUD_RATE_MASK_115_5K 0x08 +#define MC68681_BAUD_RATE_MASK_TIMER 0xdd +#define MC68681_BAUD_RATE_MASK_TIMER_16X 0xee +#define MC68681_BAUD_RATE_MASK_TIMER_1X 0xff + +#endif diff --git a/cpukit/libcsupport/include/ringbuf.h b/cpukit/libcsupport/include/ringbuf.h new file mode 100644 index 0000000000..39941d857d --- /dev/null +++ b/cpukit/libcsupport/include/ringbuf.h @@ -0,0 +1,55 @@ +/** + * @file rtems/ringbuf.h + * + * This file provides simple ring buffer functionality. + */ + +/* + * $Id$ + */ + +#ifndef _RTEMS_RINGBUF_H +#define _RTEMS_RINGBUF_H + +#ifndef RINGBUF_QUEUE_LENGTH +#define RINGBUF_QUEUE_LENGTH 128 +#endif + +typedef struct { + uint8_t buffer[RINGBUF_QUEUE_LENGTH]; + volatile int head; + volatile int tail; +} Ring_buffer_t; + +#define Ring_buffer_Initialize( _buffer ) \ + do { \ + (_buffer)->head = (_buffer)->tail = 0; \ + } while ( 0 ) + +#define Ring_buffer_Is_empty( _buffer ) \ + ( (_buffer)->head == (_buffer)->tail ) + +#define Ring_buffer_Is_full( _buffer ) \ + ( (_buffer)->head == ((_buffer)->tail + 1) % RINGBUF_QUEUE_LENGTH ) + +#define Ring_buffer_Add_character( _buffer, _ch ) \ + do { \ + uint32_t isrlevel; \ + \ + rtems_interrupt_disable( isrlevel ); \ + (_buffer)->tail = ((_buffer)->tail+1) % RINGBUF_QUEUE_LENGTH; \ + (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \ + rtems_interrupt_enable( isrlevel ); \ + } while ( 0 ) + +#define Ring_buffer_Remove_character( _buffer, _ch ) \ + do { \ + uint32_t isrlevel; \ + \ + rtems_interrupt_disable( isrlevel ); \ + (_buffer)->head = ((_buffer)->head+1) % RINGBUF_QUEUE_LENGTH; \ + (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \ + rtems_interrupt_enable( isrlevel ); \ + } while ( 0 ) + +#endif diff --git a/cpukit/libcsupport/include/rtc.h b/cpukit/libcsupport/include/rtc.h new file mode 100644 index 0000000000..cc6f8c2b80 --- /dev/null +++ b/cpukit/libcsupport/include/rtc.h @@ -0,0 +1,116 @@ +/** + * @file + * + * Real-time clock driver interface. + */ + +/* + * COPYRIGHT (c) 1989-2001. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTC_H +#define _RTEMS_RTC_H + +#include <rtems.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup rtems_rtc Real-Time Clock Driver Interface + * + * This driver interface provides support to read and set the real-time clock + * and to initialize the time of day for the system. + * + * @{ + */ + +/** + * Device file name path. + */ +#define RTC_DEVICE_NAME "/dev/rtc" + +/** + * Device driver table entry. + */ +#define RTC_DRIVER_TABLE_ENTRY \ + { rtc_initialize, rtc_open, rtc_close, \ + rtc_read, rtc_write, rtc_control } + +/** + * Initializes the real-time clock device and sets the time of day for the + * system. + * + * If the real-time clock provides an invalid time of day value the system time + * of day must remain untouched. + */ +rtems_device_driver rtc_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +/** + * Opens the real-time clock device. + */ +rtems_device_driver rtc_open( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +/** + * Closes the real-time clock device. + */ +rtems_device_driver rtc_close( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +/** + * Reads the real-time clock value. + * + * The value will be returned in a @ref rtems_time_of_day structure. + */ +rtems_device_driver rtc_read( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +/** + * Sets the real-time clock value. + * + * The value will be set from a @ref rtems_time_of_day structure. + */ +rtems_device_driver rtc_write( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +/** + * Controls the real-time clock. + */ +rtems_device_driver rtc_control( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/include/rtems/assoc.h b/cpukit/libcsupport/include/rtems/assoc.h new file mode 100644 index 0000000000..5b72b8d086 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/assoc.h @@ -0,0 +1,120 @@ +/** + * @file rtems/assoc.h + */ + +/* + * + * Rtems associativity routines. Mainly used to convert a value from + * one space to another (eg: our errno's to host errno's and v.v) + * + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_ASSOC_H +#define _RTEMS_RTEMS_ASSOC_H + +#include <stdint.h> /* uint32_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + const char *name; + uint32_t local_value; + uint32_t remote_value; +} rtems_assoc_t; + +/* + * Flag/marker for optional default value in each table + */ + +#define RTEMS_ASSOC_DEFAULT_NAME "(default)" + +const rtems_assoc_t *rtems_assoc_ptr_by_name( + const rtems_assoc_t *, + const char * +); + +const rtems_assoc_t *rtems_assoc_ptr_by_remote( + const rtems_assoc_t *, + uint32_t +); + +uint32_t rtems_assoc_remote_by_local( + const rtems_assoc_t *, + uint32_t +); + +uint32_t rtems_assoc_local_by_remote( + const rtems_assoc_t *, + uint32_t +); + +uint32_t rtems_assoc_remote_by_name( + const rtems_assoc_t *, + const char * +); +uint32_t rtems_assoc_local_by_name( + const rtems_assoc_t *, + const char * +); + +const char *rtems_assoc_name_by_local( + const rtems_assoc_t *, + uint32_t +); + +const char *rtems_assoc_name_by_remote( + const rtems_assoc_t *, + uint32_t +); + +uint32_t rtems_assoc_remote_by_local_bitfield( + const rtems_assoc_t *, + uint32_t +); + +char *rtems_assoc_name_by_local_bitfield( + const rtems_assoc_t *, + uint32_t , + char * +); + +char *rtems_assoc_name_by_remote_bitfield( + const rtems_assoc_t *, + uint32_t , + char * +); + +uint32_t rtems_assoc_local_by_remote_bitfield( + const rtems_assoc_t *, + uint32_t +); + +const rtems_assoc_t *rtems_assoc_ptr_by_local( + const rtems_assoc_t *ap, + uint32_t local_value +); + +#if defined(INSIDE_ASSOC) + +#define rtems_assoc_is_default(_ap) \ + ((_ap)->name && !strcmp((_ap)->name, RTEMS_ASSOC_DEFAULT_NAME)) + +/* + * what to return if a value is not found + * this is not reentrant, but it really shouldn't be invoked anyway + */ + +const char *rtems_assoc_name_bad( + uint32_t bad_value +); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ! _RTEMS_RTEMS_ASSOC_H */ diff --git a/cpukit/libcsupport/include/rtems/error.h b/cpukit/libcsupport/include/rtems/error.h new file mode 100644 index 0000000000..6c589e8e94 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/error.h @@ -0,0 +1,60 @@ +/** + * @file rtems/error.h + */ + +/* + * Defines and externs for rtems error reporting + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_ERROR_H +#define _RTEMS_RTEMS_ERROR_H + +#include <rtems/rtems/status.h> +#include <rtems/score/interr.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef Internal_errors_t rtems_error_code_t; + +/* + * rtems_error() and rtems_panic() support + */ + +#if 0 +/* not 16bit-int host clean */ +#define RTEMS_ERROR_ERRNO (1<<((sizeof(rtems_error_code_t) * CHAR_BIT) - 2)) /* hi bit; use 'errno' */ +#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */ +#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */ +#else +#define RTEMS_ERROR_ERRNO (0x40000000) /* hi bit; use 'errno' */ +#define RTEMS_ERROR_PANIC (0x20000000) /* err fatal; no return */ +#define RTEMS_ERROR_ABORT (0x10000000) /* err is fatal; panic */ +#endif + +#define RTEMS_ERROR_MASK \ + (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | RTEMS_ERROR_PANIC) /* all */ + +const char *rtems_status_text(rtems_status_code sc); +int rtems_error( + rtems_error_code_t error_code, + const char *printf_format, + ... +); +void rtems_panic( + const char *printf_format, + ... +) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE; + +extern int rtems_panic_in_progress; + +#ifdef __cplusplus +} +#endif + + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/rtems/framebuffer.h b/cpukit/libcsupport/include/rtems/framebuffer.h new file mode 100644 index 0000000000..a300716c58 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/framebuffer.h @@ -0,0 +1,158 @@ +/** + * @file rtems/framebuffer.h + */ + +/* + * This file describes the Frame Buffer Device Driver for all boards. + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef __RTEMS_FRAMEBUFFER_h__ +#define __RTEMS_FRAMEBUFFER_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This macro defines the standard name for the frame buffer device + * that is available to applications. + */ +#define FRAMEBUFFER_DEVICE_NAME "/dev/fb" + +/** + * This macro defines the standard device driver table entry for + * a frame buffer device driver. + */ +#define FRAME_BUFFER_DRIVER_TABLE_ENTRY \ + { frame_buffer_initialize, frame_buffer_open, frame_buffer_close, \ + frame_buffer_read, frame_buffer_write, frame_buffer_control } + +/** + * @brief Frame Buffer Initialization Entry Point + * + * This method initializes the frame buffer device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device driver is successfully initialized. + */ +rtems_device_driver frame_buffer_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Frame Buffer Open Entry Point + * + * This method opens a specific device supported by the + * frame buffer device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device driver is successfully opened. + */ +rtems_device_driver frame_buffer_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Frame Buffer Close Entry Point + * + * This method closes a specific device supported by the + * frame buffer device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device is successfully closed. + */ +rtems_device_driver frame_buffer_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Frame Buffer Read Entry Point + * + * This method reads from a specific device supported by the + * frame buffer device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device is successfully read from. + */ +rtems_device_driver frame_buffer_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Frame Buffer Write Entry Point + * + * This method writes to a specific device supported by the + * frame buffer device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device is successfully written. + */ +rtems_device_driver frame_buffer_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Frame Buffer IO Control Entry Point + * + * This method performs an IO Control operation on a + * specific device supported by the frame buffer device driver. + * + * @param[in] major is the device driver major number + * @param[in] minor is the device driver minor number + * @param[in] arg is the parameters to this call + * + * @return This method returns RTEMS_SUCCESSFUL when + * the device driver IO control operation is + * successfully performed. + */ +rtems_device_driver frame_buffer_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/rtems/gxx_wrappers.h b/cpukit/libcsupport/include/rtems/gxx_wrappers.h new file mode 100755 index 0000000000..d4d4aae799 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/gxx_wrappers.h @@ -0,0 +1,78 @@ +/* + * RTEMS threads compatibility routines for libgcc2. + * + * by: Rosimildo da Silva (rdasilva@connecttel.com) + * + * Used ideas from: + * W. Eric Norum + * Canadian Light Source + * University of Saskatchewan + * Saskatoon, Saskatchewan, CANADA + * eric@cls.usask.ca + * + * Eric sent some e-mail in the rtems-list as a start point for this + * module implementation. + * + * $Id$ + */ + +#ifndef __GCC_WRAPPERS_h +#define __GCC_WRAPPERS_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * These typedefs should match with the ones defined in the file + * gcc/gthr-rtems.h in the gcc distribution. + * FIXME: T.S, 2007/01/31: -> gcc/gthr-rtems.h still declares + * void * __gthread_key_t; + */ +typedef struct __gthread_key_ { + void *val; /* this is switched with the task */ + void (*dtor)(void*); /* this remains in place for all tasks */ +} __gthread_key, *__gthread_key_t; + +typedef int __gthread_once_t; +typedef void *__gthread_mutex_t; +typedef void *__gthread_recursive_mutex_t; + +int rtems_gxx_once(__gthread_once_t *once, void (*func) (void)); + +int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *)); + +int rtems_gxx_key_dtor (__gthread_key_t key, void *ptr); + +int rtems_gxx_key_delete (__gthread_key_t key); + +void *rtems_gxx_getspecific(__gthread_key_t key); + +int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr); + +/* + * MUTEX support + */ +void rtems_gxx_mutex_init (__gthread_mutex_t *mutex); + +int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex); + +int rtems_gxx_mutex_destroy (__gthread_mutex_t *mutex); + +int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex); + +int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex); + +void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex); + +int rtems_gxx_recursive_mutex_lock(__gthread_recursive_mutex_t *mutex); + +int rtems_gxx_recursive_mutex_trylock(__gthread_recursive_mutex_t *mutex); + +int rtems_gxx_recursive_mutex_unlock(__gthread_recursive_mutex_t *mutex); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GCC_WRAPPERS_h */ diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h new file mode 100644 index 0000000000..9dfcf851fe --- /dev/null +++ b/cpukit/libcsupport/include/rtems/libcsupport.h @@ -0,0 +1,81 @@ +/** + * @file rtems/libcsupport.h + */ + +/* libcsupport.h + * + * This include file contains the information regarding the + * RTEMS specific support for the standard C library. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_LIBCSUPPORT_H +#define _RTEMS_RTEMS_LIBCSUPPORT_H + +#include <sys/types.h> +#include <stdint.h> + +#include <rtems/score/heap.h> +#include <rtems/rtems/tasks.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void RTEMS_Malloc_Initialize( + void *heap_begin, + uintptr_t heap_size, + size_t sbrk_amount +); + +extern void malloc_dump(void); +extern void malloc_walk(size_t source, size_t printf_enabled); +void malloc_set_heap_pointer(Heap_Control *new_heap); +Heap_Control *malloc_get_heap_pointer( void ); +extern void libc_init(void); +extern int host_errno(void); +extern void fix_syscall_errno(void); +extern size_t malloc_free_space(void); +extern void open_dev_console(void); + +/* + * Prototypes required to install newlib reentrancy user extension + */ +bool newlib_create_hook( + rtems_tcb *current_task, + rtems_tcb *creating_task +); + +#define __RTEMS_NEWLIB_BEGIN 0 + +void newlib_delete_hook( + rtems_tcb *current_task, + rtems_tcb *deleted_task +); + +#define RTEMS_NEWLIB_EXTENSION \ +{ \ + newlib_create_hook, /* rtems_task_create */ \ + 0, /* rtems_task_start */ \ + 0, /* rtems_task_restart */ \ + newlib_delete_hook, /* rtems_task_delete */ \ + 0, /* task_switch */ \ + __RTEMS_NEWLIB_BEGIN, /* task_begin */ \ + 0, /* task_exitted */ \ + 0 /* fatal */ \ +} + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h new file mode 100644 index 0000000000..73c52e31d7 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/libio.h @@ -0,0 +1,1685 @@ +/** + * @file + * + * @ingroup LibIO + * + * @brief Basic IO API. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_LIBIO_H +#define _RTEMS_RTEMS_LIBIO_H + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/statvfs.h> + +#include <unistd.h> +#include <termios.h> + +#include <rtems.h> +#include <rtems/fs.h> +#include <rtems/chain.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup LibIO IO Library + * + * @brief Provides system call and file system interface definitions. + * + * 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. + * + * @{ + */ + +/** + * A 64-bit file offset for internal use by RTEMS. Based on the Newlib + * type. + */ +typedef _off64_t rtems_off64_t; + +/** + * @brief File system node types. + */ +typedef enum { + RTEMS_FILESYSTEM_INVALID_NODE_TYPE, + RTEMS_FILESYSTEM_DIRECTORY, + RTEMS_FILESYSTEM_DEVICE, + RTEMS_FILESYSTEM_HARD_LINK, + RTEMS_FILESYSTEM_SYM_LINK, + RTEMS_FILESYSTEM_MEMORY_FILE +} rtems_filesystem_node_types_t; + +/** + * @name File System Node Operations + * + * @{ + */ + +/** + * This type defines the interface to the open(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_open_t)( + rtems_libio_t *iop, + const char *pathname, + uint32_t flag, + uint32_t mode +); + +/** + * This type defines the interface to the close(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_close_t)( + rtems_libio_t *iop +); + +/** + * This type defines the interface to the read(2) system call + * support which is provided by a file system implementation. + */ +typedef ssize_t (*rtems_filesystem_read_t)( + rtems_libio_t *iop, + void *buffer, + size_t count +); + +/** + * This type defines the interface to the write(2) system call + * support which is provided by a file system implementation. + */ +typedef ssize_t (*rtems_filesystem_write_t)( + rtems_libio_t *iop, + const void *buffer, + size_t count +); + +/** + * This type defines the interface to the ioctl(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_ioctl_t)( + rtems_libio_t *iop, + uint32_t command, + void *buffer +); + +/** + * This type defines the interface to the lseek(2) system call + * support which is provided by a file system implementation. + */ +typedef rtems_off64_t (*rtems_filesystem_lseek_t)( + rtems_libio_t *iop, + rtems_off64_t length, + int whence +); + +/** + * This type defines the interface to the fstat(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_fstat_t)( + rtems_filesystem_location_info_t *loc, + struct stat *buf +); + +/** + * This type defines the interface to the fchmod(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_fchmod_t)( + rtems_filesystem_location_info_t *loc, + mode_t mode +); + +/** + * This type defines the interface to the ftruncate(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_ftruncate_t)( + rtems_libio_t *iop, + rtems_off64_t length +); + +/** + * This type defines the interface to the fpathconf(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_fpathconf_t)( + rtems_libio_t *iop, + int name +); + +/** + * This type defines the interface to the fsync(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_fsync_t)( + rtems_libio_t *iop +); + +/** + * This type defines the interface to the fdatasync(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_fdatasync_t)( + rtems_libio_t *iop +); + +/** + * This type defines the interface to the fnctl(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_fcntl_t)( + int cmd, + rtems_libio_t *iop +); + +typedef int (*rtems_filesystem_rmnod_t)( + rtems_filesystem_location_info_t *parent_loc, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN */ +); + +/** @} */ + +/** + * @brief File system node operations table. + */ +struct _rtems_filesystem_file_handlers_r { + /** + * This field points to the file system specific implementation + * of the support routine for the open(2) system call + * + * @note This method must have a filesystem specific implementation. + * + * @note There is no default implementation. + */ + rtems_filesystem_open_t open_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the close(2) system call + * + * @note This method is REQUIRED by all file systems. + * + * @note There is no default implementation. + */ + rtems_filesystem_close_t close_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the read(2) system call + * + * @note This method must have a filesystem specific implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_read_t read_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the write(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_write_t write_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the ioctl(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_ioctl_t ioctl_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the lseek(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_lseek_t lseek_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the fstat(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_fstat_t fstat_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the fchmod(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_fchmod_t fchmod_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the ftruncate(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_ftruncate_t ftruncate_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the fpathconf(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_fpathconf_t fpathconf_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the fsync(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_fsync_t fsync_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the fdatasync(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_fdatasync_t fdatasync_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the fcntl(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_fcntl_t fcntl_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the rmnod(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_rmnod_t rmnod_h; +}; + +extern const rtems_filesystem_file_handlers_r +rtems_filesystem_handlers_default; + +/** + * This method defines the interface to the default open(2) + * system call support which is provided by a file system + * implementation. + */ +int rtems_filesystem_default_open( + rtems_libio_t *iop, + const char *pathname, + uint32_t flag, + uint32_t mode +); + +/** + * This method defines the interface to the default close(2) + * system call support which is provided by a file system + * implementation. + */ +int rtems_filesystem_default_close( + rtems_libio_t *iop +); + + +/** + * This method defines the interface to the default read(2) + * system call support which is provided by a file system + * implementation. + */ +ssize_t rtems_filesystem_default_read( + rtems_libio_t *iop, + void *buffer, + size_t count +); + +/** + * This method defines the interface to the default write(2) system call + * support which is provided by a file system implementation. + */ +ssize_t rtems_filesystem_default_write( + rtems_libio_t *iop, + const void *buffer, + size_t count +); + +/** + * This method defines the interface to the default ioctl(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_ioctl( + rtems_libio_t *iop, + uint32_t command, + void *buffer +); + +/** + * This method defines the interface to the default lseek(2) system call + * support which is provided by a file system implementation. + */ +rtems_off64_t rtems_filesystem_default_lseek( + rtems_libio_t *iop, + rtems_off64_t length, + int whence +); + +/** + * This method defines the interface to the default fstat(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_fstat( + rtems_filesystem_location_info_t *loc, + struct stat *buf +); + +/** + * This method defines the interface to the default fchmod(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_fchmod( + rtems_filesystem_location_info_t *loc, + mode_t mode +); + +/** + * This method defines the interface to the default ftruncate(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_ftruncate( + rtems_libio_t *iop, + rtems_off64_t length +); + +/** + * This method defines the interface to the default fpathconf(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_fpathconf( + rtems_libio_t *iop, + int name +); + +/** + * This method defines the interface to the default fsync(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_fsync( + rtems_libio_t *iop +); + +/** + * This method defines the interface to the default fdatasync(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_fdatasync( + rtems_libio_t *iop +); + +/** + * This method defines the interface to the default fnctl(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_fcntl( + int cmd, + rtems_libio_t *iop +); + +/** + * This method defines the interface to the default rmnod(2) system call + * support which is provided by a file system implementation. + */ +int rtems_filesystem_default_rmnod( + rtems_filesystem_location_info_t *parent_loc, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN */ +); + +/** + * @name File System Operations + * + * @{ + */ + +/** + * This type defines the interface to the mknod(2) system call + * support which is provided by a file system implementation. + * + * @note 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 */ +); + +/** + * This type defines the interface that allows the + * file system implementation to parse a path and + * allocate any memory necessary for tracking purposes. + * + * @note rtems_filesystem_freenode_t must be called by + * the generic after calling this routine + */ +typedef int (*rtems_filesystem_evalpath_t)( + const char *pathname, /* IN */ + size_t pathnamelen, /* IN */ + int flags, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN/OUT */ +); + +/** + * This type defines the interface that allows the + * file system implementation to parse a path with the + * intent of creating a new node and to + * allocate any memory necessary for tracking purposes. + * + * @note rtems_filesystem_freenode_t must be called by + * the generic after calling this routine + */ +typedef int (*rtems_filesystem_evalmake_t)( + const char *path, /* IN */ + rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ + const char **name /* OUT */ +); + +/** + * This type defines the interface to the link(2) system call + * support which is provided by a file system implementation. + */ +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 */ +); + +/** + * This type defines the interface to the unlink(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_unlink_t)( + rtems_filesystem_location_info_t *parent_pathloc, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN */ +); + +/** + * This type defines the interface to the chown(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_chown_t)( + rtems_filesystem_location_info_t *pathloc, /* IN */ + uid_t owner, /* IN */ + gid_t group /* IN */ +); + +/** + * This type defines the interface to the freenod(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_freenode_t)( + rtems_filesystem_location_info_t *pathloc /* IN */ +); + +/** + * This type defines the interface that allows the implemented + * filesystem ot mount another filesystem at the given location. + */ +typedef int (* rtems_filesystem_mount_t ) ( + rtems_filesystem_mount_table_entry_t *mt_entry /* IN */ +); + +/** + * This type defines the interface that allows a file system + * implementation to do any necessary work that is needed when + * it is being mounted. + */ +typedef int (* rtems_filesystem_fsmount_me_t )( + rtems_filesystem_mount_table_entry_t *mt_entry, /* IN */ + const void *data /* IN */ +); + +/** + * This type defines the interface allow the filesystem to + * unmount a filesystem that was mounted at one of its node + * locations. + */ +typedef int (* rtems_filesystem_unmount_t ) ( + rtems_filesystem_mount_table_entry_t *mt_entry /* IN */ +); + +/** + * This type defines the interface that allows a file system + * implementation to do any necessary work that is needed when + * it is being unmounted. + */ +typedef int (* rtems_filesystem_fsunmount_me_t ) ( + rtems_filesystem_mount_table_entry_t *mt_entry /* IN */ +); + +/** + * This type defines the interface that will return the + * type of a filesystem implementations node. + */ +typedef rtems_filesystem_node_types_t (* rtems_filesystem_node_type_t) ( + rtems_filesystem_location_info_t *pathloc /* IN */ +); + +/** + * This type defines the interface to the time(2) system call + * support which is provided by a file system implementation. + */ +typedef int (* rtems_filesystem_utime_t)( + rtems_filesystem_location_info_t *pathloc, /* IN */ + time_t actime, /* IN */ + time_t modtime /* IN */ +); + +/** + * This type defines the interface to the link(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_evaluate_link_t)( + rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ + int flags /* IN */ +); + +/** + * This type defines the interface to the symlink(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_symlink_t)( + rtems_filesystem_location_info_t *loc, /* IN */ + const char *link_name, /* IN */ + const char *node_name +); + +/** + * This type defines the interface to the readlink(2) system call + * support which is provided by a file system implementation. + */ +typedef ssize_t (*rtems_filesystem_readlink_t)( + rtems_filesystem_location_info_t *loc, /* IN */ + char *buf, /* OUT */ + size_t bufsize +); + +/** + * This type defines the interface to the name(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_rename_t)( + rtems_filesystem_location_info_t *old_parent_loc, /* IN */ + rtems_filesystem_location_info_t *old_loc, /* IN */ + rtems_filesystem_location_info_t *new_parent_loc, /* IN */ + const char *name /* IN */ +); + +/** + * This type defines the interface to the statvfs(2) system call + * support which is provided by a file system implementation. + */ +typedef int (*rtems_filesystem_statvfs_t)( + rtems_filesystem_location_info_t *loc, /* IN */ + struct statvfs *buf /* OUT */ +); + +/** @} */ + +/** + * @brief File system operations table. + */ +struct _rtems_filesystem_operations_table { + + /** + * This field points to the file system specific implementation + * of the support routine that evaluates a character path and + * returns the node assocated with the last node in the path. + * + * @note This method must have a filesystem specific implementation. + * + * @note There is no default implementation. + */ + rtems_filesystem_evalpath_t evalpath_h; + + /** + * This field points to the file system specific implementation + * of the support routine that evaluates a character path and + * returns the node assocated with next to the last node in + * the path. The last node will be the new node to be created. + * + * @note This method must have a filesystem specific implementation. + * + * @note There is no default implementation. + */ + rtems_filesystem_evalmake_t evalformake_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the link(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_link_t link_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the unlink(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_unlink_t unlink_h; + + /** + * This field points to the file system specific implementation + * of a method that returns the node type of the given node. + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_node_type_t node_type_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the link(2) system call + * + * @note This method may use a mknod implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_mknod_t mknod_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the link(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_chown_t chown_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the freenod(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_freenode_t freenod_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the mount(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_mount_t mount_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the fsmount(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_fsmount_me_t fsmount_me_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the unmount(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_unmount_t unmount_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the fsunmount(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_fsunmount_me_t fsunmount_me_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the utime(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_utime_t utime_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the eval_link(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_evaluate_link_t eval_link_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the sumlink(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_symlink_t symlink_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the readlink(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_readlink_t readlink_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the rename(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_rename_t rename_h; + + /** + * This field points to the file system specific implementation + * of the support routine for the statvfs(2) system call + * + * @note This method may use a default implementation. + * + * @note The default implementation returns -1 and sets + * errno to ENOTSUP. + */ + rtems_filesystem_statvfs_t statvfs_h; +}; + +extern const rtems_filesystem_operations_table +rtems_filesystem_operations_default; + +/** + * @brief Provides a defualt routine for filesystem + * implementation of path evaluation. + */ +int rtems_filesystem_default_evalpath( + const char *pathname, + size_t pathnamelen, + int flags, + rtems_filesystem_location_info_t *pathloc +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of path evaluation for make. + */ +int rtems_filesystem_default_evalformake( + const char *path, + rtems_filesystem_location_info_t *pathloc, + const char **name +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a link command. + */ +int rtems_filesystem_default_link( + rtems_filesystem_location_info_t *to_loc, /* IN */ + rtems_filesystem_location_info_t *parent_loc, /* IN */ + const char *name /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a unlink command. + */ +int rtems_filesystem_default_unlink( + rtems_filesystem_location_info_t *parent_pathloc, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation to determine the node type. + */ +rtems_filesystem_node_types_t rtems_filesystem_default_node_type( + rtems_filesystem_location_info_t *pathloc +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation to create a new node. + */ +int rtems_filesystem_default_mknod( + const char *path, /* IN */ + mode_t mode, /* IN */ + dev_t dev, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN/OUT */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a chown command. + */ +int rtems_filesystem_default_chown( + rtems_filesystem_location_info_t *pathloc, /* IN */ + uid_t owner, /* IN */ + gid_t group /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a freenode command. + */ +int rtems_filesystem_default_freenode( + rtems_filesystem_location_info_t *pathloc /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a mount command. + */ +int rtems_filesystem_default_mount ( + rtems_filesystem_mount_table_entry_t *mt_entry /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a fsmount command. + */ +int rtems_filesystem_default_fsmount( + rtems_filesystem_mount_table_entry_t *mt_entry, /* IN */ + const void *data /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a unmount command. + */ +int rtems_filesystem_default_unmount( + rtems_filesystem_mount_table_entry_t *mt_entry /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a fsunmount command. + */ +int rtems_filesystem_default_fsunmount( + rtems_filesystem_mount_table_entry_t *mt_entry /* IN */ +); + + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a utime command. + */ +int rtems_filesystem_default_utime( + rtems_filesystem_location_info_t *pathloc, /* IN */ + time_t actime, /* IN */ + time_t modtime /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a link command. + */ +int rtems_filesystem_default_evaluate_link( + rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ + int flags /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a symlink command. + */ +int rtems_filesystem_default_symlink( + rtems_filesystem_location_info_t *loc, /* IN */ + const char *link_name, /* IN */ + const char *node_name +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a readlink command. + */ +ssize_t rtems_filesystem_default_readlink( + rtems_filesystem_location_info_t *loc, /* IN */ + char *buf, /* OUT */ + size_t bufsize +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a rename command. + */ +int rtems_filesystem_default_rename( + rtems_filesystem_location_info_t *old_parent_loc, /* IN */ + rtems_filesystem_location_info_t *old_loc, /* IN */ + rtems_filesystem_location_info_t *new_parent_loc, /* IN */ + const char *name /* IN */ +); + +/** + * @brief Provides a defualt routine for filesystem + * implementation of a statvfs command. + */ +int rtems_filesystem_default_statvfs( + rtems_filesystem_location_info_t *loc, /* IN */ + struct statvfs *buf /* OUT */ +); + +/** + * @brief Gets the mount handler for the file system @a type. + * + * @return The file system mount handler associated with the @a type, or + * @c NULL if no such association exists. + */ +rtems_filesystem_fsmount_me_t +rtems_filesystem_get_mount_handler( + const char *type +); + +/** + * @brief Contain file system specific information which is required to support + * fpathconf(). + */ +typedef struct { + int link_max; /* count */ + int max_canon; /* max formatted input line size */ + int max_input; /* max input line size */ + int name_max; /* max name length */ + int path_max; /* max path */ + int pipe_buf; /* pipe buffer size */ + int posix_async_io; /* async IO supported on fs, 0=no, 1=yes */ + int posix_chown_restrictions; /* can chown: 0=no, 1=yes */ + int posix_no_trunc; /* error on names > max name, 0=no, 1=yes */ + int posix_prio_io; /* priority IO, 0=no, 1=yes */ + int posix_sync_io; /* file can be sync'ed, 0=no, 1=yes */ + int posix_vdisable; /* special char processing, 0=no, 1=yes */ +} rtems_filesystem_limits_and_options_t; + +/** + * @brief Default pathconf settings. + * + * Override in a filesystem. + */ +extern const rtems_filesystem_limits_and_options_t rtems_filesystem_default_pathconf; + +/** + * @brief An open file data structure. + * + * It will be 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; + rtems_off64_t size; /* size of file */ + rtems_off64_t offset; /* current offset into file */ + uint32_t flags; + rtems_filesystem_location_info_t pathinfo; + rtems_id sem; + uint32_t data0; /* private to "driver" */ + void *data1; /* ... */ +}; + +/** + * @brief Paramameter block for read/write. + * + * 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_off64_t offset; + char *buffer; + uint32_t count; + uint32_t flags; + uint32_t bytes_moved; +} rtems_libio_rw_args_t; + +/** + * @brief Parameter block for open/close. + */ +typedef struct { + rtems_libio_t *iop; + uint32_t flags; + uint32_t mode; +} rtems_libio_open_close_args_t; + +/** + * @brief Parameter block for ioctl. + */ +typedef struct { + rtems_libio_t *iop; + uint32_t command; + void *buffer; + uint32_t ioctl_return; +} rtems_libio_ioctl_args_t; + +/** + * @name Flag Values + * + * @{ + */ + +#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */ +#define LIBIO_FLAGS_READ 0x0002 /* reading */ +#define LIBIO_FLAGS_WRITE 0x0004 /* writing */ +#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); + +/** + * @name External I/O Handlers + * + * @{ + */ + +typedef int (*rtems_libio_open_t)( + const char *pathname, + uint32_t flag, + uint32_t mode +); + +typedef int (*rtems_libio_close_t)( + int fd +); + +typedef ssize_t (*rtems_libio_read_t)( + int fd, + void *buffer, + size_t count +); + +typedef ssize_t (*rtems_libio_write_t)( + int fd, + const void *buffer, + size_t count +); + +typedef int (*rtems_libio_ioctl_t)( + int fd, + uint32_t command, + void *buffer +); + +typedef rtems_off64_t (*rtems_libio_lseek_t)( + int fd, + rtems_off64_t offset, + int whence +); + +/** @} */ + +/** + * @name Permission Macros + * + * @{ + */ + +/* + * 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 + +/** @} */ + +union __rtems_dev_t { + dev_t device; + struct { + rtems_device_major_number major; + rtems_device_minor_number minor; + } __overlay; +}; + +static inline dev_t rtems_filesystem_make_dev_t( + rtems_device_major_number _major, + rtems_device_minor_number _minor +) +{ + union __rtems_dev_t temp; + + temp.__overlay.major = _major; + temp.__overlay.minor = _minor; + return temp.device; +} + +static inline rtems_device_major_number rtems_filesystem_dev_major_t( + dev_t device +) +{ + union __rtems_dev_t temp; + + temp.device = device; + return temp.__overlay.major; +} + + +static inline rtems_device_minor_number rtems_filesystem_dev_minor_t( + dev_t device +) +{ + union __rtems_dev_t temp; + + temp.device = device; + return temp.__overlay.minor; +} + +#define rtems_filesystem_split_dev_t( _dev, _major, _minor ) \ + do { \ + (_major) = rtems_filesystem_dev_major_t ( _dev ); \ + (_minor) = rtems_filesystem_dev_minor_t( _dev ); \ + } while(0) + +/* + * Verifies that the permission flag is valid. + */ +#define rtems_libio_is_valid_perms( _perm ) \ + (((~RTEMS_LIBIO_PERMS_RWX) & _perm ) == 0) + +/* + * Prototypes for filesystem + */ + +void rtems_filesystem_initialize( void ); + +typedef void (*rtems_libio_init_functions_t)(void); +extern rtems_libio_init_functions_t rtems_libio_init_helper; + +void open_dev_console(void); + +typedef void (*rtems_libio_supp_functions_t)(void); +extern rtems_libio_supp_functions_t rtems_libio_supp_helper; + +typedef void (*rtems_fs_init_functions_t)(void); +extern rtems_fs_init_functions_t rtems_fs_init_helper; + +/** + * @brief Creates a directory and all its parent directories according to + * @a path. + * + * The @a mode value selects the access permissions of the directory. + * + * @retval 0 Successful operation. + * @retval -1 An error occured. The @c errno indicates the error. + */ +extern int rtems_mkdir(const char *path, mode_t mode); + +/** @} */ + +/** + * @defgroup FileSystemTypesAndMount File System Types and Mount + * + * @ingroup LibIO + * + * @brief File system types and mount. + * + * @{ + */ + +/** + * @name File System Types + * + * @{ + */ + +#define RTEMS_FILESYSTEM_TYPE_IMFS "imfs" +#define RTEMS_FILESYSTEM_TYPE_MINIIMFS "mimfs" +#define RTEMS_FILESYSTEM_TYPE_DEVFS "devfs" +#define RTEMS_FILESYSTEM_TYPE_FTPFS "ftpfs" +#define RTEMS_FILESYSTEM_TYPE_TFTPFS "tftpfs" +#define RTEMS_FILESYSTEM_TYPE_NFS "nfs" +#define RTEMS_FILESYSTEM_TYPE_DOSFS "dosfs" +#define RTEMS_FILESYSTEM_TYPE_RFS "rfs" + +/** @} */ + +/** + * @brief Mount table entry. + */ +struct rtems_filesystem_mount_table_entry_tt { + rtems_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; + + /* + * The target or mount point of the file system. + */ + const char *target; + + /* + * The type of filesystem or the name of the filesystem. + */ + const char *type; + + /* + * When someone adds a mounted filesystem on a real device, + * this will need to be used. + * + * The lower layers can manage how this is managed. Leave as a + * string. + */ + char *dev; +}; + +/** + * @brief File system options. + */ +typedef enum { + RTEMS_FILESYSTEM_READ_ONLY, + RTEMS_FILESYSTEM_READ_WRITE, + RTEMS_FILESYSTEM_BAD_OPTIONS +} rtems_filesystem_options_t; + +/** + * @brief File system table entry. + */ +typedef struct rtems_filesystem_table_t { + const char *type; + rtems_filesystem_fsmount_me_t mount_h; +} rtems_filesystem_table_t; + +/** + * @brief Static table of file systems. + * + * Externally defined by confdefs.h or the user. + */ +extern const rtems_filesystem_table_t rtems_filesystem_table []; + +/** + * @brief Registers a file system @a type. + * + * The @a mount_h handler will be used to mount a file system of this @a type. + * + * @retval 0 Successful operation. + * @retval -1 An error occured. The @c errno indicates the error. + */ +int rtems_filesystem_register( + const char *type, + rtems_filesystem_fsmount_me_t mount_h +); + +/** + * @brief Unregisters a file system @a type. + * + * @retval 0 Successful operation. + * @retval -1 An error occured. The @c errno indicates the error. + */ +int rtems_filesystem_unregister( + const char *type +); + +/** + * @brief Unmounts the file system at @a mount_path. + * + * @todo Due to file system implementation shortcomings it is possible to + * unmount file systems in use. This likely leads to heap corruption. Unmount + * only file systems which are not in use by the application. + * + * @retval 0 Successful operation. + * @retval -1 An error occured. The @c errno indicates the error. + */ +int unmount( + const char *mount_path +); + +/** + * @brief Mounts a file system at @a target. + * + * The @a source may be a path to the corresponding device file, or @c NULL. + * The @a target path must lead to an existing directory, or @c NULL. In case + * @a target is @c NULL, the root file system will be mounted. The @a data + * parameter will be forwarded to the file system initialization handler. The + * file system type is selected by @a filesystemtype and may be one of + * - RTEMS_FILESYSTEM_TYPE_DEVFS, + * - RTEMS_FILESYSTEM_TYPE_DOSFS, + * - RTEMS_FILESYSTEM_TYPE_FTPFS, + * - RTEMS_FILESYSTEM_TYPE_IMFS, + * - RTEMS_FILESYSTEM_TYPE_MINIIMFS, + * - RTEMS_FILESYSTEM_TYPE_NFS, + * - RTEMS_FILESYSTEM_TYPE_RFS, or + * - RTEMS_FILESYSTEM_TYPE_TFTPFS. + * + * Only configured or registered file system types are available. You can add + * file system types to your application configuration with + * - CONFIGURE_FILESYSTEM_DEVFS, + * - CONFIGURE_FILESYSTEM_DOSFS, + * - CONFIGURE_FILESYSTEM_FTPFS, + * - CONFIGURE_FILESYSTEM_IMFS, + * - CONFIGURE_FILESYSTEM_MINIIMFS, + * - CONFIGURE_FILESYSTEM_NFS, + * - CONFIGURE_FILESYSTEM_RFS, and + * - CONFIGURE_FILESYSTEM_TFTPFS. + * + * @see rtems_filesystem_register() and mount_and_make_target_path(). + * + * @retval 0 Successful operation. + * @retval -1 An error occured. The @c errno indicates the error. + */ +int mount( + const char *source, + const char *target, + const char *filesystemtype, + rtems_filesystem_options_t options, + const void *data +); + +/** + * @brief Mounts a file system and makes the @a target path. + * + * The @a target path will be created with rtems_mkdir() and must not be + * @c NULL. + * + * @see mount(). + * + * @retval 0 Successful operation. + * @retval -1 An error occured. The @c errno indicates the error. + */ +int mount_and_make_target_path( + const char *source, + const char *target, + const char *filesystemtype, + rtems_filesystem_options_t options, + const void *data +); + +/** + * @brief Per file system type routine. + * + * @see rtems_filesystem_iterate(). + * + * @retval true Stop the iteration. + * @retval false Continue the iteration. + */ +typedef bool (*rtems_per_filesystem_routine)( + const rtems_filesystem_table_t *fs_entry, + void *arg +); + +/** + * @brief Iterates over all file system types. + * + * For each file system type the @a routine will be called with the entry and + * the @a routine_arg parameter. + * + * Do not register or unregister file system types in @a routine. + * + * The iteration is protected by the IO library mutex. + * + * @retval true Iteration stopped due to @a routine return status. + * @retval false Iteration through all entries. + */ +bool rtems_filesystem_iterate( + rtems_per_filesystem_routine routine, + void *routine_arg +); + +/** + * @brief Per file system mount routine. + * + * @see rtems_filesystem_mount_iterate(). + * + * @retval true Stop the iteration. + * @retval false Continue the iteration. + */ +typedef bool (*rtems_per_filesystem_mount_routine)( + const rtems_filesystem_mount_table_entry_t *mt_entry, + void *arg +); + +/** + * @brief Iterates over all file system mounts. + * + * For each file system mount the @a routine will be called with the entry and + * the @a routine_arg parameter. + * + * Do not mount or unmount file systems in @a routine. + * + * The iteration is protected by the IO library mutex. + * + * @retval true Iteration stopped due to @a routine return status. + * @retval false Iteration through all entries. + */ +bool +rtems_filesystem_mount_iterate( + rtems_per_filesystem_mount_routine routine, + void *routine_arg +); + +/** + * @brief Boot time mount table entry. + */ +typedef struct { + const char *type; + rtems_filesystem_options_t fsoptions; + const char *device; + const char *mount_point; +} rtems_filesystem_mount_table_t; + +/** + * @brief Boot time mount table. + * + * @todo Only the first entry will be evaluated. Why do we need a table? + */ +extern const rtems_filesystem_mount_table_t *rtems_filesystem_mount_table; + +/** + * @brief Boot time mount table entry count. + * + * @todo Only the first entry will be evaluated. Why do we need a table? + */ +extern const int rtems_filesystem_mount_table_size; + +/** @} */ + +/** + * @defgroup Termios Termios + * + * @ingroup LibIO + * + * @brief Termios + * + * @{ + */ + +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); + ssize_t (*write)(int minor, const char *buf, size_t len); + int (*setAttributes)(int minor, const struct termios *t); + int (*stopRemoteTx)(int minor); + int (*startRemoteTx)(int minor); + int outputUsesInterrupts; +} rtems_termios_callbacks; + +void rtems_termios_initialize (void); + +/* + * CCJ: Change before opening a tty. Newer code from Eric is coming + * so extra work to handle an open tty is not worth it. If the tty + * is open, close then open it again. + */ +rtems_status_code rtems_termios_bufsize ( + int cbufsize, /* cooked buffer size */ + int raw_input, /* raw input buffer size */ + int raw_output /* raw output buffer size */ +); + +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 +); + +/** @} */ + +/** + * @brief The pathconf setting for a file system. + */ +#define rtems_filesystem_pathconf(_mte) ((_mte)->pathconf_limits_and_options) + +/** + * @brief The type of file system. Its name. + */ +#define rtems_filesystem_type(_mte) ((_mte)->type) + +/** + * @brief The mount point of a file system. + */ +#define rtems_filesystem_mount_point(_mte) ((_mte)->target) + +/** + * @brief The device entry of a file system. + */ +#define rtems_filesystem_mount_device(_mte) ((_mte)->dev) + +#ifdef __cplusplus +} +#endif + +#endif /* _RTEMS_LIBIO_H */ diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h new file mode 100644 index 0000000000..f5cb537210 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/libio_.h @@ -0,0 +1,246 @@ +/** + * @file rtems/libio_.h + */ + +/* + * Libio Internal Information + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_LIBIO__H +#define _RTEMS_RTEMS_LIBIO__H + +#include <rtems.h> +#include <rtems/libio.h> /* include before standard IO */ + +#include <sys/types.h> + +#include <errno.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * 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 uint32_t rtems_libio_number_iops; +extern rtems_libio_t *rtems_libio_iops; +extern rtems_libio_t *rtems_libio_last_iop; +extern rtems_libio_t *rtems_libio_iop_freelist; + +/* + * rtems_libio_iop + * + * Macro to return the file descriptor pointer. + */ + +#define rtems_libio_iop(_fd) \ + ((((uint32_t)(_fd)) < rtems_libio_number_iops) ? \ + &rtems_libio_iops[_fd] : 0) + +/* + * rtems_libio_iop_to_descriptor + * + * Macro to convert an internal file descriptor pointer (iop) into + * the integer file descriptor used by the "section 2" system calls. + */ + +#define rtems_libio_iop_to_descriptor(_iop) \ + ((!(_iop)) ? -1 : (_iop - rtems_libio_iops)) + +/* + * rtems_libio_check_is_open + * + * Macro to check if a file descriptor is actually open. + */ + +#define rtems_libio_check_is_open(_iop) \ + do { \ + if (((_iop)->flags & LIBIO_FLAGS_OPEN) == 0) { \ + errno = EBADF; \ + return -1; \ + } \ + } while (0) + +/* + * rtems_libio_check_fd + * + * Macro to check if a file descriptor number is valid. + */ + +#define rtems_libio_check_fd(_fd) \ + do { \ + if ((uint32_t) (_fd) >= rtems_libio_number_iops) { \ + errno = EBADF; \ + return -1; \ + } \ + } while (0) + +/* + * rtems_libio_check_buffer + * + * 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) { \ + rtems_set_errno_and_return_minus_one( EINVAL ); \ + return -1; \ + } \ + } while (0) + +/* + * rtems_filesystem_freenode + * + * Macro to free a node. + */ + +void rtems_filesystem_freenode( rtems_filesystem_location_info_t* node ); + +/* + * External structures + */ +#include <rtems/userenv.h> + +extern rtems_user_env_t * rtems_current_user_env; +extern rtems_user_env_t rtems_global_user_env; + +/* + * Instantiate a private copy of the per user information for the calling task. + */ + +rtems_status_code rtems_libio_set_private_env(void); +rtems_status_code rtems_libio_share_private_env(rtems_id task_id) ; + +static inline void rtems_libio_lock( void ) +{ + rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); +} + +static inline void rtems_libio_unlock( void ) +{ + rtems_semaphore_release( rtems_libio_semaphore ); +} + +/* + * File Descriptor Routine Prototypes + */ + +rtems_libio_t *rtems_libio_allocate(void); + +uint32_t rtems_libio_fcntl_flags( + uint32_t fcntl_flags +); + +uint32_t rtems_libio_to_fcntl_flags( + uint32_t 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_relative_path( + const char *pathname, + size_t pathnamelen, + int flags, + rtems_filesystem_location_info_t *pathloc, + int follow_link +); + +int rtems_filesystem_evaluate_path( + const char *pathname, + size_t pathnamelen, + int flags, + rtems_filesystem_location_info_t *pathloc, + int follow_link +); + +int rtems_filesystem_dirname( + const char *pathname +); + +int rtems_filesystem_prefix_separators( + const char *pathname, + int pathnamelen +); + +void rtems_filesystem_initialize(void); + +int init_fs_mount_table(void); + +int rtems_filesystem_is_separator(char ch); + +void rtems_filesystem_get_start_loc(const char *path, + int *index, + rtems_filesystem_location_info_t *loc); + +void rtems_filesystem_get_sym_start_loc(const char *path, + int *index, + rtems_filesystem_location_info_t *loc); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/rtems/malloc.h b/cpukit/libcsupport/include/rtems/malloc.h new file mode 100644 index 0000000000..af092982f7 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/malloc.h @@ -0,0 +1,186 @@ +/** + * @file rtems/malloc.h + */ + +/* + * RTEMS Malloc Extensions + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_MALLOC_H +#define _RTEMS_MALLOC_H + +#include <rtems.h> +#include <rtems/bspIo.h> + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Malloc Statistics Structure + */ +typedef struct { + uint32_t space_available; /* current size of malloc area */ + uint32_t malloc_calls; /* # calls to malloc */ + uint32_t memalign_calls; /* # calls to memalign */ + uint32_t free_calls; + uint32_t realloc_calls; + uint32_t calloc_calls; + uint32_t max_depth; /* most ever malloc'd at 1 time */ + uintmax_t lifetime_allocated; + uintmax_t lifetime_freed; +} rtems_malloc_statistics_t; + +/* + * Malloc statistics plugin + */ +typedef struct { + void (*initialize)(void); + void (*at_malloc)(void *); + void (*at_free)(void *); +} rtems_malloc_statistics_functions_t; + +extern rtems_malloc_statistics_functions_t + rtems_malloc_statistics_helpers_table; +extern rtems_malloc_statistics_functions_t *rtems_malloc_statistics_helpers; + +/* + * Malloc Heap Extension (sbrk) plugin + */ +typedef struct { + void *(*initialize)(void *, size_t); + void *(*extend)(size_t); +} rtems_malloc_sbrk_functions_t; + +extern rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table; +extern rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers; + +/* + * Malloc Plugin to Dirty Memory at Allocation Time + */ +typedef void (*rtems_malloc_dirtier_t)(void *, size_t); +extern rtems_malloc_dirtier_t rtems_malloc_dirty_helper; + +/** @brief Dirty memory function + * + * This method fills the specified area with a non-zero pattern + * to aid in debugging programs which do not initialize their + * memory allocated from the heap. + */ +void rtems_malloc_dirty_memory( + void *start, + size_t size +); + +/** @brief Print Malloc Statistic Usage Report + * + * This method fills in the called provided malloc statistics area. + * + * @return This method returns 0 if successful and -1 on error. + */ +int malloc_get_statistics( + rtems_malloc_statistics_t *stats +); + +/** @brief Print Malloc Statistic Usage Report + * + * This method prints a malloc statistics report. + * + * @note It uses printk to print the report. + */ +void malloc_report_statistics(void); + +/** @brief Print Malloc Statistic Usage Report + * + * This method prints a malloc statistics report. + * + * @param[in] context is the context to pass to the print handler + * @param[in] print is the print handler + * + * @note It uses the CALLER's routine to print the report. + */ +void malloc_report_statistics_with_plugin( + void *context, + rtems_printk_plugin_t print +); + +/** + * + * This method is a help memalign implementation which does all + * error checking done by posix_memalign() EXCEPT it does NOT + * place numeric restrictions on the alignment value. + * + * @param[in] pointer points to the user pointer + * @param[in] alignment is the desired alignment + * @param[in] size is the allocation request size in bytes + * + * @return This methods returns zero on success and a POSIX errno + * value to indicate the failure condition. On success + * *pointer will contain the address of the allocated memory. + */ +int rtems_memalign( + void **pointer, + size_t alignment, + size_t size +); + +/** + * @brief Allocates a memory area of size @a size bytes from the heap. + * + * If the alignment parameter @a alignment is not equal to zero, the allocated + * memory area will begin at an address aligned by this value. + * + * If the boundary parameter @a boundary is not equal to zero, the allocated + * memory area will fulfill a boundary constraint. The boundary value + * specifies the set of addresses which are aligned by the boundary value. The + * interior of the allocated memory area will not contain an element of this + * set. The begin or end address of the area may be a member of the set. + * + * A size value of zero will return a unique address which may be freed with + * free(). + * + * The memory allocated by this function can be released with a call to free(). + * + * @return A pointer to the begin of the allocated memory area, or @c NULL if + * no memory is available or the parameters are inconsistent. + */ +void *rtems_heap_allocate_aligned_with_boundary( + size_t size, + uintptr_t alignment, + uintptr_t boundary +); + +/** + * @brief Extends the memory available for the heap using the memory area + * starting at @a area_begin of size @a area_size bytes. + * + * There are no alignment requirements. The memory area must be big enough to + * contain some maintainance blocks. It must not overlap parts of the current + * heap areas. Disconnected subordinate heap areas will lead to used blocks + * which cover the gaps. Extending with an inappropriate memory area will + * corrupt the heap. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ADDRESS Invalid memory area. + */ +rtems_status_code rtems_heap_extend( + void *area_begin, + uintptr_t area_size +); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h new file mode 100644 index 0000000000..ebba9ca9f7 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/termiostypes.h @@ -0,0 +1,210 @@ +/** + * @file rtems/termiostypes.h + */ + +/* + * RTEMS termios device support internal data structures + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef __TERMIOSTYPES_H +#define __TERMIOSTYPES_H + +#include <rtems.h> +#include <rtems/libio.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Wakeup callback data structure + */ +struct ttywakeup { + void (*sw_pfn)(struct termios *tty, void *arg); + void *sw_arg; +}; + +/* + * Variables associated with the character buffer + */ +struct rtems_termios_rawbuf { + char *theBuf; + volatile unsigned int Head; + volatile unsigned int Tail; + volatile unsigned int Size; + rtems_id Semaphore; +}; +/* + * Variables associated with each termios instance. + * One structure for each hardware I/O device. + */ +struct rtems_termios_tty { + /* + * Linked-list of active TERMIOS devices + */ + struct rtems_termios_tty *forw; + struct rtems_termios_tty *back; + + /* + * How many times has this device been opened + */ + int refcount; + + /* + * This device + */ + rtems_device_major_number major; + rtems_device_minor_number minor; + + /* + * Mutual-exclusion semaphores + */ + rtems_id isem; + rtems_id osem; + + /* + * The canonical (cooked) character buffer + */ + char *cbuf; + int ccount; + int cindex; + + /* + * Keep track of cursor (printhead) position + */ + int column; + int read_start_column; + + /* + * The ioctl settings + */ + struct termios termios; + rtems_interval vtimeTicks; + + /* + * Raw input character buffer + */ + struct rtems_termios_rawbuf rawInBuf; + uint32_t rawInBufSemaphoreOptions; + rtems_interval rawInBufSemaphoreTimeout; + rtems_interval rawInBufSemaphoreFirstTimeout; + unsigned int rawInBufDropped; /* Statistics */ + + /* + * Raw output character buffer + */ + struct rtems_termios_rawbuf rawOutBuf; + int t_dqlen; /* count of characters dequeued from device */ + enum {rob_idle, rob_busy, rob_wait } rawOutBufState; + + /* + * Callbacks to device-specific routines + */ + rtems_termios_callbacks device; + volatile unsigned int flow_ctrl; + unsigned int lowwater,highwater; + + /* + * I/O task IDs (for task-driven drivers) + */ + rtems_id rxTaskId; + rtems_id txTaskId; + + /* + * line discipline related stuff + */ + int t_line; /* id of line discipline */ + void *t_sc; /* hook for discipline-specific data structure */ + + /* + * Wakeup callback variables + */ + struct ttywakeup tty_snd; + struct ttywakeup tty_rcv; + int tty_rcvwakeup; +}; + +struct rtems_termios_linesw { + int (*l_open) (struct rtems_termios_tty *tp); + int (*l_close)(struct rtems_termios_tty *tp); + int (*l_read )(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args); + int (*l_write)(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args); + int (*l_rint )(int c,struct rtems_termios_tty *tp); + int (*l_start)(struct rtems_termios_tty *tp); + int (*l_ioctl)(struct rtems_termios_tty *tp,rtems_libio_ioctl_args_t *args); + int (*l_modem)(struct rtems_termios_tty *tp,int flags); +}; + +/* + * FIXME: this should move to libio.h! + * values for rtems_termios_callbacks.outputUsesInterrupts + */ +#define TERMIOS_POLLED 0 +#define TERMIOS_IRQ_DRIVEN 1 +#define TERMIOS_TASK_DRIVEN 2 + +/* + * FIXME: this should move to termios.h! + */ +void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty); + +/* + * FIXME: this should move to termios.h! + * put a string to output ring buffer + */ +void rtems_termios_puts ( + const void *buf, + int len, + struct rtems_termios_tty *tty +); + +/* + * global hooks for line disciplines + */ +extern struct rtems_termios_linesw rtems_termios_linesw[]; +extern int rtems_termios_nlinesw; + +#define TTYDISC 0 /* termios tty line discipline */ +#define TABLDISC 3 /* tablet discipline */ +#define SLIPDISC 4 /* serial IP discipline */ +#define PPPDISC 5 /* PPP discipline */ +#define MAXLDISC 8 + +/* baudrate xxx integer type */ +typedef int32_t rtems_termios_baud_t; + +/* convert xxx integer to equivalent Bxxx constant */ +int rtems_termios_number_to_baud(rtems_termios_baud_t baud); + +/* convert Bxxx constant to xxx integer */ +rtems_termios_baud_t rtems_termios_baud_to_number(int termios_baud); + +/* convert Bxxx constant to index */ +int rtems_termios_baud_to_index(rtems_termios_baud_t termios_baud); + +/* + * This method is used by a driver to tell termios its + * initial baud rate. This is especially important when + * the device driver does not set the baud to the default + * of B9600. + */ +int rtems_termios_set_initial_baud( + struct rtems_termios_tty *ttyp, + rtems_termios_baud_t baud +); + +#ifdef __cplusplus +} +#endif + +#endif /* TERMIOSTYPES_H */ diff --git a/cpukit/libcsupport/include/rtems/watchdogdrv.h b/cpukit/libcsupport/include/rtems/watchdogdrv.h new file mode 100644 index 0000000000..309ebf7b81 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/watchdogdrv.h @@ -0,0 +1,73 @@ +/** + * @file rtems/watchdogdrv.h + * + * This file describes the Watchdog Driver for all boards. + * A watchdog is a hardware device that will reset the board + * if not touched in a specific way at a regular interval. + * It is a simple, yet important, part of many embedded systems. + */ + +/* + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_WATCHDOGDRV_H +#define _RTEMS_WATCHDOGDRV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This macro defines the watchdog device driver entry points. + */ +#define WATCHDOG_DRIVER_TABLE_ENTRY \ + { Watchdog_initialize, NULL, NULL, NULL, NULL, Watchdog_control } + +/** + * @brief Watchdog Driver Initialization + * + * This method initializes the watchdog hardware device. The device + * should be initialized as DISABLED since BSP initialization may + * take longer than the timeout period for the watchdog. + * + * @param[in] major is the watchdog device major number + * @param[in] minor is the watchdog device minor number + * @param[in] arguments points to device driver arguments + */ +rtems_device_driver Watchdog_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arguments +); + +/** + * @brief Watchdog Driver IO Control + * + * This method implements the IO Control device driver entry + * point for the watchdog hardware device. + * + * @param[in] major is the watchdog device major number + * @param[in] minor is the watchdog device minor number + * @param[in] arguments points to device driver arguments + */ +rtems_device_driver Watchdog_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arguments +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/spurious.h b/cpukit/libcsupport/include/spurious.h new file mode 100644 index 0000000000..9aeffb53ce --- /dev/null +++ b/cpukit/libcsupport/include/spurious.h @@ -0,0 +1,45 @@ +/** + * @file rtems/spurious.h + */ + +/* spurious.h + * + * This file describes the Spurious Interrupt Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SPURIOUS_H +#define _RTEMS_SPURIOUS_H + +#include <rtems/rtems/types.h> /* rtems_id */ +#include <rtems/io.h> /* rtems_device_driver */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPURIOUS_DRIVER_TABLE_ENTRY \ + { Spurious_Initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver Spurious_Initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + uint32_t * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/sys/filio.h b/cpukit/libcsupport/include/sys/filio.h new file mode 100644 index 0000000000..5a8b7e4bbb --- /dev/null +++ b/cpukit/libcsupport/include/sys/filio.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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. + * + * @(#)filio.h 8.1 (Berkeley) 3/28/94 + * $Id$ + */ + +#ifndef _SYS_FILIO_H_ +#define _SYS_FILIO_H_ + +#include <sys/ioccom.h> + +/* RTEMS defines all of these in sys/ioccom.h */ +#if 0 +/* Generic file-descriptor ioctl's. */ +#define FIOCLEX _IO('f', 1) /* set close on exec on fd */ +#define FIONCLEX _IO('f', 2) /* remove close on exec */ +#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */ +#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */ +#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */ +#define FIOSETOWN _IOW('f', 124, int) /* set owner */ +#define FIOGETOWN _IOR('f', 123, int) /* get owner */ +#endif + +#endif /* !_SYS_FILIO_H_ */ diff --git a/cpukit/libcsupport/include/sys/ioccom.h b/cpukit/libcsupport/include/sys/ioccom.h new file mode 100644 index 0000000000..1a7fd27ef7 --- /dev/null +++ b/cpukit/libcsupport/include/sys/ioccom.h @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The 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. + * 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. + * + * @(#)ioccom.h 8.2 (Berkeley) 3/28/94 + * $FreeBSD: src/sys/sys/ioccom.h,v 1.15 2004/04/07 04:19:49 imp Exp $ + */ +/* + * $Id$ + */ + +#ifndef _SYS_IOCCOM_H_ +#define _SYS_IOCCOM_H_ + +#include <sys/types.h> + +/* + * Ioctl's have the command encoded in the lower word, and the size of + * any in or out parameters in the upper word. The high 3 bits of the + * upper word are used to encode the in/out status of the parameter. + */ +#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ +#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) +#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16)) +#define IOCGROUP(x) (((x) >> 8) & 0xff) + +#define IOCPARM_MAX PAGE_SIZE /* max size of ioctl, mult. of PAGE_SIZE */ +#define IOC_VOID 0x20000000 /* no parameters */ +#define IOC_OUT 0x40000000 /* copy out parameters */ +#define IOC_IN 0x80000000 /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) +#define IOC_DIRMASK 0xe0000000 /* mask for IN/OUT/VOID */ + +#define _IOC(inout,group,num,len) \ + (u_int32_t) ((u_int32_t)inout | \ + (u_int32_t) ((u_int32_t)((u_int32_t)len & IOCPARM_MASK) << 16) | \ + (u_int32_t)((group) << 8) | \ + (u_int32_t)(num)) +#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0) +#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) +#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) +/* this should be _IORW, but stdio got there first */ +#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) + +/* + * IOCTL values + */ + +#define RTEMS_IO_GET_ATTRIBUTES 1 +#define RTEMS_IO_SET_ATTRIBUTES 2 +#define RTEMS_IO_TCDRAIN 3 +#define RTEMS_IO_RCVWAKEUP 4 +#define RTEMS_IO_SNDWAKEUP 5 + +/* copied from libnetworking/sys/filio.h and commented out there */ +/* Generic file-descriptor ioctl's. */ +#define FIOCLEX _IO('f', 1) /* set close on exec on fd */ +#define FIONCLEX _IO('f', 2) /* remove close on exec */ +#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */ +#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */ +#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */ +#define FIOSETOWN _IOW('f', 124, int) /* set owner */ +#define FIOGETOWN _IOR('f', 123, int) /* get owner */ + +#ifndef _KERNEL + +#include <rtems/bsd/sys/cdefs.h> + +#ifndef __ioctl_command_defined +typedef u_int32_t ioctl_command_t; +#define __ioctl_command_defined +#endif + +__BEGIN_DECLS +int ioctl(int, ioctl_command_t, ...); +__END_DECLS + +#endif /* !KERNEL */ + +#endif /* !_SYS_IOCCOM_H_ */ diff --git a/cpukit/libcsupport/include/sys/ioctl.h b/cpukit/libcsupport/include/sys/ioctl.h new file mode 100644 index 0000000000..3957396ead --- /dev/null +++ b/cpukit/libcsupport/include/sys/ioctl.h @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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. + * 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. + * + * @(#)ioctl.h 8.6 (Berkeley) 3/28/94 + * $FreeBSD: src/sys/sys/ioctl.h,v 1.13 2004/06/11 11:16:26 phk Exp $ + */ + +/* + * $Id$ + */ + +#ifndef _SYS_IOCTL_H_ +#define _SYS_IOCTL_H_ + +#include <sys/ttycom.h> + +/* + * Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ + * and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented + * notwithstanding). + */ +struct ttysize { + unsigned short ts_lines; + unsigned short ts_cols; + unsigned short ts_xxx; + unsigned short ts_yyy; +}; +#define TIOCGSIZE TIOCGWINSZ +#define TIOCSSIZE TIOCSWINSZ + +#include <sys/ioccom.h> + +#include <sys/filio.h> +#include <sys/sockio.h> + +#endif /* !_SYS_IOCTL_H_ */ diff --git a/cpukit/libcsupport/include/sys/sockio.h b/cpukit/libcsupport/include/sys/sockio.h new file mode 100644 index 0000000000..15ade24729 --- /dev/null +++ b/cpukit/libcsupport/include/sys/sockio.h @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The 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. + * 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. + * + * @(#)sockio.h 8.1 (Berkeley) 3/28/94 + * $FreeBSD: src/sys/sys/sockio.h,v 1.31 2006/07/09 06:04:00 sam Exp $ + */ + +/* + * $Id$ + */ + +#ifndef _SYS_SOCKIO_H_ +#define _SYS_SOCKIO_H_ + +#include <sys/ioccom.h> + +/* Socket ioctl's. */ +#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */ +#define SIOCSPGRP _IOW('s', 8, int) /* set process group */ +#define SIOCGPGRP _IOR('s', 9, int) /* get process group */ + +#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */ +#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */ +#define SIOCGETVIFCNT _IOWR('r', 15, struct sioc_vif_req)/* get vif pkt cnt */ +#define SIOCGETSGCNT _IOWR('r', 16, struct sioc_sg_req) /* get s,g pkt cnt */ + +#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */ +#define OSIOCGIFADDR _IOWR('i', 13, struct ifreq) /* get ifnet address */ +#define SIOCGIFADDR _IOWR('i', 33, struct ifreq) /* get ifnet address */ +#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */ +#define OSIOCGIFDSTADDR _IOWR('i', 15, struct ifreq) /* get p-p address */ +#define SIOCGIFDSTADDR _IOWR('i', 34, struct ifreq) /* get p-p address */ +#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */ +#define SIOCGIFFLAGS _IOWR('i', 17, struct ifreq) /* get ifnet flags */ +#define OSIOCGIFBRDADDR _IOWR('i', 18, struct ifreq) /* get broadcast addr */ +#define SIOCGIFBRDADDR _IOWR('i', 35, struct ifreq) /* get broadcast addr */ +#define SIOCSIFBRDADDR _IOW('i', 19, struct ifreq) /* set broadcast addr */ +#define OSIOCGIFCONF _IOWR('i', 20, struct ifconf) /* get ifnet list */ +#define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */ +#define OSIOCGIFNETMASK _IOWR('i', 21, struct ifreq) /* get net addr mask */ +#define SIOCGIFNETMASK _IOWR('i', 37, struct ifreq) /* get net addr mask */ +#define SIOCSIFNETMASK _IOW('i', 22, struct ifreq) /* set net addr mask */ +#define SIOCGIFMETRIC _IOWR('i', 23, struct ifreq) /* get IF metric */ +#define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */ +#define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */ +#define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */ + +#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */ +#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */ +#define SIOCGIFMTU _IOWR('i', 51, struct ifreq) /* get IF mtu */ +#define SIOCSIFMTU _IOW('i', 52, struct ifreq) /* set IF mtu */ +#define SIOCGIFPHYS _IOWR('i', 53, struct ifreq) /* get IF wire */ +#define SIOCSIFPHYS _IOW('i', 54, struct ifreq) /* set IF wire */ +#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */ +#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ + +/* + * RTEMS additions for setting/getting `tap' function on incoming packets. + */ +#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ +#define SIOCGIFTAP _IOW('i', 81, struct ifreq) /* get tap function */ + +#endif /* !_SYS_SOCKIO_H_ */ diff --git a/cpukit/libcsupport/include/sys/statvfs.h b/cpukit/libcsupport/include/sys/statvfs.h new file mode 100644 index 0000000000..1029eb3c6b --- /dev/null +++ b/cpukit/libcsupport/include/sys/statvfs.h @@ -0,0 +1,52 @@ +/* + * COPYRIGHT (c) 2009 Chris Johns <chrisj@rtems.org> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ +/* + * The statvfs as defined by the SUS: + * http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html + */ + +#ifndef _SYS_STATVFS_H_ +#define _SYS_STATVFS_H_ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint64_t fsblkcnt_t; +typedef uint32_t fsfilcnt_t; + +struct statvfs +{ + unsigned long f_bsize; /**< File system block size. */ + unsigned long f_frsize; /**< Fundamental file system block size. */ + fsblkcnt_t f_blocks; /**< Total number of blocks on file system in units + * of f_frsize. */ + fsblkcnt_t f_bfree; /**< Total number of free blocks. */ + fsblkcnt_t f_bavail; /**< Number of free blocks available to + * non-privileged process. */ + fsfilcnt_t f_files; /**< Total number of file serial numbers. */ + fsfilcnt_t f_ffree; /**< Total number of free file serial numbers. */ + fsfilcnt_t f_favail; /**< Number of file serial numbers available to + * non-privileged process. */ + unsigned long f_fsid; /**< File system ID. */ + unsigned long f_flag; /**< Bit mask of f_flag values. */ + unsigned long f_namemax; /**< Maximum filename length. */ +}; + +extern int statvfs(const char *, struct statvfs *); +extern int fstatvfs(int, struct statvfs *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/include/sys/termios.h b/cpukit/libcsupport/include/sys/termios.h new file mode 100644 index 0000000000..f619c95709 --- /dev/null +++ b/cpukit/libcsupport/include/sys/termios.h @@ -0,0 +1,198 @@ +/* + * POSIX termios implementation for RTEMS console device driver. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef TERMIOS_H +#define TERMIOS_H + +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CRTSCTS 020000000000 /* flow control */ + +#define RTEMS_TERMIOS_NUMBER_BAUD_RATES 20 + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +int tcdrain(int); +int tcflow(int, int); +int tcflush(int, int); +int tcgetattr(int, struct termios *); +int tcsetattr(int, int, struct termios *); +int tcdrain(int); +pid_t tcgetprgrp(int); +int tcsetprgrp(int, pid_t); +int tcsendbreak(int, int); + +speed_t cfgetospeed(const struct termios *tp); +int cfsetospeed(struct termios *tp, speed_t speed); +speed_t cfgetispeed(const struct termios *tp); +int cfsetispeed(struct termios *tp, speed_t speed); + +#ifdef __cplusplus +} +#endif + +#endif /* TERMIOS_H */ diff --git a/cpukit/libcsupport/include/sys/ttycom.h b/cpukit/libcsupport/include/sys/ttycom.h new file mode 100644 index 0000000000..f2e491bc50 --- /dev/null +++ b/cpukit/libcsupport/include/sys/ttycom.h @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 1982, 1986, 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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. + * + * @(#)ttycom.h 8.1 (Berkeley) 3/28/94 + * $Id$ + */ + +#ifndef _SYS_TTYCOM_H_ +#define _SYS_TTYCOM_H_ + +#include <sys/ioccom.h> + +/* + * Tty ioctl's except for those supported only for backwards compatibility + * with the old tty driver. + */ + +/* + * Window/terminal size structure. This information is stored by the kernel + * in order to provide a consistent interface, but is not used by the kernel. + */ +struct winsize { + unsigned short ws_row; /* rows, in characters */ + unsigned short ws_col; /* columns, in characters */ + unsigned short ws_xpixel; /* horizontal size, pixels */ + unsigned short ws_ypixel; /* vertical size, pixels */ +}; + +#define TIOCMODG _IOR('t', 3, int) /* get modem control state */ +#define TIOCMODS _IOW('t', 4, int) /* set modem control state */ +#define TIOCM_LE 0001 /* line enable */ +#define TIOCM_DTR 0002 /* data terminal ready */ +#define TIOCM_RTS 0004 /* request to send */ +#define TIOCM_ST 0010 /* secondary transmit */ +#define TIOCM_SR 0020 /* secondary receive */ +#define TIOCM_CTS 0040 /* clear to send */ +#define TIOCM_CAR 0100 /* carrier detect */ +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RNG 0200 /* ring */ +#define TIOCM_RI TIOCM_RNG +#define TIOCM_DSR 0400 /* data set ready */ + /* 8-10 compat */ +#define TIOCEXCL _IO('t', 13) /* set exclusive use of tty */ +#define TIOCNXCL _IO('t', 14) /* reset exclusive use of tty */ + /* 15 unused */ +#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */ + /* 17-18 compat */ +#define TIOCGETA _IOR('t', 19, struct termios) /* get termios struct */ +#define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */ +#define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */ +#define TIOCSETAF _IOW('t', 22, struct termios) /* drn out, fls in, set */ +#define TIOCGETD _IOR('t', 26, int) /* get line discipline */ +#define TIOCSETD _IOW('t', 27, int) /* set line discipline */ + /* 127-124 compat */ +#define TIOCSBRK _IO('t', 123) /* set break bit */ +#define TIOCCBRK _IO('t', 122) /* clear break bit */ +#define TIOCSDTR _IO('t', 121) /* set data terminal ready */ +#define TIOCCDTR _IO('t', 120) /* clear data terminal ready */ +#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */ +#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */ + /* 117-116 compat */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ +#define TIOCSTI _IOW('t', 114, char) /* simulate terminal input */ +#define TIOCNOTTY _IO('t', 113) /* void tty association */ +#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */ +#define TIOCPKT_DATA 0x00 /* data packet */ +#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */ +#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ +#define TIOCPKT_STOP 0x04 /* stop output */ +#define TIOCPKT_START 0x08 /* start output */ +#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ +#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ +#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */ +#define TIOCMBIS _IOW('t', 108, int) /* bis modem bits */ +#define TIOCMBIC _IOW('t', 107, int) /* bic modem bits */ +#define TIOCMGET _IOR('t', 106, int) /* get all modem bits */ +#define TIOCREMOTE _IOW('t', 105, int) /* remote input editing */ +#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */ +#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */ +#define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */ +#define TIOCSTAT _IO('t', 101) /* simulate ^T status message */ +#define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */ +#define TIOCCONS _IOW('t', 98, int) /* become virtual console */ +#define TIOCSCTTY _IO('t', 97) /* become controlling tty */ +#define TIOCEXT _IOW('t', 96, int) /* pty: external processing */ +#define TIOCSIG _IO('t', 95) /* pty: generate signal */ +#define TIOCDRAIN _IO('t', 94) /* wait till output drained */ +#define TIOCMSDTRWAIT _IOW('t', 91, int) /* modem: set wait on close */ +#define TIOCMGDTRWAIT _IOR('t', 90, int) /* modem: get wait on close */ +#define TIOCTIMESTAMP _IOR('t', 89, struct timeval) /* enable/get timestamp + * of last input event */ +#define TIOCDCDTIMESTAMP _IOR('t', 88, struct timeval) /* enable/get timestamp + * of last DCd rise */ +#define TIOCSDRAINWAIT _IOW('t', 87, int) /* set ttywait timeout */ +#define TIOCGDRAINWAIT _IOR('t', 86, int) /* get ttywait timeout */ +#define TIOCDSIMICROCODE _IO('t', 85) /* download microcode to + * DSI Softmodem */ + +#define TTYDISC 0 /* termios tty line discipline */ +#define TABLDISC 3 /* tablet discipline */ +#define SLIPDISC 4 /* serial IP discipline */ +#define PPPDISC 5 /* PPP discipline */ + +#endif /* !_SYS_TTYCOM_H_ */ diff --git a/cpukit/libcsupport/include/sys/utsname.h b/cpukit/libcsupport/include/sys/utsname.h new file mode 100644 index 0000000000..b1b2e6ef41 --- /dev/null +++ b/cpukit/libcsupport/include/sys/utsname.h @@ -0,0 +1,52 @@ +/* sys/utsname.h + * + * $Id$ + */ + +#ifndef __POSIX_SYS_UTSNAME_h +#define __POSIX_SYS_UTSNAME_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * 4.4.1 Get System Name (Table 4-1), P1003.1b-1993, p. 90 + * + * NOTE: The lengths of the strings in this structure are + * just long enough to reliably contain the RTEMS information. + * For example, the fields are not long enough to support + * Internet hostnames. + */ + +#ifdef _KERNEL +#define SYS_NMLN 32 /* uname(2) for the FreeBSD 1.1 ABI. */ +#endif + +#ifndef SYS_NMLN +#define SYS_NMLN 32 /* User can override. */ +#endif + +struct utsname { + char sysname[SYS_NMLN]; /* Name of this implementation of the operating system */ + char nodename[SYS_NMLN]; /* Name of this node within an implementation */ + /* specified communication network */ + char release[SYS_NMLN]; /* Current release level of this implementation */ + char version[SYS_NMLN]; /* Current version level of this release */ + char machine[SYS_NMLN]; /* Name of the hardware type on which the system */ + /* is running */ +}; + +/* + * 4.4.1 Get System Name, P1003.1b-1993, p. 90 + */ + +int uname( + struct utsname *name +); + +#ifdef __cplusplus +} +#endif +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/timerdrv.h b/cpukit/libcsupport/include/timerdrv.h new file mode 100644 index 0000000000..872c6db217 --- /dev/null +++ b/cpukit/libcsupport/include/timerdrv.h @@ -0,0 +1,34 @@ +/** + * @file rtems/timerdrv.h + * + * This file describes the Timer Driver for all boards. + */ + +/* + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_TIMERDRV_H +#define _RTEMS_TIMERDRV_H + +#include <rtems/btimer.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Intentionally empty */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/include/vmeintr.h b/cpukit/libcsupport/include/vmeintr.h new file mode 100644 index 0000000000..990592c83a --- /dev/null +++ b/cpukit/libcsupport/include/vmeintr.h @@ -0,0 +1,59 @@ +/** + * @file rtems/vmeintr.h + * + * This file is the specification for the VMEbus interface library + * which should be provided by all BSPs for VMEbus Single Board + * Computers but currently only a few do so. + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_VMEINTR_H +#define _RTEMS_VMEINTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This defines the mask which is used to determine which + * interrupt levels are affected by a call to this package. + * The LSB corresponds to VME interrupt 0 and the MSB + * to VME interrupt 7. + * + */ + +typedef uint8_t VME_interrupt_Mask; + +/* + * VME_interrupt_Disable + * + */ + +void VME_interrupt_Disable ( + VME_interrupt_Mask mask /* IN */ +); + +/* + * VME_interrupt_Disable + * + */ + +void VME_interrupt_Enable ( + VME_interrupt_Mask mask /* IN */ +); + +#ifdef __cplusplus +} +#endif + +#endif /* end of include file */ diff --git a/cpukit/libcsupport/include/zilog/z8036.h b/cpukit/libcsupport/include/zilog/z8036.h new file mode 100644 index 0000000000..707b6dd567 --- /dev/null +++ b/cpukit/libcsupport/include/zilog/z8036.h @@ -0,0 +1,106 @@ +/** + * @file rtems/zilog/z8036.h + */ + +/* + * This include file defines information related to a Zilog Z8036 + * Counter/Timer/IO Chip. It is a memory mapped part. + * + * NOTE: This file shares as much as possible with the include + * file for the Z8536 via z8x36.h. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_ZILOG_Z8036_H +#define _RTEMS_ZILOG_Z8036_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* macros */ + +#define Z8036( ptr ) ((volatile struct z8036_map *)(ptr)) + +#define Z8x36_STATE0 ( z8036 ) \ + { /*char *garbage = *(Z8036(z8036))->???; */ } + + +#define Z8x36_WRITE( z8036, reg, data ) \ + (Z8036(z8036))->reg = (data) + + +#define Z8x36_READ( z8036, reg, data ) \ + (Z8036(z8036))->reg = (data) + +/* structures */ + +struct z8036_map { +/* MAIN CONTROL REGISTERS (0x00-0x07) */ + uint8_t MASTER_INTR; /* Master Interrupt Ctl Reg */ + uint8_t MASTER_CFG; /* Master Configuration Ctl Reg */ + uint8_t PORTA_VECTOR; /* Port A - Interrupt Vector */ + uint8_t PORTB_VECTOR; /* Port B - Interrupt Vector */ + uint8_t CNT_TMR_VECTOR; /* Counter/Timer Interrupt Vector */ + uint8_t PORTC_DATA_POLARITY; /* Port C - Data Path Polarity */ + uint8_t PORTC_DIRECTION; /* Port C - Data Direction */ + uint8_t PORTC_SPECIAL_IO_CTL; /* Port C - Special IO Control */ +/* MOST OFTEN ACCESSED REGISTERS (0x08 - 0x0f) */ + uint8_t PORTA_CMD_STATUS; /* Port A - Command Status Reg */ + uint8_t PORTB_CMD_STATUS; /* Port B - Command Status Reg */ + uint8_t CT1_CMD_STATUS; /* Ctr/Timer 1 - Command Status Reg */ + uint8_t CT2_CMD_STATUS; /* Ctr/Timer 2 - Command Status Reg */ + uint8_t CT3_CMD_STATUS; /* Ctr/Timer 3 - Command Status Reg */ + uint8_t PORTA_DATA; /* Port A - Data */ + uint8_t PORTB_DATA; /* Port B - Data */ + uint8_t PORTC_DATA; /* Port C - Data */ +/* COUNTER/TIMER RELATED REGISTERS (0x10-0x1f) */ + uint8_t CT1_CUR_CNT_MSB; /* Ctr/Timer 1 - Current Count (MSB) */ + uint8_t CT1_CUR_CNT_LSB; /* Ctr/Timer 1 - Current Count (LSB) */ + uint8_t CT2_CUR_CNT_MSB; /* Ctr/Timer 2 - Current Count (MSB) */ + uint8_t CT2_CUR_CNT_LSB; /* Ctr/Timer 2 - Current Count (LSB) */ + uint8_t CT3_CUR_CNT_MSB; /* Ctr/Timer 3 - Current Count (MSB) */ + uint8_t CT3_CUR_CNT_LSB; /* Ctr/Timer 3 - Current Count (LSB) */ + uint8_t CT1_TIME_CONST_MSB; /* Ctr/Timer 1 - Time Constant (MSB) */ + uint8_t CT1_TIME_CONST_LSB; /* Ctr/Timer 1 - Time Constant (LSB) */ + uint8_t CT2_TIME_CONST_MSB; /* Ctr/Timer 2 - Time Constant (MSB) */ + uint8_t CT2_TIME_CONST_LSB; /* Ctr/Timer 2 - Time Constant (LSB) */ + uint8_t CT3_TIME_CONST_MSB; /* Ctr/Timer 3 - Time Constant (MSB) */ + uint8_t CT3_TIME_CONST_LSB; /* Ctr/Timer 3 - Time Constant (LSB) */ + uint8_t CT1_MODE_SPEC; /* Ctr/Timer 1 - Mode Specification */ + uint8_t CT2_MODE_SPEC; /* Ctr/Timer 2 - Mode Specification */ + uint8_t CT3_MODE_SPEC; /* Ctr/Timer 3 - Mode Specification */ + uint8_t CURRENT_VECTOR; /* Current Vector */ +/* PORT A SPECIFICATION REGISTERS (0x20 -0x27) */ + uint8_t PORTA_MODE; /* Port A - Mode Specification */ + uint8_t PORTA_HANDSHAKE; /* Port A - Handshake Specification */ + uint8_t PORTA_DATA_POLARITY; /* Port A - Data Path Polarity */ + uint8_t PORTA_DIRECTION; /* Port A - Data Direction */ + uint8_t PORTA_SPECIAL_IO_CTL; /* Port A - Special IO Control */ + uint8_t PORTA_PATT_POLARITY; /* Port A - Pattern Polarity */ + uint8_t PORTA_PATT_TRANS; /* Port A - Pattern Transition */ + uint8_t PORTA_PATT_MASK; /* Port A - Pattern Mask */ +/* PORT B SPECIFICATION REGISTERS (0x28-0x2f) */ + uint8_t PORTB_MODE; /* Port B - Mode Specification */ + uint8_t PORTB_HANDSHAKE; /* Port B - Handshake Specification */ + uint8_t PORTB_DATA_POLARITY; /* Port B - Data Path Polarity */ + uint8_t PORTB_DIRECTION; /* Port B - Data Direction */ + uint8_t PORTB_SPECIAL_IO_CTL; /* Port B - Special IO Control */ + uint8_t PORTB_PATT_POLARITY; /* Port B - Pattern Polarity */ + uint8_t PORTB_PATT_TRANS; /* Port B - Pattern Transition */ + uint8_t PORTB_PATT_MASK; /* Port B - Pattern Mask */ +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/include/zilog/z8530.h b/cpukit/libcsupport/include/zilog/z8530.h new file mode 100644 index 0000000000..13c63536c4 --- /dev/null +++ b/cpukit/libcsupport/include/zilog/z8530.h @@ -0,0 +1,97 @@ +/** + * @file rtems/zilog/z8530.h + */ + +/* + * This include file defines information related to a Zilog Z8530 + * SCC Chip. It is a IO mapped part. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_ZILOG_Z8530_H +#define _RTEMS_ZILOG_Z8530_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* macros */ + +#define VOL8( ptr ) ((volatile uint8_t *)(ptr)) + +#define Z8x30_STATE0 ( z8530 ) \ + { char *garbage; \ + (garbage) = *(VOL8(z8530)) \ + } + +#define Z8x30_WRITE_CONTROL( z8530, reg, data ) \ + *(VOL8(z8530)) = (reg); \ + *(VOL8(z8530)) = (data) + +#define Z8x30_READ_CONTROL( z8530, reg, data ) \ + *(VOL8(z8530)) = (reg); \ + (data) = *(VOL8(z8530)) + +#define Z8x30_WRITE_DATA( z8530, data ) \ + *(VOL8(z8530)) = (data); + +#define Z8x30_READ_DATA( z8530, data ) \ + (data) = *(VOL8(z8530)); + + +/* RR_0 Bit Definitions */ + +#define RR_0_TX_BUFFER_EMPTY 0x04 +#define RR_0_RX_DATA_AVAILABLE 0x01 + +/* read registers */ + +#define RR_0 0x00 +#define RR_1 0x01 +#define RR_2 0x02 +#define RR_3 0x03 +#define RR_4 0x04 +#define RR_5 0x05 +#define RR_6 0x06 +#define RR_7 0x07 +#define RR_8 0x08 +#define RR_9 0x09 +#define RR_10 0x0A +#define RR_11 0x0B +#define RR_12 0x0C +#define RR_13 0x0D +#define RR_14 0x0E +#define RR_15 0x0F + +/* write registers */ + +#define WR_0 0x00 +#define WR_1 0x01 +#define WR_2 0x02 +#define WR_3 0x03 +#define WR_4 0x04 +#define WR_5 0x05 +#define WR_6 0x06 +#define WR_7 0x07 +#define WR_8 0x08 +#define WR_9 0x09 +#define WR_10 0x0A +#define WR_11 0x0B +#define WR_12 0x0C +#define WR_13 0x0D +#define WR_14 0x0E +#define WR_15 0x0F + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/include/zilog/z8536.h b/cpukit/libcsupport/include/zilog/z8536.h new file mode 100644 index 0000000000..b67bd4cf9c --- /dev/null +++ b/cpukit/libcsupport/include/zilog/z8536.h @@ -0,0 +1,114 @@ +/** + * @file rtems/zilog/z8536.h + */ + +/* + * This include file defines information related to a Zilog Z8536 + * Counter/Timer/IO Chip. It is a IO mapped part. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: This file shares as much as possible with the include + * file for the Z8036 via z8x36.h. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_ZILOG_Z8536_H +#define _RTEMS_ZILOG_Z8536_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* macros */ + +#define VOL8( ptr ) ((volatile uint8_t *)(ptr)) + +#define Z8x36_STATE0 ( z8536 ) \ + { char *garbage; \ + (garbage) = *(VOL8(z8536+0xC)) \ + } + +#define Z8x36_WRITE( z8536, reg, data ) \ + *(VOL8(z8536+0xC)) = (reg); \ + *(VOL8(z8536+0xC)) = (data) + +#define Z8x36_READ( z8536, reg, data ) \ + *(VOL8(z8536+0xC)) = (reg); \ + (data) = *(VOL8(z8536+0xC)) + +/* structures */ + +/* MAIN CONTROL REGISTERS (0x00-0x07) */ +#define MASTER_INTR 0x00 /* Master Interrupt Ctl Reg */ +#define MASTER_CFG 0x01 /* Master Configuration Ctl Reg */ +#define PORTA_VECTOR 0x02 /* Port A - Interrupt Vector */ +#define PORTB_VECTOR 0x03 /* Port B - Interrupt Vector */ +#define CNT_TMR_VECTOR 0x04 /* Counter/Timer Interrupt Vector */ +#define PORTC_DATA_POLARITY 0x05 /* Port C - Data Path Polarity */ +#define PORTC_DIRECTION 0x06 /* Port C - Data Direction */ +#define PORTC_SPECIAL_IO_CTL 0x07 /* Port C - Special IO Control */ + +/* MOST OFTEN ACCESSED REGISTERS (0x08 - 0x0f) */ +#define PORTA_CMD_STATUS 0x08 /* Port A - Command Status Reg */ +#define PORTB_CMD_STATUS 0x09 /* Port B - Command Status Reg */ +#define CT1_CMD_STATUS 0x0a /* Ctr/Timer 1 - Command Status Reg */ +#define CT2_CMD_STATUS 0x0b /* Ctr/Timer 2 - Command Status Reg */ +#define CT3_CMD_STATUS 0x0c /* Ctr/Timer 3 - Command Status Reg */ +#define PORTA_DATA 0x0d /* Port A - Data */ +#define PORTB_DATA 0x0e /* Port B - Data */ +#define PORTC_DATA 0x0f /* Port C - Data */ + +/* COUNTER/TIMER RELATED REGISTERS (0x10-0x1f) */ +#define CT1_CUR_CNT_MSB 0x10 /* Ctr/Timer 1 - Current Count (MSB) */ +#define CT1_CUR_CNT_LSB 0x11 /* Ctr/Timer 1 - Current Count (LSB) */ +#define CT2_CUR_CNT_MSB 0x12 /* Ctr/Timer 2 - Current Count (MSB) */ +#define CT2_CUR_CNT_LSB 0x13 /* Ctr/Timer 2 - Current Count (LSB) */ +#define CT3_CUR_CNT_MSB 0x14 /* Ctr/Timer 3 - Current Count (MSB) */ +#define CT3_CUR_CNT_LSB 0x15 /* Ctr/Timer 3 - Current Count (LSB) */ +#define CT1_TIME_CONST_MSB 0x16 /* Ctr/Timer 1 - Time Constant (MSB) */ +#define CT1_TIME_CONST_LSB 0x17 /* Ctr/Timer 1 - Time Constant (LSB) */ +#define CT2_TIME_CONST_MSB 0x18 /* Ctr/Timer 2 - Time Constant (MSB) */ +#define CT2_TIME_CONST_LSB 0x19 /* Ctr/Timer 2 - Time Constant (LSB) */ +#define CT3_TIME_CONST_MSB 0x1a /* Ctr/Timer 3 - Time Constant (MSB) */ +#define CT3_TIME_CONST_LSB 0x1b /* Ctr/Timer 3 - Time Constant (LSB) */ +#define CT1_MODE_SPEC 0x1c /* Ctr/Timer 1 - Mode Specification */ +#define CT2_MODE_SPEC 0x1d /* Ctr/Timer 2 - Mode Specification */ +#define CT3_MODE_SPEC 0x1e /* Ctr/Timer 3 - Mode Specification */ +#define CURRENT_VECTOR 0x1f /* Current Vector */ + +/* PORT A SPECIFICATION REGISTERS (0x20 -0x27) */ +#define PORTA_MODE 0x20 /* Port A - Mode Specification */ +#define PORTA_HANDSHAKE 0x21 /* Port A - Handshake Specification */ +#define PORTA_DATA_POLARITY 0x22 /* Port A - Data Path Polarity */ +#define PORTA_DIRECTION 0x23 /* Port A - Data Direction */ +#define PORTA_SPECIAL_IO_CTL 0x24 /* Port A - Special IO Control */ +#define PORTA_PATT_POLARITY 0x25 /* Port A - Pattern Polarity */ +#define PORTA_PATT_TRANS 0x26 /* Port A - Pattern Transition */ +#define PORTA_PATT_MASK 0x27 /* Port A - Pattern Mask */ + +/* PORT B SPECIFICATION REGISTERS (0x28-0x2f) */ +#define PORTB_MODE 0x28 /* Port B - Mode Specification */ +#define PORTB_HANDSHAKE 0x29 /* Port B - Handshake Specification */ +#define PORTB_DATA_POLARITY 0x2a /* Port B - Data Path Polarity */ +#define PORTB_DIRECTION 0x2b /* Port B - Data Direction */ +#define PORTB_SPECIAL_IO_CTL 0x2c /* Port B - Special IO Control */ +#define PORTB_PATT_POLARITY 0x2d /* Port B - Pattern Polarity */ +#define PORTB_PATT_TRANS 0x2e /* Port B - Pattern Transition */ +#define PORTB_PATT_MASK 0x2f /* Port B - Pattern Mask */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/preinstall.am b/cpukit/libcsupport/preinstall.am new file mode 100644 index 0000000000..f71362fe31 --- /dev/null +++ b/cpukit/libcsupport/preinstall.am @@ -0,0 +1,118 @@ +## Automatically generated by ampolish3 - Do not edit + +if AMPOLISH3 +$(srcdir)/preinstall.am: Makefile.am + $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am +endif + +PREINSTALL_DIRS = +DISTCLEANFILES = $(PREINSTALL_DIRS) + +all-am: $(PREINSTALL_FILES) + +PREINSTALL_FILES = +CLEANFILES = $(PREINSTALL_FILES) + +$(PROJECT_INCLUDE)/rtems/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/rtems + @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems/console.h: include/console.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/console.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/console.h + +$(PROJECT_INCLUDE)/rtems/clockdrv.h: include/clockdrv.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/clockdrv.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/clockdrv.h + +$(PROJECT_INCLUDE)/rtems/framebuffer.h: include/rtems/framebuffer.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/framebuffer.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/framebuffer.h + +$(PROJECT_INCLUDE)/rtems/iosupp.h: include/iosupp.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/iosupp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/iosupp.h + +$(PROJECT_INCLUDE)/rtems/ringbuf.h: include/ringbuf.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/ringbuf.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/ringbuf.h + +$(PROJECT_INCLUDE)/rtems/rtc.h: include/rtc.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtc.h + +$(PROJECT_INCLUDE)/rtems/spurious.h: include/spurious.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/spurious.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/spurious.h + +$(PROJECT_INCLUDE)/rtems/timerdrv.h: include/timerdrv.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/timerdrv.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/timerdrv.h + +$(PROJECT_INCLUDE)/rtems/vmeintr.h: include/vmeintr.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/vmeintr.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/vmeintr.h + +$(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/rtems/motorola + @: > $(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems/motorola/mc68230.h: include/motorola/mc68230.h $(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/motorola/mc68230.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/motorola/mc68230.h + +$(PROJECT_INCLUDE)/rtems/motorola/mc68681.h: include/motorola/mc68681.h $(PROJECT_INCLUDE)/rtems/motorola/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/motorola/mc68681.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/motorola/mc68681.h + +$(PROJECT_INCLUDE)/rtems/assoc.h: include/rtems/assoc.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/assoc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/assoc.h + +$(PROJECT_INCLUDE)/rtems/error.h: include/rtems/error.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/error.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/error.h + +$(PROJECT_INCLUDE)/rtems/libcsupport.h: include/rtems/libcsupport.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/libcsupport.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/libcsupport.h + +$(PROJECT_INCLUDE)/rtems/libio.h: include/rtems/libio.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/libio.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/libio.h + +$(PROJECT_INCLUDE)/rtems/libio_.h: include/rtems/libio_.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/libio_.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/libio_.h + +$(PROJECT_INCLUDE)/rtems/malloc.h: include/rtems/malloc.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/malloc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/malloc.h + +$(PROJECT_INCLUDE)/rtems/termiostypes.h: include/rtems/termiostypes.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/termiostypes.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/termiostypes.h + +$(PROJECT_INCLUDE)/rtems/gxx_wrappers.h: include/rtems/gxx_wrappers.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/gxx_wrappers.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/gxx_wrappers.h + +$(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/rtems/zilog + @: > $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems/zilog/z8036.h: include/zilog/z8036.h $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/zilog/z8036.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/zilog/z8036.h + +$(PROJECT_INCLUDE)/rtems/zilog/z8530.h: include/zilog/z8530.h $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/zilog/z8530.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/zilog/z8530.h + +$(PROJECT_INCLUDE)/rtems/zilog/z8536.h: include/zilog/z8536.h $(PROJECT_INCLUDE)/rtems/zilog/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/zilog/z8536.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/zilog/z8536.h + diff --git a/cpukit/libcsupport/src/CASES b/cpukit/libcsupport/src/CASES new file mode 100644 index 0000000000..4578ae5009 --- /dev/null +++ b/cpukit/libcsupport/src/CASES @@ -0,0 +1,23 @@ +# +# $Id$ +# + +This is a list of cases to consider when implementing a file system: + + ++ Given a tree of this form: + + a ----- b + / + c + + Where a and b are directories and c is a link to directory b. Consider + this sequence: + + - rmdir a/b + - mknod c/b/x + - unlink c + + + + diff --git a/cpukit/libcsupport/src/README b/cpukit/libcsupport/src/README new file mode 100644 index 0000000000..ee7a90501e --- /dev/null +++ b/cpukit/libcsupport/src/README @@ -0,0 +1,37 @@ +-- +-- $Id$ +-- + +Overview of newlib support (newlib is from CYGNUS) + Each task can have its own libc state including: + open stdio files + strtok + multi precision arithmetic state + etc. + + This is implemented by a reentrancy data structure for each task. + + When a task is "started" (in RTEMS sense) the reentrancy structure + is allocated. Its address is stored in notepad[NOTEPAD_LAST]. + + When task is switched to, the value of global variable _impure_ptr + is changed to the value of the new tasks reentrancy structure. + + When a task is deleted + atexit() processing (for that task) happens + task's stdio buffers are flushed + + When exit(3) is called + calling task's atexit processing done + global libc state atexit processing done + (this will include any atexit routines installed by drivers) + executive is shutdown + causes a context switch back to bsp land + + +NOTE: + libc extension are installed by bsp_libc_init() + iff we are using clock interrupts. + This hack is necessary to allow the tmtests to avoid + timing the extensions. + diff --git a/cpukit/libcsupport/src/TODO b/cpukit/libcsupport/src/TODO new file mode 100644 index 0000000000..38cb012326 --- /dev/null +++ b/cpukit/libcsupport/src/TODO @@ -0,0 +1,14 @@ +# +# $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. + ++ Check the node allocation coment in the fchdir call. ++ Add an interface somewhere for this call.
\ No newline at end of file diff --git a/cpukit/libcsupport/src/__assert.c b/cpukit/libcsupport/src/__assert.c new file mode 100644 index 0000000000..0e90b604c6 --- /dev/null +++ b/cpukit/libcsupport/src/__assert.c @@ -0,0 +1,52 @@ +/* __assert - small RTEMS Specific Implementation + * + * COPYRIGHT (c) 2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/bspIo.h> +#include <rtems.h> + +#if defined(RTEMS_NEWLIB) && !defined(HAVE___ASSERT_FUNC) +/* + * Newlib 1.16.0 added this method. Together these provide an + * RTEMS safe, low memory implementation. + */ +void __assert_func( + const char *file, + int line, + const char *func, + const char *failedexpr +) +{ + printk("assertion \"%s\" failed: file \"%s\", line %d%s%s\n", + failedexpr, + file, + line, + (func) ? ", function: " : "", + (func) ? func : "" + ); + rtems_fatal_error_occurred(0); +} +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE___ASSERT) +void __assert( + const char *file, + int line, + const char *failedexpr +) +{ + __assert_func (file, line, NULL, failedexpr); +} +#endif diff --git a/cpukit/libcsupport/src/__getpid.c b/cpukit/libcsupport/src/__getpid.c new file mode 100644 index 0000000000..85a4c0b013 --- /dev/null +++ b/cpukit/libcsupport/src/__getpid.c @@ -0,0 +1,17 @@ +/* + * Some C Libraries reference this routine since they think getpid is + * a real system call. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +pid_t __getpid(void) +{ + return getpid(); +} diff --git a/cpukit/libcsupport/src/__gettod.c b/cpukit/libcsupport/src/__gettod.c new file mode 100644 index 0000000000..05db4ab9d0 --- /dev/null +++ b/cpukit/libcsupport/src/__gettod.c @@ -0,0 +1,86 @@ +/* + * gettimeofday() - SVR4 and BSD4.3 extension required by Newlib + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ + +#if defined(RTEMS_NEWLIB) +#include <sys/time.h> +#include <errno.h> +#include <rtems.h> +#include <rtems/seterr.h> + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_GETTIMEOFDAY) +/* + * NOTE: The solaris gettimeofday does not have a second parameter. + */ +int gettimeofday( + struct timeval *tp, + void * __tz __attribute__((unused)) +) +{ + /* struct timezone* tzp = (struct timezone*) __tz; */ + if ( !tp ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + /* + * POSIX does not seem to allow for not having a TOD so we just + * grab the time of day. + */ + _TOD_Get_timeval( tp ); + + /* + * Timezone information ignored by the OS proper. Per email + * with Eric Norum, this is how GNU/Linux, Solaris, and MacOS X + * do it. This puts us in good company. + */ + + return 0; +} +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__GETTIMEOFDAY_R) + +#include <sys/reent.h> + +/* + * "Reentrant" version + */ +int _gettimeofday_r( + struct _reent *ignored_reentrancy_stuff __attribute__((unused)), + struct timeval *tp, + struct timezone *tzp +) +{ + return gettimeofday( tp, tzp ); +} +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__GETTIMEOFDAY) +/* + * "System call" version + */ + +int _gettimeofday( + struct timeval *tp, + struct timezone *tzp +) +{ + return gettimeofday( tp, tzp ); +} +#endif + +#endif /* defined(RTEMS_NEWLIB) */ diff --git a/cpukit/libcsupport/src/__times.c b/cpukit/libcsupport/src/__times.c new file mode 100644 index 0000000000..2de529275e --- /dev/null +++ b/cpukit/libcsupport/src/__times.c @@ -0,0 +1,114 @@ +/* + * times() - POSIX 1003.1b 4.5.2 - Get Process Times + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> + +#include <sys/times.h> +#include <time.h> +#include <sys/time.h> +#include <errno.h> +#include <rtems/seterr.h> +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + #include <rtems/score/timestamp.h> +#endif + +clock_t _times( + struct tms *ptms +) +{ + rtems_interval ticks; + + if ( !ptms ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + /* + * This call does not depend on TOD being initialized and can't fail. + */ + + ticks = rtems_clock_get_ticks_since_boot(); + + /* + * RTEMS technically has no notion of system versus user time + * since there is no separation of OS from application tasks. + * But we can at least make a distinction between the number + * of ticks since boot and the number of ticks executed by this + * this thread. + */ + + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + { + Timestamp_Control per_tick; + uint32_t ticks; + uint32_t fractional_ticks; + + _Timestamp_Set( + &per_tick, + rtems_configuration_get_microseconds_per_tick() / + TOD_MICROSECONDS_PER_SECOND, + (rtems_configuration_get_nanoseconds_per_tick() % + TOD_NANOSECONDS_PER_SECOND) + ); + + _Timestamp_Divide( + &_Thread_Executing->cpu_time_used, + &per_tick, + &ticks, + &fractional_ticks + ); + ptms->tms_utime = ticks; + } + #else + ptms->tms_utime = _Thread_Executing->cpu_time_used; + #endif + ptms->tms_stime = ticks; + ptms->tms_cutime = 0; + ptms->tms_cstime = 0; + + return ticks; +} + +/* + * times() + * + * times() system call wrapper for _times() above. + */ + +clock_t times( + struct tms *ptms +) +{ + 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 __attribute__((unused)), + struct tms *ptms +) +{ + return _times( ptms ); +} +#endif diff --git a/cpukit/libcsupport/src/__usrenv.c b/cpukit/libcsupport/src/__usrenv.c new file mode 100644 index 0000000000..0b3469fa1a --- /dev/null +++ b/cpukit/libcsupport/src/__usrenv.c @@ -0,0 +1,27 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/libio.h> +#include <rtems/libio_.h> + +/* + * Global information for POSIX Process Environment Support + */ + +rtems_user_env_t rtems_global_user_env; +rtems_user_env_t * rtems_current_user_env = &rtems_global_user_env; + + diff --git a/cpukit/libcsupport/src/_calloc_r.c b/cpukit/libcsupport/src/_calloc_r.c new file mode 100644 index 0000000000..1b515d2464 --- /dev/null +++ b/cpukit/libcsupport/src/_calloc_r.c @@ -0,0 +1,30 @@ +/* + * _calloc_r Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__CALLOC_R) +#include <sys/reent.h> +#include <stdlib.h> + +void *_calloc_r( + struct _reent *ignored __attribute__((unused)), + size_t elements, + size_t size +) +{ + return calloc( elements, size ); +} +#endif diff --git a/cpukit/libcsupport/src/_free_r.c b/cpukit/libcsupport/src/_free_r.c new file mode 100644 index 0000000000..9b3eb5c285 --- /dev/null +++ b/cpukit/libcsupport/src/_free_r.c @@ -0,0 +1,29 @@ +/* + * _free_r Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__FREE_R) +#include <sys/reent.h> +#include <stdlib.h> + +void _free_r( + struct _reent *ignored __attribute__((unused)), + void *ptr +) +{ + free( ptr ); +} +#endif diff --git a/cpukit/libcsupport/src/_malloc_r.c b/cpukit/libcsupport/src/_malloc_r.c new file mode 100644 index 0000000000..9a30097324 --- /dev/null +++ b/cpukit/libcsupport/src/_malloc_r.c @@ -0,0 +1,29 @@ +/* + * _malloc_r Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__MALLOC_R) +#include <sys/reent.h> +#include <stdlib.h> + +void *_malloc_r( + struct _reent *ignored __attribute__((unused)), + size_t size +) +{ + return malloc( size ); +} +#endif diff --git a/cpukit/libcsupport/src/_realloc_r.c b/cpukit/libcsupport/src/_realloc_r.c new file mode 100644 index 0000000000..78c9faf351 --- /dev/null +++ b/cpukit/libcsupport/src/_realloc_r.c @@ -0,0 +1,30 @@ +/* + * _realloc_r Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__REALLOC_R) +#include <sys/reent.h> +#include <stdlib.h> + +void *_realloc_r( + struct _reent *ignored __attribute__((unused)), + void *ptr, + size_t size +) +{ + return realloc( ptr, size ); +} +#endif diff --git a/cpukit/libcsupport/src/_rename_r.c b/cpukit/libcsupport/src/_rename_r.c new file mode 100644 index 0000000000..51010df28e --- /dev/null +++ b/cpukit/libcsupport/src/_rename_r.c @@ -0,0 +1,113 @@ +/* + * _rename_r() - POSIX 1003.1b - 5.3.4 - Rename a file + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__RENAME_R) +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int _rename_r( + struct _reent *ptr __attribute__((unused)), + const char *old, + const char *new +) +{ + int old_parent_pathlen; + rtems_filesystem_location_info_t old_loc; + rtems_filesystem_location_info_t old_parent_loc; + rtems_filesystem_location_info_t new_parent_loc; + int i; + int result; + const char *name; + bool free_old_parentloc = false; + + /* + * Get the parent node of the old path to be renamed. Find the parent path. + */ + + old_parent_pathlen = rtems_filesystem_dirname ( old ); + + if ( old_parent_pathlen == 0 ) + rtems_filesystem_get_start_loc( old, &i, &old_parent_loc ); + else { + result = rtems_filesystem_evaluate_path( old, old_parent_pathlen, + RTEMS_LIBIO_PERMS_WRITE, + &old_parent_loc, + false ); + if ( result != 0 ) + return -1; + + free_old_parentloc = true; + } + + /* + * Start from the parent to find the node that should be under it. + */ + + old_loc = old_parent_loc; + name = old + old_parent_pathlen; + name += rtems_filesystem_prefix_separators( name, strlen( name ) ); + + result = rtems_filesystem_evaluate_relative_path( name , strlen( name ), + 0, &old_loc, false ); + if ( result != 0 ) { + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + return -1; + } + + /* + * Get the parent of the new node we are renaming to. + */ + + rtems_filesystem_get_start_loc( new, &i, &new_parent_loc ); + + result = (*new_parent_loc.ops->evalformake_h)( &new[i], &new_parent_loc, &name ); + if ( result != 0 ) { + rtems_filesystem_freenode( &new_parent_loc ); + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_filesystem_freenode( &old_loc ); + return -1; + } + + /* + * Check to see if the caller is trying to rename across file system + * boundaries. + */ + + if ( old_parent_loc.mt_entry != new_parent_loc.mt_entry ) { + rtems_filesystem_freenode( &new_parent_loc ); + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_filesystem_freenode( &old_loc ); + rtems_set_errno_and_return_minus_one( EXDEV ); + } + + result = (*new_parent_loc.ops->rename_h)( &old_parent_loc, &old_loc, &new_parent_loc, name ); + + rtems_filesystem_freenode( &new_parent_loc ); + if ( free_old_parentloc ) + rtems_filesystem_freenode( &old_parent_loc ); + rtems_filesystem_freenode( &old_loc ); + + return result; +} +#endif diff --git a/cpukit/libcsupport/src/access.c b/cpukit/libcsupport/src/access.c new file mode 100644 index 0000000000..7365d6db7d --- /dev/null +++ b/cpukit/libcsupport/src/access.c @@ -0,0 +1,48 @@ +/* + * access() - POSIX 1003.1b 5.6.3 - File Accessibility + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> + +int access( + const char *path, + int amode +) +{ + struct stat statbuf; + + if ( stat(path, &statbuf) ) + return -1; + + if ( amode & R_OK ) { + if (!( statbuf.st_mode & S_IREAD )) + return -1; + } + + if ( amode & W_OK ) { + if ( !( statbuf.st_mode & S_IWRITE ) ) + return -1; + } + + if ( amode & X_OK ) { + if ( !( statbuf.st_mode & S_IEXEC ) ) + return -1; + } + + return 0; +} diff --git a/cpukit/libcsupport/src/assoclocalbyname.c b/cpukit/libcsupport/src/assoclocalbyname.c new file mode 100644 index 0000000000..28856afc46 --- /dev/null +++ b/cpukit/libcsupport/src/assoclocalbyname.c @@ -0,0 +1,31 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + +uint32_t rtems_assoc_local_by_name( + const rtems_assoc_t *ap, + const char *name +) +{ + const rtems_assoc_t *nap; + + nap = rtems_assoc_ptr_by_name(ap, name); + if (nap) + return nap->local_value; + + return 0; +} diff --git a/cpukit/libcsupport/src/assoclocalbyremote.c b/cpukit/libcsupport/src/assoclocalbyremote.c new file mode 100644 index 0000000000..545f31b6a8 --- /dev/null +++ b/cpukit/libcsupport/src/assoclocalbyremote.c @@ -0,0 +1,31 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + +uint32_t rtems_assoc_local_by_remote( + const rtems_assoc_t *ap, + uint32_t remote_value +) +{ + const rtems_assoc_t *nap; + + nap = rtems_assoc_ptr_by_remote(ap, remote_value); + if (nap) + return nap->local_value; + + return 0; +} diff --git a/cpukit/libcsupport/src/assoclocalbyremotebitfield.c b/cpukit/libcsupport/src/assoclocalbyremotebitfield.c new file mode 100644 index 0000000000..177ca62b49 --- /dev/null +++ b/cpukit/libcsupport/src/assoclocalbyremotebitfield.c @@ -0,0 +1,34 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + + +uint32_t rtems_assoc_local_by_remote_bitfield( + const rtems_assoc_t *ap, + uint32_t remote_value +) +{ + uint32_t b; + uint32_t local_value = 0; + + for (b = 1; b; b <<= 1) { + if (b & remote_value) + local_value |= rtems_assoc_local_by_remote(ap, b); + } + + return local_value; +} diff --git a/cpukit/libcsupport/src/assocnamebad.c b/cpukit/libcsupport/src/assocnamebad.c new file mode 100644 index 0000000000..f61f4e844d --- /dev/null +++ b/cpukit/libcsupport/src/assocnamebad.c @@ -0,0 +1,40 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <inttypes.h> +#include <stdio.h> /* sprintf */ + +/* + * what to return if a value is not found + * this is not reentrant, but it really shouldn't be invoked anyway + */ + +const char * +rtems_assoc_name_bad( +#ifdef RTEMS_DEBUG + uint32_t bad_value +#else + uint32_t bad_value __attribute((unused)) +#endif +) +{ +#ifdef RTEMS_DEBUG + static char bad_buffer[32]; + + sprintf(bad_buffer, "< %" PRId32 "[0x%" PRIx32 " ] >", bad_value, bad_value); +#else + static char bad_buffer[40] = "<assocnamebad.c: : BAD NAME>"; +#endif + return bad_buffer; +} diff --git a/cpukit/libcsupport/src/assocnamebylocal.c b/cpukit/libcsupport/src/assocnamebylocal.c new file mode 100644 index 0000000000..3ba0b8c083 --- /dev/null +++ b/cpukit/libcsupport/src/assocnamebylocal.c @@ -0,0 +1,31 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + +const char *rtems_assoc_name_by_local( + const rtems_assoc_t *ap, + uint32_t local_value +) +{ + const rtems_assoc_t *nap; + + nap = rtems_assoc_ptr_by_local(ap, local_value); + if (nap) + return nap->name; + + return rtems_assoc_name_bad(local_value); +} diff --git a/cpukit/libcsupport/src/assocnamebylocalbitfield.c b/cpukit/libcsupport/src/assocnamebylocalbitfield.c new file mode 100644 index 0000000000..c9d1fa1256 --- /dev/null +++ b/cpukit/libcsupport/src/assocnamebylocalbitfield.c @@ -0,0 +1,38 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + +char *rtems_assoc_name_by_local_bitfield( + const rtems_assoc_t *ap, + uint32_t value, + char *buffer +) +{ + uint32_t b; + + *buffer = 0; + + for (b = 1; b; b <<= 1) { + if (b & value) { + if (*buffer) + strcat(buffer, " "); + strcat(buffer, rtems_assoc_name_by_local(ap, b)); + } + } + + return buffer; +} diff --git a/cpukit/libcsupport/src/assocnamebyremote.c b/cpukit/libcsupport/src/assocnamebyremote.c new file mode 100644 index 0000000000..281022c7bf --- /dev/null +++ b/cpukit/libcsupport/src/assocnamebyremote.c @@ -0,0 +1,33 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + + +const char *rtems_assoc_name_by_remote( + const rtems_assoc_t *ap, + uint32_t remote_value +) +{ + const rtems_assoc_t *nap; + nap = rtems_assoc_ptr_by_remote(ap, remote_value); + + if (nap) + return nap->name; + + return rtems_assoc_name_bad(remote_value); +} + diff --git a/cpukit/libcsupport/src/assocnamebyremotebitfield.c b/cpukit/libcsupport/src/assocnamebyremotebitfield.c new file mode 100644 index 0000000000..1293393e1e --- /dev/null +++ b/cpukit/libcsupport/src/assocnamebyremotebitfield.c @@ -0,0 +1,39 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + + +char *rtems_assoc_name_by_remote_bitfield( + const rtems_assoc_t *ap, + uint32_t value, + char *buffer +) +{ + uint32_t b; + + *buffer = 0; + + for (b = 1; b; b <<= 1) { + if (b & value) { + if (*buffer) + strcat(buffer, " "); + strcat(buffer, rtems_assoc_name_by_remote(ap, b)); + } + } + + return buffer; +} diff --git a/cpukit/libcsupport/src/assocptrbylocal.c b/cpukit/libcsupport/src/assocptrbylocal.c new file mode 100644 index 0000000000..cbf26b1bcb --- /dev/null +++ b/cpukit/libcsupport/src/assocptrbylocal.c @@ -0,0 +1,34 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + +const rtems_assoc_t *rtems_assoc_ptr_by_local( + const rtems_assoc_t *ap, + uint32_t local_value +) +{ + const rtems_assoc_t *default_ap = 0; + + if (rtems_assoc_is_default(ap)) + default_ap = ap++; + + for ( ; ap->name; ap++) + if (ap->local_value == local_value) + return ap; + + return default_ap; +} diff --git a/cpukit/libcsupport/src/assocptrbyname.c b/cpukit/libcsupport/src/assocptrbyname.c new file mode 100644 index 0000000000..457f57e434 --- /dev/null +++ b/cpukit/libcsupport/src/assocptrbyname.c @@ -0,0 +1,35 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + + +const rtems_assoc_t *rtems_assoc_ptr_by_name( + const rtems_assoc_t *ap, + const char *name +) +{ + const rtems_assoc_t *default_ap = 0; + + if (rtems_assoc_is_default(ap)) + default_ap = ap++; + + for ( ; ap->name; ap++) + if (strcmp(ap->name, name) == 0) + return ap; + + return default_ap; +} diff --git a/cpukit/libcsupport/src/assocptrbyremote.c b/cpukit/libcsupport/src/assocptrbyremote.c new file mode 100644 index 0000000000..4879c2d397 --- /dev/null +++ b/cpukit/libcsupport/src/assocptrbyremote.c @@ -0,0 +1,34 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + +const rtems_assoc_t *rtems_assoc_ptr_by_remote( + const rtems_assoc_t *ap, + uint32_t remote_value +) +{ + const rtems_assoc_t *default_ap = 0; + + if (rtems_assoc_is_default(ap)) + default_ap = ap++; + + for ( ; ap->name; ap++) + if (ap->remote_value == remote_value) + return ap; + + return default_ap; +} diff --git a/cpukit/libcsupport/src/assocremotebylocal.c b/cpukit/libcsupport/src/assocremotebylocal.c new file mode 100644 index 0000000000..23bbcc74fa --- /dev/null +++ b/cpukit/libcsupport/src/assocremotebylocal.c @@ -0,0 +1,31 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + +uint32_t rtems_assoc_remote_by_local( + const rtems_assoc_t *ap, + uint32_t local_value +) +{ + const rtems_assoc_t *nap; + + nap = rtems_assoc_ptr_by_local(ap, local_value); + if (nap) + return nap->remote_value; + + return 0; +} diff --git a/cpukit/libcsupport/src/assocremotebylocalbitfield.c b/cpukit/libcsupport/src/assocremotebylocalbitfield.c new file mode 100644 index 0000000000..3d28345847 --- /dev/null +++ b/cpukit/libcsupport/src/assocremotebylocalbitfield.c @@ -0,0 +1,33 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + + +uint32_t rtems_assoc_remote_by_local_bitfield( + const rtems_assoc_t *ap, + uint32_t local_value +) +{ + uint32_t b; + uint32_t remote_value = 0; + + for (b = 1; b; b <<= 1) + if (b & local_value) + remote_value |= rtems_assoc_remote_by_local(ap, b); + + return remote_value; +} diff --git a/cpukit/libcsupport/src/assocremotebyname.c b/cpukit/libcsupport/src/assocremotebyname.c new file mode 100644 index 0000000000..923c8d28ba --- /dev/null +++ b/cpukit/libcsupport/src/assocremotebyname.c @@ -0,0 +1,31 @@ +/* + * assoc.c + * rtems assoc routines + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define INSIDE_ASSOC + +#include <rtems.h> +#include <rtems/assoc.h> + +#include <string.h> /* strcat, strcmp */ + +uint32_t rtems_assoc_remote_by_name( + const rtems_assoc_t *ap, + const char *name +) +{ + const rtems_assoc_t *nap; + + nap = rtems_assoc_ptr_by_name(ap, name); + if (nap) + return nap->remote_value; + + return 0; +} diff --git a/cpukit/libcsupport/src/base_fs.c b/cpukit/libcsupport/src/base_fs.c new file mode 100644 index 0000000000..b5681eda63 --- /dev/null +++ b/cpukit/libcsupport/src/base_fs.c @@ -0,0 +1,114 @@ +/* + * Base file system initialization + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/libio.h> +#include <rtems/libio_.h> + +/* + * Default mode for created files. + */ + + +/* + * rtems_filesystem_initialize + * + * Initialize the foundation of the file system. This is specified + * by the structure rtems_filesystem_mount_table. The usual + * configuration is a single instantiation of the IMFS or miniIMFS with + * a single "/dev" directory in it. + */ + +void rtems_filesystem_initialize( void ) +{ + int status; + const rtems_filesystem_mount_table_t *mt; + rtems_filesystem_location_info_t loc; + + /* + * Set the default umask to "022". + */ + + rtems_filesystem_umask = 022; + + /* + * mount the first filesystem. + */ + if ( rtems_filesystem_mount_table_size == 0 ) + rtems_fatal_error_occurred( 0xABCD0001 ); + + mt = &rtems_filesystem_mount_table[0]; + + status = mount( mt->device, mt->mount_point, mt->type, mt->fsoptions, NULL ); + if ( status == -1 ) + rtems_fatal_error_occurred( 0xABCD0002 ); + + rtems_filesystem_link_counts = 0; + + /* setup the 'current' and 'root' directories + * + * NOTE: cloning the pathlocs is not strictly + * necessary. Since we implicitely let + * all threads that don't call + * libio_set_private_env() share the same + * (initial) 'root' and 'current' locs, + * we (also implicitely) assume that the + * root filesystem doesn't care about + * reference counts. + * I just inserted the code snippet below + * to remind everybody of the fact by + * making it more explicit... + * Ideally, every thread would have to + * call either share_private_env() or + * set_private_env() - but then: that's + * gonna hit performance. + * + * Till Straumann, 10/25/2002 + */ + /* Clone the root pathloc */ + rtems_filesystem_evaluate_path("/", 1, 0, &loc, 0); + rtems_filesystem_root = loc; + /* One more clone for the current node */ + rtems_filesystem_evaluate_path("/", 1, 0, &loc, 0); + rtems_filesystem_current = loc; + + /* Note: the global_env's refcnt doesn't matter + * as the global env is never released + */ + + + /* + * 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). It is actually + * created that way by the IMFS. + */ + + status = mkdir( "/dev", 0777); + if ( status != 0 ) + rtems_fatal_error_occurred( 0xABCD0003 ); + + /* + * You can't mount another filesystem properly until the mount point + * it will be mounted onto is created. Moreover, if it is going to + * use a device, then it is REALLY unfair to attempt this + * before device drivers are initialized. So we return via a base + * filesystem image and nothing auto-mounted at this point. + */ +} diff --git a/cpukit/libcsupport/src/calloc.c b/cpukit/libcsupport/src/calloc.c new file mode 100644 index 0000000000..859b4c2213 --- /dev/null +++ b/cpukit/libcsupport/src/calloc.c @@ -0,0 +1,41 @@ +/* + * calloc() + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_CALLOC) +#include "malloc_p.h" +#include <stdlib.h> + +void *calloc( + size_t nelem, + size_t elsize +) +{ + register char *cptr; + size_t length; + + MSBUMP(calloc_calls, 1); + + length = nelem * elsize; + cptr = malloc( length ); + if ( cptr ) + memset( cptr, '\0', length ); + + MSBUMP(malloc_calls, (uint32_t) -1); /* subtract off the malloc */ + + return cptr; +} +#endif diff --git a/cpukit/libcsupport/src/cfgetispeed.c b/cpukit/libcsupport/src/cfgetispeed.c new file mode 100644 index 0000000000..225c7311cc --- /dev/null +++ b/cpukit/libcsupport/src/cfgetispeed.c @@ -0,0 +1,32 @@ +/* + * cfgetispeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#if defined(RTEMS_NEWLIB) + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <termios.h> + +speed_t cfgetispeed( + const struct termios *tp +) +{ + return (tp->c_cflag / (CIBAUD / CBAUD)) & CBAUD; +} +#endif diff --git a/cpukit/libcsupport/src/cfgetospeed.c b/cpukit/libcsupport/src/cfgetospeed.c new file mode 100644 index 0000000000..e239e54758 --- /dev/null +++ b/cpukit/libcsupport/src/cfgetospeed.c @@ -0,0 +1,32 @@ +/* + * cfgetospeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#if defined(RTEMS_NEWLIB) + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <termios.h> + +speed_t cfgetospeed( + const struct termios *tp +) +{ + return tp->c_cflag & CBAUD; +} +#endif diff --git a/cpukit/libcsupport/src/cfsetispeed.c b/cpukit/libcsupport/src/cfsetispeed.c new file mode 100644 index 0000000000..383762bee1 --- /dev/null +++ b/cpukit/libcsupport/src/cfsetispeed.c @@ -0,0 +1,40 @@ +/* + * cfsetispeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#if defined(RTEMS_NEWLIB) + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <termios.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int cfsetispeed( + struct termios *tp, + speed_t speed +) +{ + if ( speed & ~CBAUD ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + tp->c_cflag = (tp->c_cflag & ~CIBAUD) | (speed * (CIBAUD / CBAUD)); + return 0; +} +#endif diff --git a/cpukit/libcsupport/src/cfsetospeed.c b/cpukit/libcsupport/src/cfsetospeed.c new file mode 100644 index 0000000000..0badcbbdc7 --- /dev/null +++ b/cpukit/libcsupport/src/cfsetospeed.c @@ -0,0 +1,40 @@ +/* + * cfsetospeed() - POSIX 1003.1b 7.1.3 - Baud Rate Functions + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#if defined(RTEMS_NEWLIB) + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <termios.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int cfsetospeed( + struct termios *tp, + speed_t speed +) +{ + if ( speed & ~CBAUD ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + tp->c_cflag = (tp->c_cflag & ~CBAUD) | speed; + return 0; +} +#endif diff --git a/cpukit/libcsupport/src/chdir.c b/cpukit/libcsupport/src/chdir.c new file mode 100644 index 0000000000..c9d05f0bef --- /dev/null +++ b/cpukit/libcsupport/src/chdir.c @@ -0,0 +1,57 @@ +/* + * chdir() - POSIX 1003.1b - 5.2.1 - Change Current Working Directory + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> + +#include <unistd.h> +#include <errno.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int chdir( + const char *pathname +) +{ + rtems_filesystem_location_info_t loc; + int result; + + if ( !pathname ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + /* + * Get the node where we wish to go. + */ + result = rtems_filesystem_evaluate_path( + pathname, strlen( pathname ), RTEMS_LIBIO_PERMS_SEARCH, &loc, true ); + if ( result != 0 ) + return -1; + + /* + * Verify you can change directory into this node. + */ + if ( (*loc.ops->node_type_h)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) { + rtems_filesystem_freenode( &loc ); + rtems_set_errno_and_return_minus_one( ENOTDIR ); + } + + rtems_filesystem_freenode( &rtems_filesystem_current ); + + rtems_filesystem_current = loc; + + return 0; +} diff --git a/cpukit/libcsupport/src/chmod.c b/cpukit/libcsupport/src/chmod.c new file mode 100644 index 0000000000..d1d9ae0f5f --- /dev/null +++ b/cpukit/libcsupport/src/chmod.c @@ -0,0 +1,46 @@ +/* + * chmod() - POSIX 1003.1b 5.6.4 - Change File Modes + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/libio.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int chmod( + const char *path, + mode_t mode +) +{ + int status; + rtems_filesystem_location_info_t loc; + int result; + + status = rtems_filesystem_evaluate_path( path, strlen( path ), 0, &loc, true ); + if ( status != 0 ) + return -1; + + result = (*loc.handlers->fchmod_h)( &loc, mode ); + + rtems_filesystem_freenode( &loc ); + + return result; +} diff --git a/cpukit/libcsupport/src/chown.c b/cpukit/libcsupport/src/chown.c new file mode 100644 index 0000000000..3cab985cad --- /dev/null +++ b/cpukit/libcsupport/src/chown.c @@ -0,0 +1,54 @@ +/* + * chown() - POSIX 1003.1b 5.6.5 - Change Owner and Group of a File + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/stat.h> +#include <errno.h> + +#include <rtems.h> +#include <rtems/libio.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int _chown_helper( + const char *path, + uid_t owner, + gid_t group, + int follow_link +) +{ + rtems_filesystem_location_info_t loc; + int result; + + if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x00, &loc, follow_link ) ) + return -1; + + result = (*loc.ops->chown_h)( &loc, owner, group ); + + rtems_filesystem_freenode( &loc ); + + return result; +} + +int chown( + const char *path, + uid_t owner, + gid_t group +) +{ + return _chown_helper( path, owner, group, true ); +} diff --git a/cpukit/libcsupport/src/chroot.c b/cpukit/libcsupport/src/chroot.c new file mode 100644 index 0000000000..ccda4d6d7a --- /dev/null +++ b/cpukit/libcsupport/src/chroot.c @@ -0,0 +1,55 @@ +/* + * chroot() - Change Root Directory + * Author: fernando.ruiz@ctv.es + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> + +#include <unistd.h> +#include <errno.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int chroot( + const char *pathname +) +{ + int result; + rtems_filesystem_location_info_t loc; + + /* an automatic call to new private env the first time */ + if (rtems_current_user_env == &rtems_global_user_env) { + rtems_libio_set_private_env(); /* try to set a new private env*/ + if (rtems_current_user_env == &rtems_global_user_env) /* not ok */ + rtems_set_errno_and_return_minus_one( ENOTSUP ); + } + + result = chdir(pathname); + if (result) { + rtems_set_errno_and_return_minus_one( errno ); + } + + /* clone the new root location */ + if (rtems_filesystem_evaluate_path(".", 1, 0, &loc, 0)) { + /* our cwd has changed, though - but there is no easy way of return :-( */ + rtems_set_errno_and_return_minus_one( errno ); + } + rtems_filesystem_freenode(&rtems_filesystem_root); + rtems_filesystem_root = loc; + + return 0; +} diff --git a/cpukit/libcsupport/src/close.c b/cpukit/libcsupport/src/close.c new file mode 100644 index 0000000000..726bca11d9 --- /dev/null +++ b/cpukit/libcsupport/src/close.c @@ -0,0 +1,57 @@ +/* + * close() - POSIX 1003.1b 6.3.1 - Close a File + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> + +int close( + int fd +) +{ + rtems_libio_t *iop; + rtems_status_code rc; + + rtems_libio_check_fd(fd); + iop = rtems_libio_iop(fd); + rtems_libio_check_is_open(iop); + + rc = RTEMS_SUCCESSFUL; + rc = (*iop->pathinfo.handlers->close_h)( iop ); + + rtems_filesystem_freenode( &iop->pathinfo ); + rtems_libio_free( iop ); + + return rc; +} + +/* + * _close_r + * + * This is the Newlib dependent reentrant version of close(). + */ + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__CLOSE_R) + +#include <reent.h> + +int _close_r( + struct _reent *ptr __attribute__((unused)), + int fd +) +{ + return close( fd ); +} +#endif diff --git a/cpukit/libcsupport/src/ctermid.c b/cpukit/libcsupport/src/ctermid.c new file mode 100644 index 0000000000..37b2f9cfc0 --- /dev/null +++ b/cpukit/libcsupport/src/ctermid.c @@ -0,0 +1,42 @@ +/* + * ctermid() - POSIX 1003.1b 4.7.1 - Generate Terminal Pathname + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#if defined(RTEMS_NEWLIB) + +#include <stdio.h> +#include <string.h> + +static char *ctermid_name = "/dev/console"; + +char *ctermid( + char *s +) +{ + if ( !s ) + return ctermid_name; + + /* + * We have no way of knowing the length of the user provided buffer. + * It may not be large enough but there is no way to know that. :( + * So this is a potential buffer owerrun that we can do nothing about. + */ + strcpy( s, ctermid_name ); + return s; +} + +#endif diff --git a/cpukit/libcsupport/src/dup.c b/cpukit/libcsupport/src/dup.c new file mode 100644 index 0000000000..684d72d92f --- /dev/null +++ b/cpukit/libcsupport/src/dup.c @@ -0,0 +1,26 @@ +/* + * dup() - POSIX 1003.1b 6.2.1 Duplicate an Open File Descriptor + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <fcntl.h> + +int dup( + int fildes +) +{ + return fcntl( fildes, F_DUPFD, 0 ); +} diff --git a/cpukit/libcsupport/src/dup2.c b/cpukit/libcsupport/src/dup2.c new file mode 100644 index 0000000000..15998f797c --- /dev/null +++ b/cpukit/libcsupport/src/dup2.c @@ -0,0 +1,52 @@ +/* + * dup2() - POSIX 1003.1b 6.2.1 Duplicate an Open File Descriptor + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <fcntl.h> + +#include <rtems/libio_.h> + +int dup2( + int fildes, + int fildes2 +) +{ + int status; + struct stat buf; + + /* + * If fildes is not valid, then fildes2 should not be closed. + */ + + status = fstat( fildes, &buf ); + if ( status == -1 ) + return -1; + + /* + * If fildes2 is not valid, then we should not do anything either. + */ + + status = fstat( fildes2, &buf ); + if ( status == -1 ) + return -1; + + /* + * This fcntl handles everything else. + */ + + return fcntl( fildes, F_DUPFD, fildes2 ); +} diff --git a/cpukit/libcsupport/src/envlock.c b/cpukit/libcsupport/src/envlock.c new file mode 100644 index 0000000000..9594e0abe3 --- /dev/null +++ b/cpukit/libcsupport/src/envlock.c @@ -0,0 +1,108 @@ +/* + * Author: Till Straumann <strauman@slac.stanford.edu>, 3/2002 + * + * $Id$ + */ + +/* provide locking for the global environment 'environ' */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <sys/reent.h> + +#include <assert.h> + +/* + * NOTES: + * - although it looks like a classical multiple-readers / single writer (MRSW) + * locking problem, we still use a single lock for the following reasons: + * 1) newlib has no provision / hook for calling different locking routines + * from setenv/putenv and getenv, respectively. + * 2) MRSW involves calling several semaphore-primitives, even in the most + * likely case of a first-reader's access. This probably takes more CPU + * time than just waiting until another reader is done; environment + * access is fast. + * - the lock implementation must allow nesting (same thread may call + * lock-lock-unlock-unlock). + * - NEWLIB-1.8.2 has an ugly BUG: if environ is NULL, _findenv_r() bails + * out leaving the lock held :-( + * + * Used by the following functions: + * findenv_r(), setenv_r(), and unsetenv_r() which are called by + * getenv(), getenv_r(), setenv(), and unsetenv(). + * + */ + +#if defined(ENVLOCK_DEDIDCATED_MUTEX) +static rtems_id envLock=0; + +static void +__rtems_envlock_init(void) +{ + extern char **environ; + rtems_status_code rc; + + if (envLock) /* already initialized */ + return; + + assert(environ && "MUST have non-NULL 'environ' due to newlib bug"); + + rc = rtems_semaphore_create( + rtems_build_name('E','N','V','S'), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, + 0, + &envLock); + if (RTEMS_SUCCESSFUL!=rc) + rtems_fatal_error_occurred(rc); +} + +void +__env_lock(struct _reent *r) +{ + /* Do lazy init */ + if (!envLock) + __rtems_envlock_init(); + /* + * Must not use a semaphore before pre-tasking hook is called. + * - it will corrupt memory :-( + */ + + if (_Thread_Executing) + rtems_semaphore_obtain(envLock, RTEMS_WAIT, RTEMS_NO_TIMEOUT); +} + +void +__env_unlock(struct _reent *r) +{ + /* + * Must not use a semaphore before pre-tasking hook is called. + * - it will corrupt memory :-( + */ + if (_Thread_Executing) + rtems_semaphore_release(envLock); +} +#else + +/* + * Reuse the libio mutex -- it is always initialized before we + * could possibly run. + */ + +#include <rtems/libio_.h> + +void +__env_lock(struct _reent *r __attribute__((unused))) +{ + rtems_libio_lock(); +} + +void +__env_unlock(struct _reent *r __attribute__((unused))) +{ + rtems_libio_unlock(); +} +#endif diff --git a/cpukit/libcsupport/src/error.c b/cpukit/libcsupport/src/error.c new file mode 100644 index 0000000000..074707c54c --- /dev/null +++ b/cpukit/libcsupport/src/error.c @@ -0,0 +1,209 @@ +/* + * report errors and panics to RTEMS' stderr. + * Currently just used by RTEMS monitor. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * These routines provide general purpose error reporting. + * rtems_error reports an error to stderr and allows use of + * printf style formatting. A newline is appended to all messages. + * + * error_flag can be specified as any of the following: + * + * RTEMS_ERROR_ERRNO -- include errno text in output + * RTEMS_ERROR_PANIC -- halts local system after output + * RTEMS_ERROR_ABORT -- abort after output + * + * It can also include a rtems_status value which can be OR'd + * with the above flags. * + * + * EXAMPLE + * #include <rtems.h> + * #include <rtems/error.h> + * rtems_error(0, "stray interrupt %d", intr); + * + * EXAMPLE + * if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL) + * { + * rtems_error(status | RTEMS_ERROR_ABORT, + * "could not create task"); + * } + * + * EXAMPLE + * if ((fd = open(pathname, O_RDNLY)) < 0) + * { + * rtems_error(RTEMS_ERROR_ERRNO, "open of '%s' failed", pathname); + * goto failed; + * } + */ + +/* This is always defined on RTEMS Scheduler Simulator and thus + * we get a redefined warning if this is not present. + */ +#ifndef __RTEMS_VIOLATE_KERNEL_VISIBILITY__ + #define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ +#endif +#include <rtems.h> + +#include <rtems/error.h> +#include <rtems/assoc.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdarg.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> /* _exit() */ + +int rtems_panic_in_progress; + +const rtems_assoc_t rtems_status_assoc[] = { + { "successful completion", RTEMS_SUCCESSFUL, 0 }, + { "returned from a thread", RTEMS_TASK_EXITTED, 0 }, + { "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, 0 }, + { "invalid object name", RTEMS_INVALID_NAME, 0 }, + { "invalid object id", RTEMS_INVALID_ID, 0 }, + { "too many", RTEMS_TOO_MANY, 0 }, + { "timed out waiting", RTEMS_TIMEOUT, 0 }, + { "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, 0 }, + { "specified size was invalid", RTEMS_INVALID_SIZE, 0 }, + { "address specified is invalid", RTEMS_INVALID_ADDRESS, 0 }, + { "number was invalid", RTEMS_INVALID_NUMBER, 0 }, + { "item has not been initialized", RTEMS_NOT_DEFINED, 0 }, + { "resources still outstanding", RTEMS_RESOURCE_IN_USE, 0 }, + { "request not satisfied", RTEMS_UNSATISFIED, 0 }, + { "thread is in wrong state", RTEMS_INCORRECT_STATE, 0 }, + { "thread already in state", RTEMS_ALREADY_SUSPENDED, 0 }, + { "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, 0 }, + { "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, 0 }, + { "called from wrong environment", RTEMS_CALLED_FROM_ISR, 0 }, + { "invalid thread priority", RTEMS_INVALID_PRIORITY, 0 }, + { "invalid date/time", RTEMS_INVALID_CLOCK, 0 }, + { "invalid node id", RTEMS_INVALID_NODE, 0 }, + { "directive not configured", RTEMS_NOT_CONFIGURED, 0 }, + { "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , 0 }, + { "directive not implemented", RTEMS_NOT_IMPLEMENTED, 0 }, + { "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, 0 }, + { "could not get enough memory", RTEMS_NO_MEMORY, 0 }, + { "driver IO error", RTEMS_IO_ERROR, 0 }, + { "internal multiprocessing only", THREAD_STATUS_PROXY_BLOCKING, 0 }, + { 0, 0, 0 }, +}; + + +const char *rtems_status_text( + rtems_status_code status +) +{ + return rtems_assoc_name_by_local(rtems_status_assoc, status); +} + + +static int rtems_verror( + rtems_error_code_t error_flag, + const char *printf_format, + va_list arglist +) +{ + int local_errno = 0; + int chars_written = 0; + rtems_status_code status; + + if (error_flag & RTEMS_ERROR_PANIC) { + if (rtems_panic_in_progress++) + _Thread_Disable_dispatch(); /* disable task switches */ + + /* don't aggravate things */ + if (rtems_panic_in_progress > 2) + return 0; + } + + (void) fflush(stdout); /* in case stdout/stderr same */ + + status = error_flag & ~RTEMS_ERROR_MASK; + if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */ + local_errno = errno; + + #if defined(RTEMS_MULTIPROCESSING) + if (_System_state_Is_multiprocessing) + fprintf(stderr, "[%" PRIu32 "] ", _Configuration_MP_table->node); + #endif + + chars_written += vfprintf(stderr, printf_format, arglist); + + if (status) + chars_written += + fprintf(stderr, " (status: %s)", rtems_status_text(status)); + + if (local_errno) { + if ((local_errno > 0) && *strerror(local_errno)) + chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno)); + else + chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno); + } + + chars_written += fprintf(stderr, "\n"); + + (void) fflush(stderr); + + return chars_written; +} + + +/* + * Report an error. + * error_flag is as above; printf_format is a normal + * printf(3) format string, with its concommitant arguments. + * + * Returns the number of characters written. + */ + +int rtems_error( + rtems_error_code_t error_flag, + const char *printf_format, + ... +) +{ + va_list arglist; + int chars_written; + + va_start(arglist, printf_format); + chars_written = rtems_verror(error_flag, printf_format, arglist); + va_end(arglist); + + if (error_flag & RTEMS_ERROR_PANIC) { + rtems_error(0, "fatal error, exiting"); + _exit(errno); + } + if (error_flag & RTEMS_ERROR_ABORT) { + rtems_error(0, "fatal error, aborting"); + abort(); + } + + return chars_written; +} + +/* + * rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...) + */ + +void rtems_panic( + const char *printf_format, + ... +) +{ + va_list arglist; + + va_start(arglist, printf_format); + (void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist); + va_end(arglist); + + rtems_error(0, "fatal error, exiting"); + _exit(errno); +} diff --git a/cpukit/libcsupport/src/eval.c b/cpukit/libcsupport/src/eval.c new file mode 100644 index 0000000000..5a9118d3e1 --- /dev/null +++ b/cpukit/libcsupport/src/eval.c @@ -0,0 +1,151 @@ +/* + * rtems_filesystem_evaluate_path() + * + * Routine to seed the evaluate path routine. + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int rtems_filesystem_evaluate_relative_path( + const char *pathname, + size_t pathnamelen, + int flags, + rtems_filesystem_location_info_t *pathloc, + int follow_link +) +{ + int result; + rtems_filesystem_node_types_t type; + + #if defined(RTEMS_DEBUG) + /* + * Verify Input parameters that should never be bad unless someone + * is implementing a new filesystem and has bugs. + */ + if ( !pathname ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + if ( !pathloc ) + rtems_set_errno_and_return_minus_one( EIO ); + #endif + + result = (*pathloc->ops->evalpath_h)( pathname, pathnamelen, flags, pathloc ); + + /* + * Get the Node type and determine if you need to follow the link or + * not. + */ + + if ( (result == 0) && follow_link ) { + + type = (*pathloc->ops->node_type_h)( pathloc ); + + if ( ( type == RTEMS_FILESYSTEM_HARD_LINK ) || + ( type == RTEMS_FILESYSTEM_SYM_LINK ) ) { + + /* what to do with the valid node pathloc points to + * if eval_link_h fails? + * Let the FS implementation deal with this case. It + * should probably free pathloc in either case: + * - if the link evaluation fails, it must free the + * original (valid) pathloc because we are going + * to return -1 and hence the FS generics won't + * cleanup pathloc. + * - if the link evaluation is successful, the updated + * pathloc will be passed up (and eventually released). + * Hence, the (valid) originial node that we submit to + * eval_link_h() should be released by the handler. + */ + + result = (*pathloc->ops->eval_link_h)( pathloc, flags ); + } + } + + return result; +} + +int rtems_filesystem_evaluate_path( + const char *pathname, + size_t pathnamelen, + int flags, + rtems_filesystem_location_info_t *pathloc, + int follow_link +) +{ + int i = 0; + + #if defined(RTEMS_DEBUG) + /* + * Verify Input parameters that should never be bad unless someone + * is implementing a new filesystem and has bugs. + */ + if ( !pathname ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + if ( !pathloc ) + rtems_set_errno_and_return_minus_one( EIO ); + #endif + + /* + * Evaluate the path using the optable evalpath. + */ + + rtems_filesystem_get_start_loc( pathname, &i, pathloc ); + + /* + * We evaluation the path relative to the start location we get got. + */ + return rtems_filesystem_evaluate_relative_path( &pathname[i], + pathnamelen - i, + flags, + pathloc, + follow_link ); +} + +int rtems_filesystem_dirname( + const char *pathname +) +{ + int len = strlen( pathname ); + + while ( len ) { + len--; + if ( rtems_filesystem_is_separator( pathname[len] ) ) + break; + } + + return len; +} + +int rtems_filesystem_prefix_separators( + const char *pathname, + int pathnamelen +) +{ + /* + * Eat any separators at start of the path. + */ + int stripped = 0; + while ( *pathname && pathnamelen && rtems_filesystem_is_separator( *pathname ) ) + { + pathname++; + pathnamelen--; + stripped++; + } + return stripped; +} diff --git a/cpukit/libcsupport/src/fchdir.c b/cpukit/libcsupport/src/fchdir.c new file mode 100644 index 0000000000..3c53d653e3 --- /dev/null +++ b/cpukit/libcsupport/src/fchdir.c @@ -0,0 +1,82 @@ +/* + * fchdir() - compatible with SVr4, 4.4BSD and X/OPEN - Change Directory + * + * COPYRIGHT (c) 1989-2000. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <sys/stat.h> +#include <errno.h> + +#include <rtems.h> +#include <rtems/libio.h> +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int fchdir( + int fd +) +{ + rtems_libio_t *iop; + rtems_filesystem_location_info_t loc, saved; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + + /* + * Now process the fchmod(). + */ + + rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); + + /* + * Verify you can change directory into this node. + */ + + if ( (*iop->pathinfo.ops->node_type_h)( &iop->pathinfo ) != + RTEMS_FILESYSTEM_DIRECTORY ) { + rtems_set_errno_and_return_minus_one( ENOTDIR ); + } + + + /* + * FIXME : I feel there should be another call to + * actually take into account the extra reference to + * this node which we are making here. I can + * see the freenode interface but do not see + * allocnode node interface. It maybe node_type. + * + * FIXED: T.Straumann: it is evaluate_path() + * but note the race condition. Threads who + * share their rtems_filesystem_current better + * be synchronized! + */ + + saved = rtems_filesystem_current; + rtems_filesystem_current = iop->pathinfo; + + /* clone the current node */ + if (rtems_filesystem_evaluate_path(".", 1, 0, &loc, 0)) { + /* cloning failed; restore original and bail out */ + rtems_filesystem_current = saved; + return -1; + } + /* release the old one */ + rtems_filesystem_freenode( &saved ); + + rtems_filesystem_current = loc; + + return 0; +} diff --git a/cpukit/libcsupport/src/fchmod.c b/cpukit/libcsupport/src/fchmod.c new file mode 100644 index 0000000000..867f40f1f8 --- /dev/null +++ b/cpukit/libcsupport/src/fchmod.c @@ -0,0 +1,45 @@ +/* + * fchmod() - POSIX 1003.1b 5.6.4 - Change File Modes + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <sys/stat.h> +#include <errno.h> + +#include <rtems.h> +#include <rtems/libio.h> +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int fchmod( + int fd, + mode_t mode +) +{ + rtems_libio_t *iop; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + + /* + * Now process the fchmod(). + */ + + rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); + + return (*iop->pathinfo.handlers->fchmod_h)( &iop->pathinfo, mode ); +} diff --git a/cpukit/libcsupport/src/fchown.c b/cpukit/libcsupport/src/fchown.c new file mode 100644 index 0000000000..13bb2b9da0 --- /dev/null +++ b/cpukit/libcsupport/src/fchown.c @@ -0,0 +1,42 @@ +/* + * fchown() - POSIX 1003.1b 5.6.5 - Change Owner and Group of a File + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/stat.h> +#include <errno.h> + +#include <rtems.h> +#include <rtems/libio.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int fchown( + int fd, + uid_t owner, + gid_t group +) +{ + rtems_libio_t *iop; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + + rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); + + return (*iop->pathinfo.ops->chown_h)( &iop->pathinfo, owner, group ); +} diff --git a/cpukit/libcsupport/src/fcntl.c b/cpukit/libcsupport/src/fcntl.c new file mode 100644 index 0000000000..988a9414ee --- /dev/null +++ b/cpukit/libcsupport/src/fcntl.c @@ -0,0 +1,184 @@ +/* + * fcntl() - POSIX 1003.1b 6.5.2 - File Control + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include <rtems.h> +#include <rtems/libio_.h> + +static int vfcntl( + int fd, + int cmd, + va_list ap +) +{ + rtems_libio_t *iop; + rtems_libio_t *diop; + int fd2; + int flags; + int mask; + int ret = 0; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + + /* + * Now process the fcntl(). + */ + + /* + * This switch should contain all the cases from POSIX. + */ + + switch ( cmd ) { + case F_DUPFD: /* dup */ + fd2 = va_arg( ap, int ); + if ( fd2 ) + diop = rtems_libio_iop( fd2 ); + else { + /* allocate a file control block */ + diop = rtems_libio_allocate(); + if ( diop == 0 ) { + ret = -1; + break; + } + } + + diop->flags = iop->flags; + diop->pathinfo = iop->pathinfo; + ret = (int) (diop - rtems_libio_iops); + break; + + case F_GETFD: /* get f_flags */ + ret = ((iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0); + break; + + 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; + break; + + case F_GETFL: /* more flags (cloexec) */ + ret = rtems_libio_to_fcntl_flags( iop->flags ); + break; + + case F_SETFL: + flags = rtems_libio_fcntl_flags( va_arg( ap, int ) ); + mask = LIBIO_FLAGS_NO_DELAY | LIBIO_FLAGS_APPEND; + + /* + * XXX If we are turning on append, should we seek to the end? + */ + + iop->flags = (iop->flags & ~mask) | (flags & mask); + break; + + case F_GETLK: + errno = ENOTSUP; + ret = -1; + break; + + case F_SETLK: + errno = ENOTSUP; + ret = -1; + break; + + case F_SETLKW: + errno = ENOTSUP; + ret = -1; + break; + + case F_SETOWN: /* for sockets. */ + errno = ENOTSUP; + ret = -1; + break; + + case F_GETOWN: /* for sockets. */ + errno = ENOTSUP; + ret = -1; + break; + + default: + errno = EINVAL; + ret = -1; + break; + } + + /* + * If we got this far successfully, then we give the optional + * filesystem specific handler a chance to process this. + */ + + if (ret >= 0) { + int err = (*iop->pathinfo.handlers->fcntl_h)( cmd, iop ); + if (err) { + errno = err; + ret = -1; + } + } + return ret; +} + +int fcntl( + int fd, + int cmd, + ... +) +{ + int ret; + va_list ap; + va_start( ap, cmd ); + ret = vfcntl(fd,cmd,ap); + va_end(ap); + return ret; +} + + +/* + * _fcntl_r + * + * This is the Newlib dependent reentrant version of fcntl(). + */ + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_FCNTL_R) + +#include <reent.h> + +int _fcntl_r( + struct _reent *ptr __attribute__((unused)), + int fd, + int cmd, + int arg +) +{ + return fcntl( fd, cmd, arg ); +} +#endif diff --git a/cpukit/libcsupport/src/fdatasync.c b/cpukit/libcsupport/src/fdatasync.c new file mode 100644 index 0000000000..de226af5c1 --- /dev/null +++ b/cpukit/libcsupport/src/fdatasync.c @@ -0,0 +1,39 @@ +/* + * fdatasync() - POSIX 1003.1b 6.6.2 - Synchronize the Data of a File + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int fdatasync( + int fd +) +{ + rtems_libio_t *iop; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); + + /* + * Now process the fdatasync(). + */ + + return (*iop->pathinfo.handlers->fdatasync_h)( iop ); +} diff --git a/cpukit/libcsupport/src/flockfile.c b/cpukit/libcsupport/src/flockfile.c new file mode 100644 index 0000000000..db83961af1 --- /dev/null +++ b/cpukit/libcsupport/src/flockfile.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2009 by + * Ralf Corsépius, Ulm, Germany. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_FLOCKFILE) && defined(HAVE_DECL_FLOCKFILE) + +#include <stdio.h> + +/* This is a non-functional stub */ +void flockfile(FILE* file) +{ +} + +#endif diff --git a/cpukit/libcsupport/src/fpathconf.c b/cpukit/libcsupport/src/fpathconf.c new file mode 100644 index 0000000000..accaae1585 --- /dev/null +++ b/cpukit/libcsupport/src/fpathconf.c @@ -0,0 +1,87 @@ +/* + * fpathconf() - POSIX 1003.1b - 5.7.1 - Configurable Pathname Varables + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> +#include <rtems/seterr.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; + + rtems_libio_check_fd(fd); + iop = rtems_libio_iop(fd); + rtems_libio_check_is_open(iop); + rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ); + + /* + * Now process the information request. + */ + + 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: + rtems_set_errno_and_return_minus_one( EINVAL ); + break; + } + + return return_value; +} diff --git a/cpukit/libcsupport/src/free.c b/cpukit/libcsupport/src/free.c new file mode 100644 index 0000000000..d3ee2937f9 --- /dev/null +++ b/cpukit/libcsupport/src/free.c @@ -0,0 +1,55 @@ +/* + * calloc() + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" +#include <stdlib.h> + +void free( + void *ptr +) +{ + MSBUMP(free_calls, 1); + + if ( !ptr ) + return; + + /* + * Do not attempt to free memory if in a critical section or ISR. + */ + if ( _System_state_Is_up(_System_state_Get()) && + !malloc_is_system_state_OK() ) { + malloc_deferred_free(ptr); + return; + } + + /* + * If configured, update the statistics + */ + if ( rtems_malloc_statistics_helpers ) + (*rtems_malloc_statistics_helpers->at_free)(ptr); + + if ( !_Protected_heap_Free( RTEMS_Malloc_Heap, ptr ) ) { + printk( "Program heap: free of bad pointer %p -- range %p - %p \n", + ptr, + RTEMS_Malloc_Heap->area_begin, + RTEMS_Malloc_Heap->area_end + ); + } + +} +#endif diff --git a/cpukit/libcsupport/src/freenode.c b/cpukit/libcsupport/src/freenode.c new file mode 100644 index 0000000000..21a9c1de91 --- /dev/null +++ b/cpukit/libcsupport/src/freenode.c @@ -0,0 +1,20 @@ +/* + * freenode() + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include <stdlib.h> +#include <rtems/libio_.h> + +void rtems_filesystem_freenode( rtems_filesystem_location_info_t *_node ) +{ + _node->ops->freenod_h(_node ); +} diff --git a/cpukit/libcsupport/src/fstat.c b/cpukit/libcsupport/src/fstat.c new file mode 100644 index 0000000000..0718c28d0d --- /dev/null +++ b/cpukit/libcsupport/src/fstat.c @@ -0,0 +1,72 @@ +/* + * fstat() - POSIX 1003.1b 5.6.2 - Get File Status + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int fstat( + int fd, + struct stat *sbuf +) +{ + rtems_libio_t *iop; + + /* + * Check to see if we were passed a valid pointer. + */ + if ( !sbuf ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + /* + * Now process the stat() request. + */ + iop = rtems_libio_iop( fd ); + rtems_libio_check_fd( fd ); + rtems_libio_check_is_open(iop); + + /* + * Zero out the stat structure so the various support + * versions of stat don't have to. + */ + memset( sbuf, 0, sizeof(struct stat) ); + + return (*iop->pathinfo.handlers->fstat_h)( &iop->pathinfo, sbuf ); +} + +/* + * _fstat_r + * + * This is the Newlib dependent reentrant version of fstat(). + */ + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_FSTAT_R) + +#include <reent.h> + +int _fstat_r( + struct _reent *ptr __attribute__((unused)), + int fd, + struct stat *buf +) +{ + return fstat( fd, buf ); +} +#endif diff --git a/cpukit/libcsupport/src/fsync.c b/cpukit/libcsupport/src/fsync.c new file mode 100644 index 0000000000..4d2fe2ae12 --- /dev/null +++ b/cpukit/libcsupport/src/fsync.c @@ -0,0 +1,39 @@ +/* + * fsync() - POSIX 1003.1b 6.6.1 - Synchronize the State of a File + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int fsync( + int fd +) +{ + rtems_libio_t *iop; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); + + /* + * Now process the fsync(). + */ + + return (*iop->pathinfo.handlers->fsync_h)( iop ); +} diff --git a/cpukit/libcsupport/src/ftruncate.c b/cpukit/libcsupport/src/ftruncate.c new file mode 100644 index 0000000000..64946d7bb6 --- /dev/null +++ b/cpukit/libcsupport/src/ftruncate.c @@ -0,0 +1,51 @@ +/* + * ftruncate() - Truncate a File to the Specified Length + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <errno.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int ftruncate( + int fd, + off_t length +) +{ + rtems_libio_t *iop; + rtems_filesystem_location_info_t loc; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + + /* + * Now process the ftruncate() request. + */ + + /* + * Make sure we are not working on a directory + */ + + loc = iop->pathinfo; + if ( (*loc.ops->node_type_h)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY ) + rtems_set_errno_and_return_minus_one( EISDIR ); + + rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); + + return (*iop->pathinfo.handlers->ftruncate_h)( iop, length ); +} diff --git a/cpukit/libcsupport/src/ftrylockfile.c b/cpukit/libcsupport/src/ftrylockfile.c new file mode 100644 index 0000000000..924690e44f --- /dev/null +++ b/cpukit/libcsupport/src/ftrylockfile.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 by + * Ralf Corsépius, Ulm, Germany. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_FTRYLOCKFILE) && defined(HAVE_DECL_FTRYLOCKFILE) + +#include <stdio.h> +#include <rtems/seterr.h> +#include <errno.h> + +/* This is a non-functional stub */ +int ftrylockfile(FILE* file) +{ + rtems_set_errno_and_return_minus_one( ENOTSUP ); +} + +#endif diff --git a/cpukit/libcsupport/src/funlockfile.c b/cpukit/libcsupport/src/funlockfile.c new file mode 100644 index 0000000000..a9f1bf3a92 --- /dev/null +++ b/cpukit/libcsupport/src/funlockfile.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2009 by + * Ralf Corsépius, Ulm, Germany. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_FUNLOCKFILE) && defined(HAVE_DECL_FUNLOCKFILE) + +#include <stdio.h> + +/* This is a non-functional stub */ +void funlockfile(FILE* file) +{ +} + +#endif diff --git a/cpukit/libcsupport/src/getchark.c b/cpukit/libcsupport/src/getchark.c new file mode 100644 index 0000000000..f501fc65f0 --- /dev/null +++ b/cpukit/libcsupport/src/getchark.c @@ -0,0 +1,25 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/bspIo.h> + +int getchark(void) +{ + if ( BSP_poll_char ) + return (*BSP_poll_char)(); + + return -1; +} diff --git a/cpukit/libcsupport/src/getcwd.c b/cpukit/libcsupport/src/getcwd.c new file mode 100644 index 0000000000..2f2be7fc72 --- /dev/null +++ b/cpukit/libcsupport/src/getcwd.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 1989, 1991 The 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. + * + * Copied from newlib 1.8.1. RTEMS can not build all of the contents + * of the UNIX directory but we need this routine. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_GETCWD + +/* + * Added these when moved to RTEMS + */ + +#define _stat stat +#define _opendir opendir +#define _fstat fstat +#define _readdir readdir +#define _closedir closedir + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getcwd.c 5.11 (Berkeley) 2/24/91"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/stat.h> +#include <errno.h> +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <reent.h> +#include <_syslist.h> + +#define bcopy(a,b,c) memmove (b,a,c) + +#define ISDOT(dp) \ + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + +#ifndef _REENT_ONLY + +char * +getcwd ( + char *pt, + size_t size) +{ + register struct dirent *dp; + register DIR *dir = 0; + register dev_t dev; + register ino_t ino; + register int first; + register char *bpt, *bup; + struct stat s; + dev_t root_dev; + ino_t root_ino; + size_t ptsize, upsize; + int save_errno; + char *ept, *eup, *up; + + /* + * If no buffer specified by the user, allocate one as necessary. + * If a buffer is specified, the size has to be non-zero. The path + * is built from the end of the buffer backwards. + */ + + if (pt) + { + ptsize = 0; + if (!size) + { + errno = EINVAL; + return (char *) NULL; + } + ept = pt + size; + } + else + { + if (!(pt = (char *) malloc (ptsize = 1024 - 4))) + { + return (char *) NULL; + } + ept = pt + ptsize; + } + bpt = ept - 1; + *bpt = '\0'; + + /* + * Allocate bytes (1024 - malloc space) for the string of "../"'s. + * Should always be enough (it's 340 levels). If it's not, allocate + * as necessary. Special * case the first stat, it's ".", not "..". + */ + + if (!(up = (char *) malloc (upsize = 1024 - 4))) + { + goto err; + } + eup = up + MAXPATHLEN; + bup = up; + up[0] = '.'; + up[1] = '\0'; + + /* Save root values, so know when to stop. */ + if (stat ("/", &s)) + goto err; + root_dev = s.st_dev; + root_ino = s.st_ino; + + errno = 0; /* XXX readdir has no error return. */ + + for (first = 1;; first = 0) + { + /* Stat the current level. */ + if (_stat (up, &s)) + goto err; + + /* Save current node values. */ + ino = s.st_ino; + dev = s.st_dev; + + /* Check for reaching root. */ + if (root_dev == dev && root_ino == ino) + { + *--bpt = '/'; + /* + * It's unclear that it's a requirement to copy the + * path to the beginning of the buffer, but it's always + * been that way and stuff would probably break. + */ + (void) bcopy (bpt, pt, ept - bpt); + free (up); + return pt; + } + + /* + * Build pointer to the parent directory, allocating memory + * as necessary. Max length is 3 for "../", the largest + * possible component name, plus a trailing NULL. + */ + + if (bup + 3 + MAXNAMLEN + 1 >= eup) + { + if (!(up = (char *) realloc (up, upsize *= 2))) + { + goto err; + } + bup = up; + eup = up + upsize; + } + *bup++ = '.'; + *bup++ = '.'; + *bup = '\0'; + + /* Open and stat parent directory. */ + if (!(dir = _opendir (up)) || _fstat (__dirfd (dir), &s)) + goto err; + + /* Add trailing slash for next directory. */ + *bup++ = '/'; + + /* + * If it's a mount point, have to stat each element because + * the inode number in the directory is for the entry in the + * parent directory, not the inode number of the mounted file. + */ + + save_errno = 0; + if (s.st_dev == dev) + { + for (;;) + { + if (!(dp = _readdir (dir))) + goto notfound; + if (dp->d_ino == ino) + break; + } + } + else + for (;;) + { + if (!(dp = _readdir (dir))) + goto notfound; + if (ISDOT (dp)) + continue; + bcopy (dp->d_name, bup, strlen (dp->d_name) + 1); + + /* Save the first error for later. */ + if (stat (up, &s)) + { + if (!save_errno) + save_errno = errno; + errno = 0; + continue; + } + if (s.st_dev == dev && s.st_ino == ino) + break; + } + + /* + * Check for length of the current name, preceding slash, + * leading slash. + */ + + if (bpt - pt <= strlen (dp->d_name) + (first ? 1 : 2)) + { + size_t len, off; + + if (!ptsize) + { + errno = ERANGE; + goto err; + } + off = bpt - pt; + len = ept - bpt; + if (!(pt = (char *) realloc (pt, ptsize *= 2))) + { + goto err; + } + bpt = pt + off; + ept = pt + ptsize; + (void) bcopy (bpt, ept - len, len); + bpt = ept - len; + } + if (!first) + *--bpt = '/'; + bpt -= strlen (dp->d_name); + bcopy (dp->d_name, bpt, strlen (dp->d_name)); + (void) _closedir (dir); + dir = 0; + + /* Truncate any file name. */ + *bup = '\0'; + } + +notfound: + /* + * If readdir set errno, use it, not any saved error; otherwise, + * didn't find the current directory in its parent directory, set + * errno to ENOENT. + */ + + if (!errno) + errno = save_errno ? save_errno : ENOENT; + /* FALLTHROUGH */ + +err: + if(dir) + (void) _closedir (dir); + if (ptsize) + free (pt); + free (up); + return (char *) NULL; +} + +#endif /* _REENT_ONLY */ + +#endif diff --git a/cpukit/libcsupport/src/getdents.c b/cpukit/libcsupport/src/getdents.c new file mode 100644 index 0000000000..d0b787cd88 --- /dev/null +++ b/cpukit/libcsupport/src/getdents.c @@ -0,0 +1,55 @@ +/* + * 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-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int getdents( + int dd_fd, + char *dd_buf, + int dd_len +) +{ + 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_h)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) + rtems_set_errno_and_return_minus_one( ENOTDIR ); + + /* + * Return the number of bytes that were actually transfered as a result + * of the read attempt. + */ + return (*iop->pathinfo.handlers->read_h)( iop, dd_buf, dd_len ); +} diff --git a/cpukit/libcsupport/src/getegid.c b/cpukit/libcsupport/src/getegid.c new file mode 100644 index 0000000000..2d89348230 --- /dev/null +++ b/cpukit/libcsupport/src/getegid.c @@ -0,0 +1,24 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/seterr.h> +#include <rtems/userenv.h> + +/* + * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs, + * P1003.1b-1993, p. 84 + */ + +gid_t getegid( void ) +{ + return _POSIX_types_Egid; +} diff --git a/cpukit/libcsupport/src/geteuid.c b/cpukit/libcsupport/src/geteuid.c new file mode 100644 index 0000000000..de35557c63 --- /dev/null +++ b/cpukit/libcsupport/src/geteuid.c @@ -0,0 +1,31 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/seterr.h> + +#include <rtems/userenv.h> + +/* + * MACRO in userenv.h +uid_t _POSIX_types_Euid = 0; +*/ + +/*PAGE + * + * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs, + * P1003.1b-1993, p. 84 + */ + +uid_t geteuid( void ) +{ + return _POSIX_types_Euid; +} diff --git a/cpukit/libcsupport/src/getgid.c b/cpukit/libcsupport/src/getgid.c new file mode 100644 index 0000000000..7074e765e5 --- /dev/null +++ b/cpukit/libcsupport/src/getgid.c @@ -0,0 +1,18 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/userenv.h> + +/* + * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs, + * P1003.1b-1993, p. 84 + */ +gid_t getgid( void ) +{ + return _POSIX_types_Gid; +} diff --git a/cpukit/libcsupport/src/getgroups.c b/cpukit/libcsupport/src/getgroups.c new file mode 100644 index 0000000000..128761c8b6 --- /dev/null +++ b/cpukit/libcsupport/src/getgroups.c @@ -0,0 +1,23 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <unistd.h> + +/*PAGE + * + * 4.2.3 Get Supplementary IDs, P1003.1b-1993, p. 86 + */ + +int getgroups( + int gidsetsize __attribute__((unused)), + gid_t grouplist[] __attribute__((unused)) +) +{ + return 0; /* no supplemental group ids */ +} diff --git a/cpukit/libcsupport/src/getlogin.c b/cpukit/libcsupport/src/getlogin.c new file mode 100644 index 0000000000..f98e7ca9e0 --- /dev/null +++ b/cpukit/libcsupport/src/getlogin.c @@ -0,0 +1,61 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <limits.h> +#include <string.h> +#include <sys/types.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/seterr.h> +#include <rtems/userenv.h> + +#include <unistd.h> +#include <pwd.h> + +/* + * 4.2.4 Get User Name, P1003.1b-1993, p. 87 + * + * NOTE: P1003.1c/D10, p. 49 adds getlogin_r(). + */ +char *getlogin( void ) +{ + (void) getlogin_r( _POSIX_types_Getlogin_buffer, LOGIN_NAME_MAX ); + return _POSIX_types_Getlogin_buffer; +} + +/* + * 4.2.4 Get User Name, P1003.1b-1993, p. 87 + * + * NOTE: P1003.1c/D10, p. 49 adds getlogin_r(). + */ +int getlogin_r( + char *name, + size_t namesize +) +{ + struct passwd *pw; + char *pname; + + if ( !name ) + return EFAULT; + + if ( namesize < LOGIN_NAME_MAX ) + return ERANGE; + + /* Set the pointer to a default name */ + pname = ""; + + pw = getpwuid(getuid()); + if ( pw ) + pname = pw->pw_name; + + strncpy( name, pname, LOGIN_NAME_MAX ); + return 0; +} diff --git a/cpukit/libcsupport/src/getpagesize.c b/cpukit/libcsupport/src/getpagesize.c new file mode 100644 index 0000000000..3ea44be1fa --- /dev/null +++ b/cpukit/libcsupport/src/getpagesize.c @@ -0,0 +1,22 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <sys/param.h> + +/* + * Get System Page Size (from SVR4 and 4.2+ BSD) + * + * This is not a functional version but the SPARC backend for at least + * gcc 2.8.1 plus gnat 3.13p and gcc 3.0.1 require it to be there and + * return a reasonable value. + */ +int getpagesize(void) +{ + return PAGE_SIZE; +} diff --git a/cpukit/libcsupport/src/getpgrp.c b/cpukit/libcsupport/src/getpgrp.c new file mode 100644 index 0000000000..0904d23883 --- /dev/null +++ b/cpukit/libcsupport/src/getpgrp.c @@ -0,0 +1,31 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <limits.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/seterr.h> + +/*PAGE + * + * 4.3.1 Get Process Group IDs, P1003.1b-1993, p. 89 + */ + +pid_t getpgrp( void ) +{ + /* + * This always succeeds and returns the process group id. For rtems, + * this will always be the local node; + */ + + return _Objects_Local_node; +} diff --git a/cpukit/libcsupport/src/getpid.c b/cpukit/libcsupport/src/getpid.c new file mode 100644 index 0000000000..55cd2a6589 --- /dev/null +++ b/cpukit/libcsupport/src/getpid.c @@ -0,0 +1,41 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/seterr.h> + +/*PAGE + * + * 4.1.1 Get Process and Parent Process IDs, P1003.1b-1993, p. 83 + */ + +pid_t getpid( void ) +{ + return _Objects_Local_node; +} + +/* + * _getpid_r + * + * This is the Newlib dependent reentrant version of getpid(). + */ + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__GETPID_R) + +#include <reent.h> + +pid_t _getpid_r( + struct _reent *ptr __attribute__((unused)) +) +{ + return getpid(); +} +#endif diff --git a/cpukit/libcsupport/src/getppid.c b/cpukit/libcsupport/src/getppid.c new file mode 100644 index 0000000000..b987f69447 --- /dev/null +++ b/cpukit/libcsupport/src/getppid.c @@ -0,0 +1,25 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/seterr.h> + +pid_t _POSIX_types_Ppid = 0; + +/*PAGE + * + * 4.1.1 Get Process and Parent Process IDs, P1003.1b-1993, p. 83 + */ + +pid_t getppid( void ) +{ + return _POSIX_types_Ppid; +} diff --git a/cpukit/libcsupport/src/getpwent.c b/cpukit/libcsupport/src/getpwent.c new file mode 100644 index 0000000000..210f4bedd5 --- /dev/null +++ b/cpukit/libcsupport/src/getpwent.c @@ -0,0 +1,438 @@ +/* + * POSIX 1003.1b - 9.2.2 - User Database Access Routines + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <ctype.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +/* + * Static, thread-unsafe, buffers + */ +static FILE *passwd_fp; +static char pwbuf[200]; +static struct passwd pwent; +static FILE *group_fp; +static char grbuf[200]; +static struct group grent; + +/* + * Initialize useable but dummy databases + */ +void init_etc_passwd_group(void) +{ + FILE *fp; + static char etc_passwd_initted = 0; + + if (etc_passwd_initted) + return; + etc_passwd_initted = 1; + mkdir("/etc", 0777); + + /* + * Initialize /etc/passwd + */ + if ((fp = fopen("/etc/passwd", "r")) != NULL) { + fclose(fp); + } + else if ((fp = fopen("/etc/passwd", "w")) != NULL) { + fprintf(fp, "root:*:0:0:root::/:/bin/sh\n" + "rtems:*:1:1:RTEMS Application::/:/bin/sh\n" + "tty:!:2:2:tty owner::/:/bin/false\n" ); + fclose(fp); + } + + /* + * Initialize /etc/group + */ + if ((fp = fopen("/etc/group", "r")) != NULL) { + fclose(fp); + } + else if ((fp = fopen("/etc/group", "w")) != NULL) { + fprintf( fp, "root:x:0:root\n" + "rtems:x:1:rtems\n" + "tty:x:2:tty\n" ); + fclose(fp); + } +} + +/* + * Extract a string value from the database + */ +static int +scanString(FILE *fp, char **name, char **bufp, size_t *nleft, int nlFlag) +{ + int c; + + *name = *bufp; + for (;;) { + c = getc(fp); + if (c == ':') { + if (nlFlag) + return 0; + break; + } + if (c == '\n') { + if (!nlFlag) + return 0; + break; + } + if (c == EOF) + return 0; + if (*nleft < 2) + return 0; + **bufp = c; + ++(*bufp); + --(*nleft); + } + **bufp = '\0'; + ++(*bufp); + --(*nleft); + return 1; +} + +/* + * Extract an integer value from the database + */ +static int +scanInt(FILE *fp, int *val) +{ + int c; + unsigned int i = 0; + unsigned int limit = INT_MAX; + int sign = 0; + int d; + + for (;;) { + c = getc(fp); + if (c == ':') + break; + if (sign == 0) { + if (c == '-') { + sign = -1; + limit++; + continue; + } + sign = 1; + } + if (!isdigit(c)) + return 0; + d = c - '0'; + if ((i > (limit / 10)) + || ((i == (limit / 10)) && (d > (limit % 10)))) + return 0; + i = i * 10 + d; + } + if (sign == 0) + return 0; + *val = i * sign; + return 1; +} + +/* + * Extract a single password record from the database + */ +static int scanpw( + FILE *fp, + struct passwd *pwd, + char *buffer, + size_t bufsize +) +{ + int pwuid, pwgid; + + if (!scanString(fp, &pwd->pw_name, &buffer, &bufsize, 0) + || !scanString(fp, &pwd->pw_passwd, &buffer, &bufsize, 0) + || !scanInt(fp, &pwuid) + || !scanInt(fp, &pwgid) + || !scanString(fp, &pwd->pw_comment, &buffer, &bufsize, 0) + || !scanString(fp, &pwd->pw_gecos, &buffer, &bufsize, 0) + || !scanString(fp, &pwd->pw_dir, &buffer, &bufsize, 0) + || !scanString(fp, &pwd->pw_shell, &buffer, &bufsize, 1)) + return 0; + pwd->pw_uid = pwuid; + pwd->pw_gid = pwgid; + return 1; +} + +static int getpw_r( + const char *name, + int uid, + struct passwd *pwd, + char *buffer, + size_t bufsize, + struct passwd **result +) +{ + FILE *fp; + int match; + + init_etc_passwd_group(); + + if ((fp = fopen("/etc/passwd", "r")) == NULL) + rtems_set_errno_and_return_minus_one( EINVAL ); + + for(;;) { + if (!scanpw(fp, pwd, buffer, bufsize)) + goto error_einval; + + if (name) { + match = (strcmp(pwd->pw_name, name) == 0); + } else { + match = (pwd->pw_uid == uid); + } + + if (match) { + fclose(fp); + *result = pwd; + return 0; + } + } +error_einval: + fclose(fp); + rtems_set_errno_and_return_minus_one( EINVAL ); +} + +int getpwnam_r( + const char *name, + struct passwd *pwd, + char *buffer, + size_t bufsize, + struct passwd **result +) +{ + return getpw_r(name, 0, pwd, buffer, bufsize, result); +} + +struct passwd *getpwnam( + const char *name +) +{ + struct passwd *p; + + if(getpwnam_r(name, &pwent, pwbuf, sizeof pwbuf, &p)) + return NULL; + return p; +} + +int getpwuid_r( + uid_t uid, + struct passwd *pwd, + char *buffer, + size_t bufsize, + struct passwd **result +) +{ + return getpw_r(NULL, uid, pwd, buffer, bufsize, result); +} + +struct passwd *getpwuid( + uid_t uid +) +{ + struct passwd *p; + + if(getpwuid_r(uid, &pwent, pwbuf, sizeof pwbuf, &p)) + return NULL; + return p; +} + +struct passwd *getpwent(void) +{ + if (passwd_fp == NULL) + return NULL; + if (!scanpw(passwd_fp, &pwent, pwbuf, sizeof pwbuf)) + return NULL; + return &pwent; +} + +void setpwent(void) +{ + init_etc_passwd_group(); + + if (passwd_fp != NULL) + fclose(passwd_fp); + passwd_fp = fopen("/etc/passwd", "r"); +} + +void endpwent(void) +{ + if (passwd_fp != NULL) + fclose(passwd_fp); +} + +/* + * Extract a single group record from the database + */ +static int scangr( + FILE *fp, + struct group *grp, + char *buffer, + size_t bufsize +) +{ + int grgid; + char *grmem, *cp; + int memcount; + + if (!scanString(fp, &grp->gr_name, &buffer, &bufsize, 0) + || !scanString(fp, &grp->gr_passwd, &buffer, &bufsize, 0) + || !scanInt(fp, &grgid) + || !scanString(fp, &grmem, &buffer, &bufsize, 1)) + return 0; + grp->gr_gid = grgid; + + /* + * Determine number of members + */ + for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) { + if(*cp == ',') + memcount++; + } + + /* + * Hack to produce (hopefully) a suitably-aligned array of pointers + */ + if (bufsize < (((memcount+1)*sizeof(char *)) + 15)) + return 0; + grp->gr_mem = (char **)(((uintptr_t)buffer + 15) & ~15); + + /* + * Fill in pointer array + */ + grp->gr_mem[0] = grmem; + for (cp = grmem, memcount = 1 ; *cp != 0 ; cp++) { + if(*cp == ',') { + *cp = '\0'; + grp->gr_mem[memcount++] = cp + 1; + } + } + grp->gr_mem[memcount] = NULL; + return 1; +} + +static int getgr_r( + const char *name, + int gid, + struct group *grp, + char *buffer, + size_t bufsize, + struct group **result +) +{ + FILE *fp; + int match; + + init_etc_passwd_group(); + + if ((fp = fopen("/etc/group", "r")) == NULL) + rtems_set_errno_and_return_minus_one( EINVAL ); + + for(;;) { + if (!scangr(fp, grp, buffer, bufsize)) + goto error_einval; + + if (name) { + match = (strcmp(grp->gr_name, name) == 0); + } else { + match = (grp->gr_gid == gid); + } + + if (match) { + fclose(fp); + *result = grp; + return 0; + } + } +error_einval: + fclose(fp); + rtems_set_errno_and_return_minus_one( EINVAL ); +} + +int getgrnam_r( + const char *name, + struct group *grp, + char *buffer, + size_t bufsize, + struct group **result +) +{ + return getgr_r(name, 0, grp, buffer, bufsize, result); +} + +struct group *getgrnam( + const char *name +) +{ + struct group *p; + + if(getgrnam_r(name, &grent, grbuf, sizeof grbuf, &p)) + return NULL; + return p; +} + +int getgrgid_r( + gid_t gid, + struct group *grp, + char *buffer, + size_t bufsize, + struct group **result +) +{ + return getgr_r(NULL, gid, grp, buffer, bufsize, result); +} + +struct group *getgrgid( + gid_t gid +) +{ + struct group *p; + + if(getgrgid_r(gid, &grent, grbuf, sizeof grbuf, &p)) + return NULL; + return p; +} + +struct group *getgrent(void) +{ + if (group_fp == NULL) + return NULL; + if (!scangr(group_fp, &grent, grbuf, sizeof grbuf)) + return NULL; + return &grent; +} + +void setgrent(void) +{ + init_etc_passwd_group(); + + if (group_fp != NULL) + fclose(group_fp); + group_fp = fopen("/etc/group", "r"); +} + +void endgrent(void) +{ + if (group_fp != NULL) + fclose(group_fp); +} diff --git a/cpukit/libcsupport/src/getrusage.c b/cpukit/libcsupport/src/getrusage.c new file mode 100644 index 0000000000..df68376e50 --- /dev/null +++ b/cpukit/libcsupport/src/getrusage.c @@ -0,0 +1,54 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/resource.h> +#include <errno.h> + +#include <rtems.h> +#include <rtems/seterr.h> + +int getrusage(int who, struct rusage *usage) +{ + struct timespec uptime; + struct timeval rtime; + + if ( !usage ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + /* + * RTEMS only has a single process so there are no children. + * The single process has been running since the system + * was booted and since there is no distinction between system + * and user time, we will just report the uptime. + */ + if (who == RUSAGE_SELF) { + rtems_clock_get_uptime( &uptime ); + + rtime.tv_sec = uptime.tv_sec; + rtime.tv_usec = uptime.tv_nsec / 1000; + + usage->ru_utime = rtime; + usage->ru_stime = rtime; + + return 0; + } + + if (who == RUSAGE_CHILDREN) { + rtems_set_errno_and_return_minus_one( ENOSYS ); + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} + diff --git a/cpukit/libcsupport/src/getuid.c b/cpukit/libcsupport/src/getuid.c new file mode 100644 index 0000000000..d3a13192fa --- /dev/null +++ b/cpukit/libcsupport/src/getuid.c @@ -0,0 +1,28 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/userenv.h> + +/* + * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs, + * P1003.1b-1993, p. 84 + */ +uid_t getuid( void ) +{ + return _POSIX_types_Uid; +} + diff --git a/cpukit/libcsupport/src/gxx_wrappers.c b/cpukit/libcsupport/src/gxx_wrappers.c new file mode 100644 index 0000000000..e3d300a9f2 --- /dev/null +++ b/cpukit/libcsupport/src/gxx_wrappers.c @@ -0,0 +1,295 @@ +/* + * RTEMS threads compatibility routines for libgcc2. + * + * by: Rosimildo da Silva (rdasilva@connecttel.com) + * + * Used ideas from: + * W. Eric Norum + * Canadian Light Source + * University of Saskatchewan + * Saskatoon, Saskatchewan, CANADA + * eric@cls.usask.ca + * + * Eric sent some e-mail in the rtems-list as a start point for this + * module implementation. + * + * $Id$ + */ + +/* + * This file is only used if using gcc + */ +#if defined(__GNUC__) + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/gxx_wrappers.h> + +#include <stdlib.h> + +#include <rtems.h> + +/* uncomment this if you need to debug this interface */ +/*#define DEBUG_GXX_WRAPPERS 1*/ + +int rtems_gxx_once(__gthread_once_t *once, void (*func) (void)) +{ + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: once=%x, func=%x\n", *once, func ); + #endif + + if ( *(volatile __gthread_once_t *)once == 0 ) { + rtems_mode saveMode; + __gthread_once_t o; + + rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode); + if ( (o = *(volatile __gthread_once_t *)once) == 0 ) { + *(volatile __gthread_once_t *)once = 1; + } + rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode); + if ( o == 0 ) + (*func)(); + } + return 0; +} + +int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *)) +{ + rtems_status_code status; + + /* Ok, this can be a bit tricky. We are going to return a "key" as a + * pointer to the buffer that will hold the value of the key itself. + * We have to to this, because the others functions on this interface + * deal with the value of the key, as used with the POSIX API. + */ + /* Do not pull your hair, trust me this works. :-) */ + __gthread_key_t new_key = (__gthread_key_t) malloc( sizeof( *new_key ) ); + *key = new_key; + new_key->val = NULL; + new_key->dtor = dtor; + + #ifdef DEBUG_GXX_WRAPPERS + printk( + "gxx_wrappers: create key=%x, dtor=%x, new_key=%x\n", key, dtor, new_key + ); + #endif + + /* register with RTEMS the buffer that will hold the key values */ + status = rtems_task_variable_add( RTEMS_SELF, (void **)new_key, dtor ); + if ( status == RTEMS_SUCCESSFUL ) + return 0; + + free( new_key ); + return -1; +} + +int rtems_gxx_key_dtor (__gthread_key_t key, void *ptr) +{ + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: dtor key=%x, ptr=%x\n", key, ptr ); + #endif + + key->val = 0; + return 0; +} + +int rtems_gxx_key_delete (__gthread_key_t key) +{ + rtems_status_code status; + + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: delete key=%x\n", key ); + #endif + + /* register with RTEMS the buffer that will hold the key values */ + status = rtems_task_variable_delete( RTEMS_SELF, (void **)key ); + if ( status == RTEMS_SUCCESSFUL ) { + /* Hmm - hopefully all tasks using this key have gone away... */ + if ( key ) free( *(void **)key ); + return 0; + } + key = NULL; + return 0; +} + +void *rtems_gxx_getspecific(__gthread_key_t key) +{ + rtems_status_code status; + void *p= 0; + + /* register with RTEMS the buffer that will hold the key values */ + status = rtems_task_variable_get( RTEMS_SELF, (void **)key, &p ); + if ( status == RTEMS_SUCCESSFUL ) { + /* We do not have to do this, but what the heck ! */ + p= key->val; + } else { + /* fisrt time, always set to zero, it is unknown the value that the others + * threads are using at the moment of this call + */ + status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor ); + if ( status != RTEMS_SUCCESSFUL ) { + _Internal_error_Occurred( + INTERNAL_ERROR_CORE, + true, + INTERNAL_ERROR_GXX_KEY_ADD_FAILED + ); + } + key->val = (void *)0; + } + + #ifdef DEBUG_GXX_WRAPPERS + printk( + "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n", + key, + p, + rtems_task_self() + ); + #endif + return p; +} + +int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr) +{ + rtems_status_code status; + + #ifdef DEBUG_GXX_WRAPPERS + printk( + "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n", + key, + ptr, + rtems_task_self() + ); + #endif + + /* register with RTEMS the buffer that will hold the key values */ + status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor ); + if ( status == RTEMS_SUCCESSFUL ) { + /* now let's set the proper value */ + key->val = (void *)ptr; + return 0; + } + return -1; +} + + +/* + * MUTEX support + */ +void rtems_gxx_mutex_init (__gthread_mutex_t *mutex) +{ + rtems_status_code status; + + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: mutex init =%X\n", *mutex ); + #endif + + status = rtems_semaphore_create( + rtems_build_name ('G', 'C', 'C', '2'), + 1, + RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE| + RTEMS_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL, + 0, + (rtems_id *)mutex + ); + if ( status != RTEMS_SUCCESSFUL ) { + #ifdef DEBUG_GXX_WRAPPERS + printk( + "gxx_wrappers: mutex init failed %s (%d)\n", + rtems_status_text(status), + status + ); + #endif + _Internal_error_Occurred( + INTERNAL_ERROR_CORE, + true, + INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED + ); + } + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: mutex init complete =%X\n", *mutex ); + #endif +} + +int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex) +{ + rtems_status_code status; + + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: lock mutex=%X\n", *mutex ); + #endif + + status = rtems_semaphore_obtain( + *(rtems_id *)mutex, + RTEMS_WAIT, + RTEMS_NO_TIMEOUT + ); + if ( status == RTEMS_SUCCESSFUL ) + return 0; + return -1; +} + +int rtems_gxx_mutex_destroy (__gthread_mutex_t *mutex) +{ + rtems_status_code status; + + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: destroy mutex=%X\n", *mutex ); + #endif + + status = rtems_semaphore_delete(*(rtems_id *)mutex); + if ( status == RTEMS_SUCCESSFUL ) + return 0; + return -1; +} + +int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex) +{ + rtems_status_code status; + + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: trylock mutex=%X\n", *mutex ); + #endif + + status = rtems_semaphore_obtain (*(rtems_id *)mutex, RTEMS_NO_WAIT, 0); + if ( status == RTEMS_SUCCESSFUL ) + return 0; + return -1; +} + +int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex) +{ + rtems_status_code status; + + #ifdef DEBUG_GXX_WRAPPERS + printk( "gxx_wrappers: unlock mutex=%X\n", *mutex ); + #endif + + status = rtems_semaphore_release( *(rtems_id *)mutex ); + if ( status == RTEMS_SUCCESSFUL ) + return 0; + return -1; +} + +void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex) +{ + rtems_gxx_mutex_init(mutex); +} + +int rtems_gxx_recursive_mutex_lock(__gthread_recursive_mutex_t *mutex) +{ + return rtems_gxx_mutex_lock(mutex); +} + +int rtems_gxx_recursive_mutex_trylock(__gthread_recursive_mutex_t *mutex) +{ + return rtems_gxx_mutex_trylock(mutex); +} + +int rtems_gxx_recursive_mutex_unlock(__gthread_recursive_mutex_t *mutex) +{ + return rtems_gxx_mutex_unlock(mutex); +} + +#endif /* __GNUC__ */ diff --git a/cpukit/libcsupport/src/ioctl.c b/cpukit/libcsupport/src/ioctl.c new file mode 100644 index 0000000000..ae8a88bd77 --- /dev/null +++ b/cpukit/libcsupport/src/ioctl.c @@ -0,0 +1,54 @@ +/* + * 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-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +#include <unistd.h> + +int ioctl( + int fd, + ioctl_command_t command, + ... +) +{ + va_list ap; + rtems_status_code rc; + rtems_libio_t *iop; + void *buffer; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + + va_start(ap, command); + + buffer = va_arg(ap, void *); + + /* + * Now process the ioctl(). + */ + rc = (*iop->pathinfo.handlers->ioctl_h)( iop, command, buffer ); + + va_end( ap ); + return rc; +} diff --git a/cpukit/libcsupport/src/isatty.c b/cpukit/libcsupport/src/isatty.c new file mode 100644 index 0000000000..b29ce7b53d --- /dev/null +++ b/cpukit/libcsupport/src/isatty.c @@ -0,0 +1,35 @@ +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_ISATTY + +#include <sys/stat.h> + +int isatty( + int fd +) +{ + struct stat buf; + + if (fstat (fd, &buf) < 0) + return 0; + + if (S_ISCHR (buf.st_mode)) + return 1; + + return 0; +} + +#endif diff --git a/cpukit/libcsupport/src/isatty_r.c b/cpukit/libcsupport/src/isatty_r.c new file mode 100644 index 0000000000..3e2e2baa14 --- /dev/null +++ b/cpukit/libcsupport/src/isatty_r.c @@ -0,0 +1,35 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * _isatty_r + * + * This is the Newlib dependent reentrant version of isatty(). + */ + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__ISATTY_R) + +#include <unistd.h> +#include <reent.h> +#include <sys/stat.h> + +int _isatty_r( + struct _reent *ptr __attribute__((unused)), + int fd +) +{ + return isatty( fd ); +} +#endif diff --git a/cpukit/libcsupport/src/issetugid.c b/cpukit/libcsupport/src/issetugid.c new file mode 100644 index 0000000000..84a2d9ce61 --- /dev/null +++ b/cpukit/libcsupport/src/issetugid.c @@ -0,0 +1,16 @@ +/* + * Dummy version of BSD routine + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_ISSETUGID) +int issetugid (void) +{ + return 0; +} +#endif diff --git a/cpukit/libcsupport/src/kill_noposix.c b/cpukit/libcsupport/src/kill_noposix.c new file mode 100644 index 0000000000..8b7898b3f8 --- /dev/null +++ b/cpukit/libcsupport/src/kill_noposix.c @@ -0,0 +1,48 @@ +/* + * Marginal implementations of some POSIX API routines + * to be used when POSIX is disabled. + * + * + kill + * + _kill_r + * + __kill + * + sleep + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> + +#include <unistd.h> + +/* + * These are directly supported (and completely correct) in the posix api. + */ + +#if !defined(RTEMS_POSIX_API) +int kill( pid_t pid, int sig ) +{ + return 0; +} + +#if defined(RTEMS_NEWLIB) +#include <reent.h> + +int _kill_r( struct _reent *ptr, pid_t pid, int sig ) +{ + return 0; +} +#endif + +int __kill( pid_t pid, int sig ) +{ + return 0; +} +#endif diff --git a/cpukit/libcsupport/src/lchown.c b/cpukit/libcsupport/src/lchown.c new file mode 100644 index 0000000000..c244e08879 --- /dev/null +++ b/cpukit/libcsupport/src/lchown.c @@ -0,0 +1,31 @@ +/* + * lchown() - POSIX 1003.1b 5.6.5 - Change Owner and Group of a File + * But Do Not Follow a Symlink + * + * Written by: Vinu Rajashekhar <vinutheraj@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/stat.h> + +#include <rtems.h> + +int _chown_helper( const char *path, uid_t owner, gid_t group, int follow_link); + +int lchown( + const char *path, + uid_t owner, + gid_t group +) +{ + return _chown_helper( path, owner, group, false ); +} diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c new file mode 100644 index 0000000000..d080d01596 --- /dev/null +++ b/cpukit/libcsupport/src/libio.c @@ -0,0 +1,278 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <rtems.h> +#include <rtems/libio_.h> +#include <rtems/assoc.h> + +/* define this to alias O_NDELAY to O_NONBLOCK, i.e., + * O_NDELAY is accepted on input but fcntl(F_GETFL) returns + * O_NONBLOCK. This is because rtems has no distinction + * between the two (but some systems have). + * Note that accepting this alias creates a problem: + * an application trying to clear the non-blocking flag + * using a + * + * fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NDELAY); + * + * does (silently) ignore the operation. + */ +#undef ACCEPT_O_NDELAY_ALIAS + +/* + * rtems_libio_fcntl_flags + * + * Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand + */ + +const 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 }, +}; + +const rtems_assoc_t status_flags_assoc[] = { +#ifdef ACCEPT_O_NDELAY_ALIAS + { "NO DELAY", LIBIO_FLAGS_NO_DELAY, O_NDELAY }, +#endif + { "NONBLOCK", LIBIO_FLAGS_NO_DELAY, O_NONBLOCK }, + { "APPEND", LIBIO_FLAGS_APPEND, O_APPEND }, + { "CREATE", LIBIO_FLAGS_CREATE, O_CREAT }, + { 0, 0, 0 }, +}; + +uint32_t rtems_libio_fcntl_flags( + uint32_t fcntl_flags +) +{ + uint32_t flags = 0; + uint32_t 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 + */ + + flags |= + rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags); + return flags; +} + +/* + * rtems_libio_to_fcntl_flags + * + * Convert RTEMS internal flags to UNIX fnctl(2) flags + */ + +uint32_t rtems_libio_to_fcntl_flags( + uint32_t flags +) +{ + uint32_t fcntl_flags = 0; + + if ( (flags & LIBIO_FLAGS_READ_WRITE) == LIBIO_FLAGS_READ_WRITE ) { + fcntl_flags |= O_RDWR; + } else if ( (flags & LIBIO_FLAGS_READ) == LIBIO_FLAGS_READ) { + fcntl_flags |= O_RDONLY; + } else if ( (flags & LIBIO_FLAGS_WRITE) == LIBIO_FLAGS_WRITE) { + fcntl_flags |= O_WRONLY; + } + + if ( (flags & LIBIO_FLAGS_NO_DELAY) == LIBIO_FLAGS_NO_DELAY ) { + fcntl_flags |= O_NONBLOCK; + } + + if ( (flags & LIBIO_FLAGS_APPEND) == LIBIO_FLAGS_APPEND ) { + fcntl_flags |= O_APPEND; + } + + if ( (flags & LIBIO_FLAGS_CREATE) == LIBIO_FLAGS_CREATE ) { + fcntl_flags |= O_CREAT; + } + + return fcntl_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. + */ + +rtems_libio_t *rtems_libio_allocate( void ) +{ + rtems_libio_t *iop, *next; + rtems_status_code rc; + rtems_id sema; + + rtems_libio_lock(); + + if (rtems_libio_iop_freelist) { + rc = rtems_semaphore_create( + RTEMS_LIBIO_IOP_SEM(rtems_libio_iop_freelist - rtems_libio_iops), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, + 0, + &sema + ); + if (rc != RTEMS_SUCCESSFUL) + goto failed; + iop = rtems_libio_iop_freelist; + next = iop->data1; + (void) memset( iop, 0, sizeof(rtems_libio_t) ); + iop->flags = LIBIO_FLAGS_OPEN; + iop->sem = sema; + rtems_libio_iop_freelist = next; + goto done; + } + +failed: + iop = 0; + +done: + rtems_libio_unlock(); + return iop; +} + +/* + * rtems_libio_free + * + * This routine frees the resources associated with an IOP (file descriptor) + * and clears the slot in the IOP Table. + */ + +void rtems_libio_free( + rtems_libio_t *iop +) +{ + rtems_libio_lock(); + + if (iop->sem) + rtems_semaphore_delete(iop->sem); + + iop->flags &= ~LIBIO_FLAGS_OPEN; + iop->data1 = rtems_libio_iop_freelist; + rtems_libio_iop_freelist = iop; + + rtems_libio_unlock(); +} + +/* + * 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 at least 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. + */ + +int rtems_libio_is_open_files_in_fs( + rtems_filesystem_mount_table_entry_t * fs_mt_entry +) +{ + rtems_libio_t *iop; + int result = 0; + uint32_t i; + + rtems_libio_lock(); + + /* + * Look for any active file descriptor entry. + */ + + for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){ + + if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) { + + /* + * Check if this node is under the file system that we + * are trying to dismount. + */ + + if ( iop->pathinfo.mt_entry == fs_mt_entry ) { + result = 1; + break; + } + } + } + + rtems_libio_unlock(); + + return result; +} + +/* + * 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. + */ + +int rtems_libio_is_file_open( + void *node_access +) +{ + rtems_libio_t *iop; + int result=0; + uint32_t i; + + rtems_libio_lock(); + + /* + * Look for any active file descriptor entry. + */ + + for (iop=rtems_libio_iops,i=0; i < rtems_libio_number_iops; iop++, i++){ + if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) { + + /* + * Check if this node is under the file system that we + * are trying to dismount. + */ + + if ( iop->pathinfo.node_access == node_access ) { + result = 1; + break; + } + } + } + + rtems_libio_unlock(); + + return result; +} diff --git a/cpukit/libcsupport/src/libio_init.c b/cpukit/libcsupport/src/libio_init.c new file mode 100644 index 0000000000..a6b99870a5 --- /dev/null +++ b/cpukit/libcsupport/src/libio_init.c @@ -0,0 +1,89 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> /* libio_.h pulls in rtems */ +#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 <errno.h> + +#include <errno.h> +#include <string.h> /* strcmp */ +#include <unistd.h> +#include <stdlib.h> /* calloc() */ + +#include <rtems/libio.h> /* libio.h not pulled in by rtems */ + +/* + * File descriptor Table Information + */ + +rtems_id rtems_libio_semaphore; +rtems_libio_t *rtems_libio_iops; +rtems_libio_t *rtems_libio_iop_freelist; + +/* + * rtems_libio_init + * + * Called by BSP startup code to initialize the libio subsystem. + */ + +void rtems_libio_init( void ) +{ + rtems_status_code rc; + uint32_t i; + rtems_libio_t *iop; + + 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); + + iop = rtems_libio_iop_freelist = rtems_libio_iops; + for (i = 0 ; (i + 1) < rtems_libio_number_iops ; i++, iop++) + iop->data1 = iop + 1; + iop->data1 = NULL; + } + + /* + * 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. + */ + + if (rtems_fs_init_helper) + (* rtems_fs_init_helper)(); +} diff --git a/cpukit/libcsupport/src/libio_sockets.c b/cpukit/libcsupport/src/libio_sockets.c new file mode 100644 index 0000000000..c67e19d78c --- /dev/null +++ b/cpukit/libcsupport/src/libio_sockets.c @@ -0,0 +1,73 @@ +/* + * This file contains the support infrastructure used to manage the + * table of integer style file descriptors used by the socket calls. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +/* + * Convert an RTEMS file descriptor to a BSD socket pointer. + */ + +struct socket *rtems_bsdnet_fdToSocket( + int fd +) +{ + rtems_libio_t *iop; + + /* same as rtems_libio_check_fd(_fd) but different return */ + if ((uint32_t)fd >= rtems_libio_number_iops) { + errno = EBADF; + return NULL; + } + iop = &rtems_libio_iops[fd]; + + /* same as rtems_libio_check_is_open(iop) but different return */ + if ((iop->flags & LIBIO_FLAGS_OPEN) == 0) { + errno = EBADF; + return NULL; + } + + if (iop->data1 == NULL) + errno = EBADF; + return iop->data1; +} + +/* + * Create an RTEMS file descriptor for a socket + */ + +int rtems_bsdnet_makeFdForSocket( + void *so, + const rtems_filesystem_file_handlers_r *h +) +{ + rtems_libio_t *iop; + int fd; + + iop = rtems_libio_allocate(); + if (iop == 0) + rtems_set_errno_and_return_minus_one( ENFILE ); + + fd = iop - rtems_libio_iops; + iop->flags |= LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ; + iop->data0 = fd; + iop->data1 = so; + iop->pathinfo.handlers = h; + iop->pathinfo.ops = &rtems_filesystem_operations_default; + return fd; +} diff --git a/cpukit/libcsupport/src/link.c b/cpukit/libcsupport/src/link.c new file mode 100644 index 0000000000..11b6521dea --- /dev/null +++ b/cpukit/libcsupport/src/link.c @@ -0,0 +1,94 @@ +/* + * link() - POSIX 1003.1b - 5.3.4 - Create a new link + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/libio.h> +#include <errno.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.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, strlen( 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_h)( &new[i], &parent_loc, &name_start ); + if ( result != 0 ) { + rtems_filesystem_freenode( &existing_loc ); + return -1; + } + + /* + * Check to see if the caller is trying to link across file system + * boundaries. + */ + + if ( parent_loc.mt_entry != existing_loc.mt_entry ) { + rtems_filesystem_freenode( &existing_loc ); + rtems_filesystem_freenode( &parent_loc ); + rtems_set_errno_and_return_minus_one( EXDEV ); + } + + result = (*parent_loc.ops->link_h)( &existing_loc, &parent_loc, name_start ); + + rtems_filesystem_freenode( &existing_loc ); + rtems_filesystem_freenode( &parent_loc ); + + return result; +} + +/* + * _link_r + * + * This is the Newlib dependent reentrant version of link(). + */ + +#if defined(RTEMS_NEWLIB) + +#include <reent.h> + +int _link_r( + struct _reent *ptr __attribute__((unused)), + const char *existing, + const char *new +) +{ + return link( existing, new ); +} +#endif diff --git a/cpukit/libcsupport/src/lseek.c b/cpukit/libcsupport/src/lseek.c new file mode 100644 index 0000000000..3f37029807 --- /dev/null +++ b/cpukit/libcsupport/src/lseek.c @@ -0,0 +1,94 @@ +/* + * lseek() - POSIX 1003.1b 6.5.3 - Reposition Read/Write File Offset + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +off_t lseek( + int fd, + off_t offset, + int whence +) +{ + rtems_libio_t *iop; + off_t old_offset; + off_t status; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open(iop); + + /* + * Now process the lseek(). + */ + + old_offset = iop->offset; + 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: + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + /* + * At this time, handlers assume iop->offset has the desired + * new offset. + */ + + status = (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence ); + if ( status == (off_t) -1 ) + iop->offset = old_offset; + + /* + * So if the operation failed, we have to restore iop->offset. + */ + + return status; +} + +/* + * _lseek_r + * + * This is the Newlib dependent reentrant version of lseek(). + */ + +#if defined(RTEMS_NEWLIB) && !defined(HAVE__LSEEK_R) + +#include <reent.h> + +off_t _lseek_r( + struct _reent *ptr __attribute__((unused)), + int fd, + off_t offset, + int whence +) +{ + return lseek( fd, offset, whence ); +} +#endif diff --git a/cpukit/libcsupport/src/lstat.c b/cpukit/libcsupport/src/lstat.c new file mode 100644 index 0000000000..f034f4aa76 --- /dev/null +++ b/cpukit/libcsupport/src/lstat.c @@ -0,0 +1,22 @@ +/* + * lstat() - BSD 4.3 and SVR4 - Get File Status + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define _STAT_NAME lstat +#define _STAT_R_NAME _lstat_r +#define _STAT_FOLLOW_LINKS false + +#include "stat.c" diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c new file mode 100644 index 0000000000..6bb77a4630 --- /dev/null +++ b/cpukit/libcsupport/src/malloc.c @@ -0,0 +1,83 @@ +/* + * RTEMS Malloc Family Implementation + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include <stdlib.h> +#include <errno.h> + +#include "malloc_p.h" + +void *malloc( + size_t size +) +{ + void *return_this; + + MSBUMP(malloc_calls, 1); + + /* + * If some free's have been deferred, then do them now. + */ + malloc_deferred_frees_process(); + + /* + * Validate the parameters + */ + if ( !size ) + return (void *) 0; + + /* + * Do not attempt to allocate memory if not in correct system state. + */ + if ( _System_state_Is_up(_System_state_Get()) && + !malloc_is_system_state_OK() ) + return NULL; + + /* + * Try to give a segment in the current heap if there is not + * enough space then try to grow the heap. + * If this fails then return a NULL pointer. + */ + + return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size ); + + if ( !return_this ) { + if (rtems_malloc_sbrk_helpers) + return_this = (*rtems_malloc_sbrk_helpers->extend)( size ); + if ( !return_this ) { + errno = ENOMEM; + return (void *) 0; + } + } + + /* + * If the user wants us to dirty the allocated memory, then do it. + */ + if ( rtems_malloc_dirty_helper ) + (*rtems_malloc_dirty_helper)( return_this, size ); + + /* + * If configured, update the statistics + */ + if ( rtems_malloc_statistics_helpers ) + (*rtems_malloc_statistics_helpers->at_malloc)(return_this); + + return return_this; +} + +#endif diff --git a/cpukit/libcsupport/src/malloc_deferred.c b/cpukit/libcsupport/src/malloc_deferred.c new file mode 100644 index 0000000000..4289a899bc --- /dev/null +++ b/cpukit/libcsupport/src/malloc_deferred.c @@ -0,0 +1,60 @@ +/* + * Process free requests deferred because they were from ISR + * or other critical section. + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include <stdlib.h> +#include <errno.h> + +#include "malloc_p.h" + +rtems_chain_control RTEMS_Malloc_GC_list; + +bool malloc_is_system_state_OK(void) +{ + if ( _Thread_Dispatch_disable_level > 0 ) + return false; + + if ( _ISR_Nest_level > 0 ) + return false; + + return true; +} + +void malloc_deferred_frees_initialize(void) +{ + rtems_chain_initialize_empty(&RTEMS_Malloc_GC_list); +} + +void malloc_deferred_frees_process(void) +{ + rtems_chain_node *to_be_freed; + + /* + * If some free's have been deferred, then do them now. + */ + while ((to_be_freed = rtems_chain_get(&RTEMS_Malloc_GC_list)) != NULL) + free(to_be_freed); +} + +void malloc_deferred_free( + void *pointer +) +{ + rtems_chain_append(&RTEMS_Malloc_GC_list, (rtems_chain_node *)pointer); +} +#endif diff --git a/cpukit/libcsupport/src/malloc_dirtier.c b/cpukit/libcsupport/src/malloc_dirtier.c new file mode 100644 index 0000000000..eb6ae7ccf3 --- /dev/null +++ b/cpukit/libcsupport/src/malloc_dirtier.c @@ -0,0 +1,30 @@ +/* + * RTEMS Malloc Family -- Dirty Memory from Malloc + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/malloc.h> +#include "malloc_p.h" + +#include <errno.h> + +void rtems_malloc_dirty_memory( + void *start, + size_t size +) +{ + (void) memset(start, 0xCF, size); +} diff --git a/cpukit/libcsupport/src/malloc_get_statistics.c b/cpukit/libcsupport/src/malloc_get_statistics.c new file mode 100644 index 0000000000..c13a1555e8 --- /dev/null +++ b/cpukit/libcsupport/src/malloc_get_statistics.c @@ -0,0 +1,33 @@ +/* + * malloc_get_statistics Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" + +int malloc_get_statistics( + rtems_malloc_statistics_t *stats +) +{ + if ( !stats ) + return -1; + _RTEMS_Lock_allocator(); + *stats = rtems_malloc_statistics; + _RTEMS_Unlock_allocator(); + return 0; +} + +#endif diff --git a/cpukit/libcsupport/src/malloc_initialize.c b/cpukit/libcsupport/src/malloc_initialize.c new file mode 100644 index 0000000000..e00a868e5a --- /dev/null +++ b/cpukit/libcsupport/src/malloc_initialize.c @@ -0,0 +1,114 @@ +/** + * @file + * + * @brief Malloc initialization implementation. + */ + +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/malloc.h> +#include <rtems/score/wkspace.h> +#include "malloc_p.h" + +/* FIXME: Dummy function */ +#ifndef RTEMS_NEWLIB +void RTEMS_Malloc_Initialize( + void *heap_begin, + uintptr_t heap_size, + size_t sbrk_amount +) +{ +} +#else +rtems_malloc_statistics_t rtems_malloc_statistics; +extern bool rtems_unified_work_area; + +void RTEMS_Malloc_Initialize( + void *heap_begin, + uintptr_t heap_size, + size_t sbrk_amount +) +{ + /* + * If configured, initialize the statistics support + */ + if ( rtems_malloc_statistics_helpers != NULL ) { + (*rtems_malloc_statistics_helpers->initialize)(); + } + + /* + * Initialize the garbage collection list to start with nothing on it. + */ + malloc_deferred_frees_initialize(); + + /* + * Initialize the optional sbrk support for extending the heap + */ + if ( rtems_malloc_sbrk_helpers != NULL ) { + heap_begin = (*rtems_malloc_sbrk_helpers->initialize)( + heap_begin, + sbrk_amount + ); + heap_size = (uintptr_t) sbrk_amount; + } + + /* + * If this system is configured to use the same heap for + * the RTEMS Workspace and C Program Heap, then we need to + * be very very careful about destroying the initialization + * that has already been done. + */ + + /* + * If the BSP is not clearing out the workspace, then it is most likely + * not clearing out the initial memory for the heap. There is no + * standard supporting zeroing out the heap memory. But much code + * with UNIX history seems to assume that memory malloc'ed during + * initialization (before any free's) is zero'ed. This is true most + * of the time under UNIX because zero'ing memory when it is first + * given to a process eliminates the chance of a process seeing data + * left over from another process. This would be a security violation. + */ + + if ( + !rtems_unified_work_area + && rtems_configuration_get_do_zero_of_workspace() + ) { + memset( heap_begin, 0, heap_size ); + } + + /* + * Unfortunately we cannot use assert if this fails because if this + * has failed we do not have a heap and if we do not have a heap + * STDIO cannot work because there will be no buffers. + */ + + if ( !rtems_unified_work_area ) { + uintptr_t status = _Protected_heap_Initialize( + RTEMS_Malloc_Heap, + heap_begin, + heap_size, + CPU_HEAP_ALIGNMENT + ); + if ( status == 0 ) { + rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); + } + } + + MSBUMP( space_available, _Protected_heap_Get_size(RTEMS_Malloc_Heap) ); +} +#endif diff --git a/cpukit/libcsupport/src/malloc_p.h b/cpukit/libcsupport/src/malloc_p.h new file mode 100644 index 0000000000..f93f0b9287 --- /dev/null +++ b/cpukit/libcsupport/src/malloc_p.h @@ -0,0 +1,45 @@ +/* + * RTEMS Malloc Family Internal Header + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ +#include <rtems.h> +#include <rtems/libcsupport.h> +#include <rtems/score/protectedheap.h> +#include <rtems/malloc.h> + +#ifdef RTEMS_NEWLIB +#include <sys/reent.h> +#endif + +#include <stdint.h> +#include <rtems/chain.h> + +/* + * Basic management data + */ +extern Heap_Control *RTEMS_Malloc_Heap; + +/* + * Malloc Statistics Structure + */ +extern rtems_malloc_statistics_t rtems_malloc_statistics; + +#define MSBUMP(_f,_n) rtems_malloc_statistics._f += (_n) + +/* + * Process deferred free operations + */ +bool malloc_is_system_state_OK(void); +void malloc_deferred_frees_initialize(void); +void malloc_deferred_frees_process(void); +void malloc_deferred_free(void *); diff --git a/cpukit/libcsupport/src/malloc_report_statistics.c b/cpukit/libcsupport/src/malloc_report_statistics.c new file mode 100644 index 0000000000..24f5505429 --- /dev/null +++ b/cpukit/libcsupport/src/malloc_report_statistics.c @@ -0,0 +1,26 @@ +/* + * malloc_report_statistics Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" + +void malloc_report_statistics(void) +{ + malloc_report_statistics_with_plugin( NULL, printk_plugin ); +} + +#endif diff --git a/cpukit/libcsupport/src/malloc_report_statistics_plugin.c b/cpukit/libcsupport/src/malloc_report_statistics_plugin.c new file mode 100644 index 0000000000..637587190a --- /dev/null +++ b/cpukit/libcsupport/src/malloc_report_statistics_plugin.c @@ -0,0 +1,61 @@ +/* + * malloc_report_statistics with plugin Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" +#include "inttypes.h" + +void malloc_report_statistics_with_plugin( + void *context, + rtems_printk_plugin_t print +) +{ + rtems_malloc_statistics_t *s; + uintmax_t allocated; + + s = &rtems_malloc_statistics; + + allocated = s->lifetime_allocated - s->lifetime_freed; + + (*print)( + context, + "Malloc statistics\n" + " avail:%"PRIu32"k allocated:%"PRIu32"k (%"PRId32"%%) " + "max:%"PRIu32"k (%"PRIu32"%%)" + " lifetime:%"PRIu32"k freed:%"PRIu32"k\n", + s->space_available / 1024, + allocated / 1024, + /* avoid float! */ + (allocated * 100) / s->space_available, + s->max_depth / 1024, + (s->max_depth * 100) / s->space_available, + (uint32_t) (s->lifetime_allocated / 1024), + (uint32_t) (s->lifetime_freed / 1024) + ); + (*print)( + context, + " Call counts: malloc:%"PRIu32" memalign:%"PRIu32" free:%"PRIu32 + " realloc:%"PRIu32" calloc:%"PRIu32"\n", + s->malloc_calls, + s->memalign_calls, + s->free_calls, + s->realloc_calls, + s->calloc_calls + ); +} + +#endif diff --git a/cpukit/libcsupport/src/malloc_sbrk_helpers.c b/cpukit/libcsupport/src/malloc_sbrk_helpers.c new file mode 100644 index 0000000000..e917fd36af --- /dev/null +++ b/cpukit/libcsupport/src/malloc_sbrk_helpers.c @@ -0,0 +1,112 @@ +/* + * RTEMS Malloc -- SBRK Support Plugin + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> /* sbrk */ + +#include <rtems.h> +#include <rtems/malloc.h> +#include "malloc_p.h" + +#include <errno.h> + +size_t RTEMS_Malloc_Sbrk_amount; + +void *malloc_sbrk_initialize( + void *starting_address, + size_t length +) +{ + uintptr_t old_address; + uintptr_t uaddress; + + RTEMS_Malloc_Sbrk_amount = length; + + /* + * If the starting address is 0 then we are to attempt to + * get length worth of memory using sbrk. Make sure we + * align the address that we get back. + */ + + if (!starting_address) { + uaddress = (uintptr_t)sbrk(length); + + if (uaddress == (uintptr_t) -1) { + rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); + /* DOES NOT RETURN!!! */ + } + + if (uaddress & (CPU_HEAP_ALIGNMENT-1)) { + old_address = uaddress; + uaddress = (uaddress + CPU_HEAP_ALIGNMENT) & ~(CPU_HEAP_ALIGNMENT-1); + + /* + * adjust the length by whatever we aligned by + */ + length -= uaddress - old_address; + } + + starting_address = (void *)uaddress; + } + return starting_address; +} + +void *malloc_sbrk_extend_and_allocate( + size_t size +) +{ + uint32_t sbrk_amount; + void *starting_address; + uint32_t the_size; + void *return_this; + + /* + * Round to the "requested sbrk amount" so hopefully we won't have + * to grow again for a while. This effectively does sbrk() calls + * in "page" amounts. + */ + + sbrk_amount = RTEMS_Malloc_Sbrk_amount; + + if ( sbrk_amount == 0 ) + return (void *) 0; + + the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount); + + starting_address = (void *) sbrk(the_size); + if ( starting_address == (void*) -1 ) + return (void *) 0; + + if ( !_Protected_heap_Extend( + RTEMS_Malloc_Heap, starting_address, the_size) ) { + sbrk(-the_size); + errno = ENOMEM; + return (void *) 0; + } + + MSBUMP(space_available, the_size); + + return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size ); + return return_this; +} + + +rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table = { + malloc_sbrk_initialize, + malloc_sbrk_extend_and_allocate +}; + + diff --git a/cpukit/libcsupport/src/malloc_statistics_helpers.c b/cpukit/libcsupport/src/malloc_statistics_helpers.c new file mode 100644 index 0000000000..fcd9a5cbde --- /dev/null +++ b/cpukit/libcsupport/src/malloc_statistics_helpers.c @@ -0,0 +1,75 @@ + +/* + * _calloc_r Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" + +#include <sys/reent.h> +#include <stdlib.h> + + +static void rtems_malloc_statistics_initialize( void ) +{ + /* + * Zero all the statistics + */ + (void) memset(&rtems_malloc_statistics, 0, sizeof(rtems_malloc_statistics)); +} + +static void rtems_malloc_statistics_at_malloc( + void *pointer +) +{ + uintptr_t actual_size = 0; + uint32_t current_depth; + rtems_malloc_statistics_t *s = &rtems_malloc_statistics; + + if ( !pointer ) + return; + + _Protected_heap_Get_block_size(RTEMS_Malloc_Heap, pointer, &actual_size); + + MSBUMP(lifetime_allocated, actual_size); + + current_depth = (uint32_t) (s->lifetime_allocated - s->lifetime_freed); + if (current_depth > s->max_depth) + s->max_depth = current_depth; +} + +/* + * If the pointer is not in the heap, then we won't be able to get its + * size and thus we skip updating the statistics. + */ +static void rtems_malloc_statistics_at_free( + void *pointer +) +{ + uintptr_t size; + + if (_Protected_heap_Get_block_size(RTEMS_Malloc_Heap, pointer, &size) ) { + MSBUMP(lifetime_freed, size); + } +} + +rtems_malloc_statistics_functions_t rtems_malloc_statistics_helpers_table = { + rtems_malloc_statistics_initialize, + rtems_malloc_statistics_at_malloc, + rtems_malloc_statistics_at_free, +}; + +#endif diff --git a/cpukit/libcsupport/src/malloc_walk.c b/cpukit/libcsupport/src/malloc_walk.c new file mode 100644 index 0000000000..6b6602b2ff --- /dev/null +++ b/cpukit/libcsupport/src/malloc_walk.c @@ -0,0 +1,28 @@ +/* + * malloc_walk Implementation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" + +#include <stdlib.h> + +void malloc_walk(size_t source, size_t printf_enabled) +{ + _Protected_heap_Walk( RTEMS_Malloc_Heap, (int) source, printf_enabled ); +} + +#endif diff --git a/cpukit/libcsupport/src/mallocfreespace.c b/cpukit/libcsupport/src/mallocfreespace.c new file mode 100644 index 0000000000..cb0eb1f2ea --- /dev/null +++ b/cpukit/libcsupport/src/mallocfreespace.c @@ -0,0 +1,42 @@ +/* + * RTEMS Malloc Get Free Information + * + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ +#include <rtems.h> +#include <rtems/libcsupport.h> +#include <rtems/score/protectedheap.h> + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <errno.h> +#include <string.h> + +#include "malloc_p.h" + +/* + * Find amount of free heap remaining + */ + +size_t malloc_free_space( void ) +{ + Heap_Information info; + + _Protected_heap_Get_free_information( RTEMS_Malloc_Heap, &info ); + return (size_t) info.largest; +} diff --git a/cpukit/libcsupport/src/mallocgetheapptr.c b/cpukit/libcsupport/src/mallocgetheapptr.c new file mode 100644 index 0000000000..b0df2f57fb --- /dev/null +++ b/cpukit/libcsupport/src/mallocgetheapptr.c @@ -0,0 +1,26 @@ +/* + * RTEMS Malloc Get Heap Pointer -- Primarily for Debug + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ +#include <rtems.h> +#include <rtems/libcsupport.h> +#include "malloc_p.h" + +Heap_Control *malloc_get_heap_pointer( void ) +{ + return RTEMS_Malloc_Heap; +} diff --git a/cpukit/libcsupport/src/mallocinfo.c b/cpukit/libcsupport/src/mallocinfo.c new file mode 100644 index 0000000000..d1c3266aeb --- /dev/null +++ b/cpukit/libcsupport/src/mallocinfo.c @@ -0,0 +1,39 @@ +/* + * RTEMS Malloc Get Status Information + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ +#include <rtems.h> +#include <rtems/libcsupport.h> +#include <rtems/score/protectedheap.h> + +extern Heap_Control *RTEMS_Malloc_Heap; + +/* + * Find amount of free heap remaining + */ + +int malloc_info( + Heap_Information_block *the_info +) +{ + if ( !the_info ) + return -1; + + _Protected_heap_Get_information( RTEMS_Malloc_Heap, the_info ); + return 0; +} diff --git a/cpukit/libcsupport/src/mallocsetheapptr.c b/cpukit/libcsupport/src/mallocsetheapptr.c new file mode 100644 index 0000000000..e0d1471750 --- /dev/null +++ b/cpukit/libcsupport/src/mallocsetheapptr.c @@ -0,0 +1,28 @@ +/* + * RTEMS Malloc Set Heap Pointer -- Primarily for Debug + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ +#include <rtems.h> +#include <rtems/libcsupport.h> +#include "malloc_p.h" + +void malloc_set_heap_pointer( + Heap_Control *new_heap +) +{ + RTEMS_Malloc_Heap = new_heap; +} diff --git a/cpukit/libcsupport/src/mkdir.c b/cpukit/libcsupport/src/mkdir.c new file mode 100644 index 0000000000..2fae8a733a --- /dev/null +++ b/cpukit/libcsupport/src/mkdir.c @@ -0,0 +1,30 @@ +/* + * mkdir() - POSIX 1003.1b 5.4.1 - Make a Directory + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +int mkdir( + const char *pathname, + mode_t mode +) +{ + return mknod( pathname, mode | S_IFDIR, 0LL); +} diff --git a/cpukit/libcsupport/src/mkfifo.c b/cpukit/libcsupport/src/mkfifo.c new file mode 100644 index 0000000000..efe6207bf8 --- /dev/null +++ b/cpukit/libcsupport/src/mkfifo.c @@ -0,0 +1,28 @@ +/* + * mkfifo() - POSIX 1003.1b 5.4.1 - Make a FIFO Special File + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> + +int mkfifo( + const char *path, + mode_t mode +) +{ + return mknod( path, mode | S_IFIFO, 0LL ); +} diff --git a/cpukit/libcsupport/src/mknod.c b/cpukit/libcsupport/src/mknod.c new file mode 100644 index 0000000000..29aff43c31 --- /dev/null +++ b/cpukit/libcsupport/src/mknod.c @@ -0,0 +1,73 @@ +/* + * 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-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.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; + + /* + * The file type is field within the mode. Check we have a sane mode set. + */ + switch (mode & S_IFMT) + { + case S_IFDIR: + case S_IFCHR: + case S_IFBLK: + case S_IFREG: + case S_IFIFO: + break; + default: + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + rtems_filesystem_get_start_loc( pathname, &i, &temp_loc ); + + result = (*temp_loc.ops->evalformake_h)( + &pathname[i], + &temp_loc, + &name_start + ); + if ( result != 0 ) + return -1; + + result = (*temp_loc.ops->mknod_h)( name_start, mode, dev, &temp_loc ); + + rtems_filesystem_freenode( &temp_loc ); + + return result; +} diff --git a/cpukit/libcsupport/src/mount-mgr.c b/cpukit/libcsupport/src/mount-mgr.c new file mode 100644 index 0000000000..c610ff6998 --- /dev/null +++ b/cpukit/libcsupport/src/mount-mgr.c @@ -0,0 +1,169 @@ +/* + * mount() + * + * Mange the mount table. You can iterate on mounts and file systems, as well + * as add and remove file systems not in the file system confiration table. + * + * COPYRIGHT (c) Chris Johns <chrisj@rtems.org> 2010. + * + * Copyright (c) 2010 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <rtems/chain.h> +#include <rtems/seterr.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <rtems/libio_.h> + +typedef struct { + rtems_chain_node node; + rtems_filesystem_table_t entry; +} filesystem_node; + +static RTEMS_CHAIN_DEFINE_EMPTY(filesystem_chain); + +bool rtems_filesystem_iterate( + rtems_per_filesystem_routine routine, + void *routine_arg +) +{ + const rtems_filesystem_table_t *table_entry = &rtems_filesystem_table [0]; + rtems_chain_node *node = NULL; + bool stop = false; + + while ( table_entry->type && !stop ) { + stop = (*routine)( table_entry, routine_arg ); + ++table_entry; + } + + if ( !stop ) { + rtems_libio_lock(); + for ( + node = rtems_chain_first( &filesystem_chain ); + !rtems_chain_is_tail( &filesystem_chain, node ) && !stop; + node = rtems_chain_next( node ) + ) { + const filesystem_node *fsn = (filesystem_node *) node; + + stop = (*routine)( &fsn->entry, routine_arg ); + } + rtems_libio_unlock(); + } + + return stop; +} + +typedef struct { + const char *type; + rtems_filesystem_fsmount_me_t mount_h; +} find_arg; + +static bool find_handler(const rtems_filesystem_table_t *entry, void *arg) +{ + find_arg *fa = arg; + + if ( strcmp( entry->type, fa->type ) != 0 ) { + return false; + } else { + fa->mount_h = entry->mount_h; + + return true; + } +} + +rtems_filesystem_fsmount_me_t +rtems_filesystem_get_mount_handler( + const char *type +) +{ + find_arg fa = { + .type = type, + .mount_h = NULL + }; + + if ( type != NULL ) { + rtems_filesystem_iterate( find_handler, &fa ); + } + + return fa.mount_h; +} + +int +rtems_filesystem_register( + const char *type, + rtems_filesystem_fsmount_me_t mount_h +) +{ + size_t type_size = strlen(type) + 1; + size_t fsn_size = sizeof( filesystem_node ) + type_size; + filesystem_node *fsn = malloc( fsn_size ); + char *type_storage = (char *) fsn + sizeof( *fsn ); + + if ( fsn == NULL ) + rtems_set_errno_and_return_minus_one( ENOMEM ); + + memcpy(type_storage, type, type_size); + fsn->entry.type = type_storage; + fsn->entry.mount_h = mount_h; + + rtems_libio_lock(); + if ( rtems_filesystem_get_mount_handler( type ) == NULL ) { + rtems_chain_append( &filesystem_chain, &fsn->node ); + } else { + rtems_libio_unlock(); + free( fsn ); + + rtems_set_errno_and_return_minus_one( EINVAL ); + } + rtems_libio_unlock(); + + return 0; +} + +int +rtems_filesystem_unregister( + const char *type +) +{ + rtems_chain_node *node = NULL; + + if ( type == NULL ) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + rtems_libio_lock(); + for ( + node = rtems_chain_first( &filesystem_chain ); + !rtems_chain_is_tail( &filesystem_chain, node ); + node = rtems_chain_next( node ) + ) { + filesystem_node *fsn = (filesystem_node *) node; + + if ( strcmp( fsn->entry.type, type ) == 0 ) { + rtems_chain_extract( node ); + free( fsn ); + rtems_libio_unlock(); + + return 0; + } + } + rtems_libio_unlock(); + + rtems_set_errno_and_return_minus_one( ENOENT ); +} diff --git a/cpukit/libcsupport/src/mount-mktgt.c b/cpukit/libcsupport/src/mount-mktgt.c new file mode 100644 index 0000000000..3b4d50aded --- /dev/null +++ b/cpukit/libcsupport/src/mount-mktgt.c @@ -0,0 +1,56 @@ +/** + * @file + * + * @ingroup LibIO + * + * @brief mount_and_make_target_path() implementation. + */ + +/* + * Copyright (c) 2010 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> + +#include <rtems/libio.h> + +int mount_and_make_target_path( + const char *source, + const char *target, + const char *filesystemtype, + rtems_filesystem_options_t options, + const void *data +) +{ + int rv = -1; + + if (target != NULL) { + rv = rtems_mkdir(target, S_IRWXU | S_IRWXG | S_IRWXO); + if (rv == 0) { + rv = mount( + source, + target, + filesystemtype, + options, + data + ); + } + } else { + errno = EINVAL; + } + + return rv; +} diff --git a/cpukit/libcsupport/src/mount.c b/cpukit/libcsupport/src/mount.c new file mode 100644 index 0000000000..00a07aab3a --- /dev/null +++ b/cpukit/libcsupport/src/mount.c @@ -0,0 +1,282 @@ +/* + * 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-2010. + * On-Line Applications Research Corporation (OAR). + * + * Copyright (c) 2010 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <rtems/chain.h> +#include <rtems/seterr.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <rtems/libio_.h> + +static RTEMS_CHAIN_DEFINE_EMPTY(mount_chain); + +/* + * Default pathconfs. + */ +const rtems_filesystem_limits_and_options_t rtems_filesystem_default_pathconf = { + 5, /* link_max: count */ + 128, /* max_canon: max formatted input line size */ + 7, /* max_input: max input line size */ + 255, /* name_max: max name */ + 255, /* path_max: max path */ + 1024, /* pipe_buf: pipe buffer size */ + 0, /* posix_async_io: async IO supported on fs, 0=no, 1=yes */ + 0 , /* posix_chown_restrictions: can chown: 0=no, 1=yes */ + 1, /* posix_no_trunc: error on filenames > max name, 0=no, 1=yes */ + 0, /* posix_prio_io: priority IO, 0=no, 1=yes */ + 0, /* posix_sync_io: file can be sync'ed, 0=no, 1=yes */ + 0 /* posix_vdisable: special char processing, 0=no, 1=yes */ +}; + +static bool is_node_fs_root( + const rtems_filesystem_mount_table_entry_t *mt_entry, + void *arg +) +{ + return arg == mt_entry->mt_fs_root.node_access; +} + +static rtems_filesystem_mount_table_entry_t *alloc_mount_table_entry( + const char *source_or_null, + const char *target_or_null, + const char *filesystemtype, + size_t *target_length_ptr +) +{ + const char *target = target_or_null != NULL ? target_or_null : "/"; + size_t filesystemtype_size = strlen( filesystemtype ) + 1; + size_t source_size = source_or_null != NULL ? + strlen( source_or_null ) + 1 : 0; + size_t target_size = strlen( target ) + 1; + size_t size = sizeof( rtems_filesystem_mount_table_entry_t ) + + filesystemtype_size + source_size + target_size; + rtems_filesystem_mount_table_entry_t *mt_entry = calloc( 1, size ); + + if ( mt_entry != NULL ) { + char *str = (char *) mt_entry + sizeof( *mt_entry ); + + memcpy( str, filesystemtype, filesystemtype_size ); + mt_entry->type = str; + str += filesystemtype_size; + + memcpy( str, source_or_null, source_size ); + mt_entry->dev = str; + str += source_size; + + memcpy( str, target, target_size ); + mt_entry->target = str; + } + + *target_length_ptr = target_size - 1; + + return mt_entry; +} + +/* + * 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( + const char *source, + const char *target, + const char *filesystemtype, + rtems_filesystem_options_t options, + const void *data +) +{ + rtems_filesystem_fsmount_me_t mount_h = NULL; + rtems_filesystem_location_info_t loc; + rtems_filesystem_mount_table_entry_t *mt_entry = NULL; + rtems_filesystem_location_info_t *loc_to_free = NULL; + bool has_target = target != NULL; + size_t target_length = 0; + + /* + * Are the file system options valid? + */ + + if ( options != RTEMS_FILESYSTEM_READ_ONLY && + options != RTEMS_FILESYSTEM_READ_WRITE ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * Get mount handler + */ + mount_h = rtems_filesystem_get_mount_handler( filesystemtype ); + if ( !mount_h ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * Allocate a mount table entry + */ + mt_entry = alloc_mount_table_entry( + source, + target, + filesystemtype, + &target_length + ); + if ( !mt_entry ) + rtems_set_errno_and_return_minus_one( ENOMEM ); + + mt_entry->mt_fs_root.mt_entry = mt_entry; + mt_entry->options = options; + mt_entry->pathconf_limits_and_options = rtems_filesystem_default_pathconf; + + /* + * The mount_point should be a directory with read/write/execute + * permissions in the existing tree. + */ + + if ( has_target ) { + if ( rtems_filesystem_evaluate_path( + target, target_length, RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 ) + goto cleanup_and_bail; + + loc_to_free = &loc; + + /* + * Test to see if it is a directory + */ + + if ( loc.ops->node_type_h( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) { + errno = ENOTDIR; + goto cleanup_and_bail; + } + + /* + * You can only mount one file system onto a single mount point. + */ + + if ( rtems_filesystem_mount_iterate( is_node_fs_root, loc.node_access ) ) { + errno = EBUSY; + goto cleanup_and_bail; + } + + /* + * This must be a good mount point, so move the location information + * into the allocated mount entry. Note: the information that + * may have been allocated in loc should not be sent to freenode + * until the system is unmounted. It may be needed to correctly + * traverse the tree. + */ + + mt_entry->mt_point_node.node_access = loc.node_access; + mt_entry->mt_point_node.handlers = loc.handlers; + mt_entry->mt_point_node.ops = loc.ops; + mt_entry->mt_point_node.mt_entry = loc.mt_entry; + + /* + * This link to the parent is only done when we are dealing with system + * below the base file system + */ + + if ( loc.ops->mount_h( mt_entry ) ) { + goto cleanup_and_bail; + } + } else { + /* + * Do we already have a base file system ? + */ + if ( !rtems_chain_is_empty( &mount_chain ) ) { + errno = EINVAL; + goto cleanup_and_bail; + } + + /* + * This is a mount of the base file system --> The + * mt_point_node.node_access will be left to null to indicate that this + * is the root of the entire file system. + */ + } + + if ( (*mount_h)( mt_entry, data ) ) { + /* + * Try to undo the mount operation + */ + loc.ops->unmount_h( mt_entry ); + goto cleanup_and_bail; + } + + /* + * Add the mount table entry to the mount table chain + */ + rtems_libio_lock(); + rtems_chain_append( &mount_chain, &mt_entry->Node ); + rtems_libio_unlock(); + + if ( !has_target ) + rtems_filesystem_root = mt_entry->mt_fs_root; + + return 0; + +cleanup_and_bail: + + free( mt_entry ); + + if ( loc_to_free ) + rtems_filesystem_freenode( loc_to_free ); + + return -1; +} + +bool rtems_filesystem_mount_iterate( + rtems_per_filesystem_mount_routine routine, + void *routine_arg +) +{ + rtems_chain_node *node = NULL; + bool stop = false; + + rtems_libio_lock(); + for ( + node = rtems_chain_first( &mount_chain ); + !rtems_chain_is_tail( &mount_chain, node ) && !stop; + node = rtems_chain_next( node ) + ) { + const rtems_filesystem_mount_table_entry_t *mt_entry = + (rtems_filesystem_mount_table_entry_t *) node; + + stop = (*routine)( mt_entry, routine_arg ); + } + rtems_libio_unlock(); + + return stop; +} diff --git a/cpukit/libcsupport/src/newlibc_exit.c b/cpukit/libcsupport/src/newlibc_exit.c new file mode 100644 index 0000000000..818ba884f4 --- /dev/null +++ b/cpukit/libcsupport/src/newlibc_exit.c @@ -0,0 +1,160 @@ +/* + * 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.rtems.com/license/LICENSE. + * + * $Id$ + * + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ +#include <rtems.h> + +#if defined(RTEMS_NEWLIB) +#include <rtems/libcsupport.h> + +/* Since we compile with strict ANSI we need to undef it to get + * prototypes for extensions + */ +#undef __STRICT_ANSI__ + +#include <stdlib.h> /* for free() */ +#include <string.h> /* for memset() */ + +#include <sys/reent.h> /* for extern of _REENT (aka _impure_ptr) */ +#include <errno.h> + +#include <stdio.h> + +int _fwalk(struct _reent *ptr, int (*function) (FILE *) ); + +/* do we think we are reentrant? */ +extern int libc_reentrant; +extern struct _reent * const _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__; + +/* + * CYGNUS newlib routine that does atexit() processing and flushes + * stdio streams + * undocumented + */ + +extern void _wrapup_reent(struct _reent *); +extern void _reclaim_reent(struct _reent *); + +void libc_wrapup(void) +{ + /* + * In case RTEMS is already down, don't do this. It could be + * dangerous. + */ + + if (!_System_state_Is_up(_System_state_Get())) + return; + + /* + * This was already done if the user called exit() directly . + _wrapup_reent(0); + */ + + if (_REENT != _global_impure_ptr) { + _wrapup_reent(_global_impure_ptr); +#if 0 + /* Don't reclaim this one, just in case we do printfs + * on the way out to ROM. + */ + _reclaim_reent(&libc_global_reent); +#endif + _REENT = _global_impure_ptr; + } + + /* + * Try to drain output buffers. + * + * Should this be changed to do *all* file streams? + * _fwalk (_REENT, fclose); + */ + + fclose (stdin); + fclose (stdout); + fclose (stderr); +} + +/* + * Function: _exit + * Created: 94/12/10 + * + * Description: + * Called from exit() after it does atexit() processing and stdio fflush's + * + * called from bottom of exit() to really delete the task. + * If we are using reentrant libc, then let the delete extension + * do all the work, otherwise if a shutdown is in progress, + * then just do it. + * + * Parameters: + * exit status + * + * Returns: + * does not return + * + * Side Effects: + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ + +#include <unistd.h> + +/* FIXME: These defines are a blatant hack */ + #define EXIT_SYMBOL _exit + + #if defined(__AVR__) + #undef __USE_INIT_FINI__ + #endif + #if defined(__USE_INIT_FINI__) + #if defined(__m32r__) + #define FINI_SYMBOL __fini + #else + #define FINI_SYMBOL _fini + #endif + + extern void FINI_SYMBOL( void ); + #endif + +void EXIT_SYMBOL(int status) +{ + /* + * If the toolset uses init/fini sections, then we need to + * run the global destructors now. + */ + #if defined(__USE_INIT_FINI__) + FINI_SYMBOL(); + #endif + + /* + * We need to do the exit processing on the global reentrancy structure. + * This has already been done on the per task reentrancy structure + * associated with this task. + */ + + libc_wrapup(); + rtems_shutdown_executive(status); + for (;;) ; /* to avoid warnings */ +} + + +#endif diff --git a/cpukit/libcsupport/src/newlibc_init.c b/cpukit/libcsupport/src/newlibc_init.c new file mode 100644 index 0000000000..4d2cef5405 --- /dev/null +++ b/cpukit/libcsupport/src/newlibc_init.c @@ -0,0 +1,41 @@ +/* + * 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.rtems.com/license/LICENSE. + * + * $Id$ + * + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) + +/* + * Init libc for CYGNUS newlib + * + * Set up _REENT to use our global libc_global_reent. + * (newlib provides a global of its own, but we prefer our own name for it) + * + * If reentrancy is desired (which it should be), then + * we install the task extension hooks to maintain the + * newlib reentrancy global variable _REENT on task + * create, delete, switch, exit, etc. + * + */ + + +void +libc_init(void) +{ +} + +#endif diff --git a/cpukit/libcsupport/src/newlibc_reent.c b/cpukit/libcsupport/src/newlibc_reent.c new file mode 100644 index 0000000000..1315dc35dc --- /dev/null +++ b/cpukit/libcsupport/src/newlibc_reent.c @@ -0,0 +1,170 @@ +/* + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ +#include <rtems.h> + +#if defined(RTEMS_NEWLIB) +#include <rtems/libcsupport.h> + +/* Since we compile with strict ANSI we need to undef it to get + * prototypes for extensions + */ +#undef __STRICT_ANSI__ + +#include <stdlib.h> /* for free() */ +#include <string.h> /* for memset() */ + +#include <sys/reent.h> /* for extern of _REENT (aka _impure_ptr) */ +#include <errno.h> + +/* + * NOTE: + * There is some problem with doing this on the hpux version + * of the UNIX simulator (symptom is printf core dumps), so + * we just don't for now. + * Not sure if this is a problem with hpux, newlib, or something else. + */ + +#include <stdio.h> + +int _fwalk(struct _reent *ptr, int (*function) (FILE *) ); + +extern struct _reent * const _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__; +/* + * reent struct allocation moved here from libc_start_hook() to avoid + * mutual exclusion problems when memory is allocated from the start hook. + * + * Memory is also now allocated from the workspace rather than the heap. + * -- ptorre 9/30/03 + */ +bool newlib_create_hook( + rtems_tcb *current_task __attribute__((unused)), + rtems_tcb *creating_task +) +{ + struct _reent *ptr; + + if (_Thread_libc_reent == 0) + { + _REENT = _global_impure_ptr; + + _Thread_Set_libc_reent (&_REENT); + } + + /* NOTE: The RTEMS malloc is reentrant without a reent ptr since + * it is based on the Classic API Region Manager. + */ + + #define REENT_MALLOCED 0 + #if REENT_MALLOCED + ptr = (struct _reent *) calloc(1, sizeof(struct _reent)); + #else + /* It is OK to allocate from the workspace because these + * hooks run with thread dispatching disabled. + */ + ptr = (struct _reent *) _Workspace_Allocate(sizeof(struct _reent)); + #endif + + if (ptr) { + _REENT_INIT_PTR((ptr)); /* GCC extension: structure constants */ + creating_task->libc_reent = ptr; + return TRUE; + } + + return FALSE; +} + +/* + * Called for all user TASKS (system tasks are MPCI Receive Server and IDLE) + */ + +#ifdef NEED_SETVBUF +void newlib_begin_hook(rtems_tcb *current_task) +{ + setvbuf( stdout, NULL, _IOLBF, BUFSIZ ); +} +#endif + +/* + * Called when a task is deleted. + * Must restore the new lib reentrancy state for the new current + * task. + * + */ + +int newlib_free_buffers( + FILE *fp +) +{ + switch ( fileno(fp) ) { + case 0: + case 1: + case 2: + if (fp->_flags & __SMBF) { + free( fp->_bf._base ); + fp->_flags &= ~__SMBF; + fp->_bf._base = fp->_p = (unsigned char *) NULL; + } + break; + default: + fclose(fp); + } + return 0; +} + +void newlib_delete_hook( + rtems_tcb *current_task, + rtems_tcb *deleted_task +) +{ + struct _reent *ptr; + + /* + * The reentrancy structure was allocated by newlib using malloc() + */ + + if (current_task == deleted_task) { + ptr = _REENT; + } else { + ptr = deleted_task->libc_reent; + } + + if (ptr && ptr != _global_impure_ptr) { +/* + _wrapup_reent(ptr); + _reclaim_reent(ptr); +*/ + /* + * Just in case there are some buffers lying around. + */ + _fwalk(ptr, newlib_free_buffers); +#if REENT_MALLOCED + free(ptr); +#else + _Workspace_Free(ptr); +#endif + } + + deleted_task->libc_reent = NULL; + + /* + * Require the switch back to another task to install its own + */ + + if ( current_task == deleted_task ) { + _REENT = 0; + } +} + +#endif diff --git a/cpukit/libcsupport/src/open.c b/cpukit/libcsupport/src/open.c new file mode 100644 index 0000000000..a49ebfec0d --- /dev/null +++ b/cpukit/libcsupport/src/open.c @@ -0,0 +1,215 @@ +/* + * open() - POSIX 1003.1 5.3.1 - Open a File + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> +#include <fcntl.h> +#include <rtems/libio_.h> +#include <rtems/seterr.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 either 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 loc; + rtems_filesystem_location_info_t *loc_to_free = NULL; + 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, strlen( pathname ), eval_flags, &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; + } + + /* + * After we do the mknod(), we have to evaluate the path to get the + * "loc" structure needed to actually have the file itself open. + * So we created it, and then we need to have "look it up." + */ + status = rtems_filesystem_evaluate_path( + pathname, strlen( pathname ), 0x0, &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; + loc_to_free = &loc; + goto done; + } + + loc_to_free = &loc; + + /* + * Fill in the file control block based on the loc structure + * returned by successful path evaluation. + */ + iop->flags |= rtems_libio_fcntl_flags( flags ); + iop->pathinfo = loc; + + rc = (*iop->pathinfo.handlers->open_h)( iop, pathname, flags, mode ); + if ( rc ) { + rc = errno; + goto done; + } + + /* + * Optionally truncate the file. + */ + if ( (flags & O_TRUNC) == O_TRUNC ) { + rc = ftruncate( iop - rtems_libio_iops, 0 ); + if ( rc ) { + if(errno) rc = errno; + close( iop - rtems_libio_iops ); + /* those are released by close(): */ + iop = 0; + loc_to_free = NULL; + } + } + + /* + * Single exit and clean up path. + */ +done: + va_end(ap); + + if ( rc ) { + if ( iop ) + rtems_libio_free( iop ); + if ( loc_to_free ) + rtems_filesystem_freenode( loc_to_free ); + rtems_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) && !defined(HAVE__OPEN_R) + +#include <reent.h> + +int _open_r( + struct _reent *ptr __attribute__((unused)), + const char *buf, + int flags, + int mode +) +{ + return open( buf, flags, mode ); +} +#endif diff --git a/cpukit/libcsupport/src/open_dev_console.c b/cpukit/libcsupport/src/open_dev_console.c new file mode 100644 index 0000000000..ce01a9276e --- /dev/null +++ b/cpukit/libcsupport/src/open_dev_console.c @@ -0,0 +1,51 @@ +/* + * open_dev_console - open /dev/console + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/libio.h> +#include <fcntl.h> + +/* + * This is a replaceable stub which opens the console, if present. + */ +void open_dev_console(void) +{ + int stdin_fd; + int stdout_fd; + int stderr_fd; + + /* + * Attempt to open /dev/console. + */ + if ((stdin_fd = open("/dev/console", O_RDONLY, 0)) == -1) { + /* + * There may not be a console driver so this is OK. + */ + return; + } + + /* + * But if we find /dev/console once, we better find it twice more + * or something is REALLY wrong. + */ + if ((stdout_fd = open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred( 0x55544431 ); /* error STD1 */ + + if ((stderr_fd = open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred( 0x55544432 ); /* error STD2 */ +} + diff --git a/cpukit/libcsupport/src/pathconf.c b/cpukit/libcsupport/src/pathconf.c new file mode 100644 index 0000000000..d16f899e95 --- /dev/null +++ b/cpukit/libcsupport/src/pathconf.c @@ -0,0 +1,41 @@ +/* + * pathconf() - POSIX 1003.1b - 5.7.1 - Configurable Pathname Varables + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +long pathconf( + const char *path, + int name +) +{ + int status; + int fd; + + fd = open( path, O_RDONLY ); + if ( fd == -1 ) + return -1; + + status = fpathconf( fd, name ); + + (void) close( fd ); + + return status; +} diff --git a/cpukit/libcsupport/src/pipe.c b/cpukit/libcsupport/src/pipe.c new file mode 100644 index 0000000000..13b2eb5dc6 --- /dev/null +++ b/cpukit/libcsupport/src/pipe.c @@ -0,0 +1,32 @@ +/* + * pipe() - POSIX 1003.1b 6.1.1 Create an Inter-Process Channel + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <sys/types.h> +#include <rtems/seterr.h> + +extern int pipe_create(int filsdes[2]); + +int pipe( + int filsdes[2] +) +{ + if (filsdes == NULL) + rtems_set_errno_and_return_minus_one( EFAULT ); + + return pipe_create(filsdes); +} diff --git a/cpukit/libcsupport/src/posix_memalign.c b/cpukit/libcsupport/src/posix_memalign.c new file mode 100644 index 0000000000..cde55f042b --- /dev/null +++ b/cpukit/libcsupport/src/posix_memalign.c @@ -0,0 +1,44 @@ +/* + * posix_memalign() + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" + +#include <stdlib.h> +#include <errno.h> + +int posix_memalign( + void **pointer, + size_t alignment, + size_t size +) +{ + /* + * Update call statistics + */ + MSBUMP(memalign_calls, 1); + + if (((alignment - 1) & alignment) != 0 || (alignment < sizeof(void *))) + return EINVAL; + + /* + * rtems_memalign does all of the error checking work EXCEPT + * for adding restrictionso on the alignment. + */ + return rtems_memalign( pointer, alignment, size ); +} +#endif diff --git a/cpukit/libcsupport/src/printk.c b/cpukit/libcsupport/src/printk.c new file mode 100644 index 0000000000..3ac7c8616a --- /dev/null +++ b/cpukit/libcsupport/src/printk.c @@ -0,0 +1,39 @@ +/* + * (C) Copyright 1997 - + * - NavIST Group - Real-Time Distributed Systems and Industrial Automation + * + * http://pandora.ist.utl.pt + * + * Instituto Superior Tecnico * Lisboa * PORTUGAL + * + * Disclaimer: + * + * This file is provided "AS IS" without warranty of any kind, either + * expressed or implied. + * + * This code is based on code by: Jose Rufino - IST + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> +#include <stdio.h> +#include <rtems/bspIo.h> + +/* + * printk + * + * Kernel printf function requiring minimal infrastructure. + */ +void printk(const char *fmt, ...) +{ + va_list ap; /* points to each unnamed argument in turn */ + + va_start(ap, fmt); /* make ap point to 1st unnamed arg */ + vprintk(fmt, ap); + va_end(ap); /* clean up when done */ +} diff --git a/cpukit/libcsupport/src/printk_plugin.c b/cpukit/libcsupport/src/printk_plugin.c new file mode 100644 index 0000000000..60d93a96af --- /dev/null +++ b/cpukit/libcsupport/src/printk_plugin.c @@ -0,0 +1,34 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> +#include <rtems/bspIo.h> + +int printk_plugin( + void *ignored __attribute__((unused)), + const char *format, + ... +) +{ + va_list arg_pointer; + + va_start (arg_pointer, format); + + vprintk( format, arg_pointer ); + + va_end(arg_pointer); /* clean up when done */ + + return 0; +} diff --git a/cpukit/libcsupport/src/privateenv.c b/cpukit/libcsupport/src/privateenv.c new file mode 100644 index 0000000000..89137200b7 --- /dev/null +++ b/cpukit/libcsupport/src/privateenv.c @@ -0,0 +1,204 @@ +/* + * Instantiate a private user environment for the calling thread. + * + * Submitted by: fernando.ruiz@ctv.es (correo@fernando-ruiz.com) + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> /* free */ + +#include <rtems.h> +#include <rtems/chain.h> +#include <rtems/libio_.h> + +/* cleanup a user environment + * NOTE: this must be called with + * thread dispatching disabled! + */ +static void +free_user_env(void *venv) +{ + rtems_user_env_t *env = (rtems_user_env_t*) venv ; + + if (env != &rtems_global_user_env + #ifdef HAVE_USERENV_REFCNT + && --env->refcnt <= 0 + #endif + ) { + rtems_filesystem_freenode( &env->current_directory); + rtems_filesystem_freenode( &env->root_directory); + free(env); + } +} + +rtems_status_code rtems_libio_set_private_env(void) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_id task_id = rtems_task_self(); + rtems_filesystem_location_info_t root_loc; + rtems_filesystem_location_info_t current_loc; + rtems_user_env_t *new_env = NULL; + int rv = 0; + + rv = rtems_filesystem_evaluate_path("/", 1, 0, &root_loc, 0); + if (rv != 0) + goto error_0; + + rv = rtems_filesystem_evaluate_path("/", 1, 0, ¤t_loc, 0); + if (rv != 0) + goto error_1; + + /* + * Malloc is necessary whenever the current task does not + * have its own environment in place. This could be: + * a) it never had one + * OR + * b) it shared another task's environment + */ + + /* + * Bharath: I'm not sure if the check can be reduced to + * if( rtems_current_user_env->task_id != task_id ) { + */ + + if ( + rtems_current_user_env == &rtems_global_user_env + || rtems_current_user_env->task_id != task_id + ) { + new_env = malloc(sizeof(rtems_user_env_t)); + if (new_env == NULL) + goto error_2; + + #ifdef HAVE_USERENV_REFCNT + new_env->refcnt = 1; + #endif + + sc = rtems_task_variable_add( + RTEMS_SELF, + (void*)&rtems_current_user_env, + (void(*)(void *))free_user_env + ); + if (sc != RTEMS_SUCCESSFUL) + goto error_3; + + rtems_current_user_env = new_env; + } + + /* Inherit the global values */ + *rtems_current_user_env = rtems_global_user_env; + + rtems_current_user_env->task_id = task_id; + + /* + * Clone the pathlocs. In contrast to most other code we must _not_ free the + * original locs because what we are trying to do here is forking off clones. + * The reason is a pathloc can be allocated by the file system and needs to + * be freed when deleting the environment. + */ + rtems_filesystem_root = root_loc; + rtems_filesystem_current = current_loc; + + return RTEMS_SUCCESSFUL; + +error_3: + free(new_env); + +error_2: + rtems_filesystem_freenode(¤t_loc); + +error_1: + rtems_filesystem_freenode(&root_loc); + +error_0: + return RTEMS_NO_MEMORY; +} + +/* + * Share the same private environment between two tasks: + * Task_id (remote) and RTEMS_SELF(current). + */ + +/* NOTE: + * + * THIS CODE HAS NO PROTECTION IMPLEMENTED + * + * Tasks who wish to share their environments must + * + * a) assert that no participants are concurrently + * executing + * libio_share_private_env() and/or libio_set_private_env() + * + * b) mutex access to rtems_filesystem_current, rtems_filesytem_root + * while changing any of those (chdir(), chroot()). + */ + +rtems_status_code rtems_libio_share_private_env(rtems_id task_id) +{ + rtems_status_code sc; + rtems_user_env_t * shared_user_env; + rtems_id current_task_id; + + /* + * get current task id + */ + current_task_id = rtems_task_self(); + + /* + * If this was an attempt to share the task with self, + * if somebody wanted to do it... Lets tell them, its shared + */ + + if( task_id == current_task_id ) + return RTEMS_SUCCESSFUL; + /* + * Try to get the requested user environment + */ + sc = rtems_task_variable_get( + task_id, + (void*)&rtems_current_user_env, + (void*)&shared_user_env ); + + /* + * If it was not successful, return the error code + */ + if (sc != RTEMS_SUCCESSFUL) + return sc; + + /* + * If we are here, we have the required environment to be + * shared with the current task + */ + + /* + * If we have a current environment in place, we need to + * free it, since we will be sharing the variable with the + * shared_user_env + */ + + if (rtems_current_user_env->task_id==current_task_id) { + rtems_user_env_t *tmp = rtems_current_user_env; + free_user_env( tmp ); + } + + /* the current_user_env is the same pointer that remote env */ + rtems_current_user_env = shared_user_env; + + /* increase the reference count */ +#ifdef HAVE_USERENV_REFCNT + rtems_current_user_env->refcnt++; +#endif + + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/libcsupport/src/putk.c b/cpukit/libcsupport/src/putk.c new file mode 100644 index 0000000000..d804cf05e8 --- /dev/null +++ b/cpukit/libcsupport/src/putk.c @@ -0,0 +1,30 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/bspIo.h> + +/* + * putk + * + * Kernel putk (e.g. puts) function requiring minimal infrastrure. + */ +void putk(const char *s) +{ + const char *p; + + for (p=s ; *p ; p++ ) + BSP_output_char(*p); + BSP_output_char('\n'); +} diff --git a/cpukit/libcsupport/src/read.c b/cpukit/libcsupport/src/read.c new file mode 100644 index 0000000000..f4c3bdc322 --- /dev/null +++ b/cpukit/libcsupport/src/read.c @@ -0,0 +1,67 @@ +/* + * read() - POSIX 1003.1b 6.4.1 - Read From a File + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +ssize_t read( + int fd, + void *buffer, + size_t count +) +{ + ssize_t rc; + rtems_libio_t *iop; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open( iop ); + rtems_libio_check_buffer( buffer ); + rtems_libio_check_count( count ); + rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); + + /* + * Now process the read(). + */ + rc = (*iop->pathinfo.handlers->read_h)( 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) && !defined(HAVE__READ_R) + +#include <reent.h> + +ssize_t _read_r( + struct _reent *ptr __attribute__((unused)), + int fd, + void *buf, + size_t nbytes +) +{ + return read( fd, buf, nbytes ); +} +#endif diff --git a/cpukit/libcsupport/src/readdir_r.c b/cpukit/libcsupport/src/readdir_r.c new file mode 100644 index 0000000000..f1d53ae593 --- /dev/null +++ b/cpukit/libcsupport/src/readdir_r.c @@ -0,0 +1,30 @@ +/* + * readdir_r - reentrant version of readdir() + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_READDIR_R + +#include <sys/types.h> +#include <dirent.h> +#include <errno.h> +#include <stdio.h> + +/* + * The RTEMS version of readdir is already thread-safe. + */ + +int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) +{ + *result = readdir(dirp); + if (*result) + *entry = **result; + return *result ? 0 : errno; +} + +#endif diff --git a/cpukit/libcsupport/src/readlink.c b/cpukit/libcsupport/src/readlink.c new file mode 100644 index 0000000000..1880ed667e --- /dev/null +++ b/cpukit/libcsupport/src/readlink.c @@ -0,0 +1,48 @@ +/* + * readlink() - POSIX 1003.1b - X.X.X - XXX + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +ssize_t readlink( + const char *pathname, + char *buf, + size_t bufsize +) +{ + rtems_filesystem_location_info_t loc; + int result; + + if (!buf) + rtems_set_errno_and_return_minus_one( EFAULT ); + + result = rtems_filesystem_evaluate_path( pathname, strlen( pathname ), + 0, &loc, false ); + if ( result != 0 ) + return -1; + + if ( (*loc.ops->node_type_h)( &loc ) != RTEMS_FILESYSTEM_SYM_LINK ){ + rtems_filesystem_freenode( &loc ); + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + result = (*loc.ops->readlink_h)( &loc, buf, bufsize ); + + rtems_filesystem_freenode( &loc ); + + return result; +} diff --git a/cpukit/libcsupport/src/readv.c b/cpukit/libcsupport/src/readv.c new file mode 100644 index 0000000000..6b33760504 --- /dev/null +++ b/cpukit/libcsupport/src/readv.c @@ -0,0 +1,120 @@ +/* + * readv() - POSIX 1003.1 - Read a Vector + * + * OpenGroup URL: + * + * http://www.opengroup.org/onlinepubs/009695399/functions/readv.html + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/uio.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +ssize_t readv( + int fd, + const struct iovec *iov, + int iovcnt +) +{ + ssize_t total; + int v; + int bytes; + rtems_libio_t *iop; + bool all_zeros; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open( iop ); + rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); + + /* + * Argument validation on IO vector + */ + if ( !iov ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( iovcnt <= 0 ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( iovcnt > IOV_MAX ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * OpenGroup says that you are supposed to return EINVAL if the + * sum of the iov_len values in the iov array would overflow a + * ssize_t. + * + * Also we would like to ensure that no IO is performed if there + * are obvious errors in the iovec. So this extra loop ensures + * that we do not do anything if there is an argument error. + */ + + all_zeros = true; + for ( total=0, v=0 ; v < iovcnt ; v++ ) { + ssize_t old; + + /* + * iov[v].iov_len cannot be less than 0 because size_t is unsigned. + * So we only check for zero. + */ + if ( iov[v].iov_base == 0 ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* check for wrap */ + old = total; + total += iov[v].iov_len; + if ( total < old ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( iov[v].iov_len ) + all_zeros = false; + } + + /* + * A readv with all zeros logically has no effect. Even though + * OpenGroup didn't address this case as they did with writev(), + * we will handle it the same way for symmetry. + */ + if ( all_zeros == true ) { + return 0; + } + + /* + * Now process the readv(). + */ + for ( total=0, v=0 ; v < iovcnt ; v++ ) { + bytes = (*iop->pathinfo.handlers->read_h)( + iop, + iov[v].iov_base, + iov[v].iov_len + ); + + if ( bytes < 0 ) + return -1; + + if ( bytes > 0 ) { + iop->offset += bytes; + total += bytes; + } + + if (bytes != iov[ v ].iov_len) + break; + } + + return total; +} diff --git a/cpukit/libcsupport/src/realloc.c b/cpukit/libcsupport/src/realloc.c new file mode 100644 index 0000000000..3689f32e61 --- /dev/null +++ b/cpukit/libcsupport/src/realloc.c @@ -0,0 +1,88 @@ +/* + * calloc() + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" +#include <stdlib.h> +#include <errno.h> + +void *realloc( + void *ptr, + size_t size +) +{ + uintptr_t old_size; + char *new_area; + + MSBUMP(realloc_calls, 1); + + /* + * Do not attempt to allocate memory if in a critical section or ISR. + */ + + if (_System_state_Is_up(_System_state_Get())) { + if (_Thread_Dispatch_disable_level > 0) + return (void *) 0; + + if (_ISR_Nest_level > 0) + return (void *) 0; + } + + /* + * Continue with realloc(). + */ + if ( !ptr ) + return malloc( size ); + + if ( !size ) { + free( ptr ); + return (void *) 0; + } + + if ( !_Protected_heap_Get_block_size(RTEMS_Malloc_Heap, ptr, &old_size) ) { + errno = EINVAL; + return (void *) 0; + } + + /* + * Now resize it. + */ + if ( _Protected_heap_Resize_block( RTEMS_Malloc_Heap, ptr, size ) ) { + return ptr; + } + + /* + * There used to be a free on this error case but it is wrong to + * free the memory per OpenGroup Single UNIX Specification V2 + * and the C Standard. + */ + + new_area = malloc( size ); + + MSBUMP(malloc_calls, (uint32_t) -1); /* subtract off the malloc */ + + if ( !new_area ) { + return (void *) 0; + } + + memcpy( new_area, ptr, (size < old_size) ? size : old_size ); + free( ptr ); + + return new_area; + +} +#endif diff --git a/cpukit/libcsupport/src/rmdir.c b/cpukit/libcsupport/src/rmdir.c new file mode 100644 index 0000000000..d7d4edf675 --- /dev/null +++ b/cpukit/libcsupport/src/rmdir.c @@ -0,0 +1,95 @@ +/* + * rmdir() - POSIX 1003.1b - 5.2.2 - Remove a Directory + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int rmdir( + const char *pathname +) +{ + int parentpathlen; + const char *name; + rtems_filesystem_location_info_t parentloc; + rtems_filesystem_location_info_t loc; + int i; + int result; + bool free_parentloc = false; + + /* + * Get the parent node of the node we wish to remove. Find the parent path. + */ + + parentpathlen = rtems_filesystem_dirname ( pathname ); + + if ( parentpathlen == 0 ) + rtems_filesystem_get_start_loc( pathname, &i, &parentloc ); + else { + result = rtems_filesystem_evaluate_path(pathname, parentpathlen, + RTEMS_LIBIO_PERMS_WRITE, + &parentloc, + false ); + if ( result != 0 ) + return -1; + + free_parentloc = true; + } + + /* + * Start from the parent to find the node that should be under it. + */ + + loc = parentloc; + name = pathname + parentpathlen; + name += rtems_filesystem_prefix_separators( name, strlen( name ) ); + + result = rtems_filesystem_evaluate_relative_path( name , strlen( name ), + 0, &loc, false ); + if ( result != 0 ) { + if ( free_parentloc ) + rtems_filesystem_freenode( &parentloc ); + return -1; + } + + /* + * Verify you can remove this node as a directory. + */ + if ( (*loc.ops->node_type_h)( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) { + rtems_filesystem_freenode( &loc ); + if ( free_parentloc ) + rtems_filesystem_freenode( &parentloc ); + rtems_set_errno_and_return_minus_one( ENOTDIR ); + } + + /* + * Use the filesystems rmnod to remove the node. + */ + + result = (*loc.handlers->rmnod_h)( &parentloc, &loc ); + + rtems_filesystem_freenode( &loc ); + if ( free_parentloc ) + rtems_filesystem_freenode( &parentloc ); + + return result; +} diff --git a/cpukit/libcsupport/src/rtems_heap_extend.c b/cpukit/libcsupport/src/rtems_heap_extend.c new file mode 100644 index 0000000000..5916852278 --- /dev/null +++ b/cpukit/libcsupport/src/rtems_heap_extend.c @@ -0,0 +1,45 @@ +/** + * @file + * + * @ingroup libcsupport + * + * @brief rtems_heap_extend() implementation. + */ + +/* + * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" + +rtems_status_code rtems_heap_extend( + void *area_begin, + uintptr_t area_size +) +{ + bool ok = _Protected_heap_Extend(RTEMS_Malloc_Heap, area_begin, area_size); + + if (ok) { + return RTEMS_SUCCESSFUL; + } else { + return RTEMS_INVALID_ADDRESS; + } +} +#endif /* RTEMS_NEWLIB */ diff --git a/cpukit/libcsupport/src/rtems_malloc.c b/cpukit/libcsupport/src/rtems_malloc.c new file mode 100644 index 0000000000..fcd99438f0 --- /dev/null +++ b/cpukit/libcsupport/src/rtems_malloc.c @@ -0,0 +1,56 @@ +/** + * @file + * + * @ingroup libcsupport + * + * @brief rtems_malloc() implementation. + */ + +/* + * Copyright (c) 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" + +void *rtems_heap_allocate_aligned_with_boundary( + size_t size, + uintptr_t alignment, + uintptr_t boundary +) +{ + if ( + _System_state_Is_up( _System_state_Get() ) + && !malloc_is_system_state_OK() + ) { + return NULL; + } + + malloc_deferred_frees_process(); + + /* FIXME: Statistics, boundary checks */ + + return _Protected_heap_Allocate_aligned_with_boundary( + RTEMS_Malloc_Heap, + size, + alignment, + boundary + ); +} + +#endif diff --git a/cpukit/libcsupport/src/rtems_memalign.c b/cpukit/libcsupport/src/rtems_memalign.c new file mode 100644 index 0000000000..2d64cbbfd6 --- /dev/null +++ b/cpukit/libcsupport/src/rtems_memalign.c @@ -0,0 +1,72 @@ +/* + * rtems_memalign() - Raw aligned allocate from Protected Heap + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_NEWLIB +#include "malloc_p.h" + +#include <stdlib.h> +#include <errno.h> + +int rtems_memalign( + void **pointer, + size_t alignment, + size_t size +) +{ + void *return_this; + + /* + * Parameter error checks + */ + if ( !pointer ) + return EINVAL; + + *pointer = NULL; + + /* + * Do not attempt to allocate memory if not in correct system state. + */ + if ( _System_state_Is_up(_System_state_Get()) && + !malloc_is_system_state_OK() ) + return EINVAL; + + /* + * If some free's have been deferred, then do them now. + */ + malloc_deferred_frees_process(); + + /* + * Perform the aligned allocation requested + */ + return_this = _Protected_heap_Allocate_aligned( + RTEMS_Malloc_Heap, + size, + alignment + ); + if ( !return_this ) + return ENOMEM; + + /* + * If configured, update the more involved statistics + */ + if ( rtems_malloc_statistics_helpers ) + (*rtems_malloc_statistics_helpers->at_malloc)(pointer); + + *pointer = return_this; + return 0; +} +#endif diff --git a/cpukit/libcsupport/src/rtems_mkdir.c b/cpukit/libcsupport/src/rtems_mkdir.c new file mode 100644 index 0000000000..86ef7e1b84 --- /dev/null +++ b/cpukit/libcsupport/src/rtems_mkdir.c @@ -0,0 +1,141 @@ +/** + * @file + * + * @ingroup LibIO + * + * @brief rtems_mkdir() implementation. + * + * The implementation is based on FreeBSD 'bin/mkdir/mkdir.c' revision 163213. + */ + +/*- + * Copyright (c) 2010 embedded brains GmbH. + * + * Copyright (c) 1983, 1992, 1993 + * The 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. + * 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 HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <rtems/libio.h> + +/* + * Returns 1 if a directory has been created, + * 2 if it already existed, and 0 on failure. + */ +static int +build(char *path, mode_t omode) +{ + struct stat sb; + mode_t numask, oumask; + int first, last, retval; + char *p; + + p = path; + oumask = 0; + retval = 1; + if (p[0] == '/') /* Skip leading '/'. */ + ++p; + for (first = 1, last = 0; !last ; ++p) { + if (p[0] == '\0') + last = 1; + else if (p[0] != '/') + continue; + *p = '\0'; + if (!last && p[1] == '\0') + last = 1; + if (first) { + /* + * POSIX 1003.2: + * For each dir operand that does not name an existing + * directory, effects equivalent to those caused by the + * following command shall occcur: + * + * mkdir -p -m $(umask -S),u+wx $(dirname dir) && + * mkdir [-m mode] dir + * + * We change the user's umask and then restore it, + * instead of doing chmod's. + */ + oumask = umask(0); + numask = oumask & ~(S_IWUSR | S_IXUSR); + (void)umask(numask); + first = 0; + } + if (last) + (void)umask(oumask); + if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) { + if (errno == EEXIST || errno == EISDIR) { + if (stat(path, &sb) < 0) { + retval = 0; + break; + } else if (!S_ISDIR(sb.st_mode)) { + if (last) + errno = EEXIST; + else + errno = ENOTDIR; + retval = 0; + break; + } + if (last) + retval = 2; + } else { + retval = 0; + break; + } + } + if (!last) + *p = '/'; + } + if (!first && !last) + (void)umask(oumask); + return (retval); +} + +int +rtems_mkdir(const char *path, mode_t mode) +{ + int success = 0; + char *dup_path = strdup(path); + + if (dup_path != NULL) { + success = build(dup_path, mode); + free(dup_path); + } + + return success != 0 ? 0 : -1; +} diff --git a/cpukit/libcsupport/src/setegid.c b/cpukit/libcsupport/src/setegid.c new file mode 100644 index 0000000000..04b93fa070 --- /dev/null +++ b/cpukit/libcsupport/src/setegid.c @@ -0,0 +1,26 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/seterr.h> +#include <rtems/userenv.h> + +/* + * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs, + * P1003.1b-1993, p. 84 + */ +int setegid( + gid_t gid +) +{ + _POSIX_types_Egid = gid; + return 0; +} diff --git a/cpukit/libcsupport/src/seteuid.c b/cpukit/libcsupport/src/seteuid.c new file mode 100644 index 0000000000..262641cde3 --- /dev/null +++ b/cpukit/libcsupport/src/seteuid.c @@ -0,0 +1,24 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/userenv.h> + +int seteuid( uid_t euid ) +{ + _POSIX_types_Euid = euid; + return 0; +} diff --git a/cpukit/libcsupport/src/setgid.c b/cpukit/libcsupport/src/setgid.c new file mode 100644 index 0000000000..908899cf72 --- /dev/null +++ b/cpukit/libcsupport/src/setgid.c @@ -0,0 +1,21 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/userenv.h> + +/* + * + * 4.2.2 Set User and Group IDs, P1003.1b-1993, p. 84 + */ +int setgid( + gid_t gid +) +{ + _POSIX_types_Gid = gid; + return 0; +} diff --git a/cpukit/libcsupport/src/setpgid.c b/cpukit/libcsupport/src/setpgid.c new file mode 100644 index 0000000000..ba8f7afc62 --- /dev/null +++ b/cpukit/libcsupport/src/setpgid.c @@ -0,0 +1,24 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <errno.h> +#include <rtems/seterr.h> + +/*PAGE + * + * 4.3.3 Set Process Group ID for Job Control, P1003.1b-1993, p. 89 + */ + +int setpgid( + pid_t pid __attribute__((unused)), + pid_t pgid __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/libcsupport/src/setsid.c b/cpukit/libcsupport/src/setsid.c new file mode 100644 index 0000000000..cbebdb4952 --- /dev/null +++ b/cpukit/libcsupport/src/setsid.c @@ -0,0 +1,21 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/seterr.h> + +/*PAGE + * + * 4.3.2 Create Session and Set Process Group ID, P1003.1b-1993, p. 88 + */ + +pid_t setsid( void ) +{ + rtems_set_errno_and_return_minus_one( EPERM ); +} diff --git a/cpukit/libcsupport/src/setuid.c b/cpukit/libcsupport/src/setuid.c new file mode 100644 index 0000000000..0e4234ba09 --- /dev/null +++ b/cpukit/libcsupport/src/setuid.c @@ -0,0 +1,30 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#include <rtems/userenv.h> + +/* + * + * 4.2.2 Set User and Group IDs, P1003.1b-1993, p. 84 + */ +int setuid( + uid_t uid +) +{ + _POSIX_types_Uid = uid; + return 0; +} diff --git a/cpukit/libcsupport/src/stat.c b/cpukit/libcsupport/src/stat.c new file mode 100644 index 0000000000..9f06deaa52 --- /dev/null +++ b/cpukit/libcsupport/src/stat.c @@ -0,0 +1,97 @@ +/* + * stat() - POSIX 1003.1b 5.6.2 - Get File Status + * + * Reused from lstat(). + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * lstat() and stat() share the same implementation with a minor + * difference on how links are evaluated. + */ + +#ifndef _STAT_NAME +#define _STAT_NAME stat +#define _STAT_R_NAME _stat_r +#define _STAT_FOLLOW_LINKS true +#endif + + +#include <rtems.h> + +#include <rtems/libio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int _STAT_NAME( + 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 ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + status = rtems_filesystem_evaluate_path( path, strlen( path ), + 0, &loc, _STAT_FOLLOW_LINKS ); + if ( status != 0 ) + return -1; + + /* + * Zero out the stat structure so the various support + * versions of stat don't have to. + */ + + memset( buf, 0, sizeof(struct stat) ); + + status = (*loc.handlers->fstat_h)( &loc, buf ); + + rtems_filesystem_freenode( &loc ); + + return status; +} + +/* + * _stat_r, _lstat_r + * + * This is the Newlib dependent reentrant version of stat() and lstat(). + */ + +#if defined(RTEMS_NEWLIB) + +#include <reent.h> + +int _STAT_R_NAME( + struct _reent *ptr __attribute__((unused)), + const char *path, + struct stat *buf +) +{ + return _STAT_NAME( path, buf ); +} +#endif diff --git a/cpukit/libcsupport/src/statvfs.c b/cpukit/libcsupport/src/statvfs.c new file mode 100644 index 0000000000..599aa7edc1 --- /dev/null +++ b/cpukit/libcsupport/src/statvfs.c @@ -0,0 +1,52 @@ +/* + * COPYRIGHT (c) 2009 Chris Johns <chrisj@rtems.org> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ +/* + * The statvfs as defined by the SUS: + * http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +#include <sys/statvfs.h> + +int +statvfs (const char *path, struct statvfs *sb) +{ + rtems_filesystem_location_info_t loc; + rtems_filesystem_location_info_t *fs_mount_root; + rtems_filesystem_mount_table_entry_t *mt_entry; + int result; + + /* + * Get + * The root node of the mounted filesytem. + * The node for the directory that the fileystem is mounted on. + * The mount entry that is being refered to. + */ + + if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x0, &loc, true ) ) + return -1; + + mt_entry = loc.mt_entry; + fs_mount_root = &mt_entry->mt_fs_root; + + memset (sb, 0, sizeof (struct statvfs)); + + result = ( fs_mount_root->ops->statvfs_h )( fs_mount_root, sb ); + + rtems_filesystem_freenode( &loc ); + + return result; +} diff --git a/cpukit/libcsupport/src/strlcat.c b/cpukit/libcsupport/src/strlcat.c new file mode 100644 index 0000000000..b617cb93e8 --- /dev/null +++ b/cpukit/libcsupport/src/strlcat.c @@ -0,0 +1,41 @@ +/* + * utils.c - various utility functions used in pppd. + * + * Copyright (c) 1999 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#ifndef HAVE_STRLCAT +/* + * strlcat - like strcat/strncat, doesn't overflow destination buffer, + * always leaves destination null-terminated (for len > 0). + */ +size_t +strlcat( + char *dest, + const char *src, + size_t len ) +{ + size_t dlen = strlen(dest); + + return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); +} +#endif diff --git a/cpukit/libcsupport/src/strlcpy.c b/cpukit/libcsupport/src/strlcpy.c new file mode 100644 index 0000000000..2773e877cb --- /dev/null +++ b/cpukit/libcsupport/src/strlcpy.c @@ -0,0 +1,49 @@ +/* + * utils.c - various utility functions used in pppd. + * + * Copyright (c) 1999 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#ifndef HAVE_STRLCPY +/* + * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, + * always leaves destination null-terminated (for len > 0). + */ +size_t +strlcpy(dest, src, len) + char *dest; + const char *src; + size_t len; +{ + size_t ret = strlen(src); + + if (len != 0) { + if (ret < len) + strcpy(dest, src); + else { + strncpy(dest, src, len - 1); + dest[len-1] = 0; + } + } + return ret; +} +#endif diff --git a/cpukit/libcsupport/src/sup_fs_get_start_loc.c b/cpukit/libcsupport/src/sup_fs_get_start_loc.c new file mode 100644 index 0000000000..89f7efbb0d --- /dev/null +++ b/cpukit/libcsupport/src/sup_fs_get_start_loc.c @@ -0,0 +1,48 @@ + /** + * @file src/sup_fs_get_start_loc.c + */ + +/* + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +/* + * rtems_filesystem_get_start_loc + * + * Function to determine if path is absolute or relative + * + * Parameters: + * + * path : IN - path to be checked + * index: OUT - 0, if relative, 1 if absolute + * loc : OUT - location info of root fs if absolute + * location info of current fs if relative + * + * Returns: void + */ + +/* Includes */ + +#include "rtems/libio_.h" + +void rtems_filesystem_get_start_loc(const char *path, + int *index, + rtems_filesystem_location_info_t *loc) +{ + if (rtems_filesystem_is_separator(path[0])) { + *loc = rtems_filesystem_root; + *index = 1; + } + else { + *loc = rtems_filesystem_current; + *index = 0; + } +} diff --git a/cpukit/libcsupport/src/sup_fs_get_sym_start_loc.c b/cpukit/libcsupport/src/sup_fs_get_sym_start_loc.c new file mode 100644 index 0000000000..4bcc964a46 --- /dev/null +++ b/cpukit/libcsupport/src/sup_fs_get_sym_start_loc.c @@ -0,0 +1,47 @@ + /** + * @file src/sup_fs_get_sym_start_loc.c + */ + +/* + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +/* + * rtems_filesystem_get_sym_start_loc + * + * Function to determine if path is absolute or relative + * + * Parameters: + * + * path : IN - path to be checked + * index: OUT - 0, if relative, 1 if absolute + * loc : OUT - location info of root fs if absolute + * location info of current fs if relative + * + * Returns: void + */ + +/* Includes */ + +#include "rtems/libio_.h" + +void rtems_filesystem_get_sym_start_loc(const char *path, + int *index, + rtems_filesystem_location_info_t *loc) +{ + if (rtems_filesystem_is_separator(path[0])) { + *loc = rtems_filesystem_root; + *index = 1; + } + else { + *index = 0; + } +} diff --git a/cpukit/libcsupport/src/sup_fs_is_separator.c b/cpukit/libcsupport/src/sup_fs_is_separator.c new file mode 100644 index 0000000000..affd606271 --- /dev/null +++ b/cpukit/libcsupport/src/sup_fs_is_separator.c @@ -0,0 +1,30 @@ +/** + * @file src/sup_fs_is_separator.c + */ + +/* + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + + +/* + * rtems_filesystem_is_separator + * + * Function to determine if a character is a path name separator. + * This was originally a macro in libio_.h + * + * NOTE: This function handles MS-DOS and UNIX style names. + */ + +int rtems_filesystem_is_separator(char ch) +{ + return ((ch == '/') || (ch == '\\') || (ch == '\0')); +} diff --git a/cpukit/libcsupport/src/symlink.c b/cpukit/libcsupport/src/symlink.c new file mode 100644 index 0000000000..be29980911 --- /dev/null +++ b/cpukit/libcsupport/src/symlink.c @@ -0,0 +1,42 @@ +/* + * symlink() - POSIX 1003.1b - X.X.X - XXX + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> +#include <rtems/seterr.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_h)( &sympath[i], &loc, &name_start ); + if ( result != 0 ) + return -1; + + result = (*loc.ops->symlink_h)( &loc, actualpath, name_start); + + rtems_filesystem_freenode( &loc ); + + return result; +} diff --git a/cpukit/libcsupport/src/sync.c b/cpukit/libcsupport/src/sync.c new file mode 100644 index 0000000000..e1deefc293 --- /dev/null +++ b/cpukit/libcsupport/src/sync.c @@ -0,0 +1,101 @@ +/* + * sync() - XXX ??? where is this defined + * + * This function operates by as follows: + * for all threads + * for all FILE * + * fsync() + * fdatasync() + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* Since we compile with strict ANSI we need to undef it to get + * prototypes for extensions + */ +#undef __STRICT_ANSI__ +int fdatasync(int); /* still not always prototyped */ + + +#include <unistd.h> +#include <stdio.h> + +#include <rtems.h> +/* +#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ + +#include <rtems/libio_.h> +#include <rtems/seterr.h> +*/ + +/* XXX check standards -- Linux version appears to be void */ +void _fwalk(struct _reent *, void *); + + +static void sync_wrapper(FILE *f) +{ + int fn = fileno(f); + + /* + * We are explicitly NOT checking the return values as it does not + * matter if they succeed. We are just making a best faith attempt + * at both and trusting that we were passed a good FILE pointer. + */ + fsync(fn); + fdatasync(fn); +} + +/* iterate over all FILE *'s for this thread */ +static void sync_per_thread(Thread_Control *t) +{ + struct _reent *current_reent; + struct _reent *this_reent; + + /* + * The sync_wrapper() function will operate on the current thread's + * reent structure so we will temporarily use that. + */ + this_reent = t->libc_reent; + if ( this_reent ) { + current_reent = _Thread_Executing->libc_reent; + _Thread_Executing->libc_reent = this_reent; + _fwalk (t->libc_reent, sync_wrapper); + _Thread_Executing->libc_reent = current_reent; + } +} + +/* + * _global_impure_ptr is not prototyped in any .h files. + * We have to extern it here. + */ +extern struct _reent * const _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__; + +void sync(void) +{ + + /* + * Walk the one used initially by RTEMS. + */ + _fwalk(_global_impure_ptr, sync_wrapper); + + /* + * XXX Do we walk the one used globally by newlib? + * XXX Do we need the RTEMS global one? + */ + + /* + * Now walk all the per-thread reentrancy structures. + */ + rtems_iterate_over_all_threads(sync_per_thread); +} diff --git a/cpukit/libcsupport/src/tcdrain.c b/cpukit/libcsupport/src/tcdrain.c new file mode 100644 index 0000000000..c2e9d5e2ee --- /dev/null +++ b/cpukit/libcsupport/src/tcdrain.c @@ -0,0 +1,36 @@ +/* + * tcdrain() - POSIX 1003.1b 7.2.2 - Line Control Functions + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#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 <rtems/libio.h> + +int tcdrain( + int fd +) +{ + return ioctl( fd, RTEMS_IO_TCDRAIN, 0 ); +} + +#endif diff --git a/cpukit/libcsupport/src/tcflow.c b/cpukit/libcsupport/src/tcflow.c new file mode 100644 index 0000000000..d4d3945f38 --- /dev/null +++ b/cpukit/libcsupport/src/tcflow.c @@ -0,0 +1,44 @@ +/* + * tcflow() - POSIX 1003.1b 7.2.2 - Line Control Functions + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) +#include <termios.h> +#include <unistd.h> +#include <errno.h> +#include <rtems/seterr.h> + +int tcflow ( + int fd __attribute__((unused)), + int action +) +{ + switch (action) { + case TCOOFF: + case TCOON: + case TCIOFF: + case TCION: + default: + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + /* fd is not validated */ + + /* When this is supported, implement it here */ + rtems_set_errno_and_return_minus_one( ENOTSUP ); +} + +#endif diff --git a/cpukit/libcsupport/src/tcflush.c b/cpukit/libcsupport/src/tcflush.c new file mode 100644 index 0000000000..6546966384 --- /dev/null +++ b/cpukit/libcsupport/src/tcflush.c @@ -0,0 +1,50 @@ +/* + * tcflush() - POSIX 1003.1b 7.2.2 - Line Control Functions + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#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 <rtems/seterr.h> +#include <rtems/libio.h> + +int tcflush ( + int fd __attribute__((unused)), + int queue +) +{ + switch (queue) { + case TCIFLUSH: + case TCOFLUSH: + case TCIOFLUSH: + default: + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + /* fd is not validated */ + + /* When this is supported, implement it here */ + rtems_set_errno_and_return_minus_one( ENOTSUP ); + return 0; +} + +#endif diff --git a/cpukit/libcsupport/src/tcgetattr.c b/cpukit/libcsupport/src/tcgetattr.c new file mode 100644 index 0000000000..8d4eb0618b --- /dev/null +++ b/cpukit/libcsupport/src/tcgetattr.c @@ -0,0 +1,36 @@ +/* + * tcgetattr() - POSIX 1003.1b 7.2.1 - Get and Set State + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#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 <rtems/libio.h> + +int tcgetattr( + int fd, + struct termios *tp +) +{ + return ioctl( fd, RTEMS_IO_GET_ATTRIBUTES, tp ); +} +#endif diff --git a/cpukit/libcsupport/src/tcgetpgrp.c b/cpukit/libcsupport/src/tcgetpgrp.c new file mode 100644 index 0000000000..8894e46eef --- /dev/null +++ b/cpukit/libcsupport/src/tcgetpgrp.c @@ -0,0 +1,28 @@ +/* + * tcgetprgrp() - POSIX 1003.1b 7.2.3 - Get Foreground Process Group ID + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_NEWLIB) && !defined(HAVE_TCGETPGRP) + +#include <sys/types.h> +#include <unistd.h> + +pid_t tcgetpgrp(int fd __attribute__((unused))) +{ + return getpid(); +} + +#endif diff --git a/cpukit/libcsupport/src/tcsendbreak.c b/cpukit/libcsupport/src/tcsendbreak.c new file mode 100644 index 0000000000..300e7a8f85 --- /dev/null +++ b/cpukit/libcsupport/src/tcsendbreak.c @@ -0,0 +1,36 @@ +/* + * tcsendbreak() - POSIX 1003.1b 7.2.2 - Line Control Functions + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#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 <rtems/libio.h> + +int tcsendbreak ( + int fd __attribute__((unused)), + int duration __attribute__((unused)) ) +{ + return 0; +} + +#endif diff --git a/cpukit/libcsupport/src/tcsetattr.c b/cpukit/libcsupport/src/tcsetattr.c new file mode 100644 index 0000000000..187c1df584 --- /dev/null +++ b/cpukit/libcsupport/src/tcsetattr.c @@ -0,0 +1,51 @@ +/* + * tcsetattr() - POSIX 1003.1b 7.2.1 - Get and Set State + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#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 <rtems/libio.h> +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int tcsetattr( + int fd, + int opt, + struct termios *tp +) +{ + switch (opt) { + default: + rtems_set_errno_and_return_minus_one( ENOTSUP ); + + case TCSADRAIN: + if (ioctl( fd, RTEMS_IO_TCDRAIN, NULL ) < 0) + return -1; + /* + * Fall through to.... + */ + case TCSANOW: + return ioctl( fd, RTEMS_IO_SET_ATTRIBUTES, tp ); + } +} +#endif diff --git a/cpukit/libcsupport/src/tcsetpgrp.c b/cpukit/libcsupport/src/tcsetpgrp.c new file mode 100644 index 0000000000..f8e48025b6 --- /dev/null +++ b/cpukit/libcsupport/src/tcsetpgrp.c @@ -0,0 +1,36 @@ +/* + * tcsetprgrp() - POSIX 1003.1b 7.2.4 - Set Foreground Process Group ID + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#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 <rtems/libio.h> + +int tcsetpgrp( + int fd __attribute__((unused)), + pid_t pid __attribute__((unused)) ) +{ + return 0; +} + +#endif diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c new file mode 100644 index 0000000000..4085c5e4a2 --- /dev/null +++ b/cpukit/libcsupport/src/termios.c @@ -0,0 +1,1480 @@ +/* + * TERMIOS serial line support + * + * Author: + * W. Eric Norum + * Saskatchewan Accelerator Laboratory + * University of Saskatchewan + * Saskatoon, Saskatchewan, CANADA + * eric@skatter.usask.ca + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/libio.h> +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <unistd.h> +#include <sys/ttycom.h> + +#include <rtems/termiostypes.h> + +/* + * The size of the cooked buffer + */ +#define CBUFSIZE (rtems_termios_cbufsize) + +/* + * The sizes of the raw message buffers. + * On most architectures it is quite a bit more + * efficient if these are powers of two. + */ +#define RAW_INPUT_BUFFER_SIZE (rtems_termios_raw_input_size) +#define RAW_OUTPUT_BUFFER_SIZE (rtems_termios_raw_output_size) + +/* fields for "flow_ctrl" status */ +#define FL_IREQXOF 1 /* input queue requests stop of incoming data */ +#define FL_ISNTXOF 2 /* XOFF has been sent to other side of line */ +#define FL_IRTSOFF 4 /* RTS has been turned off for other side.. */ + +#define FL_ORCVXOF 0x10 /* XOFF has been received */ +#define FL_OSTOP 0x20 /* output has been stopped due to XOFF */ + +#define FL_MDRTS 0x100 /* input controlled with RTS/CTS handshake */ +#define FL_MDXON 0x200 /* input controlled with XON/XOFF protocol */ +#define FL_MDXOF 0x400 /* output controlled with XON/XOFF protocol */ + +#define NODISC(n) \ + { NULL, NULL, NULL, NULL, \ + NULL, NULL, NULL, NULL } +/* + * FIXME: change rtems_termios_linesw entries consistent + * with rtems_termios_linesw entry usage... + */ +struct rtems_termios_linesw rtems_termios_linesw[MAXLDISC] = +{ + NODISC(0), /* 0- termios-built-in */ + NODISC(1), /* 1- defunct */ + NODISC(2), /* 2- NTTYDISC */ + NODISC(3), /* TABLDISC */ + NODISC(4), /* SLIPDISC */ + NODISC(5), /* PPPDISC */ + NODISC(6), /* loadable */ + NODISC(7), /* loadable */ +}; + +int rtems_termios_nlinesw = + sizeof (rtems_termios_linesw) / sizeof (rtems_termios_linesw[0]); + +extern struct rtems_termios_tty *rtems_termios_ttyHead; +extern struct rtems_termios_tty *rtems_termios_ttyTail; +extern rtems_id rtems_termios_ttyMutex; + +static int rtems_termios_cbufsize = 256; +static int rtems_termios_raw_input_size = 128; +static int rtems_termios_raw_output_size = 64; + +static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument); +static rtems_task rtems_termios_txdaemon(rtems_task_argument argument); +/* + * some constants for I/O daemon task creation + */ +#define TERMIOS_TXTASK_PRIO 10 +#define TERMIOS_RXTASK_PRIO 9 +#define TERMIOS_TXTASK_STACKSIZE 1024 +#define TERMIOS_RXTASK_STACKSIZE 1024 +/* + * some events to be sent to the I/O tasks + */ +#define TERMIOS_TX_START_EVENT RTEMS_EVENT_1 +#define TERMIOS_TX_TERMINATE_EVENT RTEMS_EVENT_0 + +#define TERMIOS_RX_PROC_EVENT RTEMS_EVENT_1 +#define TERMIOS_RX_TERMINATE_EVENT RTEMS_EVENT_0 + +/* + * Open a termios device + */ +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 sc; + rtems_libio_open_close_args_t *args = arg; + struct rtems_termios_tty *tty; + + /* + * See if the device has already been opened + */ + sc = rtems_semaphore_obtain( + rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) + return sc; + + for (tty = rtems_termios_ttyHead ; tty != NULL ; tty = tty->forw) { + if ((tty->major == major) && (tty->minor == minor)) + break; + } + + if (tty == NULL) { + static char c = 'a'; + + /* + * Create a new device + */ + tty = calloc (1, sizeof (struct rtems_termios_tty)); + if (tty == NULL) { + rtems_semaphore_release (rtems_termios_ttyMutex); + return RTEMS_NO_MEMORY; + } + /* + * allocate raw input buffer + */ + tty->rawInBuf.Size = RAW_INPUT_BUFFER_SIZE; + tty->rawInBuf.theBuf = malloc (tty->rawInBuf.Size); + if (tty->rawInBuf.theBuf == NULL) { + free(tty); + rtems_semaphore_release (rtems_termios_ttyMutex); + return RTEMS_NO_MEMORY; + } + /* + * allocate raw output buffer + */ + tty->rawOutBuf.Size = RAW_OUTPUT_BUFFER_SIZE; + tty->rawOutBuf.theBuf = malloc (tty->rawOutBuf.Size); + if (tty->rawOutBuf.theBuf == NULL) { + free((void *)(tty->rawInBuf.theBuf)); + free(tty); + rtems_semaphore_release (rtems_termios_ttyMutex); + return RTEMS_NO_MEMORY; + } + /* + * allocate cooked buffer + */ + tty->cbuf = malloc (CBUFSIZE); + if (tty->cbuf == NULL) { + free((void *)(tty->rawOutBuf.theBuf)); + free((void *)(tty->rawInBuf.theBuf)); + free(tty); + rtems_semaphore_release (rtems_termios_ttyMutex); + return RTEMS_NO_MEMORY; + } + /* + * Initialize wakeup callbacks + */ + tty->tty_snd.sw_pfn = NULL; + tty->tty_snd.sw_arg = NULL; + tty->tty_rcv.sw_pfn = NULL; + tty->tty_rcv.sw_arg = NULL; + tty->tty_rcvwakeup = 0; + + /* + * link tty + */ + tty->forw = rtems_termios_ttyHead; + tty->back = NULL; + if (rtems_termios_ttyHead != NULL) + rtems_termios_ttyHead->back = tty; + rtems_termios_ttyHead = tty; + if (rtems_termios_ttyTail == NULL) + rtems_termios_ttyTail = tty; + + tty->minor = minor; + tty->major = major; + + /* + * Set up mutex semaphores + */ + sc = rtems_semaphore_create ( + rtems_build_name ('T', 'R', 'i', c), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &tty->isem); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + sc = rtems_semaphore_create ( + rtems_build_name ('T', 'R', 'o', c), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &tty->osem); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + sc = rtems_semaphore_create ( + rtems_build_name ('T', 'R', 'x', c), + 0, + RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_FIFO, + RTEMS_NO_PRIORITY, + &tty->rawOutBuf.Semaphore); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + tty->rawOutBufState = rob_idle; + + /* + * Set callbacks + */ + tty->device = *callbacks; + + /* + * Create I/O tasks + */ + if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) { + sc = rtems_task_create ( + rtems_build_name ('T', 'x', 'T', c), + TERMIOS_TXTASK_PRIO, + TERMIOS_TXTASK_STACKSIZE, + RTEMS_NO_PREEMPT | RTEMS_NO_TIMESLICE | + RTEMS_NO_ASR, + RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, + &tty->txTaskId); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + sc = rtems_task_create ( + rtems_build_name ('R', 'x', 'T', c), + TERMIOS_RXTASK_PRIO, + TERMIOS_RXTASK_STACKSIZE, + RTEMS_NO_PREEMPT | RTEMS_NO_TIMESLICE | + RTEMS_NO_ASR, + RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, + &tty->rxTaskId); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + + } + if ((tty->device.pollRead == NULL) || + (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN)){ + sc = rtems_semaphore_create ( + rtems_build_name ('T', 'R', 'r', c), + 0, + RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &tty->rawInBuf.Semaphore); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + } + + /* + * Set default parameters + */ + tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL; + tty->termios.c_oflag = OPOST | ONLCR | XTABS; + tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL; + tty->termios.c_lflag = + ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL; + + tty->termios.c_cc[VINTR] = '\003'; + tty->termios.c_cc[VQUIT] = '\034'; + tty->termios.c_cc[VERASE] = '\177'; + tty->termios.c_cc[VKILL] = '\025'; + tty->termios.c_cc[VEOF] = '\004'; + tty->termios.c_cc[VEOL] = '\000'; + tty->termios.c_cc[VEOL2] = '\000'; + tty->termios.c_cc[VSTART] = '\021'; + tty->termios.c_cc[VSTOP] = '\023'; + tty->termios.c_cc[VSUSP] = '\032'; + tty->termios.c_cc[VREPRINT] = '\022'; + tty->termios.c_cc[VDISCARD] = '\017'; + tty->termios.c_cc[VWERASE] = '\027'; + tty->termios.c_cc[VLNEXT] = '\026'; + + /* start with no flow control, clear flow control flags */ + tty->flow_ctrl = 0; + /* + * set low/highwater mark for XON/XOFF support + */ + tty->lowwater = tty->rawInBuf.Size * 1/2; + tty->highwater = tty->rawInBuf.Size * 3/4; + /* + * Bump name characer + */ + if (c++ == 'z') + c = 'a'; + + } + args->iop->data1 = tty; + if (!tty->refcount++) { + if (tty->device.firstOpen) + (*tty->device.firstOpen)(major, minor, arg); + + /* + * start I/O tasks, if needed + */ + if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) { + sc = rtems_task_start( + tty->rxTaskId, rtems_termios_rxdaemon, (rtems_task_argument)tty); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + + sc = rtems_task_start( + tty->txTaskId, rtems_termios_txdaemon, (rtems_task_argument)tty); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + } + } + rtems_semaphore_release (rtems_termios_ttyMutex); + return RTEMS_SUCCESSFUL; +} + +/* + * Drain output queue + */ +static void +drainOutput (struct rtems_termios_tty *tty) +{ + rtems_interrupt_level level; + rtems_status_code sc; + + if (tty->device.outputUsesInterrupts != TERMIOS_POLLED) { + rtems_interrupt_disable (level); + while (tty->rawOutBuf.Tail != tty->rawOutBuf.Head) { + tty->rawOutBufState = rob_wait; + rtems_interrupt_enable (level); + sc = rtems_semaphore_obtain( + tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + rtems_interrupt_disable (level); + } + rtems_interrupt_enable (level); + } +} + +rtems_status_code +rtems_termios_close (void *arg) +{ + rtems_libio_open_close_args_t *args = arg; + struct rtems_termios_tty *tty = args->iop->data1; + rtems_status_code sc; + + sc = rtems_semaphore_obtain( + rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + if (--tty->refcount == 0) { + if (rtems_termios_linesw[tty->t_line].l_close != NULL) { + /* + * call discipline-specific close + */ + sc = rtems_termios_linesw[tty->t_line].l_close(tty); + } else { + /* + * default: just flush output buffer + */ + sc = rtems_semaphore_obtain(tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred (sc); + } + drainOutput (tty); + rtems_semaphore_release (tty->osem); + } + + if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) { + /* + * send "terminate" to I/O tasks + */ + sc = rtems_event_send( tty->rxTaskId, TERMIOS_RX_TERMINATE_EVENT ); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + sc = rtems_event_send( tty->txTaskId, TERMIOS_TX_TERMINATE_EVENT ); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + } + if (tty->device.lastClose) + (*tty->device.lastClose)(tty->major, tty->minor, arg); + if (tty->forw == NULL) { + rtems_termios_ttyTail = tty->back; + if ( rtems_termios_ttyTail != NULL ) { + rtems_termios_ttyTail->forw = NULL; + } + } else { + tty->forw->back = tty->back; + } + + if (tty->back == NULL) { + rtems_termios_ttyHead = tty->forw; + if ( rtems_termios_ttyHead != NULL ) { + rtems_termios_ttyHead->back = NULL; + } + } else { + tty->back->forw = tty->forw; + } + + rtems_semaphore_delete (tty->isem); + rtems_semaphore_delete (tty->osem); + rtems_semaphore_delete (tty->rawOutBuf.Semaphore); + if ((tty->device.pollRead == NULL) || + (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN)) + rtems_semaphore_delete (tty->rawInBuf.Semaphore); + free (tty->rawInBuf.theBuf); + free (tty->rawOutBuf.theBuf); + free (tty->cbuf); + free (tty); + } + rtems_semaphore_release (rtems_termios_ttyMutex); + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_termios_bufsize ( + int cbufsize, + int raw_input, + int raw_output +) +{ + rtems_termios_cbufsize = cbufsize; + rtems_termios_raw_input_size = raw_input; + rtems_termios_raw_output_size = raw_output; + return RTEMS_SUCCESSFUL; +} + +static void +termios_set_flowctrl(struct rtems_termios_tty *tty) +{ + rtems_interrupt_level level; + /* + * check for flow control options to be switched off + */ + + /* check for outgoing XON/XOFF flow control switched off */ + if (( tty->flow_ctrl & FL_MDXON) && + !(tty->termios.c_iflag & IXON)) { + /* clear related flags in flow_ctrl */ + tty->flow_ctrl &= ~(FL_MDXON | FL_ORCVXOF); + + /* has output been stopped due to received XOFF? */ + if (tty->flow_ctrl & FL_OSTOP) { + /* disable interrupts */ + rtems_interrupt_disable(level); + tty->flow_ctrl &= ~FL_OSTOP; + /* check for chars in output buffer (or rob_state?) */ + if (tty->rawOutBufState != rob_idle) { + /* if chars available, call write function... */ + (*tty->device.write)( + tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1); + } + /* reenable interrupts */ + rtems_interrupt_enable(level); + } + } + /* check for incoming XON/XOFF flow control switched off */ + if (( tty->flow_ctrl & FL_MDXOF) && !(tty->termios.c_iflag & IXOFF)) { + /* clear related flags in flow_ctrl */ + tty->flow_ctrl &= ~(FL_MDXOF); + /* FIXME: what happens, if we had sent XOFF but not yet XON? */ + tty->flow_ctrl &= ~(FL_ISNTXOF); + } + + /* check for incoming RTS/CTS flow control switched off */ + if (( tty->flow_ctrl & FL_MDRTS) && !(tty->termios.c_cflag & CRTSCTS)) { + /* clear related flags in flow_ctrl */ + tty->flow_ctrl &= ~(FL_MDRTS); + + /* restart remote Tx, if it was stopped */ + if ((tty->flow_ctrl & FL_IRTSOFF) && (tty->device.startRemoteTx != NULL)) { + tty->device.startRemoteTx(tty->minor); + } + tty->flow_ctrl &= ~(FL_IRTSOFF); + } + + /* + * check for flow control options to be switched on + */ + /* check for incoming RTS/CTS flow control switched on */ + if (tty->termios.c_cflag & CRTSCTS) { + tty->flow_ctrl |= FL_MDRTS; + } + /* check for incoming XON/XOF flow control switched on */ + if (tty->termios.c_iflag & IXOFF) { + tty->flow_ctrl |= FL_MDXOF; + } + /* check for outgoing XON/XOF flow control switched on */ + if (tty->termios.c_iflag & IXON) { + tty->flow_ctrl |= FL_MDXON; + } +} + +rtems_status_code +rtems_termios_ioctl (void *arg) +{ + rtems_libio_ioctl_args_t *args = arg; + struct rtems_termios_tty *tty = args->iop->data1; + struct ttywakeup *wakeup = (struct ttywakeup *)args->buffer; + rtems_status_code sc; + + args->ioctl_return = 0; + sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) { + args->ioctl_return = sc; + return sc; + } + switch (args->command) { + default: + if (rtems_termios_linesw[tty->t_line].l_ioctl != NULL) { + sc = rtems_termios_linesw[tty->t_line].l_ioctl(tty,args); + } + else { + sc = RTEMS_INVALID_NUMBER; + } + break; + + case RTEMS_IO_GET_ATTRIBUTES: + *(struct termios *)args->buffer = tty->termios; + break; + + case RTEMS_IO_SET_ATTRIBUTES: + tty->termios = *(struct termios *)args->buffer; + + /* check for and process change in flow control options */ + termios_set_flowctrl(tty); + + if (tty->termios.c_lflag & ICANON) { + tty->rawInBufSemaphoreOptions = RTEMS_WAIT; + tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT; + tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; + } else { + tty->vtimeTicks = tty->termios.c_cc[VTIME] * + rtems_clock_get_ticks_per_second() / 10; + if (tty->termios.c_cc[VTIME]) { + tty->rawInBufSemaphoreOptions = RTEMS_WAIT; + tty->rawInBufSemaphoreTimeout = tty->vtimeTicks; + if (tty->termios.c_cc[VMIN]) + tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; + else + tty->rawInBufSemaphoreFirstTimeout = tty->vtimeTicks; + } else { + if (tty->termios.c_cc[VMIN]) { + tty->rawInBufSemaphoreOptions = RTEMS_WAIT; + tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT; + tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT; + } else { + tty->rawInBufSemaphoreOptions = RTEMS_NO_WAIT; + } + } + } + if (tty->device.setAttributes) + (*tty->device.setAttributes)(tty->minor, &tty->termios); + break; + + case RTEMS_IO_TCDRAIN: + drainOutput (tty); + break; + + case RTEMS_IO_SNDWAKEUP: + tty->tty_snd = *wakeup; + break; + + case RTEMS_IO_RCVWAKEUP: + tty->tty_rcv = *wakeup; + break; + + /* + * FIXME: add various ioctl code handlers + */ + +#if 1 /* FIXME */ + case TIOCSETD: + /* + * close old line discipline + */ + if (rtems_termios_linesw[tty->t_line].l_close != NULL) { + sc = rtems_termios_linesw[tty->t_line].l_close(tty); + } + tty->t_line=*(int*)(args->buffer); + tty->t_sc = NULL; /* ensure that no more valid data */ + /* + * open new line discipline + */ + if (rtems_termios_linesw[tty->t_line].l_open != NULL) { + sc = rtems_termios_linesw[tty->t_line].l_open(tty); + } + break; + case TIOCGETD: + *(int*)(args->buffer)=tty->t_line; + break; +#endif + case FIONREAD: { + int rawnc = tty->rawInBuf.Tail - tty->rawInBuf.Head; + if ( rawnc < 0 ) + rawnc += tty->rawInBuf.Size; + /* Half guess that this is the right operation */ + *(int *)args->buffer = tty->ccount - tty->cindex + rawnc; + } + break; + } + + rtems_semaphore_release (tty->osem); + args->ioctl_return = sc; + return sc; +} + +/* + * Send characters to device-specific code + */ +void +rtems_termios_puts ( + const void *_buf, int len, struct rtems_termios_tty *tty) +{ + const unsigned char *buf = _buf; + unsigned int newHead; + rtems_interrupt_level level; + rtems_status_code sc; + + if (tty->device.outputUsesInterrupts == TERMIOS_POLLED) { + (*tty->device.write)(tty->minor, (void *)buf, len); + return; + } + newHead = tty->rawOutBuf.Head; + while (len) { + /* + * Performance improvement could be made here. + * Copy multiple bytes to raw buffer: + * if (len > 1) && (space to buffer end, or tail > 1) + * ncopy = MIN (len, space to buffer end or tail) + * memcpy (raw buffer, buf, ncopy) + * buf += ncopy + * len -= ncopy + * + * To minimize latency, the memcpy should be done + * with interrupts enabled. + */ + newHead = (newHead + 1) % tty->rawOutBuf.Size; + rtems_interrupt_disable (level); + while (newHead == tty->rawOutBuf.Tail) { + tty->rawOutBufState = rob_wait; + rtems_interrupt_enable (level); + sc = rtems_semaphore_obtain( + tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + rtems_interrupt_disable (level); + } + tty->rawOutBuf.theBuf[tty->rawOutBuf.Head] = *buf++; + tty->rawOutBuf.Head = newHead; + if (tty->rawOutBufState == rob_idle) { + /* check, whether XOFF has been received */ + if (!(tty->flow_ctrl & FL_ORCVXOF)) { + (*tty->device.write)(tty->minor, + (char *)&tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1); + } else { + /* remember that output has been stopped due to flow ctrl*/ + tty->flow_ctrl |= FL_OSTOP; + } + tty->rawOutBufState = rob_busy; + } + rtems_interrupt_enable (level); + len--; + } +} + +/* + * Handle output processing + */ +static void +oproc (unsigned char c, struct rtems_termios_tty *tty) +{ + int i; + + if (tty->termios.c_oflag & OPOST) { + switch (c) { + case '\n': + if (tty->termios.c_oflag & ONLRET) + tty->column = 0; + if (tty->termios.c_oflag & ONLCR) { + rtems_termios_puts ("\r", 1, tty); + tty->column = 0; + } + break; + + case '\r': + if ((tty->termios.c_oflag & ONOCR) && (tty->column == 0)) + return; + if (tty->termios.c_oflag & OCRNL) { + c = '\n'; + if (tty->termios.c_oflag & ONLRET) + tty->column = 0; + break; + } + tty->column = 0; + break; + + case '\t': + i = 8 - (tty->column & 7); + if ((tty->termios.c_oflag & TABDLY) == XTABS) { + tty->column += i; + rtems_termios_puts ( " ", i, tty); + return; + } + tty->column += i; + break; + + case '\b': + if (tty->column > 0) + tty->column--; + break; + + default: + if (tty->termios.c_oflag & OLCUC) + c = toupper(c); + if (!iscntrl(c)) + tty->column++; + break; + } + } + rtems_termios_puts (&c, 1, tty); +} + +rtems_status_code +rtems_termios_write (void *arg) +{ + rtems_libio_rw_args_t *args = arg; + struct rtems_termios_tty *tty = args->iop->data1; + rtems_status_code sc; + + sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) + return sc; + if (rtems_termios_linesw[tty->t_line].l_write != NULL) { + sc = rtems_termios_linesw[tty->t_line].l_write(tty,args); + rtems_semaphore_release (tty->osem); + return sc; + } + if (tty->termios.c_oflag & OPOST) { + uint32_t count = args->count; + char *buffer = args->buffer; + while (count--) + oproc (*buffer++, tty); + args->bytes_moved = args->count; + } else { + rtems_termios_puts (args->buffer, args->count, tty); + args->bytes_moved = args->count; + } + rtems_semaphore_release (tty->osem); + return sc; +} + +/* + * Echo a typed character + */ +static void +echo (unsigned char c, struct rtems_termios_tty *tty) +{ + if ((tty->termios.c_lflag & ECHOCTL) && + iscntrl(c) && (c != '\t') && (c != '\n')) { + char echobuf[2]; + + echobuf[0] = '^'; + echobuf[1] = c ^ 0x40; + rtems_termios_puts (echobuf, 2, tty); + tty->column += 2; + } else { + oproc (c, tty); + } +} + +/* + * Erase a character or line + * FIXME: Needs support for WERASE and ECHOPRT. + * FIXME: Some of the tests should check for IEXTEN, too. + */ +static void +erase (struct rtems_termios_tty *tty, int lineFlag) +{ + if (tty->ccount == 0) + return; + if (lineFlag) { + if (!(tty->termios.c_lflag & ECHO)) { + tty->ccount = 0; + return; + } + if (!(tty->termios.c_lflag & ECHOE)) { + tty->ccount = 0; + echo (tty->termios.c_cc[VKILL], tty); + if (tty->termios.c_lflag & ECHOK) + echo ('\n', tty); + return; + } + } + + while (tty->ccount) { + unsigned char c = tty->cbuf[--tty->ccount]; + + if (tty->termios.c_lflag & ECHO) { + if (!lineFlag && !(tty->termios.c_lflag & ECHOE)) { + echo (tty->termios.c_cc[VERASE], tty); + } else if (c == '\t') { + int col = tty->read_start_column; + int i = 0; + + /* + * Find the character before the tab + */ + while (i != tty->ccount) { + c = tty->cbuf[i++]; + if (c == '\t') { + col = (col | 7) + 1; + } else if (iscntrl (c)) { + if (tty->termios.c_lflag & ECHOCTL) + col += 2; + } else { + col++; + } + } + + /* + * Back up over the tab + */ + while (tty->column > col) { + rtems_termios_puts ("\b", 1, tty); + tty->column--; + } + } + else { + if (iscntrl (c) && (tty->termios.c_lflag & ECHOCTL)) { + rtems_termios_puts ("\b \b", 3, tty); + if (tty->column) + tty->column--; + } + if (!iscntrl (c) || (tty->termios.c_lflag & ECHOCTL)) { + rtems_termios_puts ("\b \b", 3, tty); + if (tty->column) + tty->column--; + } + } + } + if (!lineFlag) + break; + } +} + +/* + * Process a single input character + */ +static int +iproc (unsigned char c, struct rtems_termios_tty *tty) +{ + if (tty->termios.c_iflag & ISTRIP) + c &= 0x7f; + + if (tty->termios.c_iflag & IUCLC) + c = tolower (c); + + if (c == '\r') { + if (tty->termios.c_iflag & IGNCR) + return 0; + if (tty->termios.c_iflag & ICRNL) + c = '\n'; + } else if ((c == '\n') && (tty->termios.c_iflag & INLCR)) { + c = '\r'; + } + + if ((c != '\0') && (tty->termios.c_lflag & ICANON)) { + if (c == tty->termios.c_cc[VERASE]) { + erase (tty, 0); + return 0; + } + else if (c == tty->termios.c_cc[VKILL]) { + erase (tty, 1); + return 0; + } + else if (c == tty->termios.c_cc[VEOF]) { + return 1; + } else if (c == '\n') { + if (tty->termios.c_lflag & (ECHO | ECHONL)) + echo (c, tty); + tty->cbuf[tty->ccount++] = c; + return 1; + } else if ((c == tty->termios.c_cc[VEOL]) || + (c == tty->termios.c_cc[VEOL2])) { + if (tty->termios.c_lflag & ECHO) + echo (c, tty); + tty->cbuf[tty->ccount++] = c; + return 1; + } + } + + /* + * FIXME: Should do IMAXBEL handling somehow + */ + if (tty->ccount < (CBUFSIZE-1)) { + if (tty->termios.c_lflag & ECHO) + echo (c, tty); + tty->cbuf[tty->ccount++] = c; + } + return 0; +} + +/* + * Process input character, with semaphore. + */ +static int +siproc (unsigned char c, struct rtems_termios_tty *tty) +{ + int i; + + /* + * Obtain output semaphore if character will be echoed + */ + if (tty->termios.c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ECHOPRT|ECHOCTL|ECHOKE)) { + rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + i = iproc (c, tty); + rtems_semaphore_release (tty->osem); + } + else { + i = iproc (c, tty); + } + return i; +} + +/* + * Fill the input buffer by polling the device + */ +static rtems_status_code +fillBufferPoll (struct rtems_termios_tty *tty) +{ + int n; + + if (tty->termios.c_lflag & ICANON) { + for (;;) { + n = (*tty->device.pollRead)(tty->minor); + if (n < 0) { + rtems_task_wake_after (1); + } else { + if (siproc (n, tty)) + break; + } + } + } else { + rtems_interval then, now; + + then = rtems_clock_get_ticks_since_boot(); + for (;;) { + n = (*tty->device.pollRead)(tty->minor); + if (n < 0) { + if (tty->termios.c_cc[VMIN]) { + if (tty->termios.c_cc[VTIME] && tty->ccount) { + now = rtems_clock_get_ticks_since_boot(); + if ((now - then) > tty->vtimeTicks) { + break; + } + } + } else { + if (!tty->termios.c_cc[VTIME]) + break; + now = rtems_clock_get_ticks_since_boot(); + if ((now - then) > tty->vtimeTicks) { + break; + } + } + rtems_task_wake_after (1); + } else { + siproc (n, tty); + if (tty->ccount >= tty->termios.c_cc[VMIN]) + break; + if (tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME]) + then = rtems_clock_get_ticks_since_boot(); + } + } + } + return RTEMS_SUCCESSFUL; +} + +/* + * Fill the input buffer from the raw input queue + */ +static rtems_status_code +fillBufferQueue (struct rtems_termios_tty *tty) +{ + rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout; + rtems_status_code sc; + int wait = (int)1; + + while ( wait ) { + /* + * Process characters read from raw queue + */ + while ((tty->rawInBuf.Head != tty->rawInBuf.Tail) && + (tty->ccount < (CBUFSIZE-1))) { + unsigned char c; + unsigned int newHead; + + newHead = (tty->rawInBuf.Head + 1) % tty->rawInBuf.Size; + c = tty->rawInBuf.theBuf[newHead]; + tty->rawInBuf.Head = newHead; + if(((tty->rawInBuf.Tail-newHead+tty->rawInBuf.Size) + % tty->rawInBuf.Size) + < tty->lowwater) { + tty->flow_ctrl &= ~FL_IREQXOF; + /* if tx stopped and XON should be sent... */ + if (((tty->flow_ctrl & (FL_MDXON | FL_ISNTXOF)) + == (FL_MDXON | FL_ISNTXOF)) + && ((tty->rawOutBufState == rob_idle) + || (tty->flow_ctrl & FL_OSTOP))) { + /* XON should be sent now... */ + (*tty->device.write)( + tty->minor, (void *)&(tty->termios.c_cc[VSTART]), 1); + } else if (tty->flow_ctrl & FL_MDRTS) { + tty->flow_ctrl &= ~FL_IRTSOFF; + /* activate RTS line */ + if (tty->device.startRemoteTx != NULL) { + tty->device.startRemoteTx(tty->minor); + } + } + } + + /* continue processing new character */ + if (tty->termios.c_lflag & ICANON) { + if (siproc (c, tty)) + wait = 0; + } else { + siproc (c, tty); + if (tty->ccount >= tty->termios.c_cc[VMIN]) + wait = 0; + } + timeout = tty->rawInBufSemaphoreTimeout; + } + + /* + * Wait for characters + */ + if ( wait ) { + sc = rtems_semaphore_obtain( + tty->rawInBuf.Semaphore, tty->rawInBufSemaphoreOptions, timeout); + if (sc != RTEMS_SUCCESSFUL) + break; + } + } + return RTEMS_SUCCESSFUL; +} + +rtems_status_code +rtems_termios_read (void *arg) +{ + rtems_libio_rw_args_t *args = arg; + struct rtems_termios_tty *tty = args->iop->data1; + uint32_t count = args->count; + char *buffer = args->buffer; + rtems_status_code sc; + + sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) + return sc; + + if (rtems_termios_linesw[tty->t_line].l_read != NULL) { + sc = rtems_termios_linesw[tty->t_line].l_read(tty,args); + tty->tty_rcvwakeup = 0; + rtems_semaphore_release (tty->isem); + return sc; + } + + if (tty->cindex == tty->ccount) { + tty->cindex = tty->ccount = 0; + tty->read_start_column = tty->column; + if (tty->device.pollRead != NULL && + tty->device.outputUsesInterrupts == TERMIOS_POLLED) + sc = fillBufferPoll (tty); + else + sc = fillBufferQueue (tty); + + if (sc != RTEMS_SUCCESSFUL) + tty->cindex = tty->ccount = 0; + } + while (count && (tty->cindex < tty->ccount)) { + *buffer++ = tty->cbuf[tty->cindex++]; + count--; + } + args->bytes_moved = args->count - count; + tty->tty_rcvwakeup = 0; + rtems_semaphore_release (tty->isem); + return sc; +} + +/* + * signal receive interrupt to rx daemon + * NOTE: This routine runs in the context of the + * device receive interrupt handler. + */ +void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty) +{ + /* + * send event to rx daemon task + */ + rtems_event_send(tty->rxTaskId,TERMIOS_RX_PROC_EVENT); +} + +/* + * Place characters on raw queue. + * NOTE: This routine runs in the context of the + * device receive interrupt handler. + * Returns the number of characters dropped because of overflow. + */ +int +rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len) +{ + struct rtems_termios_tty *tty = ttyp; + unsigned int newTail; + char c; + int dropped = 0; + bool flow_rcv = false; /* true, if flow control char received */ + rtems_interrupt_level level; + + if (rtems_termios_linesw[tty->t_line].l_rint != NULL) { + while (len--) { + c = *buf++; + rtems_termios_linesw[tty->t_line].l_rint(c,tty); + } + + /* + * check to see if rcv wakeup callback was set + */ + if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) { + (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg); + tty->tty_rcvwakeup = 1; + } + return 0; + } + + while (len--) { + c = *buf++; + /* FIXME: implement IXANY: any character restarts output */ + /* if incoming XON/XOFF controls outgoing stream: */ + if (tty->flow_ctrl & FL_MDXON) { + /* if received char is V_STOP and V_START (both are equal value) */ + if (c == tty->termios.c_cc[VSTOP]) { + if (c == tty->termios.c_cc[VSTART]) { + /* received VSTOP and VSTART==VSTOP? */ + /* then toggle "stop output" status */ + tty->flow_ctrl = tty->flow_ctrl ^ FL_ORCVXOF; + } + else { + /* VSTOP received (other code than VSTART) */ + /* stop output */ + tty->flow_ctrl |= FL_ORCVXOF; + } + flow_rcv = true; + } + else if (c == tty->termios.c_cc[VSTART]) { + /* VSTART received */ + /* restart output */ + tty->flow_ctrl &= ~FL_ORCVXOF; + flow_rcv = true; + } + } + if (flow_rcv) { + /* restart output according to FL_ORCVXOF flag */ + if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) == FL_OSTOP) { + /* disable interrupts */ + rtems_interrupt_disable(level); + tty->flow_ctrl &= ~FL_OSTOP; + /* check for chars in output buffer (or rob_state?) */ + if (tty->rawOutBufState != rob_idle) { + /* if chars available, call write function... */ + (*tty->device.write)( + tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1); + } + /* reenable interrupts */ + rtems_interrupt_enable(level); + } + } else { + newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size; + /* if chars_in_buffer > highwater */ + rtems_interrupt_disable(level); + if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size) + % tty->rawInBuf.Size) > tty->highwater) && + !(tty->flow_ctrl & FL_IREQXOF)) { + /* incoming data stream should be stopped */ + tty->flow_ctrl |= FL_IREQXOF; + if ((tty->flow_ctrl & (FL_MDXOF | FL_ISNTXOF)) + == (FL_MDXOF ) ) { + if ((tty->flow_ctrl & FL_OSTOP) || + (tty->rawOutBufState == rob_idle)) { + /* if tx is stopped due to XOFF or out of data */ + /* call write function here */ + tty->flow_ctrl |= FL_ISNTXOF; + (*tty->device.write)(tty->minor, + (void *)&(tty->termios.c_cc[VSTOP]), 1); + } + } else if ((tty->flow_ctrl & (FL_MDRTS | FL_IRTSOFF)) == (FL_MDRTS) ) { + tty->flow_ctrl |= FL_IRTSOFF; + /* deactivate RTS line */ + if (tty->device.stopRemoteTx != NULL) { + tty->device.stopRemoteTx(tty->minor); + } + } + } + + /* reenable interrupts */ + rtems_interrupt_enable(level); + + if (newTail == tty->rawInBuf.Head) { + dropped++; + } else { + tty->rawInBuf.theBuf[newTail] = c; + tty->rawInBuf.Tail = newTail; + + /* + * check to see if rcv wakeup callback was set + */ + if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) { + (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg); + tty->tty_rcvwakeup = 1; + } + } + } + } + + tty->rawInBufDropped += dropped; + rtems_semaphore_release (tty->rawInBuf.Semaphore); + return dropped; +} + +/* + * in task-driven mode, this function is called in Tx task context + * in interrupt-driven mode, this function is called in TxIRQ context + */ +int +rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) +{ + unsigned int newTail; + int nToSend; + rtems_interrupt_level level; + int len; + + /* check for XOF/XON to send */ + if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF)) + == (FL_MDXOF | FL_IREQXOF)) { + /* XOFF should be sent now... */ + (*tty->device.write)(tty->minor, (void *)&(tty->termios.c_cc[VSTOP]), 1); + + rtems_interrupt_disable(level); + tty->t_dqlen--; + tty->flow_ctrl |= FL_ISNTXOF; + rtems_interrupt_enable(level); + + nToSend = 1; + + } else if ((tty->flow_ctrl & (FL_IREQXOF | FL_ISNTXOF)) == FL_ISNTXOF) { + /* NOTE: send XON even, if no longer in XON/XOFF mode... */ + /* XON should be sent now... */ + /* + * FIXME: this .write call will generate another + * dequeue callback. This will advance the "Tail" in the data + * buffer, although the corresponding data is not yet out! + * Therefore the dequeue "length" should be reduced by 1 + */ + (*tty->device.write)(tty->minor, (void *)&(tty->termios.c_cc[VSTART]), 1); + + rtems_interrupt_disable(level); + tty->t_dqlen--; + tty->flow_ctrl &= ~FL_ISNTXOF; + rtems_interrupt_enable(level); + + nToSend = 1; + } else { + if ( tty->rawOutBuf.Head == tty->rawOutBuf.Tail ) { + /* + * buffer was empty + */ + if (tty->rawOutBufState == rob_wait) { + /* + * this should never happen... + */ + rtems_semaphore_release (tty->rawOutBuf.Semaphore); + } + return 0; + } + + rtems_interrupt_disable(level); + len = tty->t_dqlen; + tty->t_dqlen = 0; + rtems_interrupt_enable(level); + + newTail = (tty->rawOutBuf.Tail + len) % tty->rawOutBuf.Size; + tty->rawOutBuf.Tail = newTail; + if (tty->rawOutBufState == rob_wait) { + /* + * wake up any pending writer task + */ + rtems_semaphore_release (tty->rawOutBuf.Semaphore); + } + + if (newTail == tty->rawOutBuf.Head) { + /* + * Buffer has become empty + */ + tty->rawOutBufState = rob_idle; + nToSend = 0; + + /* + * check to see if snd wakeup callback was set + */ + if ( tty->tty_snd.sw_pfn != NULL) { + (*tty->tty_snd.sw_pfn)(&tty->termios, tty->tty_snd.sw_arg); + } + } + /* check, whether output should stop due to received XOFF */ + else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF)) + == (FL_MDXON | FL_ORCVXOF)) { + /* Buffer not empty, but output stops due to XOFF */ + /* set flag, that output has been stopped */ + rtems_interrupt_disable(level); + tty->flow_ctrl |= FL_OSTOP; + tty->rawOutBufState = rob_busy; /*apm*/ + rtems_interrupt_enable(level); + nToSend = 0; + } else { + /* + * Buffer not empty, start tranmitter + */ + if (newTail > tty->rawOutBuf.Head) + nToSend = tty->rawOutBuf.Size - newTail; + else + nToSend = tty->rawOutBuf.Head - newTail; + /* when flow control XON or XOF, don't send blocks of data */ + /* to allow fast reaction on incoming flow ctrl and low latency*/ + /* for outgoing flow control */ + if (tty->flow_ctrl & (FL_MDXON | FL_MDXOF)) { + nToSend = 1; + } + tty->rawOutBufState = rob_busy; /*apm*/ + (*tty->device.write)( + tty->minor, &tty->rawOutBuf.theBuf[newTail], nToSend); + } + tty->rawOutBuf.Tail = newTail; /*apm*/ + } + return nToSend; +} + +/* + * Characters have been transmitted + * NOTE: This routine runs in the context of the + * device transmit interrupt handler. + * The second argument is the number of characters transmitted so far. + * This value will always be 1 for devices which generate an interrupt + * for each transmitted character. + * It returns number of characters left to transmit + */ +int +rtems_termios_dequeue_characters (void *ttyp, int len) +{ + struct rtems_termios_tty *tty = ttyp; + rtems_status_code sc; + + /* + * sum up character count already sent + */ + tty->t_dqlen += len; + + if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) { + /* + * send wake up to transmitter task + */ + sc = rtems_event_send(tty->txTaskId, TERMIOS_TX_START_EVENT); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + return 0; /* nothing to output in IRQ... */ + } + + if (tty->t_line == PPPDISC ) { + /* + * call any line discipline start function + */ + if (rtems_termios_linesw[tty->t_line].l_start != NULL) { + rtems_termios_linesw[tty->t_line].l_start(tty); + } + return 0; /* nothing to output in IRQ... */ + } + + return rtems_termios_refill_transmitter(tty); +} + +/* + * this task actually processes any transmit events + */ +static rtems_task rtems_termios_txdaemon(rtems_task_argument argument) +{ + struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument; + rtems_event_set the_event; + + while (1) { + /* + * wait for rtems event + */ + rtems_event_receive( + (TERMIOS_TX_START_EVENT | TERMIOS_TX_TERMINATE_EVENT), + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &the_event + ); + if ((the_event & TERMIOS_TX_TERMINATE_EVENT) != 0) { + tty->txTaskId = 0; + rtems_task_delete(RTEMS_SELF); + } + + /* + * call any line discipline start function + */ + if (rtems_termios_linesw[tty->t_line].l_start != NULL) { + rtems_termios_linesw[tty->t_line].l_start(tty); + } + + /* + * try to push further characters to device + */ + rtems_termios_refill_transmitter(tty); + } +} + +/* + * this task actually processes any receive events + */ +static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument) +{ + struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument; + rtems_event_set the_event; + int c; + char c_buf; + + while (1) { + /* + * wait for rtems event + */ + rtems_event_receive( + (TERMIOS_RX_PROC_EVENT | TERMIOS_RX_TERMINATE_EVENT), + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &the_event + ); + if ((the_event & TERMIOS_RX_TERMINATE_EVENT) != 0) { + tty->rxTaskId = 0; + rtems_task_delete(RTEMS_SELF); + } + + /* + * do something + */ + c = tty->device.pollRead(tty->minor); + if (c != EOF) { + /* + * pollRead did call enqueue on its own + */ + c_buf = c; + rtems_termios_enqueue_raw_characters ( tty,&c_buf,1); + } + } +} diff --git a/cpukit/libcsupport/src/termios_baud2index.c b/cpukit/libcsupport/src/termios_baud2index.c new file mode 100644 index 0000000000..8bd6b867b8 --- /dev/null +++ b/cpukit/libcsupport/src/termios_baud2index.c @@ -0,0 +1,50 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/termios.h> +#include <rtems/termiostypes.h> + +int rtems_termios_baud_to_index( + rtems_termios_baud_t termios_baud +) +{ + int baud_index; + + switch (termios_baud) { + case B0: baud_index = 0; break; + case B50: baud_index = 1; break; + case B75: baud_index = 2; break; + case B110: baud_index = 3; break; + case B134: baud_index = 4; break; + case B150: baud_index = 5; break; + case B200: baud_index = 6; break; + case B300: baud_index = 7; break; + case B600: baud_index = 8; break; + case B1200: baud_index = 9; break; + case B1800: baud_index = 10; break; + case B2400: baud_index = 11; break; + case B4800: baud_index = 12; break; + case B9600: baud_index = 13; break; + case B19200: baud_index = 14; break; + case B38400: baud_index = 15; break; + case B57600: baud_index = 16; break; + case B115200: baud_index = 17; break; + case B230400: baud_index = 18; break; + case B460800: baud_index = 19; break; + default: baud_index = -1; break; + } + + return baud_index; +} diff --git a/cpukit/libcsupport/src/termios_baud2num.c b/cpukit/libcsupport/src/termios_baud2num.c new file mode 100644 index 0000000000..57b908ebee --- /dev/null +++ b/cpukit/libcsupport/src/termios_baud2num.c @@ -0,0 +1,33 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/termios.h> +#include <rtems/termiostypes.h> +#include <rtems/assoc.h> + +extern rtems_assoc_t termios_assoc_table[]; + +int32_t rtems_termios_baud_to_number( + int termios_baud +) +{ + int baud; + + baud = rtems_assoc_local_by_remote( termios_assoc_table, termios_baud ); + if ( baud == 0 && termios_baud != 0 ) + return -1; + + return baud; +} diff --git a/cpukit/libcsupport/src/termios_baudtable.c b/cpukit/libcsupport/src/termios_baudtable.c new file mode 100644 index 0000000000..92d1c6b809 --- /dev/null +++ b/cpukit/libcsupport/src/termios_baudtable.c @@ -0,0 +1,42 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/termios.h> +#include <rtems/termiostypes.h> +#include <rtems/assoc.h> + +rtems_assoc_t termios_assoc_table[] = { + { "B0", 0, B0 }, + { "B50", 50, B50 }, + { "B75", 75, B75 }, + { "B110", 110, B110 }, + { "B134", 134, B134 }, + { "B150", 150, B150 }, + { "B200", 200, B200 }, + { "B300", 300, B300 }, + { "B600", 600, B600 }, + { "B1200", 1200, B1200 }, + { "B1800", 1800, B1800 }, + { "B2400", 2400, B2400 }, + { "B4800", 4800, B4800 }, + { "B9600", 9600, B9600 }, + { "B19200", 19200, B19200 }, + { "B38400", 38400, B38400 }, + { "B57600", 57600, B57600 }, + { "B115200", 115200, B115200 }, + { "B230400", 230400, B230400 }, + { "B460800", 460800, B460800 }, + { NULL, 0, 0 } +}; diff --git a/cpukit/libcsupport/src/termios_num2baud.c b/cpukit/libcsupport/src/termios_num2baud.c new file mode 100644 index 0000000000..3725609135 --- /dev/null +++ b/cpukit/libcsupport/src/termios_num2baud.c @@ -0,0 +1,32 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/termios.h> +#include <rtems/termiostypes.h> +#include <rtems/assoc.h> + +extern rtems_assoc_t termios_assoc_table[]; + +int rtems_termios_number_to_baud( + int32_t baud +) +{ + int termios_baud; + + termios_baud = rtems_assoc_remote_by_local( termios_assoc_table, baud ); + if ( termios_baud == 0 && baud != 0 ) + return -1; + return termios_baud; +} diff --git a/cpukit/libcsupport/src/termios_setinitialbaud.c b/cpukit/libcsupport/src/termios_setinitialbaud.c new file mode 100644 index 0000000000..282f5533de --- /dev/null +++ b/cpukit/libcsupport/src/termios_setinitialbaud.c @@ -0,0 +1,33 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/termios.h> +#include <rtems/termiostypes.h> + +int rtems_termios_set_initial_baud( + struct rtems_termios_tty *ttyp, + int32_t baud +) +{ + int cflags_baud; + + cflags_baud = rtems_termios_number_to_baud(baud); + if ( cflags_baud == -1 ) + return -1; + + ttyp->termios.c_cflag = (ttyp->termios.c_cflag & ~CBAUD) | cflags_baud; + + return 0; +} diff --git a/cpukit/libcsupport/src/termiosinitialize.c b/cpukit/libcsupport/src/termiosinitialize.c new file mode 100644 index 0000000000..b6660fe342 --- /dev/null +++ b/cpukit/libcsupport/src/termiosinitialize.c @@ -0,0 +1,54 @@ +/* + * Termios initialization routine + * + * Author: + * W. Eric Norum + * Saskatchewan Accelerator Laboratory + * University of Saskatchewan + * Saskatoon, Saskatchewan, CANADA + * eric@skatter.usask.ca + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems.h> +#include <rtems/libio.h> +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <unistd.h> + +struct rtems_termios_tty *rtems_termios_ttyHead; +struct rtems_termios_tty *rtems_termios_ttyTail; +rtems_id rtems_termios_ttyMutex; + +void +rtems_termios_initialize (void) +{ + rtems_status_code sc; + + /* + * Create the mutex semaphore for the tty list + */ + if (!rtems_termios_ttyMutex) { + sc = rtems_semaphore_create ( + rtems_build_name ('T', 'R', 'm', 'i'), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &rtems_termios_ttyMutex); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + } +} diff --git a/cpukit/libcsupport/src/truncate.c b/cpukit/libcsupport/src/truncate.c new file mode 100644 index 0000000000..7a0a98b4bd --- /dev/null +++ b/cpukit/libcsupport/src/truncate.c @@ -0,0 +1,43 @@ +/* + * 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-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> + +int truncate( + const char *path, + off_t length +) +{ + int status; + int fd; + + fd = open( path, O_WRONLY ); + if ( fd == -1 ) + return -1; + + status = ftruncate( fd, length ); + + (void) close( fd ); + + return status; +} diff --git a/cpukit/libcsupport/src/ttyname.c b/cpukit/libcsupport/src/ttyname.c new file mode 100644 index 0000000000..ed0b5cbdc1 --- /dev/null +++ b/cpukit/libcsupport/src/ttyname.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1988, 1993 + * The 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. + */ + +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_TTYNAME + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <dirent.h> +#include <termios.h> +#include <unistd.h> +#include <string.h> +#include <paths.h> +#include <_syslist.h> +#include <errno.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +static char ttyname_buf[sizeof (_PATH_DEV) + MAXNAMLEN]; + +/* + * ttyname_r() - POSIX 1003.1b 4.7.2 - Demetermine Terminal Device Name + */ +int ttyname_r( + int fd, + char *name, + size_t namesize +) +{ + struct stat sb; + struct termios tty; + struct dirent *dirp; + DIR *dp; + struct stat dsb; + char *rval; + + /* Must be a terminal. */ + if (tcgetattr (fd, &tty) < 0) + rtems_set_errno_and_return_minus_one(EBADF); + + /* Must be a character device. */ + if (fstat (fd, &sb) || !S_ISCHR (sb.st_mode)) + rtems_set_errno_and_return_minus_one(EBADF); + + if ((dp = opendir (_PATH_DEV)) == NULL) + rtems_set_errno_and_return_minus_one(EBADF); + + /* Place the base directory in the path. */ + strncpy (name, _PATH_DEV, namesize); + + for (rval = NULL; (dirp = readdir (dp)) != NULL ;) + { + if (dirp->d_ino != sb.st_ino) + continue; + strcpy (name + sizeof (_PATH_DEV) - 1, dirp->d_name); + if (stat (name, &dsb) || sb.st_dev != dsb.st_dev || + sb.st_ino != dsb.st_ino) + continue; + rval = name; + break; + } + (void) closedir (dp); + return 0; +} + +/* + * ttyname() - POSIX 1003.1b 4.7.2 - Determine Terminal Device Name + */ + +char *ttyname( + int fd +) +{ + if ( !ttyname_r( fd, ttyname_buf, sizeof(ttyname_buf) ) ) + return ttyname_buf; + return NULL; +} + +#endif diff --git a/cpukit/libcsupport/src/umask.c b/cpukit/libcsupport/src/umask.c new file mode 100644 index 0000000000..32bf79e2b9 --- /dev/null +++ b/cpukit/libcsupport/src/umask.c @@ -0,0 +1,33 @@ +/* + * umask() - POSIX 1003.1b 5.3.3 - Set File Creation Mask + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> + +#include <rtems/libio_.h> + +mode_t umask( + mode_t cmask +) +{ + mode_t old_mask; + + old_mask = rtems_filesystem_umask; + rtems_filesystem_umask = cmask; + + return old_mask; +} diff --git a/cpukit/libcsupport/src/unlink.c b/cpukit/libcsupport/src/unlink.c new file mode 100644 index 0000000000..bb28959b6d --- /dev/null +++ b/cpukit/libcsupport/src/unlink.c @@ -0,0 +1,103 @@ +/* + * unlink() - POSIX 1003.1b - 5.5.1 - Remove an existing link + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int unlink( + const char *path +) +{ + int parentpathlen; + const char *name; + rtems_filesystem_location_info_t parentloc; + rtems_filesystem_location_info_t loc; + int i; + int result; + bool free_parentloc = false; + + /* + * Get the node to be unlinked. Find the parent path first. + */ + + parentpathlen = rtems_filesystem_dirname ( path ); + + if ( parentpathlen == 0 ) + rtems_filesystem_get_start_loc( path, &i, &parentloc ); + else { + result = rtems_filesystem_evaluate_path( path, parentpathlen, + RTEMS_LIBIO_PERMS_WRITE, + &parentloc, + false ); + if ( result != 0 ) + return -1; + + free_parentloc = true; + } + + /* + * Start from the parent to find the node that should be under it. + */ + + loc = parentloc; + name = path + parentpathlen; + name += rtems_filesystem_prefix_separators( name, strlen( name ) ); + + result = rtems_filesystem_evaluate_relative_path( name , strlen( name ), + 0, &loc, false ); + if ( result != 0 ) { + if ( free_parentloc ) + rtems_filesystem_freenode( &parentloc ); + return -1; + } + + if ( (*loc.ops->node_type_h)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY ) { + rtems_filesystem_freenode( &loc ); + if ( free_parentloc ) + rtems_filesystem_freenode( &parentloc ); + rtems_set_errno_and_return_minus_one( EISDIR ); + } + + result = (*loc.ops->unlink_h)( &parentloc, &loc ); + + rtems_filesystem_freenode( &loc ); + if ( free_parentloc ) + rtems_filesystem_freenode( &parentloc ); + + return result; +} + +/* + * _unlink_r + * + * This is the Newlib dependent reentrant version of unlink(). + */ + +#if defined(RTEMS_NEWLIB) + +#include <reent.h> + +int _unlink_r( + struct _reent *ptr __attribute__((unused)), + const char *path +) +{ + return unlink( path ); +} +#endif diff --git a/cpukit/libcsupport/src/unmount.c b/cpukit/libcsupport/src/unmount.c new file mode 100644 index 0000000000..a2c67f7098 --- /dev/null +++ b/cpukit/libcsupport/src/unmount.c @@ -0,0 +1,162 @@ +/* + * 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-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> +#include <rtems/chain.h> + +static bool is_fs_below_mount_point( + const rtems_filesystem_mount_table_entry_t *mt_entry, + void *arg +) +{ + return arg == mt_entry->mt_point_node.mt_entry; +} + +/* + * unmount + * + * This routine will attempt to unmount the file system that has been + * is mounted a path. If the operation is successful, 0 will + * be returned to the calling routine. Otherwise, 1 will be returned. + */ + +int unmount( + const char *path +) +{ + rtems_filesystem_location_info_t loc; + rtems_filesystem_location_info_t *fs_root_loc; + rtems_filesystem_location_info_t *fs_mount_loc; + rtems_filesystem_mount_table_entry_t *mt_entry; + + /* + * Get + * The root node of the mounted filesytem. + * The node for the directory that the fileystem is mounted on. + * The mount entry that is being refered to. + */ + + if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x0, &loc, true ) ) + return -1; + + mt_entry = loc.mt_entry; + fs_mount_loc = &mt_entry->mt_point_node; + fs_root_loc = &mt_entry->mt_fs_root; + + /* + * Verify this is the root node for the file system to be unmounted. + */ + + if ( fs_root_loc->node_access != loc.node_access ){ + rtems_filesystem_freenode( &loc ); + rtems_set_errno_and_return_minus_one( EACCES ); + } + + /* + * Free the loc node and just use the nodes from the mt_entry . + */ + + rtems_filesystem_freenode( &loc ); + + /* + * Verify the current node is not in this filesystem. + * XXX - Joel I have a question here wasn't code added + * that made the current node thread based instead + * of system based? I thought it was but it doesn't + * look like it in this version. + */ + + if ( rtems_filesystem_current.mt_entry == mt_entry ) + rtems_set_errno_and_return_minus_one( EBUSY ); + + /* + * Verify there are no file systems below the path specified + */ + + if ( rtems_filesystem_mount_iterate( is_fs_below_mount_point, + fs_root_loc->mt_entry ) ) + rtems_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( mt_entry ) == 1 ) + rtems_set_errno_and_return_minus_one( EBUSY ); + + /* + * Allow the file system being unmounted on to do its cleanup. + * If it fails it will set the errno to the approprate value + * and the fileystem will not be modified. + */ + + if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 ) + return -1; + + /* + * Allow the mounted filesystem to unmark the use of the root node. + * + * Run the unmount function for the subordinate file system. + * + * If we fail to unmount the filesystem remount it on the base filesystems + * directory node. + * + * NOTE: Fatal error is called in a case which should never happen + * This was response was questionable but the best we could + * come up with. + */ + + if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0){ + if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 ) + rtems_fatal_error_occurred( 0 ); + return -1; + } + + /* + * Extract the mount table entry from the chain + */ + + rtems_libio_lock(); + rtems_chain_extract( &mt_entry->Node ); + rtems_libio_unlock(); + + /* + * Free the memory node that was allocated in mount + * Free the memory associated with the extracted mount table entry. + */ + + rtems_filesystem_freenode( fs_mount_loc ); + free( mt_entry ); + + return 0; +} diff --git a/cpukit/libcsupport/src/utime.c b/cpukit/libcsupport/src/utime.c new file mode 100644 index 0000000000..25bcb0761b --- /dev/null +++ b/cpukit/libcsupport/src/utime.c @@ -0,0 +1,47 @@ +/* + * utime() - POSIX 1003.1b 5.5.6 - Set File Access and Modification Times + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <utime.h> +#include <errno.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +int utime( + const char *path, + const struct utimbuf *times +) +{ + rtems_filesystem_location_info_t temp_loc; + int result; + struct utimbuf now; + + if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x00, &temp_loc, true ) ) + return -1; + + if ( times == NULL ) { + now.actime = now.modtime = time( NULL ); + times = &now; + } + + result = (*temp_loc.ops->utime_h)( &temp_loc, times->actime, times->modtime ); + + rtems_filesystem_freenode( &temp_loc ); + + return result; +} diff --git a/cpukit/libcsupport/src/utimes.c b/cpukit/libcsupport/src/utimes.c new file mode 100644 index 0000000000..b2070a9431 --- /dev/null +++ b/cpukit/libcsupport/src/utimes.c @@ -0,0 +1,33 @@ +/* + * Written by: Vinu Rajashekhar <vinutheraj@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <utime.h> +#include <sys/time.h> + +int utimes( + const char *path, + const struct timeval times[2] +) +{ + struct utimbuf timeinsecs; + + if ( times == NULL ) + return utime( path, NULL ); + + timeinsecs.actime = (time_t) times[0].tv_sec; + timeinsecs.modtime = (time_t) times[1].tv_sec; + + return utime( path, &timeinsecs ); +} diff --git a/cpukit/libcsupport/src/utsname.c b/cpukit/libcsupport/src/utsname.c new file mode 100644 index 0000000000..564a762942 --- /dev/null +++ b/cpukit/libcsupport/src/utsname.c @@ -0,0 +1,49 @@ +/* + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <sys/utsname.h> +#include <inttypes.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/seterr.h> + +/*PAGE + * + * 4.4.1 Get System Name, P1003.1b-1993, p. 90 + */ + +int uname( + struct utsname *name +) +{ + /* XXX: Here is what Solaris returns... + sysname = SunOS + nodename = node_name + release = 5.3 + version = Generic_101318-12 + machine = sun4m + */ + + if ( !name ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + strncpy( name->sysname, "RTEMS", sizeof(name->sysname) ); + + snprintf( name->nodename, sizeof(name->nodename), "Node %" PRId16, _Objects_Local_node ); + + strncpy( name->release, RTEMS_VERSION, sizeof(name->release) ); + + strncpy( name->version, "", sizeof(name->version) ); + + snprintf( name->machine, sizeof(name->machine), "%s/%s", CPU_NAME, CPU_MODEL_NAME ); + + return 0; +} diff --git a/cpukit/libcsupport/src/vprintk.c b/cpukit/libcsupport/src/vprintk.c new file mode 100644 index 0000000000..852b5e302f --- /dev/null +++ b/cpukit/libcsupport/src/vprintk.c @@ -0,0 +1,191 @@ +/* + * (C) Copyright 1997 - + * - NavIST Group - Real-Time Distributed Systems and Industrial Automation + * + * http://pandora.ist.utl.pt + * + * Instituto Superior Tecnico * Lisboa * PORTUGAL + * + * Disclaimer: + * + * This file is provided "AS IS" without warranty of any kind, either + * expressed or implied. + * + * This code is based on code by: Jose Rufino - IST + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> +#include <stdio.h> +#include <stdbool.h> +#include <rtems/bspIo.h> + +static void printNum( + long num, + unsigned base, + bool sign, + unsigned maxwidth, + char lead +); + +/* + * vprintk + * + * A simplified version of printf intended for use when the + * console is not yet initialized or in ISR's. + * + * Arguments: + * as in printf: fmt - format string, ... - unnamed arguments. + */ +void vprintk( + const char *fmt, + va_list ap +) +{ + for (; *fmt != '\0'; fmt++) { + unsigned base = 0; + unsigned width = 0; + bool lflag = false; + bool minus = false; + bool sign = false; + char lead = ' '; + char c; + + if (*fmt != '%') { + BSP_output_char(*fmt); + continue; + } + fmt++; + if (*fmt == '0' ) { + lead = '0'; + fmt++; + } + if (*fmt == '-' ) { + minus = true; + fmt++; + } + while (*fmt >= '0' && *fmt <= '9' ) { + width *= 10; + width += ((unsigned) *fmt - '0'); + fmt++; + } + + if ((c = *fmt) == 'l') { + lflag = true; + c = *++fmt; + } + if ( c == 'c' ) { + /* need a cast here since va_arg() only takes fully promoted types */ + char chr = (char) va_arg(ap, int); + BSP_output_char(chr); + continue; + } + if ( c == 's' ) { + unsigned i, len; + char *s, *str; + + str = va_arg(ap, char *); + + if ( str == NULL ) { + str = ""; + } + + /* calculate length of string */ + for ( len=0, s=str ; *s ; len++, s++ ) + ; + + /* leading spaces */ + if ( !minus ) + for ( i=len ; i<width ; i++ ) + BSP_output_char(' '); + + /* no width option */ + if (width == 0) { + width = len; + } + + /* output the string */ + for ( i=0 ; i<width && *str ; str++ ) + BSP_output_char(*str); + + /* trailing spaces */ + if ( minus ) + for ( i=len ; i<width ; i++ ) + BSP_output_char(' '); + + continue; + } + + /* must be a numeric format or something unsupported */ + if ( c == 'o' || c == 'O' ) { + base = 8; sign = false; + } else if ( c == 'i' || c == 'I' || + c == 'd' || c == 'D' ) { + base = 10; sign = true; + } else if ( c == 'u' || c == 'U' ) { + base = 10; sign = false; + } else if ( c == 'x' || c == 'X' ) { + base = 16; sign = false; + } else if ( c == 'p' ) { + base = 16; sign = false; lflag = true; + } else { + BSP_output_char(c); + continue; + } + + printNum( + lflag ? va_arg(ap, long) : (long) va_arg(ap, int), + base, + sign, + width, + lead + ); + } +} + +/* + * printNum - print number in a given base. + * Arguments + * num - number to print + * base - base used to print the number. + */ +static void printNum( + long num, + unsigned base, + bool sign, + unsigned maxwidth, + char lead +) +{ + unsigned long unsigned_num; + unsigned long n; + unsigned count; + char toPrint[20]; + + if ( sign && (num < 0) ) { + BSP_output_char('-'); + unsigned_num = (unsigned long) -num; + if (maxwidth) maxwidth--; + } else { + unsigned_num = (unsigned long) num; + } + + count = 0; + while ((n = unsigned_num / base) > 0) { + toPrint[count++] = (char) (unsigned_num - (n * base)); + unsigned_num = n; + } + toPrint[count++] = (char) unsigned_num; + + for (n=maxwidth ; n > count; n-- ) + BSP_output_char(lead); + + for (n = 0; n < count; n++) { + BSP_output_char("0123456789ABCDEF"[(int)(toPrint[count-(n+1)])]); + } +} diff --git a/cpukit/libcsupport/src/write.c b/cpukit/libcsupport/src/write.c new file mode 100644 index 0000000000..b723f426b6 --- /dev/null +++ b/cpukit/libcsupport/src/write.c @@ -0,0 +1,53 @@ +/* + * write() - POSIX 1003.1b 6.4.2 - Write to a File + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +/* + * write + * + * This routine writes count bytes from from buffer pointed to by buffer + * to the file associated with the open file descriptor, fildes. + */ + +ssize_t write( + int fd, + const void *buffer, + size_t count +) +{ + ssize_t rc; + rtems_libio_t *iop; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open( iop ); + rtems_libio_check_buffer( buffer ); + rtems_libio_check_count( count ); + rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); + + /* + * Now process the write() request. + */ + rc = (*iop->pathinfo.handlers->write_h)( iop, buffer, count ); + + if ( rc > 0 ) + iop->offset += rc; + + return rc; +} diff --git a/cpukit/libcsupport/src/write_r.c b/cpukit/libcsupport/src/write_r.c new file mode 100644 index 0000000000..ad142a7364 --- /dev/null +++ b/cpukit/libcsupport/src/write_r.c @@ -0,0 +1,40 @@ +/* + * write_r() - POSIX 1003.1b 6.4.2 - Write to a File + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +/* + * _write_r + * + * This is the Newlib dependent reentrant version of write(). + */ + +#if defined(RTEMS_NEWLIB) + +#include <reent.h> + +_ssize_t _write_r( + struct _reent *ptr __attribute__((unused)), + int fd, + const void *buf, + size_t nbytes +) +{ + return write( fd, buf, nbytes ); +} +#endif diff --git a/cpukit/libcsupport/src/writev.c b/cpukit/libcsupport/src/writev.c new file mode 100644 index 0000000000..380e325365 --- /dev/null +++ b/cpukit/libcsupport/src/writev.c @@ -0,0 +1,128 @@ +/* + * writev() - POSIX 1003.1 - Read a Vector + * + * OpenGroup URL: + * + * http://www.opengroup.org/onlinepubs/009695399/functions/writev.html + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/uio.h> + +#include <rtems/libio_.h> +#include <rtems/seterr.h> + +ssize_t writev( + int fd, + const struct iovec *iov, + int iovcnt +) +{ + ssize_t total; + int v; + int bytes; + rtems_libio_t *iop; + ssize_t old; + bool all_zeros; + + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_is_open( iop ); + rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); + + /* + * Argument validation on IO vector + */ + if ( !iov ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( iovcnt <= 0 ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( iovcnt > IOV_MAX ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * OpenGroup says that you are supposed to return EINVAL if the + * sum of the iov_len values in the iov array would overflow a + * ssize_t. + * + * Also we would like to ensure that no IO is performed if there + * are obvious errors in the iovec. So this extra loop ensures + * that we do not do anything if there is an argument error. + * + * In addition,the OpenGroup specification says that if all the + * iov_len entries are zero, then the call has no effect. So + * this loop does that check as well and sets "all-zero" appropriately. + * The variable "all_zero" is used as an early exit point before + * entering the write loop. + */ + all_zeros = true; + for ( old=0, total=0, v=0 ; v < iovcnt ; v++ ) { + + /* + * iov[v].iov_len cannot be less than 0 because size_t is unsigned. + * So we only check for zero. + */ + if ( iov[v].iov_base == 0 ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( iov[v].iov_len ) + all_zeros = false; + + /* check for wrap */ + old = total; + total += iov[v].iov_len; + if ( total < old || total > SSIZE_MAX ) + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + /* + * A writev with all zeros is supposed to have no effect per OpenGroup. + */ + if ( all_zeros == true ) { + return 0; + } + + /* + * Now process the writev(). + */ + for ( total=0, v=0 ; v < iovcnt ; v++ ) { + /* all zero lengths has no effect */ + if ( iov[v].iov_len == 0 ) + continue; + + bytes = (*iop->pathinfo.handlers->write_h)( + iop, + iov[v].iov_base, + iov[v].iov_len + ); + + if ( bytes < 0 ) + return -1; + + if ( bytes > 0 ) { + iop->offset += bytes; + total += bytes; + } + + if (bytes != iov[ v ].iov_len) + break; + } + + return total; +} + |