forked from Imagelibrary/rtems
2008-10-14 Wei Shen <cquark@gmail.com>
* Makefile.am, preinstall.am, libcsupport/src/mknod.c, libcsupport/src/open.c, libcsupport/src/pipe.c, libfs/Makefile.am, libfs/preinstall.am, libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_creat.c, libfs/src/imfs/imfs_debug.c, libfs/src/imfs/imfs_eval.c, libfs/src/imfs/imfs_initsupp.c, libfs/src/imfs/imfs_mknod.c, libfs/src/imfs/imfs_stat.c, libfs/src/imfs/memfile.c: Initial commit of POSIX pipe support. * libfs/src/imfs/imfs_fifo.c, libfs/src/pipe/fifo.c, libfs/src/pipe/pipe.c, libfs/src/pipe/pipe.h: New files.
This commit is contained in:
@@ -1,3 +1,15 @@
|
||||
2008-10-14 Wei Shen <cquark@gmail.com>
|
||||
|
||||
* Makefile.am, preinstall.am, libcsupport/src/mknod.c,
|
||||
libcsupport/src/open.c, libcsupport/src/pipe.c, libfs/Makefile.am,
|
||||
libfs/preinstall.am, libfs/src/imfs/imfs.h,
|
||||
libfs/src/imfs/imfs_creat.c, libfs/src/imfs/imfs_debug.c,
|
||||
libfs/src/imfs/imfs_eval.c, libfs/src/imfs/imfs_initsupp.c,
|
||||
libfs/src/imfs/imfs_mknod.c, libfs/src/imfs/imfs_stat.c,
|
||||
libfs/src/imfs/memfile.c: Initial commit of POSIX pipe support.
|
||||
* libfs/src/imfs/imfs_fifo.c, libfs/src/pipe/fifo.c,
|
||||
libfs/src/pipe/pipe.c, libfs/src/pipe/pipe.h: New files.
|
||||
|
||||
2008-10-03 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
* libcsupport/src/printk.c: Addresses can be larger than integers
|
||||
|
||||
@@ -79,6 +79,9 @@ include_rtems_HEADERS += include/rtems/irq-extension.h
|
||||
## libfs
|
||||
include_rtems_HEADERS += libfs/src/imfs/imfs.h
|
||||
|
||||
## POSIX FIFO/pipe
|
||||
include_rtems_HEADERS += libfs/src/pipe/pipe.h
|
||||
|
||||
## devfs
|
||||
include_rtems_HEADERS += libfs/src/devfs/devfs.h
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@ int mknod(
|
||||
if ( !(mode & (S_IFREG|S_IFCHR|S_IFBLK|S_IFIFO) ) )
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
if ( S_ISFIFO(mode) )
|
||||
rtems_set_errno_and_return_minus_one( ENOTSUP );
|
||||
|
||||
rtems_filesystem_get_start_loc( pathname, &i, &temp_loc );
|
||||
|
||||
if ( !temp_loc.ops->evalformake_h ) {
|
||||
|
||||
@@ -164,8 +164,10 @@ int open(
|
||||
}
|
||||
|
||||
rc = (*iop->handlers->open_h)( iop, pathname, flags, mode );
|
||||
if ( rc )
|
||||
if ( rc ) {
|
||||
rc = errno;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Optionally truncate the file.
|
||||
|
||||
@@ -16,11 +16,17 @@
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
extern int pipe_create(int filsdes[2]);
|
||||
|
||||
int pipe(
|
||||
int filsdes[2]
|
||||
)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
if (filsdes == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
return pipe_create(filsdes);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ libimfs_a_SOURCES += src/imfs/imfs_chown.c src/imfs/imfs_config.c \
|
||||
src/imfs/imfs_mknod.c src/imfs/imfs_mount.c src/imfs/imfs_fchmod.c \
|
||||
src/imfs/imfs_unlink.c src/imfs/imfs_unmount.c src/imfs/imfs_utime.c \
|
||||
src/imfs/imfs_ntype.c src/imfs/imfs_stat.c src/imfs/imfs_getchild.c \
|
||||
src/imfs/memfile.c src/imfs/deviceio.c \
|
||||
src/imfs/memfile.c src/imfs/imfs_fifo.c src/imfs/deviceio.c \
|
||||
src/imfs/imfs_handlers_device.c src/imfs/imfs_handlers_directory.c \
|
||||
src/imfs/imfs_handlers_link.c src/imfs/imfs_handlers_memfile.c \
|
||||
src/imfs/imfs_debug.c src/imfs/imfs_rmnod.c src/imfs/imfs_symlink.c \
|
||||
@@ -43,6 +43,11 @@ libimfs_a_SOURCES += src/imfs/imfs_chown.c src/imfs/imfs_config.c \
|
||||
src/devfs/devfs.h
|
||||
endif
|
||||
|
||||
# POSIX FIFO/pipe
|
||||
if ! UNIX
|
||||
libimfs_a_SOURCES += src/pipe/fifo.c src/pipe/pipe.c src/pipe/pipe.h
|
||||
endif
|
||||
|
||||
# dosfs
|
||||
|
||||
if LIBDOSFS
|
||||
|
||||
@@ -5,3 +5,5 @@ $(srcdir)/preinstall.am: Makefile.am
|
||||
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
|
||||
endif
|
||||
|
||||
if ! UNIX
|
||||
endif
|
||||
|
||||
@@ -25,6 +25,8 @@ extern "C" {
|
||||
#include <limits.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include <rtems/pipe.h>
|
||||
|
||||
/*
|
||||
* File name macros
|
||||
*/
|
||||
@@ -59,6 +61,10 @@ typedef struct {
|
||||
char *name;
|
||||
} IMFS_sym_link_t;
|
||||
|
||||
typedef struct {
|
||||
pipe_control_t *pipe;
|
||||
} IMFS_fifo_t;
|
||||
|
||||
/*
|
||||
* IMFS "memfile" information
|
||||
*
|
||||
@@ -84,7 +90,7 @@ typedef struct {
|
||||
extern int imfs_rq_memfile_bytes_per_block;
|
||||
extern int imfs_memfile_bytes_per_block;
|
||||
|
||||
#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
|
||||
#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
|
||||
#define IMFS_MEMFILE_BLOCK_SLOTS \
|
||||
(IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
|
||||
|
||||
@@ -135,8 +141,9 @@ typedef struct {
|
||||
#define IMFS_SYM_LINK RTEMS_FILESYSTEM_SYM_LINK
|
||||
#define IMFS_MEMORY_FILE RTEMS_FILESYSTEM_MEMORY_FILE
|
||||
#define IMFS_LINEAR_FILE (IMFS_MEMORY_FILE + 1)
|
||||
#define IMFS_FIFO (IMFS_LINEAR_FILE + 1)
|
||||
|
||||
#define IMFS_NUMBER_OF_TYPES (IMFS_LINEAR_FILE + 1)
|
||||
#define IMFS_NUMBER_OF_TYPES (IMFS_FIFO + 1)
|
||||
|
||||
typedef union {
|
||||
IMFS_directory_t directory;
|
||||
@@ -145,6 +152,7 @@ typedef union {
|
||||
IMFS_sym_link_t sym_link;
|
||||
IMFS_memfile_t file;
|
||||
IMFS_linearfile_t linearfile;
|
||||
IMFS_fifo_t fifo;
|
||||
} IMFS_types_union;
|
||||
|
||||
/*
|
||||
@@ -196,12 +204,12 @@ struct IMFS_jnode_tt {
|
||||
_jnode->stat_ctime = (time_t) tv.tv_sec; \
|
||||
} while (0)
|
||||
|
||||
#define IMFS_atime_mtime_update( _jnode ) \
|
||||
#define IMFS_mtime_ctime_update( _jnode ) \
|
||||
do { \
|
||||
struct timeval tv; \
|
||||
gettimeofday( &tv, 0 ); \
|
||||
_jnode->stat_mtime = (time_t) tv.tv_sec; \
|
||||
_jnode->stat_atime = (time_t) tv.tv_sec; \
|
||||
_jnode->stat_ctime = (time_t) tv.tv_sec; \
|
||||
} while (0)
|
||||
|
||||
typedef struct {
|
||||
@@ -230,6 +238,7 @@ extern const rtems_filesystem_file_handlers_r IMFS_directory_handlers;
|
||||
extern const rtems_filesystem_file_handlers_r IMFS_device_handlers;
|
||||
extern const rtems_filesystem_file_handlers_r IMFS_link_handlers;
|
||||
extern const rtems_filesystem_file_handlers_r IMFS_memfile_handlers;
|
||||
extern const rtems_filesystem_file_handlers_r IMFS_fifo_handlers;
|
||||
extern const rtems_filesystem_operations_table IMFS_ops;
|
||||
extern const rtems_filesystem_operations_table miniIMFS_ops;
|
||||
extern const rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS;
|
||||
|
||||
@@ -112,6 +112,10 @@ IMFS_jnode_t *IMFS_create_node(
|
||||
node->info.file.triply_indirect = 0;
|
||||
break;
|
||||
|
||||
case IMFS_FIFO:
|
||||
node->info.fifo.pipe = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
@@ -98,6 +98,11 @@ void IMFS_print_jnode(
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
case IMFS_FIFO:
|
||||
fprintf(stdout, " FIFO not printed\n" );
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stdout, " bad type %d\n", the_jnode->type );
|
||||
assert(0);
|
||||
|
||||
@@ -57,6 +57,9 @@ int IMFS_Set_handlers(
|
||||
case IMFS_MEMORY_FILE:
|
||||
loc->handlers = fs_info->memfile_handlers;
|
||||
break;
|
||||
case IMFS_FIFO:
|
||||
loc->handlers = &IMFS_fifo_handlers;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
151
cpukit/libfs/src/imfs/imfs_fifo.c
Normal file
151
cpukit/libfs/src/imfs/imfs_fifo.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* imfs_fifo.c: FIFO support for IMFS
|
||||
*
|
||||
* Author: Wei Shen <cquark@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 <stdlib.h>
|
||||
#include <rtems/libio_.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
#include "imfs.h"
|
||||
|
||||
#define JNODE2PIPE(_jnode) ( (_jnode)->info.fifo.pipe )
|
||||
|
||||
#define LIBIO2PIPE(_iop) ( JNODE2PIPE((IMFS_jnode_t *)(_iop)->file_info) )
|
||||
|
||||
/* Set errno and return -1 if error, else return _err */
|
||||
#define IMFS_FIFO_RETURN(_err) \
|
||||
do { \
|
||||
if (_err < 0) \
|
||||
rtems_set_errno_and_return_minus_one(-_err); \
|
||||
return _err; \
|
||||
} while (0)
|
||||
|
||||
int IMFS_fifo_open(
|
||||
rtems_libio_t *iop,
|
||||
const char *pathname,
|
||||
uint32_t flag,
|
||||
uint32_t mode
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *jnode = iop->file_info;
|
||||
|
||||
int err = fifo_open(&JNODE2PIPE(jnode), iop);
|
||||
IMFS_FIFO_RETURN(err);
|
||||
}
|
||||
|
||||
int IMFS_fifo_close(
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *jnode = iop->file_info;
|
||||
|
||||
int err = pipe_release(&JNODE2PIPE(jnode), iop);
|
||||
|
||||
if (! err) {
|
||||
iop->flags &= ~LIBIO_FLAGS_OPEN;
|
||||
/* Free jnode if file is already unlinked and no one opens it */
|
||||
if (! rtems_libio_is_file_open(jnode) && jnode->st_nlink < 1)
|
||||
free(jnode);
|
||||
}
|
||||
|
||||
IMFS_FIFO_RETURN(err);
|
||||
}
|
||||
|
||||
ssize_t IMFS_fifo_read(
|
||||
rtems_libio_t *iop,
|
||||
void *buffer,
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *jnode = iop->file_info;
|
||||
|
||||
int err = pipe_read(JNODE2PIPE(jnode), buffer, count, iop);
|
||||
if (err > 0)
|
||||
IMFS_update_atime(jnode);
|
||||
|
||||
IMFS_FIFO_RETURN(err);
|
||||
}
|
||||
|
||||
ssize_t IMFS_fifo_write(
|
||||
rtems_libio_t *iop,
|
||||
const void *buffer,
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
IMFS_jnode_t *jnode = iop->file_info;
|
||||
|
||||
int err = pipe_write(JNODE2PIPE(jnode), buffer, count, iop);
|
||||
if (err > 0) {
|
||||
IMFS_mtime_ctime_update(jnode);
|
||||
}
|
||||
|
||||
IMFS_FIFO_RETURN(err);
|
||||
}
|
||||
|
||||
int IMFS_fifo_ioctl(
|
||||
rtems_libio_t *iop,
|
||||
uint32_t command,
|
||||
void *buffer
|
||||
)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (command == FIONBIO) {
|
||||
if (buffer == NULL)
|
||||
err = -EFAULT;
|
||||
else {
|
||||
if (*(int *)buffer)
|
||||
iop->flags |= LIBIO_FLAGS_NO_DELAY;
|
||||
else
|
||||
iop->flags &= ~LIBIO_FLAGS_NO_DELAY;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
err = pipe_ioctl(LIBIO2PIPE(iop), command, buffer, iop);
|
||||
|
||||
IMFS_FIFO_RETURN(err);
|
||||
}
|
||||
|
||||
int IMFS_fifo_lseek(
|
||||
rtems_libio_t *iop,
|
||||
off_t offset,
|
||||
int whence
|
||||
)
|
||||
{
|
||||
int err = pipe_lseek(LIBIO2PIPE(iop), offset, whence, iop);
|
||||
IMFS_FIFO_RETURN(err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler table for IMFS FIFO nodes
|
||||
*/
|
||||
|
||||
const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = {
|
||||
IMFS_fifo_open,
|
||||
IMFS_fifo_close,
|
||||
IMFS_fifo_read,
|
||||
IMFS_fifo_write,
|
||||
IMFS_fifo_ioctl,
|
||||
IMFS_fifo_lseek,
|
||||
IMFS_stat,
|
||||
IMFS_fchmod,
|
||||
NULL, /* ftruncate */
|
||||
NULL, /* fpathconf */
|
||||
NULL, /* fsync */
|
||||
NULL, /* fdatasync */
|
||||
IMFS_fcntl,
|
||||
IMFS_rmnod,
|
||||
};
|
||||
@@ -47,17 +47,17 @@ static int IMFS_determine_bytes_per_block(
|
||||
* check, whether requested bytes per block is valid
|
||||
*/
|
||||
for (bit_mask = 16;
|
||||
!is_valid && (bit_mask <= 512);
|
||||
!is_valid && (bit_mask <= 512);
|
||||
bit_mask <<= 1) {
|
||||
if (bit_mask == requested_bytes_per_block) {
|
||||
is_valid = true;
|
||||
}
|
||||
}
|
||||
*dest_bytes_per_block = ((is_valid)
|
||||
*dest_bytes_per_block = ((is_valid)
|
||||
? requested_bytes_per_block
|
||||
: default_bytes_per_block);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ int IMFS_initialize_support(
|
||||
IMFS_determine_bytes_per_block(&imfs_memfile_bytes_per_block,
|
||||
imfs_rq_memfile_bytes_per_block,
|
||||
IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK);
|
||||
|
||||
|
||||
/*
|
||||
* Create the root node
|
||||
*
|
||||
@@ -121,5 +121,8 @@ int IMFS_initialize_support(
|
||||
jnode = temp_mt_entry->mt_fs_root.node_access;
|
||||
jnode->st_ino = fs_info->ino_count;
|
||||
|
||||
/* Initialize POSIX FIFO/pipe module */
|
||||
rtems_pipe_initialize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,10 @@ int IMFS_mknod(
|
||||
else if ( S_ISBLK(mode) || S_ISCHR(mode) ) {
|
||||
type = IMFS_DEVICE;
|
||||
rtems_filesystem_split_dev_t( dev, info.device.major, info.device.minor );
|
||||
} else {
|
||||
}
|
||||
else if (S_ISFIFO(mode))
|
||||
type = IMFS_FIFO;
|
||||
else {
|
||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,10 @@ int IMFS_stat(
|
||||
buf->st_size = 0;
|
||||
break;
|
||||
|
||||
case IMFS_FIFO:
|
||||
buf->st_size = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
rtems_set_errno_and_return_minus_one( ENOTSUP );
|
||||
break;
|
||||
|
||||
@@ -844,7 +844,7 @@ fprintf(stdout, "write %d in %d: %*s\n", to_copy, block, to_copy, src );
|
||||
copied += to_copy;
|
||||
}
|
||||
|
||||
IMFS_atime_mtime_update( the_jnode );
|
||||
IMFS_mtime_ctime_update( the_jnode );
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
551
cpukit/libfs/src/pipe/fifo.c
Normal file
551
cpukit/libfs/src/pipe/fifo.c
Normal file
@@ -0,0 +1,551 @@
|
||||
/*
|
||||
* fifo.c: POSIX FIFO/pipe for RTEMS
|
||||
*
|
||||
* Author: Wei Shen <cquark@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$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "pipe.h"
|
||||
|
||||
|
||||
#define MIN(a, b) ((a) < (b)? (a): (b))
|
||||
|
||||
#define LIBIO_ACCMODE(_iop) ((_iop)->flags & LIBIO_FLAGS_READ_WRITE)
|
||||
#define LIBIO_NODELAY(_iop) ((_iop)->flags & LIBIO_FLAGS_NO_DELAY)
|
||||
|
||||
extern uint16_t rtems_pipe_no;
|
||||
static rtems_id rtems_pipe_semaphore = 0;
|
||||
|
||||
|
||||
#define PIPE_EMPTY(_pipe) (_pipe->Length == 0)
|
||||
#define PIPE_FULL(_pipe) (_pipe->Length == _pipe->Size)
|
||||
#define PIPE_SPACE(_pipe) (_pipe->Size - _pipe->Length)
|
||||
#define PIPE_WSTART(_pipe) ((_pipe->Start + _pipe->Length) % _pipe->Size)
|
||||
|
||||
#define PIPE_LOCK(_pipe) \
|
||||
( rtems_semaphore_obtain(_pipe->Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT) \
|
||||
== RTEMS_SUCCESSFUL )
|
||||
|
||||
#define PIPE_UNLOCK(_pipe) rtems_semaphore_release(_pipe->Semaphore)
|
||||
|
||||
#define PIPE_READWAIT(_pipe) \
|
||||
( rtems_barrier_wait(_pipe->readBarrier, RTEMS_NO_TIMEOUT) \
|
||||
== RTEMS_SUCCESSFUL)
|
||||
|
||||
#define PIPE_WRITEWAIT(_pipe) \
|
||||
( rtems_barrier_wait(_pipe->writeBarrier, RTEMS_NO_TIMEOUT) \
|
||||
== RTEMS_SUCCESSFUL)
|
||||
|
||||
#define PIPE_WAKEUPREADERS(_pipe) \
|
||||
do {uint32_t n; rtems_barrier_release(_pipe->readBarrier, &n); } while(0)
|
||||
|
||||
#define PIPE_WAKEUPWRITERS(_pipe) \
|
||||
do {uint32_t n; rtems_barrier_release(_pipe->writeBarrier, &n); } while(0)
|
||||
|
||||
|
||||
#ifdef RTEMS_POSIX_API
|
||||
|
||||
#include <rtems/rtems/barrier.inl>
|
||||
#include <rtems/score/thread.inl>
|
||||
|
||||
/* Set barriers to be interruptible by signals. */
|
||||
static void pipe_interruptible(pipe_control_t *pipe)
|
||||
{
|
||||
Objects_Locations location;
|
||||
|
||||
_Barrier_Get(pipe->readBarrier, &location)->Barrier.Wait_queue.state
|
||||
|= STATES_INTERRUPTIBLE_BY_SIGNAL;
|
||||
_Thread_Enable_dispatch();
|
||||
_Barrier_Get(pipe->writeBarrier, &location)->Barrier.Wait_queue.state
|
||||
|= STATES_INTERRUPTIBLE_BY_SIGNAL;
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Alloc pipe control structure, buffer, and resources.
|
||||
* Called with rtems_pipe_semaphore held.
|
||||
*/
|
||||
static int pipe_alloc(
|
||||
pipe_control_t **pipep
|
||||
)
|
||||
{
|
||||
static char c = 'a';
|
||||
pipe_control_t *pipe;
|
||||
int err = -ENOMEM;
|
||||
|
||||
pipe = malloc(sizeof(pipe_control_t));
|
||||
if (pipe == NULL)
|
||||
return err;
|
||||
memset(pipe, 0, sizeof(pipe_control_t));
|
||||
|
||||
pipe->Size = PIPE_BUF;
|
||||
pipe->Buffer = malloc(pipe->Size);
|
||||
if (! pipe->Buffer)
|
||||
goto err_buf;
|
||||
|
||||
err = -EINTR;
|
||||
if (rtems_barrier_create(
|
||||
rtems_build_name ('P', 'I', 'r', c),
|
||||
RTEMS_BARRIER_MANUAL_RELEASE, 0,
|
||||
&pipe->readBarrier) != RTEMS_SUCCESSFUL)
|
||||
goto err_rbar;
|
||||
if (rtems_barrier_create(
|
||||
rtems_build_name ('P', 'I', 'w', c),
|
||||
RTEMS_BARRIER_MANUAL_RELEASE, 0,
|
||||
&pipe->writeBarrier) != RTEMS_SUCCESSFUL)
|
||||
goto err_wbar;
|
||||
if (rtems_semaphore_create(
|
||||
rtems_build_name ('P', 'I', 's', c), 1,
|
||||
RTEMS_BINARY_SEMAPHORE | RTEMS_FIFO,
|
||||
RTEMS_NO_PRIORITY, &pipe->Semaphore) != RTEMS_SUCCESSFUL)
|
||||
goto err_sem;
|
||||
|
||||
#ifdef RTEMS_POSIX_API
|
||||
pipe_interruptible(pipe);
|
||||
#endif
|
||||
|
||||
*pipep = pipe;
|
||||
if (c ++ == 'z')
|
||||
c = 'a';
|
||||
return 0;
|
||||
|
||||
err_sem:
|
||||
rtems_barrier_delete(pipe->writeBarrier);
|
||||
err_wbar:
|
||||
rtems_barrier_delete(pipe->readBarrier);
|
||||
err_rbar:
|
||||
free(pipe->Buffer);
|
||||
err_buf:
|
||||
free(pipe);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Called with rtems_pipe_semaphore held. */
|
||||
static inline void pipe_free(
|
||||
pipe_control_t *pipe
|
||||
)
|
||||
{
|
||||
rtems_barrier_delete(pipe->readBarrier);
|
||||
rtems_barrier_delete(pipe->writeBarrier);
|
||||
rtems_semaphore_delete(pipe->Semaphore);
|
||||
free(pipe->Buffer);
|
||||
free(pipe);
|
||||
}
|
||||
|
||||
/*
|
||||
* If called with *pipep = NULL, pipe_new will call pipe_alloc to allocate a
|
||||
* pipe control structure and set *pipep to its address.
|
||||
* pipe is locked, when pipe_new returns with no error.
|
||||
*/
|
||||
static int pipe_new(
|
||||
pipe_control_t **pipep
|
||||
)
|
||||
{
|
||||
pipe_control_t *pipe;
|
||||
int err = 0;
|
||||
|
||||
if (rtems_semaphore_obtain(rtems_pipe_semaphore,
|
||||
RTEMS_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL)
|
||||
return -EINTR;
|
||||
|
||||
pipe = *pipep;
|
||||
if (pipe == NULL) {
|
||||
err = pipe_alloc(&pipe);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (! PIPE_LOCK(pipe))
|
||||
err = -EINTR;
|
||||
|
||||
if (*pipep == NULL) {
|
||||
if (err)
|
||||
pipe_free(pipe);
|
||||
else
|
||||
*pipep = pipe;
|
||||
}
|
||||
|
||||
out:
|
||||
rtems_semaphore_release(rtems_pipe_semaphore);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface to file system close.
|
||||
*
|
||||
* *pipep points to pipe control structure. When the last user releases pipe,
|
||||
* it will be set to NULL.
|
||||
*/
|
||||
int pipe_release(
|
||||
pipe_control_t **pipep,
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
pipe_control_t *pipe = *pipep;
|
||||
uint32_t mode;
|
||||
|
||||
rtems_status_code sc;
|
||||
sc = rtems_semaphore_obtain(pipe->Semaphore,
|
||||
RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
/* WARN pipe not released! */
|
||||
if(sc != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(sc);
|
||||
|
||||
mode = LIBIO_ACCMODE(iop);
|
||||
if (mode & LIBIO_FLAGS_READ)
|
||||
pipe->Readers --;
|
||||
if (mode & LIBIO_FLAGS_WRITE)
|
||||
pipe->Writers --;
|
||||
|
||||
sc = rtems_semaphore_obtain(rtems_pipe_semaphore,
|
||||
RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
/* WARN pipe not freed and pipep not set to NULL! */
|
||||
if(sc != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(sc);
|
||||
|
||||
PIPE_UNLOCK(pipe);
|
||||
|
||||
if (pipe->Readers == 0 && pipe->Writers == 0) {
|
||||
#if 0
|
||||
/* To delete an anonymous pipe file when all users closed it */
|
||||
if (pipe->Anonymous)
|
||||
delfile = TRUE;
|
||||
#endif
|
||||
pipe_free(pipe);
|
||||
*pipep = NULL;
|
||||
}
|
||||
else if (pipe->Readers == 0 && mode != LIBIO_FLAGS_WRITE)
|
||||
/* Notify waiting Writers that all their partners left */
|
||||
PIPE_WAKEUPWRITERS(pipe);
|
||||
else if (pipe->Writers == 0 && mode != LIBIO_FLAGS_READ)
|
||||
PIPE_WAKEUPREADERS(pipe);
|
||||
|
||||
rtems_semaphore_release(rtems_pipe_semaphore);
|
||||
|
||||
#if 0
|
||||
if (! delfile)
|
||||
return 0;
|
||||
if (iop->pathinfo.ops->unlink_h == NULL)
|
||||
return 0;
|
||||
|
||||
/* This is safe for IMFS, but how about other FSes? */
|
||||
iop->flags &= ~LIBIO_FLAGS_OPEN;
|
||||
if(iop->pathinfo.ops->unlink_h(&iop->pathinfo))
|
||||
return -errno;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface to file system open.
|
||||
*
|
||||
* *pipep points to pipe control structure. If called with *pipep = NULL,
|
||||
* fifo_open will try allocating and initializing a control structure. If the
|
||||
* call succeeds, *pipep will be set to address of new control structure.
|
||||
*/
|
||||
int fifo_open(
|
||||
pipe_control_t **pipep,
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
pipe_control_t *pipe;
|
||||
uint prevCounter;
|
||||
int err;
|
||||
|
||||
err = pipe_new(pipep);
|
||||
if (err)
|
||||
return err;
|
||||
pipe = *pipep;
|
||||
|
||||
switch (LIBIO_ACCMODE(iop)) {
|
||||
case LIBIO_FLAGS_READ:
|
||||
pipe->readerCounter ++;
|
||||
if (pipe->Readers ++ == 0)
|
||||
PIPE_WAKEUPWRITERS(pipe);
|
||||
|
||||
if (pipe->Writers == 0) {
|
||||
/* Not an error */
|
||||
if (LIBIO_NODELAY(iop))
|
||||
break;
|
||||
|
||||
prevCounter = pipe->writerCounter;
|
||||
err = -EINTR;
|
||||
/* Wait until a writer opens the pipe */
|
||||
do {
|
||||
PIPE_UNLOCK(pipe);
|
||||
if (! PIPE_READWAIT(pipe))
|
||||
goto out_error;
|
||||
if (! PIPE_LOCK(pipe))
|
||||
goto out_error;
|
||||
} while (prevCounter == pipe->writerCounter);
|
||||
}
|
||||
break;
|
||||
|
||||
case LIBIO_FLAGS_WRITE:
|
||||
if (pipe->Readers == 0 && LIBIO_NODELAY(iop)) {
|
||||
err = -ENXIO;
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
pipe->writerCounter ++;
|
||||
if (pipe->Writers ++ == 0)
|
||||
PIPE_WAKEUPREADERS(pipe);
|
||||
|
||||
if (pipe->Readers == 0) {
|
||||
prevCounter = pipe->readerCounter;
|
||||
err = -EINTR;
|
||||
do {
|
||||
PIPE_UNLOCK(pipe);
|
||||
if (! PIPE_WRITEWAIT(pipe))
|
||||
goto out_error;
|
||||
if (! PIPE_LOCK(pipe))
|
||||
goto out_error;
|
||||
} while (prevCounter == pipe->readerCounter);
|
||||
}
|
||||
break;
|
||||
|
||||
case LIBIO_FLAGS_READ_WRITE:
|
||||
pipe->readerCounter ++;
|
||||
if (pipe->Readers ++ == 0)
|
||||
PIPE_WAKEUPWRITERS(pipe);
|
||||
pipe->writerCounter ++;
|
||||
if (pipe->Writers ++ == 0)
|
||||
PIPE_WAKEUPREADERS(pipe);
|
||||
break;
|
||||
}
|
||||
|
||||
PIPE_UNLOCK(pipe);
|
||||
return 0;
|
||||
|
||||
out_error:
|
||||
pipe_release(pipep, iop);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface to file system read.
|
||||
*/
|
||||
ssize_t pipe_read(
|
||||
pipe_control_t *pipe,
|
||||
void *buffer,
|
||||
size_t count,
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
int chunk, chunk1, read = 0, ret = 0;
|
||||
|
||||
if (! PIPE_LOCK(pipe))
|
||||
return -EINTR;
|
||||
|
||||
while (read < count) {
|
||||
while (PIPE_EMPTY(pipe)) {
|
||||
/* Not an error */
|
||||
if (pipe->Writers == 0)
|
||||
goto out_locked;
|
||||
|
||||
if (LIBIO_NODELAY(iop)) {
|
||||
ret = -EAGAIN;
|
||||
goto out_locked;
|
||||
}
|
||||
|
||||
/* Wait until pipe is no more empty or no writer exists */
|
||||
pipe->waitingReaders ++;
|
||||
PIPE_UNLOCK(pipe);
|
||||
if (! PIPE_READWAIT(pipe))
|
||||
ret = -EINTR;
|
||||
if (! PIPE_LOCK(pipe)) {
|
||||
/* WARN waitingReaders not restored! */
|
||||
ret = -EINTR;
|
||||
goto out_nolock;
|
||||
}
|
||||
pipe->waitingReaders --;
|
||||
if (ret != 0)
|
||||
goto out_locked;
|
||||
}
|
||||
|
||||
/* Read chunk bytes */
|
||||
chunk = MIN(count - read, pipe->Length);
|
||||
chunk1 = pipe->Size - pipe->Start;
|
||||
if (chunk > chunk1) {
|
||||
memcpy(buffer + read, pipe->Buffer + pipe->Start, chunk1);
|
||||
memcpy(buffer + read + chunk1, pipe->Buffer, chunk - chunk1);
|
||||
}
|
||||
else
|
||||
memcpy(buffer + read, pipe->Buffer + pipe->Start, chunk);
|
||||
|
||||
pipe->Start += chunk;
|
||||
pipe->Start %= pipe->Size;
|
||||
pipe->Length -= chunk;
|
||||
/* For buffering optimization */
|
||||
if (PIPE_EMPTY(pipe))
|
||||
pipe->Start = 0;
|
||||
|
||||
if (pipe->waitingWriters > 0)
|
||||
PIPE_WAKEUPWRITERS(pipe);
|
||||
read += chunk;
|
||||
}
|
||||
|
||||
out_locked:
|
||||
PIPE_UNLOCK(pipe);
|
||||
|
||||
out_nolock:
|
||||
if (read > 0)
|
||||
return read;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface to file system write.
|
||||
*/
|
||||
ssize_t pipe_write(
|
||||
pipe_control_t *pipe,
|
||||
const void *buffer,
|
||||
size_t count,
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
int chunk, chunk1, written = 0, ret = 0;
|
||||
|
||||
/* Write nothing */
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
if (! PIPE_LOCK(pipe))
|
||||
return -EINTR;
|
||||
|
||||
if (pipe->Readers == 0) {
|
||||
ret = -EPIPE;
|
||||
goto out_locked;
|
||||
}
|
||||
|
||||
/* Write of PIPE_BUF bytes or less shall not be interleaved */
|
||||
chunk = count <= pipe->Size ? count : 1;
|
||||
|
||||
while (written < count) {
|
||||
while (PIPE_SPACE(pipe) < chunk) {
|
||||
if (LIBIO_NODELAY(iop)) {
|
||||
ret = -EAGAIN;
|
||||
goto out_locked;
|
||||
}
|
||||
|
||||
/* Wait until there is chunk bytes space or no reader exists */
|
||||
pipe->waitingWriters ++;
|
||||
PIPE_UNLOCK(pipe);
|
||||
if (! PIPE_WRITEWAIT(pipe))
|
||||
ret = -EINTR;
|
||||
if (! PIPE_LOCK(pipe)) {
|
||||
/* WARN waitingWriters not restored! */
|
||||
ret = -EINTR;
|
||||
goto out_nolock;
|
||||
}
|
||||
pipe->waitingWriters --;
|
||||
if (ret != 0)
|
||||
goto out_locked;
|
||||
|
||||
if (pipe->Readers == 0) {
|
||||
ret = -EPIPE;
|
||||
goto out_locked;
|
||||
}
|
||||
}
|
||||
|
||||
chunk = MIN(count - written, PIPE_SPACE(pipe));
|
||||
chunk1 = pipe->Size - PIPE_WSTART(pipe);
|
||||
if (chunk > chunk1) {
|
||||
memcpy(pipe->Buffer + PIPE_WSTART(pipe), buffer + written, chunk1);
|
||||
memcpy(pipe->Buffer, buffer + written + chunk1, chunk - chunk1);
|
||||
}
|
||||
else
|
||||
memcpy(pipe->Buffer + PIPE_WSTART(pipe), buffer + written, chunk);
|
||||
|
||||
pipe->Length += chunk;
|
||||
if (pipe->waitingReaders > 0)
|
||||
PIPE_WAKEUPREADERS(pipe);
|
||||
written += chunk;
|
||||
/* Write of more than PIPE_BUF bytes can be interleaved */
|
||||
chunk = 1;
|
||||
}
|
||||
|
||||
out_locked:
|
||||
PIPE_UNLOCK(pipe);
|
||||
|
||||
out_nolock:
|
||||
#ifdef RTEMS_POSIX_API
|
||||
/* Signal SIGPIPE */
|
||||
if (ret == -EPIPE)
|
||||
kill(getpid(), SIGPIPE);
|
||||
#endif
|
||||
|
||||
if (written > 0)
|
||||
return written;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface to file system ioctl.
|
||||
*/
|
||||
int pipe_ioctl(
|
||||
pipe_control_t *pipe,
|
||||
uint32_t cmd,
|
||||
void *buffer,
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
if (cmd == FIONREAD) {
|
||||
if (buffer == NULL)
|
||||
return -EFAULT;
|
||||
|
||||
if (! PIPE_LOCK(pipe))
|
||||
return -EINTR;
|
||||
|
||||
/* Return length of pipe */
|
||||
*(uint *)buffer = pipe->Length;
|
||||
PIPE_UNLOCK(pipe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface to file system lseek.
|
||||
*/
|
||||
int pipe_lseek(
|
||||
pipe_control_t *pipe,
|
||||
off_t offset,
|
||||
int whence,
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
/* Seek on pipe is not supported */
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization of FIFO/pipe module.
|
||||
*/
|
||||
void rtems_pipe_initialize (void)
|
||||
{
|
||||
if (rtems_pipe_semaphore)
|
||||
return;
|
||||
|
||||
rtems_status_code sc;
|
||||
sc = rtems_semaphore_create(
|
||||
rtems_build_name ('P', 'I', 'P', 'E'), 1,
|
||||
RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||
RTEMS_NO_PRIORITY, &rtems_pipe_semaphore);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred (sc);
|
||||
|
||||
rtems_interval now;
|
||||
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
|
||||
rtems_pipe_no = now;
|
||||
}
|
||||
83
cpukit/libfs/src/pipe/pipe.c
Normal file
83
cpukit/libfs/src/pipe/pipe.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* pipe.c: anonymous pipe
|
||||
*
|
||||
* Author: Wei Shen <cquark@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$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <rtems/libio_.h>
|
||||
#include <rtems/seterr.h>
|
||||
|
||||
/* Incremental number added to names of anonymous pipe files */
|
||||
uint16_t rtems_pipe_no = 0;
|
||||
|
||||
/*
|
||||
* Called by pipe() to create an anonymous pipe.
|
||||
*/
|
||||
int pipe_create(
|
||||
int filsdes[2]
|
||||
)
|
||||
{
|
||||
rtems_filesystem_location_info_t loc;
|
||||
rtems_libio_t *iop;
|
||||
int err = 0;
|
||||
|
||||
/* Create /tmp if not exists */
|
||||
if (rtems_filesystem_evaluate_path("/tmp", RTEMS_LIBIO_PERMS_RWX, &loc, TRUE)
|
||||
!= 0) {
|
||||
if (errno != ENOENT)
|
||||
return -1;
|
||||
if (mkdir("/tmp", S_IRWXU|S_IRWXG|S_IRWXO|S_ISVTX) != 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
rtems_filesystem_freenode(&loc);
|
||||
|
||||
/* /tmp/.fifoXXXX */
|
||||
char fifopath[15];
|
||||
memcpy(fifopath, "/tmp/.fifo", 10);
|
||||
sprintf(fifopath + 10, "%04x", rtems_pipe_no ++);
|
||||
|
||||
/* Try creating FIFO file until find an available file name */
|
||||
while (mkfifo(fifopath, S_IRUSR|S_IWUSR) != 0) {
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
/* Just try once... */
|
||||
return -1;
|
||||
sprintf(fifopath + 10, "%04x", rtems_pipe_no ++);
|
||||
}
|
||||
|
||||
/* Non-blocking open to avoid waiting for writers */
|
||||
filsdes[0] = open(fifopath, O_RDONLY | O_NONBLOCK);
|
||||
if (filsdes[0] < 0) {
|
||||
err = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Reset open file to blocking mode */
|
||||
iop = rtems_libio_iop(filsdes[0]);
|
||||
iop->flags &= ~LIBIO_FLAGS_NO_DELAY;
|
||||
|
||||
filsdes[1] = open(fifopath, O_WRONLY);
|
||||
|
||||
if (filsdes[1] < 0) {
|
||||
err = errno;
|
||||
close(filsdes[0]);
|
||||
}
|
||||
|
||||
out:
|
||||
/* Delete file at errors, or else if pipe is successfully created
|
||||
the file node will be deleted after it is closed by all. */
|
||||
unlink(fifopath);
|
||||
|
||||
if (! err)
|
||||
return 0;
|
||||
rtems_set_errno_and_return_minus_one(err);
|
||||
}
|
||||
113
cpukit/libfs/src/pipe/pipe.h
Normal file
113
cpukit/libfs/src/pipe/pipe.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* pipe.h: header of POSIX FIFO/pipe
|
||||
*
|
||||
* Author: Wei Shen <cquark@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$
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_PIPE_H
|
||||
#define _RTEMS_PIPE_H
|
||||
|
||||
#include <rtems/libio.h>
|
||||
|
||||
/* Control block to manage each pipe */
|
||||
typedef struct pipe_control {
|
||||
char *Buffer;
|
||||
uint Size;
|
||||
uint Start;
|
||||
uint Length;
|
||||
uint Readers;
|
||||
uint Writers;
|
||||
uint waitingReaders;
|
||||
uint waitingWriters;
|
||||
uint readerCounter; /* incremental counters */
|
||||
uint writerCounter; /* for differentiation of successive opens */
|
||||
rtems_id Semaphore;
|
||||
rtems_id readBarrier; /* wait queues */
|
||||
rtems_id writeBarrier;
|
||||
#if 0
|
||||
boolean Anonymous; /* anonymous pipe or FIFO */
|
||||
#endif
|
||||
} pipe_control_t;
|
||||
|
||||
/*
|
||||
* Called by pipe() to create an anonymous pipe.
|
||||
*/
|
||||
int pipe_create(
|
||||
int filsdes[2]
|
||||
);
|
||||
|
||||
/*
|
||||
* Interface to file system close.
|
||||
*
|
||||
* *pipep points to pipe control structure. When the last user releases pipe,
|
||||
* it will be set to NULL.
|
||||
*/
|
||||
int pipe_release(
|
||||
pipe_control_t **pipep,
|
||||
rtems_libio_t *iop
|
||||
);
|
||||
|
||||
/*
|
||||
* Interface to file system open.
|
||||
*
|
||||
* *pipep points to pipe control structure. If called with *pipep = NULL,
|
||||
* fifo_open will try allocating and initializing a control structure. If the
|
||||
* call succeeds, *pipep will be set to address of new control structure.
|
||||
*/
|
||||
int fifo_open(
|
||||
pipe_control_t **pipep,
|
||||
rtems_libio_t *iop
|
||||
);
|
||||
|
||||
/*
|
||||
* Interface to file system read.
|
||||
*/
|
||||
ssize_t pipe_read(
|
||||
pipe_control_t *pipe,
|
||||
void *buffer,
|
||||
size_t count,
|
||||
rtems_libio_t *iop
|
||||
);
|
||||
|
||||
/*
|
||||
* Interface to file system write.
|
||||
*/
|
||||
ssize_t pipe_write(
|
||||
pipe_control_t *pipe,
|
||||
const void *buffer,
|
||||
size_t count,
|
||||
rtems_libio_t *iop
|
||||
);
|
||||
|
||||
/*
|
||||
* Interface to file system ioctl.
|
||||
*/
|
||||
int pipe_ioctl(
|
||||
pipe_control_t *pipe,
|
||||
uint32_t cmd,
|
||||
void *buffer,
|
||||
rtems_libio_t *iop
|
||||
);
|
||||
|
||||
/*
|
||||
* Interface to file system lseek.
|
||||
*/
|
||||
int pipe_lseek(
|
||||
pipe_control_t *pipe,
|
||||
off_t offset,
|
||||
int whence,
|
||||
rtems_libio_t *iop
|
||||
);
|
||||
|
||||
/*
|
||||
* Initialization of FIFO/pipe module.
|
||||
*/
|
||||
void rtems_pipe_initialize (void);
|
||||
|
||||
#endif /* #define _RTEMS_PIPE_H */
|
||||
@@ -146,6 +146,10 @@ $(PROJECT_INCLUDE)/rtems/imfs.h: libfs/src/imfs/imfs.h $(PROJECT_INCLUDE)/rtems/
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/imfs.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/imfs.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/pipe.h: libfs/src/pipe/pipe.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/pipe.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/pipe.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/devfs.h: libfs/src/devfs/devfs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/devfs.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/devfs.h
|
||||
|
||||
Reference in New Issue
Block a user