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:
Joel Sherrill
2008-10-14 15:06:25 +00:00
parent c1fe2a115a
commit e2324c081a
20 changed files with 977 additions and 17 deletions
+12
View File
@@ -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
+3
View File
@@ -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
-3
View File
@@ -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 ) {
+3 -1
View File
@@ -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.
+8 -2
View 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);
}
+6 -1
View File
@@ -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
+2
View File
@@ -5,3 +5,5 @@ $(srcdir)/preinstall.am: Makefile.am
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
endif
if ! UNIX
endif
+13 -4
View File
@@ -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;
+4
View File
@@ -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;
+5
View File
@@ -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);
+3
View File
@@ -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
View 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,
};
+7 -4
View File
@@ -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;
}
+4 -1
View File
@@ -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 );
}
+4
View File
@@ -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;
+1 -1
View File
@@ -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;
}
File diff suppressed because it is too large Load Diff
+83
View 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
View 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 */
+4
View File
@@ -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