2008-07-29 Chris Johns <chrisj@rtems.org>

* libblock/Makefile.am: Removed src/show_bdbuf.c.

	* libblock/src/show_bdbuf.c: Removed.

	* libblock/include/rtems/bdbuf.h, cpukit/libblock/src/bdbuf.c:
	Rewritten the bdbuf code. Remove pre-emption disable, score
	access, fixed many bugs and increased performance.

	* libblock/include/rtems/blkdev.h: Added
	RTEMS_BLKDEV_CAPABILITIES block device request. Cleaned up
	comments. Added block and user fields to the sg buffer
	request. Move to rtems_* namespace.

	* libblock/include/rtems/diskdevs.h,
	cpukit/libblock/src/diskdevs.c: Move to rtems_* namespace. Add a
	capabilities field for drivers. Change rtems_disk_lookup to
	rtems_disk_obtain to match the release call. You do not lookup and
	release a disk, you obtain and release a disk.

	* libblock/include/rtems/ide_part_table.h,
	libblock/include/rtems/ramdisk.h, libblock/src/ide_part_table.c:
	Move to rtems_* namespace.

	* libblock/include/rtems/nvdisk.h: Formatting change.

	* libblock/src/blkdev.c: Move to rtems_* namespace. Change
	rtems_disk_lookup to rtems_disk_obtain

	* libblock/src/flashdisk.c: Move to rtems_* namespace. Use the new
	support for the block number in the scatter/grather request
	struct. This allows non-continuous buffer requests for those
	drivers that can support increasing performance.

	* libblock/src/nvdisk.c: Move to rtems_* namespace. Removed
	warnings. Added better error checking. Fixed some comments.

	* libblock/src/ramdisk.c: Move to rtems_* namespace. Added some
	trace functions to help debugging upper layers. Use the new
	support for the block number in the scatter/grather request
	struct. This allows non-continuous buffer requests for those
	drivers that can support increasing performance.

	* libfs/src/dosfs/fat.c, libfs/src/dosfs/fat.h: Use new chains
	API. Removed temporary hack and changed
	set_errno_and_return_minus_one to
	rtems_set_errno_and_return_minus_one. Move fat_buf_access from
	header and stopped it being inlined. Updated to libblock changes.

	* libfs/src/dosfs/fat_fat_operations.c,
	libfs/src/dosfs/fat_file.c, libfs/src/dosfs/msdos_create.c,
	libfs/src/dosfs/msdos_dir.c, libfs/src/dosfs/msdos_eval.c,
	libfs/src/dosfs/msdos_file.c, libfs/src/dosfs/msdos_format.c,
	libfs/src/dosfs/msdos_free.c, libfs/src/dosfs/msdos_initsupp.c,
	libfs/src/dosfs/msdos_misc.c, libfs/src/dosfs/msdos_mknod.c: Use
	new chains API. Removed temporary hack and changed
	set_errno_and_return_minus_one to
	rtems_set_errno_and_return_minus_one. Updated to libblock changes.

	* libmisc/Makefile.am: Add new ls and rm command files.

	* libmisc/shell/cmp-ls.c, libmisc/shell/extern-ls.h,
	libmisc/shell/filemode.c, libmisc/shell/print-ls.c,
	libmisc/shell/pwcache.c, libmisc/shell/utils-ls.c,
	libmisc/shell/vis.c, shell/vis.h: New.

	* libmisc/shell/extern-cp.h, libmisc/shell/main_cp.c,
	libmisc/shell/utils-cp.c: Fixed the usage call bug.

	* libmisc/shell/main_blksync.c: Updated to the new block IO ioctl
	command.

	* libmisc/shell/main_ls.c, libmisc/shell/main_rm.c: Updated to BSD
	commands with more features.

	* score/src/coremutex.c: Fix the strick order mutex code.

	* libmisc/shell/shell.c: Change shell tasks mode to be timeslice
	and no ASR.

	* sapi/include/confdefs.h: Change ata_driver_task_priority to
	rtems_ata_driver_task_priority. Add the new BD buf cache
	parameters with defaults.

	* score/src/interr.c: Do not return if the CPU halt call returns.
This commit is contained in:
Chris Johns
2008-07-29 02:21:15 +00:00
parent 1b39f1892b
commit 3899a5379f
47 changed files with 6241 additions and 2448 deletions

View File

@@ -1,3 +1,90 @@
2008-07-29 Chris Johns <chrisj@rtems.org>
* libblock/Makefile.am: Removed src/show_bdbuf.c.
* libblock/src/show_bdbuf.c: Removed.
* libblock/include/rtems/bdbuf.h, cpukit/libblock/src/bdbuf.c:
Rewritten the bdbuf code. Remove pre-emption disable, score
access, fixed many bugs and increased performance.
* libblock/include/rtems/blkdev.h: Added
RTEMS_BLKDEV_CAPABILITIES block device request. Cleaned up
comments. Added block and user fields to the sg buffer
request. Move to rtems_* namespace.
* libblock/include/rtems/diskdevs.h,
cpukit/libblock/src/diskdevs.c: Move to rtems_* namespace. Add a
capabilities field for drivers. Change rtems_disk_lookup to
rtems_disk_obtain to match the release call. You do not lookup and
release a disk, you obtain and release a disk.
* libblock/include/rtems/ide_part_table.h,
libblock/include/rtems/ramdisk.h, libblock/src/ide_part_table.c:
Move to rtems_* namespace.
* libblock/include/rtems/nvdisk.h: Formatting change.
* libblock/src/blkdev.c: Move to rtems_* namespace. Change
rtems_disk_lookup to rtems_disk_obtain
* libblock/src/flashdisk.c: Move to rtems_* namespace. Use the new
support for the block number in the scatter/grather request
struct. This allows non-continuous buffer requests for those
drivers that can support increasing performance.
* libblock/src/nvdisk.c: Move to rtems_* namespace. Removed
warnings. Added better error checking. Fixed some comments.
* libblock/src/ramdisk.c: Move to rtems_* namespace. Added some
trace functions to help debugging upper layers. Use the new
support for the block number in the scatter/grather request
struct. This allows non-continuous buffer requests for those
drivers that can support increasing performance.
* libfs/src/dosfs/fat.c, libfs/src/dosfs/fat.h: Use new chains
API. Removed temporary hack and changed
set_errno_and_return_minus_one to
rtems_set_errno_and_return_minus_one. Move fat_buf_access from
header and stopped it being inlined. Updated to libblock changes.
* libfs/src/dosfs/fat_fat_operations.c,
libfs/src/dosfs/fat_file.c, libfs/src/dosfs/msdos_create.c,
libfs/src/dosfs/msdos_dir.c, libfs/src/dosfs/msdos_eval.c,
libfs/src/dosfs/msdos_file.c, libfs/src/dosfs/msdos_format.c,
libfs/src/dosfs/msdos_free.c, libfs/src/dosfs/msdos_initsupp.c,
libfs/src/dosfs/msdos_misc.c, libfs/src/dosfs/msdos_mknod.c: Use
new chains API. Removed temporary hack and changed
set_errno_and_return_minus_one to
rtems_set_errno_and_return_minus_one. Updated to libblock changes.
* libmisc/Makefile.am: Add new ls and rm command files.
* libmisc/shell/cmp-ls.c, libmisc/shell/extern-ls.h,
libmisc/shell/filemode.c, libmisc/shell/print-ls.c,
libmisc/shell/pwcache.c, libmisc/shell/utils-ls.c,
libmisc/shell/vis.c, shell/vis.h: New.
* libmisc/shell/extern-cp.h, libmisc/shell/main_cp.c,
libmisc/shell/utils-cp.c: Fixed the usage call bug.
* libmisc/shell/main_blksync.c: Updated to the new block IO ioctl
command.
* libmisc/shell/main_ls.c, libmisc/shell/main_rm.c: Updated to BSD
commands with more features.
* score/src/coremutex.c: Fix the strick order mutex code.
* libmisc/shell/shell.c: Change shell tasks mode to be timeslice
and no ASR.
* sapi/include/confdefs.h: Change ata_driver_task_priority to
rtems_ata_driver_task_priority. Add the new BD buf cache
parameters with defaults.
* score/src/interr.c: Do not return if the CPU halt call returns.
2008-07-24 Sebastian Huber <sebastian.huber@embedded-brains.de>
* libcsupport/include/rtems/libcsupport.h: Moved declaration of

View File

@@ -8,7 +8,7 @@ include $(top_srcdir)/automake/compile.am
if !UNIX
noinst_LIBRARIES = libblock.a
libblock_a_SOURCES = src/bdbuf.c src/blkdev.c src/diskdevs.c src/flashdisk.c \
src/ramdisk.c src/ide_part_table.c src/show_bdbuf.c src/nvdisk.c \
src/ramdisk.c src/ide_part_table.c src/nvdisk.c \
src/nvdisk-sram.c \
include/rtems/bdbuf.h include/rtems/blkdev.h \
include/rtems/diskdevs.h include/rtems/flashdisk.h \

View File

@@ -25,116 +25,143 @@ extern "C" {
#include "rtems/blkdev.h"
#include "rtems/diskdevs.h"
/*
* To manage buffers we using Buffer Descriptors.
* To speed-up buffer lookup descriptors are organized in AVL-Tree.
* The fields 'dev' and 'block' are search key.
/**
* State of a buffer in the cache.
*/
/* Buffer descriptors
* Descriptors organized in AVL-tree to speedup buffer lookup.
* dev and block fields are search key in AVL-tree.
* Modified buffers, free buffers and used buffers linked in 'mod', 'free' and
* 'lru' chains appropriately.
*/
typedef struct bdbuf_buffer {
Chain_Node link; /* Link in the lru, mod or free chains */
struct bdbuf_avl_node {
signed char cache; /* Cache */
struct bdbuf_buffer* left; /* Left Child */
struct bdbuf_buffer* right; /* Right Child */
signed char bal; /* The balance of the sub-tree */
} avl;
dev_t dev; /* device number */
blkdev_bnum block; /* block number on the device */
unsigned char *buffer; /* Pointer to the buffer memory area */
rtems_status_code status; /* Last I/O operation completion status */
int error; /* If status != RTEMS_SUCCESSFUL, this field contains
errno value which can be used by user later */
boolean modified:1; /* =1 if buffer was modified */
boolean in_progress:1; /* =1 if exchange with disk is in progress;
need to wait on semaphore */
boolean actual:1; /* Buffer contains actual data */
int use_count; /* Usage counter; incremented when somebody use
this buffer; decremented when buffer released
without modification or when buffer is flushed
by swapout task */
rtems_bdpool_id pool; /* Identifier of buffer pool to which this buffer
belongs */
CORE_mutex_Control transfer_sema;
/* Transfer operation semaphore */
} bdbuf_buffer;
/*
* the following data structures are internal to the bdbuf layer,
* but it is convenient to have them visible from the outside for inspection
*/
/*
* The groups of the blocks with the same size are collected in the
* bd_pool. Note that a several of the buffer's groups with the
* same size can exists.
*/
typedef struct bdbuf_pool
typedef enum
{
bdbuf_buffer *tree; /* Buffer descriptor lookup AVL tree root */
RTEMS_BDBUF_STATE_EMPTY = 0, /* Not in use. */
RTEMS_BDBUF_STATE_READ_AHEAD = 1, /* Holds read ahead data only */
RTEMS_BDBUF_STATE_CACHED = 2, /* In the cache and available */
RTEMS_BDBUF_STATE_ACCESS = 3, /* The user has the buffer */
RTEMS_BDBUF_STATE_MODIFIED = 4, /* In the cache but modified */
RTEMS_BDBUF_STATE_ACCESS_MODIFIED = 5, /* With the user but modified */
RTEMS_BDBUF_STATE_SYNC = 6, /* Requested to be sync'ed */
RTEMS_BDBUF_STATE_TRANSFER = 7 /* Being transferred to or from disk */
} rtems_bdbuf_buf_state;
Chain_Control free; /* Free buffers list */
Chain_Control lru; /* Last recently used list */
/**
* To manage buffers we using buffer descriptors (BD). A BD holds a buffer plus
* a range of other information related to managing the buffer in the cache. To
* speed-up buffer lookup descriptors are organized in AVL-Tree. The fields
* 'dev' and 'block' are search keys.
*/
typedef struct rtems_bdbuf_buffer
{
rtems_chain_node link; /* Link in the BD onto a number of lists. */
int blksize; /* The size of the blocks (in bytes) */
int nblks; /* Number of blocks in this pool */
rtems_id bufget_sema; /* Buffer obtain counting semaphore */
void *mallocd_bufs; /* Pointer to the malloc'd buffer memory,
or NULL, if buffer memory provided in
buffer configuration */
bdbuf_buffer *bdbufs; /* Pointer to table of buffer descriptors
allocated for this buffer pool. */
} bdbuf_pool;
struct rtems_bdbuf_avl_node
{
signed char cache; /* Cache */
struct rtems_bdbuf_buffer* left; /* Left Child */
struct rtems_bdbuf_buffer* right; /* Right Child */
signed char bal; /* The balance of the sub-tree */
} avl;
/* Buffering layer context definition */
struct bdbuf_context {
bdbuf_pool *pool; /* Table of buffer pools */
int npools; /* Number of entries in pool table */
dev_t dev; /* device number */
rtems_blkdev_bnum block; /* block number on the device */
Chain_Control mod; /* Modified buffers list */
rtems_id flush_sema; /* Buffer flush semaphore; counting
semaphore; incremented when buffer
flushed to the disk; decremented when
buffer modified */
rtems_id swapout_task; /* Swapout task ID */
};
/*
* the context of the buffering layer, visible for inspection
*/
extern struct bdbuf_context rtems_bdbuf_ctx;
unsigned char* buffer; /* Pointer to the buffer memory area */
int error; /* If not 0 indicate an error value (errno)
* which can be used by user later */
/* bdbuf_config structure describes block configuration (size,
* amount, memory location) for buffering layer
volatile rtems_bdbuf_buf_state state; /* State of the buffer. */
volatile uint32_t waiters; /* The number of threads waiting on this
* buffer. */
rtems_bdpool_id pool; /* Identifier of buffer pool to which this buffer
belongs */
volatile uint32_t hold_timer; /* Timer to indicate how long a buffer
* has been held in the cache modified. */
} rtems_bdbuf_buffer;
/**
* The groups of the blocks with the same size are collected in a pool. Note
* that a several of the buffer's groups with the same size can exists.
*/
typedef struct rtems_bdbuf_pool
{
int blksize; /* The size of the blocks (in bytes) */
int nblks; /* Number of blocks in this pool */
uint32_t flags; /* Configuration flags */
rtems_id lock; /* The pool lock. Lock this data and
* all BDs. */
rtems_id sync_lock; /* Sync calls lock writes. */
boolean sync_active; /* True if a sync is active. */
rtems_id sync_requester; /* The sync requester. */
dev_t sync_device; /* The device to sync */
rtems_bdbuf_buffer* tree; /* Buffer descriptor lookup AVL tree
* root */
rtems_chain_control ready; /* Free buffers list (or read-ahead) */
rtems_chain_control lru; /* Last recently used list */
rtems_chain_control modified; /* Modified buffers list */
rtems_chain_control sync; /* Buffers to sync list */
rtems_id access; /* Obtain if waiting for a buffer in the
* ACCESS state. */
volatile uint32_t access_waiters; /* Count of access blockers. */
rtems_id transfer; /* Obtain if waiting for a buffer in the
* TRANSFER state. */
volatile uint32_t transfer_waiters; /* Count of transfer blockers. */
rtems_id waiting; /* Obtain if waiting for a buffer and the
* none are available. */
volatile uint32_t wait_waiters; /* Count of waiting blockers. */
rtems_bdbuf_buffer* bds; /* Pointer to table of buffer descriptors
* allocated for this buffer pool. */
void* buffers; /* The buffer's memory. */
} rtems_bdbuf_pool;
/**
* Configuration structure describes block configuration (size, amount, memory
* location) for buffering layer pool.
*/
typedef struct rtems_bdbuf_pool_config {
int size; /* Size of block */
int num; /* Number of blocks of appropriate size */
unsigned char* mem_area; /* Pointer to the blocks location or NULL, in this
* case memory for blocks will be allocated by
* Buffering Layer with the help of RTEMS partition
* manager */
} rtems_bdbuf_pool_config;
/**
* External references provided by the user for each pool in the system.
*/
extern rtems_bdbuf_pool_config rtems_bdbuf_pool_configuration[];
extern int rtems_bdbuf_pool_configuration_size;
/**
* Buffering configuration definition. See confdefs.h for support on using this
* structure.
*/
typedef struct rtems_bdbuf_config {
int size; /* Size of block */
int num; /* Number of blocks of appropriate size */
unsigned char *mem_area;
/* Pointer to the blocks location or NULL, in this
case memory for blocks will be allocated by
Buffering Layer with the help of RTEMS partition
manager */
int max_read_ahead_blocks; /*<< Number of blocks to read ahead. */
int max_write_blocks; /*<< Number of blocks to write at once. */
rtems_task_priority swapout_priority; /*<< Priority of the swap out task. */
uint32_t swapout_period; /*<< Period swapout checks buf timers. */
uint32_t swap_block_hold; /*<< Period a buffer is held. */
} rtems_bdbuf_config;
extern rtems_bdbuf_config rtems_bdbuf_configuration[];
extern int rtems_bdbuf_configuration_size;
/**
* External referernce to the configuration. The configuration is provided by
* the user.
*/
extern rtems_bdbuf_config rtems_bdbuf_configuration;
#define SWAPOUT_TASK_DEFAULT_PRIORITY 15
extern rtems_task_priority swapout_task_priority;
/**
* The max_read_ahead_blocks value is altered if there are fewer buffers
* than this defined max. This stops thrashing in the cache.
*/
#define RTEMS_BDBUF_MAX_READ_AHEAD_BLOCKS_DEFAULT 32
#define RTEMS_BDBUF_MAX_WRITE_BLOCKS_DEFAULT 16
#define RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT 15
#define RTEMS_BDBUF_SWAPOUT_TASK_SWAP_PERIOD_DEFAULT 250 /* milli-seconds */
#define RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT 1000 /* milli-seconds */
/* rtems_bdbuf_init --
* Prepare buffering layer to work - initialize buffer descritors
@@ -143,17 +170,12 @@ extern rtems_task_priority swapout_task_priority;
* amount requested. After initialization all blocks is placed into
* free elements lists.
*
* PARAMETERS:
* conf_table - pointer to the buffers configuration table
* size - number of entries in configuration table
*
* RETURNS:
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
* or error code if error is occured)
*/
rtems_status_code
rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size);
rtems_bdbuf_init ();
/* rtems_bdbuf_get --
* Obtain block buffer. If specified block already cached (i.e. there's
@@ -177,8 +199,8 @@ rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size);
* SIDE EFFECTS:
* bufget_sema semaphore obtained by this primitive.
*/
rtems_status_code
rtems_bdbuf_get(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
rtems_status_code
rtems_bdbuf_get(dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd);
/* rtems_bdbuf_read --
* (Similar to the rtems_bdbuf_get, except reading data from media)
@@ -201,8 +223,8 @@ rtems_bdbuf_get(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
* SIDE EFFECTS:
* bufget_sema and transfer_sema semaphores obtained by this primitive.
*/
rtems_status_code
rtems_bdbuf_read(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
rtems_status_code
rtems_bdbuf_read(dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd);
/* rtems_bdbuf_release --
* Release buffer allocated before. This primitive decrease the
@@ -223,8 +245,8 @@ rtems_bdbuf_read(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
* SIDE EFFECTS:
* flush_sema and bufget_sema semaphores may be released by this primitive.
*/
rtems_status_code
rtems_bdbuf_release(bdbuf_buffer *bd_buf);
rtems_status_code
rtems_bdbuf_release(rtems_bdbuf_buffer* bd);
/* rtems_bdbuf_release_modified --
* Release buffer allocated before, assuming that it is _modified_ by
@@ -244,8 +266,8 @@ rtems_bdbuf_release(bdbuf_buffer *bd_buf);
* SIDE EFFECTS:
* flush_sema semaphore may be released by this primitive.
*/
rtems_status_code
rtems_bdbuf_release_modified(bdbuf_buffer *bd_buf);
rtems_status_code
rtems_bdbuf_release_modified(rtems_bdbuf_buffer* bd);
/* rtems_bdbuf_sync --
* Wait until specified buffer synchronized with disk. Invoked on exchanges
@@ -265,8 +287,8 @@ rtems_bdbuf_release_modified(bdbuf_buffer *bd_buf);
* SIDE EFFECTS:
* Primitive may be blocked on transfer_sema semaphore.
*/
rtems_status_code
rtems_bdbuf_sync(bdbuf_buffer *bd_buf);
rtems_status_code
rtems_bdbuf_sync(rtems_bdbuf_buffer* bd);
/* rtems_bdbuf_syncdev --
* Synchronize with disk all buffers containing the blocks belonging to
@@ -279,8 +301,8 @@ rtems_bdbuf_sync(bdbuf_buffer *bd_buf);
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
* or error code if error is occured)
*/
rtems_status_code
rtems_bdbuf_syncdev(dev_t dev);
rtems_status_code
rtems_bdbuf_syncdev(dev_t dev);
/* rtems_bdbuf_find_pool --
* Find first appropriate buffer pool. This primitive returns the index
@@ -297,8 +319,8 @@ rtems_bdbuf_syncdev(dev_t dev);
* of 2), RTEMS_NOT_DEFINED if buffer pool for this or greater block size
* is not configured.
*/
rtems_status_code
rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool);
rtems_status_code
rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool);
/* rtems_bdbuf_get_pool_info --
* Obtain characteristics of buffer pool with specified number.
@@ -316,8 +338,8 @@ rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool);
* NOTE:
* Buffer pools enumerated contiguously starting from 0.
*/
rtems_status_code
rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size, int *blocks);
rtems_status_code
rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size, int *blocks);
#ifdef __cplusplus
}

View File

@@ -20,67 +20,92 @@
extern "C" {
#endif
/* Interface with device drivers
* Block device looks, initialized and behaves like traditional RTEMS device
* driver. Heart of the block device driver is in BIOREQUEST ioctl. This call
* puts I/O request to the block device queue, in priority order, for
* asynchronous processing. When driver executes request, req_done
* function invoked, so callee knows about it. Look for details below.
/*
* Interface with device drivers Block device looks, initialized and behaves
* like traditional RTEMS device driver. Heart of the block device driver is in
* BIOREQUEST ioctl. This call puts I/O request to the block device queue, in
* priority order, for asynchronous processing. When driver executes request,
* req_done function invoked, so callee knows about it. Look for details below.
*/
/* Block device block number datatype */
typedef uint32_t blkdev_bnum;
/*
* Block device block number datatype
*/
typedef uint32_t rtems_blkdev_bnum;
/* Block device request type */
typedef enum blkdev_request_op {
BLKDEV_REQ_READ, /* Read operation */
BLKDEV_REQ_WRITE /* Write operation */
} blkdev_request_op;
typedef enum rtems_blkdev_request_op {
RTEMS_BLKDEV_REQ_READ, /* Read operation */
RTEMS_BLKDEV_REQ_WRITE, /* Write operation */
RTEMS_BLKDEV_CAPABILITIES /* Capabilities request */
} rtems_blkdev_request_op;
/* Type for block device request done callback function.
/**
* ATA multi-sector buffer requests only supported. This option
* means the cache will only supply multiple buffers that are
* inorder so the ATA multi-sector command can be used. This is a
* hack to work around the current ATA driver.
*/
#define RTEMS_BLKDEV_CAP_MULTISECTOR_CONT (1 << 0)
/*
* @typedef rtems_blkdev_request_cb
*
* PARAMETERS:
* arg - argument supplied in blkdev_request
* status - rtems status code for this operation
* errno - errno value to be passed to the user when
* Type for block device request done callback function.
*
* @param arg Argument supplied in blkdev_request
* @param status RTEMS status code for this operation
* @param errno errno value to be passed to the user when
* status != RTEMS_SUCCESSFUL
*/
typedef void (* blkdev_request_cb)(void *arg,
rtems_status_code status,
int error);
typedef void (* rtems_blkdev_request_cb)(void *arg,
rtems_status_code status,
int error);
/* blkdev_sg_buffer
/**
* @struct rtems_blkdev_sg_buffer
* Block device scatter/gather buffer structure
*/
typedef struct blkdev_sg_buffer {
typedef struct rtems_blkdev_sg_buffer {
uint32_t block; /* The block number */
uint32_t length; /* Buffer length */
void *buffer; /* Buffer pointer */
} blkdev_sg_buffer;
void *buffer; /* Buffer pointer */
void *user; /* User pointer */
} rtems_blkdev_sg_buffer;
/* blkdev_request (Block Device Request) structure is
* used to read/write a number of blocks from/to device.
*/
typedef struct blkdev_request {
blkdev_request_op req; /* Block device operation (read or write) */
blkdev_request_cb req_done; /* Callback function */
void *done_arg; /* Argument to be passed to callback function*/
rtems_status_code status; /* Last I/O operation completion status */
int error; /* If status != RTEMS_SUCCESSFUL, this field
* contains error code
*/
blkdev_bnum start; /* Start block number */
uint32_t count; /* Number of blocks to be exchanged */
uint32_t bufnum; /* Number of buffers provided */
typedef struct rtems_blkdev_request {
/* Block device operation (read or write) */
rtems_blkdev_request_op req;
/* Callback function */
rtems_blkdev_request_cb req_done;
/* Argument to be passed to callback function*/
void *done_arg;
/* Last I/O operation completion status */
rtems_status_code status;
/* If status != RTEMS_SUCCESSFUL, this field contains error code */
int error;
/* Start block number */
rtems_blkdev_bnum start;
/* Number of blocks to be exchanged */
uint32_t count;
/* Number of buffers provided */
uint32_t bufnum;
blkdev_sg_buffer bufs[0];/* List of scatter/gather buffers */
} blkdev_request;
/* The task requesting the IO operation. */
rtems_id io_task;
/* List of scatter/gather buffers */
rtems_blkdev_sg_buffer bufs[0];
} rtems_blkdev_request;
/* Block device IOCTL request codes */
#define BLKIO_REQUEST _IOWR('B', 1, blkdev_request)
#define BLKIO_GETBLKSIZE _IO('B', 2)
#define BLKIO_GETSIZE _IO('B', 3)
#define BLKIO_SYNCDEV _IO('B', 4)
#define RTEMS_BLKIO_REQUEST _IOWR('B', 1, rtems_blkdev_request)
#define RTEMS_BLKIO_GETBLKSIZE _IO('B', 2)
#define RTEMS_BLKIO_GETSIZE _IO('B', 3)
#define RTEMS_BLKIO_SYNCDEV _IO('B', 4)
/* Device driver interface conventions suppose that driver may
* contain initialize/open/close/read/write/ioctl entry points. These
@@ -90,7 +115,7 @@ typedef struct blkdev_request {
* all block devices and appropriate ioctl handlers.
*/
#define GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES \
#define RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES \
rtems_blkdev_generic_open, rtems_blkdev_generic_close, \
rtems_blkdev_generic_read, rtems_blkdev_generic_write, \
rtems_blkdev_generic_ioctl

View File

@@ -21,44 +21,47 @@ extern "C" {
#include <rtems/libio.h>
#include <stdlib.h>
#include "rtems/blkdev.h"
/* Buffer pool identifier */
typedef int rtems_bdpool_id;
/* Block device ioctl handler */
typedef int (* block_device_ioctl) (dev_t dev, uint32_t req, void *argp);
#include "rtems/blkdev.h"
/* disk_device: Entry of this type created for every disk device (both for
* logical and physical disks).
/* Driver capabilities. */
/* Block device ioctl handler */
typedef int (* rtems_block_device_ioctl) (dev_t dev, uint32_t req, void *argp);
/* rtems_disk_device: Entry of this type created for every disk device
* (both for logical and physical disks).
* Array of arrays of pointers to disk_device structures maintained. First
* table indexed by major number and second table indexed by minor number.
* Such data organization allow quick lookup using data structure of
* moderated size.
*/
typedef struct disk_device {
dev_t dev; /* Device ID (major + minor) */
struct disk_device *phys_dev; /* Physical device ID (the same
as dev if this entry specifies
the physical device) */
char *name; /* Disk device name */
int uses; /* Use counter. Device couldn't be
removed if it is in use. */
int start; /* Starting block number (0 for
physical devices, block offset
on the related physical device
for logical device) */
int size; /* Size of physical or logical disk
in disk blocks */
int block_size; /* Size of device block (minimum
transfer unit) in bytes
(must be power of 2) */
int block_size_log2; /* log2 of block_size */
rtems_bdpool_id pool; /* Buffer pool assigned to this
device */
block_device_ioctl ioctl; /* ioctl handler for this block
device */
} disk_device;
typedef struct rtems_disk_device {
dev_t dev; /* Device ID (major + minor) */
struct rtems_disk_device *phys_dev; /* Physical device ID (the same
as dev if this entry specifies
the physical device) */
uint32_t capabilities; /* Driver capabilities. */
char *name; /* Disk device name */
int uses; /* Use counter. Device couldn't be
removed if it is in use. */
int start; /* Starting block number (0 for
physical devices, block offset
on the related physical device
for logical device) */
int size; /* Size of physical or logical disk
in disk blocks */
int block_size; /* Size of device block (minimum
transfer unit) in bytes
(must be power of 2) */
int block_size_log2; /* log2 of block_size */
rtems_bdpool_id pool; /* Buffer pool assigned to this
device */
rtems_block_device_ioctl ioctl; /* ioctl handler for this block
device */
} rtems_disk_device;
/* rtems_disk_create_phys --
* Create physical disk entry. This function usually invoked from
@@ -84,7 +87,7 @@ typedef struct disk_device {
*/
rtems_status_code
rtems_disk_create_phys(dev_t dev, int block_size, int disk_size,
block_device_ioctl handler,
rtems_block_device_ioctl handler,
const char *name);
/* rtems_disk_create_log --
@@ -131,7 +134,7 @@ rtems_disk_create_log(dev_t dev, dev_t phys, int start, int size, char *name);
rtems_status_code
rtems_disk_delete(dev_t dev);
/* rtems_disk_lookup --
/* rtems_disk_obtain --
* Find block device descriptor by its device identifier. This function
* increment usage counter to 1. User should release disk_device structure
* by invoking rtems_disk_release primitive.
@@ -143,8 +146,8 @@ rtems_disk_delete(dev_t dev);
* pointer to the block device descriptor, or NULL if no such device
* exists.
*/
disk_device *
rtems_disk_lookup(dev_t dev);
rtems_disk_device *
rtems_disk_obtain(dev_t dev);
/* rtems_disk_release --
* Release disk_device structure (decrement usage counter to 1).
@@ -159,7 +162,7 @@ rtems_disk_lookup(dev_t dev);
* It should be implemented as inline function.
*/
rtems_status_code
rtems_disk_release(disk_device *dd);
rtems_disk_release(rtems_disk_device *dd);
/* rtems_disk_next --
* Disk device enumerator. Looking for device having device number larger
@@ -172,7 +175,7 @@ rtems_disk_release(disk_device *dd);
* RETURNS:
* Pointer to the disk descriptor for next disk device, or NULL if all
* devices enumerated. */
disk_device *
rtems_disk_device *
rtems_disk_next(dev_t dev);
/* rtems_diskio_initialize --

View File

@@ -77,16 +77,18 @@
* sector_data_t --
* corresponds to the sector on the device
*/
typedef struct sector_data_s
typedef struct rtems_sector_data_s
{
uint32_t sector_num; /* sector number on the device */
uint8_t data[0]; /* raw sector data */
} sector_data_t;
} rtems_sector_data_t;
/*
* Enum partition types
* see list at http://ata-atapi.com/hiwtab.htm
*
* @todo Should these have RTEMS before them.
*/
enum {
EMPTY_PARTITION = 0x00,
@@ -108,29 +110,32 @@ enum {
/* Forward declaration */
struct disk_desc_s;
struct rtems_disk_desc_s;
/*
* part_desc_t --
* contains all neccessary information about partition
*/
typedef struct part_desc_s {
typedef struct rtems_part_desc_s {
uint8_t bootable; /* is the partition active */
uint8_t sys_type; /* type of partition */
uint8_t log_id; /* logical number of partition */
uint32_t start; /* first partition sector, in absolute numeration */
uint32_t start; /* first partition sector, in absolute
* numeration */
uint32_t size; /* size in sectors */
uint32_t end; /* last partition sector, end = start + size - 1 */
struct disk_desc_s *disk_desc; /* descriptor of disk, partition contains in */
struct part_desc_s *ext_part; /* extended partition containing this one */
struct rtems_disk_desc_s *disk_desc; /* descriptor of disk, partition
* contains in */
struct rtems_part_desc_s *ext_part; /* extended partition containing this
* one */
/* partitions, containing in this one */
struct part_desc_s *sub_part[RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER];
} part_desc_t;
struct rtems_part_desc_s *sub_part[RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER];
} rtems_part_desc_t;
typedef struct disk_desc_s {
typedef struct rtems_disk_desc_s {
dev_t dev; /* device number */
/* device name in /dev filesystem */
@@ -142,8 +147,8 @@ typedef struct disk_desc_s {
int last_log_id; /* used for logical disks enumerating */
/* primary partition descriptors */
part_desc_t *partitions[RTEMS_IDE_PARTITION_MAX_PARTITION_NUMBER];
} disk_desc_t;
rtems_part_desc_t *partitions[RTEMS_IDE_PARTITION_MAX_PARTITION_NUMBER];
} rtems_disk_desc_t;
#ifdef __cplusplus
extern "C" {
@@ -160,7 +165,7 @@ extern "C" {
* N/A
*/
void
rtems_ide_part_table_free(disk_desc_t *disk_desc);
rtems_ide_part_table_free(rtems_disk_desc_t *disk_desc);
/*
@@ -176,7 +181,7 @@ rtems_ide_part_table_free(disk_desc_t *disk_desc);
* RTEMS_SUCCESSFUL if success, or -1 and corresponding errno else
*/
rtems_status_code
rtems_ide_part_table_get(const char *dev_name, disk_desc_t *disk_desc);
rtems_ide_part_table_get(const char *dev_name, rtems_disk_desc_t *disk_desc);
/*

View File

@@ -164,7 +164,7 @@ typedef struct rtems_nvdisk_config
const rtems_nvdisk_device_desc* devices; /**< The device descriptions. */
uint32_t flags; /**< Set of flags to control
driver. */
uint32_t info_level; /**< Default info level. */
uint32_t info_level; /**< Default info level. */
} rtems_nvdisk_config;
/*

View File

@@ -47,7 +47,7 @@ ramdisk_initialize(
void *arg);
#define RAMDISK_DRIVER_TABLE_ENTRY \
{ ramdisk_initialize, GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES }
{ ramdisk_initialize, RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES }
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@@ -38,10 +38,10 @@ rtems_blkdev_generic_read(
unsigned int block;
unsigned int blkofs;
dev_t dev;
disk_device *dd;
rtems_disk_device *dd;
dev = rtems_filesystem_make_dev_t(major, minor);
dd = rtems_disk_lookup(dev);
dd = rtems_disk_obtain(dev);
if (dd == NULL)
return RTEMS_INVALID_NUMBER;
@@ -57,7 +57,7 @@ rtems_blkdev_generic_read(
while (count > 0)
{
bdbuf_buffer *diskbuf;
rtems_bdbuf_buffer *diskbuf;
int copy;
rtems_status_code rc;
@@ -99,10 +99,10 @@ rtems_blkdev_generic_write(
unsigned int blkofs;
dev_t dev;
rtems_status_code rc;
disk_device *dd;
rtems_disk_device *dd;
dev = rtems_filesystem_make_dev_t(major, minor);
dd = rtems_disk_lookup(dev);
dd = rtems_disk_obtain(dev);
if (dd == NULL)
return RTEMS_INVALID_NUMBER;
@@ -118,7 +118,7 @@ rtems_blkdev_generic_write(
while (count > 0)
{
bdbuf_buffer *diskbuf;
rtems_bdbuf_buffer *diskbuf;
int copy;
if ((blkofs == 0) && (count >= block_size))
@@ -156,10 +156,10 @@ rtems_blkdev_generic_open(
void * arg)
{
dev_t dev;
disk_device *dd;
rtems_disk_device *dd;
dev = rtems_filesystem_make_dev_t(major, minor);
dd = rtems_disk_lookup(dev);
dd = rtems_disk_obtain(dev);
if (dd == NULL)
return RTEMS_INVALID_NUMBER;
@@ -181,10 +181,10 @@ rtems_blkdev_generic_close(
void * arg)
{
dev_t dev;
disk_device *dd;
rtems_disk_device *dd;
dev = rtems_filesystem_make_dev_t(major, minor);
dd = rtems_disk_lookup(dev);
dd = rtems_disk_obtain(dev);
if (dd == NULL)
return RTEMS_INVALID_NUMBER;
@@ -206,32 +206,32 @@ rtems_blkdev_generic_ioctl(
{
rtems_libio_ioctl_args_t *args = arg;
dev_t dev;
disk_device *dd;
rtems_disk_device *dd;
int rc;
dev = rtems_filesystem_make_dev_t(major, minor);
dd = rtems_disk_lookup(dev);
dd = rtems_disk_obtain(dev);
if (dd == NULL)
return RTEMS_INVALID_NUMBER;
switch (args->command)
{
case BLKIO_GETBLKSIZE:
case RTEMS_BLKIO_GETBLKSIZE:
args->ioctl_return = dd->block_size;
break;
case BLKIO_GETSIZE:
case RTEMS_BLKIO_GETSIZE:
args->ioctl_return = dd->size;
break;
case BLKIO_SYNCDEV:
case RTEMS_BLKIO_SYNCDEV:
rc = rtems_bdbuf_syncdev(dd->dev);
args->ioctl_return = (rc == RTEMS_SUCCESSFUL ? 0 : -1);
break;
case BLKIO_REQUEST:
case RTEMS_BLKIO_REQUEST:
{
blkdev_request *req = args->buffer;
rtems_blkdev_request *req = args->buffer;
req->start += dd->start;
args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
req);

View File

@@ -23,13 +23,13 @@
#define DISKTAB_INITIAL_SIZE 32
/* Table of disk devices having the same major number */
struct disk_device_table {
disk_device **minor; /* minor-indexed disk device table */
typedef struct rtems_disk_device_table {
rtems_disk_device **minor; /* minor-indexed disk device table */
int size; /* Number of entries in the table */
};
} rtems_disk_device_table;
/* Pointer to [major].minor[minor] indexed array of disk devices */
static struct disk_device_table *disktab;
static rtems_disk_device_table *disktab;
/* Number of allocated entries in disktab table */
static int disktab_size;
@@ -64,24 +64,24 @@ static volatile rtems_boolean diskdevs_protected;
* pointer to the disk device descriptor entry, or NULL if no memory
* available for its creation.
*/
static disk_device *
static rtems_disk_device *
create_disk_entry(dev_t dev)
{
rtems_device_major_number major;
rtems_device_minor_number minor;
struct disk_device **d;
rtems_disk_device **d;
rtems_filesystem_split_dev_t (dev, major, minor);
if (major >= disktab_size)
{
struct disk_device_table *p;
rtems_disk_device_table *p;
int newsize;
int i;
newsize = disktab_size * 2;
if (major >= newsize)
newsize = major + 1;
p = realloc(disktab, sizeof(struct disk_device_table) * newsize);
p = realloc(disktab, sizeof(rtems_disk_device_table) * newsize);
if (p == NULL)
return NULL;
p += disktab_size;
@@ -97,7 +97,7 @@ create_disk_entry(dev_t dev)
(minor >= disktab[major].size))
{
int newsize;
disk_device **p;
rtems_disk_device **p;
int i;
int s = disktab[major].size;
@@ -108,7 +108,8 @@ create_disk_entry(dev_t dev)
if (minor >= newsize)
newsize = minor + 1;
p = realloc(disktab[major].minor, sizeof(disk_device *) * newsize);
p = realloc(disktab[major].minor,
sizeof(rtems_disk_device *) * newsize);
if (p == NULL)
return NULL;
disktab[major].minor = p;
@@ -121,7 +122,7 @@ create_disk_entry(dev_t dev)
d = disktab[major].minor + minor;
if (*d == NULL)
{
*d = calloc(1, sizeof(disk_device));
*d = calloc(1, sizeof(rtems_disk_device));
}
return *d;
}
@@ -136,12 +137,12 @@ create_disk_entry(dev_t dev)
* Pointer to the disk device descriptor corresponding to the specified
* device number, or NULL if disk device with such number not exists.
*/
static inline disk_device *
static rtems_disk_device *
get_disk_entry(dev_t dev)
{
rtems_device_major_number major;
rtems_device_minor_number minor;
struct disk_device_table *dtab;
rtems_disk_device_table *dtab;
rtems_filesystem_split_dev_t (dev, major, minor);
@@ -171,9 +172,9 @@ get_disk_entry(dev_t dev)
* no memory available).
*/
static rtems_status_code
create_disk(dev_t dev, const char *name, disk_device **diskdev)
create_disk(dev_t dev, const char *name, rtems_disk_device **diskdev)
{
disk_device *dd;
rtems_disk_device *dd;
char *n;
dd = get_disk_entry(dev);
@@ -234,12 +235,12 @@ create_disk(dev_t dev, const char *name, disk_device **diskdev)
*/
rtems_status_code
rtems_disk_create_phys(dev_t dev, int block_size, int disk_size,
block_device_ioctl handler,
rtems_block_device_ioctl handler,
const char *name)
{
int bs_log2;
int i;
disk_device *dd;
rtems_disk_device *dd;
rtems_status_code rc;
rtems_bdpool_id pool;
rtems_device_major_number major;
@@ -284,6 +285,11 @@ rtems_disk_create_phys(dev_t dev, int block_size, int disk_size,
rc = rtems_io_register_name(name, major, minor);
if (handler (dd->phys_dev->dev,
RTEMS_BLKDEV_CAPABILITIES,
&dd->capabilities) < 0)
dd->capabilities = 0;
diskdevs_protected = FALSE;
rtems_semaphore_release(diskdevs_mutex);
@@ -317,8 +323,8 @@ rtems_disk_create_phys(dev_t dev, int block_size, int disk_size,
rtems_status_code
rtems_disk_create_log(dev_t dev, dev_t phys, int start, int size, char *name)
{
disk_device *dd;
disk_device *pdd;
rtems_disk_device *dd;
rtems_disk_device *pdd;
rtems_status_code rc;
rtems_device_major_number major;
rtems_device_minor_number minor;
@@ -393,12 +399,12 @@ rtems_disk_delete(dev_t dev)
used = 0;
for (maj = 0; maj < disktab_size; maj++)
{
struct disk_device_table *dtab = disktab + maj;
rtems_disk_device_table *dtab = disktab + maj;
if (dtab != NULL)
{
for (min = 0; min < dtab->size; min++)
{
disk_device *dd = dtab->minor[min];
rtems_disk_device *dd = dtab->minor[min];
if ((dd != NULL) && (dd->phys_dev->dev == dev))
used += dd->uses;
}
@@ -415,12 +421,12 @@ rtems_disk_delete(dev_t dev)
/* Delete this device and all of its logical devices */
for (maj = 0; maj < disktab_size; maj++)
{
struct disk_device_table *dtab = disktab +maj;
rtems_disk_device_table *dtab = disktab +maj;
if (dtab != NULL)
{
for (min = 0; min < dtab->size; min++)
{
disk_device *dd = dtab->minor[min];
rtems_disk_device *dd = dtab->minor[min];
if ((dd != NULL) && (dd->phys_dev->dev == dev))
{
unlink(dd->name);
@@ -437,7 +443,7 @@ rtems_disk_delete(dev_t dev)
return rc;
}
/* rtems_disk_lookup --
/* rtems_disk_obtain --
* Find block device descriptor by its device identifier.
*
* PARAMETERS:
@@ -447,11 +453,11 @@ rtems_disk_delete(dev_t dev)
* pointer to the block device descriptor, or NULL if no such device
* exists.
*/
disk_device *
rtems_disk_lookup(dev_t dev)
rtems_disk_device *
rtems_disk_obtain(dev_t dev)
{
rtems_interrupt_level level;
disk_device *dd;
rtems_disk_device *dd;
rtems_status_code rc;
rtems_interrupt_disable(level);
@@ -480,7 +486,7 @@ rtems_disk_lookup(dev_t dev)
}
/* rtems_disk_release --
* Release disk_device structure (decrement usage counter to 1).
* Release rtems_disk_device structure (decrement usage counter to 1).
*
* PARAMETERS:
* dd - pointer to disk device structure
@@ -489,7 +495,7 @@ rtems_disk_lookup(dev_t dev)
* RTEMS_SUCCESSFUL
*/
rtems_status_code
rtems_disk_release(disk_device *dd)
rtems_disk_release(rtems_disk_device *dd)
{
rtems_interrupt_level level;
rtems_interrupt_disable(level);
@@ -510,12 +516,12 @@ rtems_disk_release(disk_device *dd)
* Pointer to the disk descriptor for next disk device, or NULL if all
* devices enumerated.
*/
disk_device *
rtems_disk_device *
rtems_disk_next(dev_t dev)
{
rtems_device_major_number major;
rtems_device_minor_number minor;
struct disk_device_table *dtab;
rtems_disk_device_table *dtab;
dev++;
rtems_filesystem_split_dev_t (dev, major, minor);
@@ -562,7 +568,7 @@ rtems_disk_io_initialize(void)
return RTEMS_SUCCESSFUL;
disktab_size = DISKTAB_INITIAL_SIZE;
disktab = calloc(disktab_size, sizeof(struct disk_device_table));
disktab = calloc(disktab_size, sizeof(rtems_disk_device_table));
if (disktab == NULL)
return RTEMS_NO_MEMORY;
@@ -578,8 +584,7 @@ rtems_disk_io_initialize(void)
return rc;
}
rc = rtems_bdbuf_init(rtems_bdbuf_configuration,
rtems_bdbuf_configuration_size);
rc = rtems_bdbuf_init();
if (rc != RTEMS_SUCCESSFUL)
{
@@ -612,12 +617,12 @@ rtems_disk_io_done(void)
/* Free data structures */
for (maj = 0; maj < disktab_size; maj++)
{
struct disk_device_table *dtab = disktab + maj;
rtems_disk_device_table *dtab = disktab + maj;
if (dtab != NULL)
{
for (min = 0; min < dtab->size; min++)
{
disk_device *dd = dtab->minor[min];
rtems_disk_device *dd = dtab->minor[min];
unlink(dd->name);
free(dd->name);
free(dd);

View File

@@ -2057,14 +2057,13 @@ rtems_fdisk_write_block (rtems_flashdisk* fd,
* @retval int The ioctl return value.
*/
static int
rtems_fdisk_read (rtems_flashdisk* fd, blkdev_request* req)
rtems_fdisk_read (rtems_flashdisk* fd, rtems_blkdev_request* req)
{
blkdev_sg_buffer* sg = req->bufs;
uint32_t block = req->start;
uint32_t b;
int ret = 0;
rtems_blkdev_sg_buffer* sg = req->bufs;
uint32_t b;
int ret = 0;
for (b = 0; b < req->bufnum; b++, block++, sg++)
for (b = 0; b < req->bufnum; b++, sg++)
{
uint32_t length = sg->length;
@@ -2077,7 +2076,7 @@ rtems_fdisk_read (rtems_flashdisk* fd, blkdev_request* req)
length = fd->block_size;
}
ret = rtems_fdisk_read_block (fd, block, sg->buffer);
ret = rtems_fdisk_read_block (fd, sg->block, sg->buffer);
if (ret)
break;
@@ -2098,14 +2097,13 @@ rtems_fdisk_read (rtems_flashdisk* fd, blkdev_request* req)
* @retval int The ioctl return value.
*/
static int
rtems_fdisk_write (rtems_flashdisk* fd, blkdev_request* req)
rtems_fdisk_write (rtems_flashdisk* fd, rtems_blkdev_request* req)
{
blkdev_sg_buffer* sg = req->bufs;
uint32_t block = req->start;
uint32_t b;
int ret = 0;
rtems_blkdev_sg_buffer* sg = req->bufs;
uint32_t b;
int ret = 0;
for (b = 0; b < req->bufnum; b++, block++, sg++)
for (b = 0; b < req->bufnum; b++, sg++)
{
if (sg->length != fd->block_size)
{
@@ -2113,7 +2111,7 @@ rtems_fdisk_write (rtems_flashdisk* fd, blkdev_request* req)
"bd:%d fd:%d", sg->length, fd->block_size);
}
ret = rtems_fdisk_write_block (fd, block, sg->buffer);
ret = rtems_fdisk_write_block (fd, sg->block, sg->buffer);
if (ret)
break;
@@ -2356,7 +2354,7 @@ static int
rtems_fdisk_ioctl (dev_t dev, uint32_t req, void* argp)
{
rtems_device_minor_number minor = rtems_filesystem_dev_minor_t (dev);
blkdev_request* r = argp;
rtems_blkdev_request* r = argp;
rtems_status_code sc;
errno = 0;
@@ -2368,7 +2366,7 @@ rtems_fdisk_ioctl (dev_t dev, uint32_t req, void* argp)
{
switch (req)
{
case BLKIO_REQUEST:
case RTEMS_BLKIO_REQUEST:
if ((minor >= rtems_flashdisk_count) ||
(rtems_flashdisks[minor].device_count == 0))
{
@@ -2378,11 +2376,11 @@ rtems_fdisk_ioctl (dev_t dev, uint32_t req, void* argp)
{
switch (r->req)
{
case BLKDEV_REQ_READ:
case RTEMS_BLKDEV_REQ_READ:
errno = rtems_fdisk_read (&rtems_flashdisks[minor], r);
break;
case BLKDEV_REQ_WRITE:
case RTEMS_BLKDEV_REQ_WRITE:
errno = rtems_fdisk_write (&rtems_flashdisks[minor], r);
break;

View File

@@ -46,18 +46,18 @@
* and does not support devices with sector size other than 512 bytes
*/
static rtems_status_code
get_sector(dev_t dev, uint32_t sector_num, sector_data_t **sector)
get_sector(dev_t dev, uint32_t sector_num, rtems_sector_data_t **sector)
{
sector_data_t *s;
bdbuf_buffer *buf;
rtems_status_code rc;
rtems_sector_data_t *s;
rtems_bdbuf_buffer *buf;
rtems_status_code rc;
if (sector == NULL)
{
return RTEMS_INTERNAL_ERROR;
}
s = (sector_data_t *) malloc(sizeof(sector_data_t) + RTEMS_IDE_SECTOR_SIZE);
s = (rtems_sector_data_t *) malloc(sizeof(rtems_sector_data_t) + RTEMS_IDE_SECTOR_SIZE);
if (s == NULL)
{
return RTEMS_NO_MEMORY;
@@ -92,7 +92,7 @@ get_sector(dev_t dev, uint32_t sector_num, sector_data_t **sector)
* TRUE if sector has msdos signature, FALSE otherwise
*/
static rtems_boolean
msdos_signature_check (sector_data_t *sector)
msdos_signature_check (rtems_sector_data_t *sector)
{
uint8_t *p = sector->data + RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_OFFSET;
@@ -156,10 +156,10 @@ is_fat_partition(uint8_t type)
* RTEMS_INTERNAL_ERROR, if other error occurs.
*/
static rtems_status_code
data_to_part_desc(uint8_t *data, part_desc_t **new_part_desc)
data_to_part_desc(uint8_t *data, rtems_part_desc_t **new_part_desc)
{
part_desc_t *part_desc;
uint32_t temp;
rtems_part_desc_t *part_desc;
uint32_t temp;
if (new_part_desc == NULL)
{
@@ -168,7 +168,7 @@ data_to_part_desc(uint8_t *data, part_desc_t **new_part_desc)
*new_part_desc = NULL;
if ((part_desc = calloc(1, sizeof(part_desc_t))) == NULL)
if ((part_desc = calloc(1, sizeof(rtems_part_desc_t))) == NULL)
{
return RTEMS_NO_MEMORY;
}
@@ -219,15 +219,15 @@ data_to_part_desc(uint8_t *data, part_desc_t **new_part_desc)
* RTEMS_INTERNAL_ERROR if other error occurs.
*/
static rtems_status_code
read_extended_partition(uint32_t start, part_desc_t *ext_part)
read_extended_partition(uint32_t start, rtems_part_desc_t *ext_part)
{
int i;
dev_t dev;
sector_data_t *sector;
uint32_t here;
uint8_t *data;
part_desc_t *new_part_desc;
rtems_status_code rc;
int i;
dev_t dev;
rtems_sector_data_t *sector;
uint32_t here;
uint8_t *data;
rtems_part_desc_t *new_part_desc;
rtems_status_code rc;
if ((ext_part == NULL) || (ext_part->disk_desc == NULL))
{
@@ -286,7 +286,7 @@ read_extended_partition(uint32_t start, part_desc_t *ext_part)
}
else
{
disk_desc_t *disk_desc = new_part_desc->disk_desc;
rtems_disk_desc_t *disk_desc = new_part_desc->disk_desc;
disk_desc->partitions[disk_desc->last_log_id] = new_part_desc;
new_part_desc->log_id = ++disk_desc->last_log_id;
new_part_desc->start += here;
@@ -314,14 +314,14 @@ read_extended_partition(uint32_t start, part_desc_t *ext_part)
* RTEMS_INTERNAL_ERROR otherwise
*/
static rtems_status_code
read_mbr(disk_desc_t *disk_desc)
read_mbr(rtems_disk_desc_t *disk_desc)
{
int part_num;
sector_data_t *sector;
part_desc_t *part_desc;
uint8_t *data;
rtems_status_code rc;
dev_t dev = disk_desc->dev;
int part_num;
rtems_sector_data_t *sector;
rtems_part_desc_t *part_desc;
uint8_t *data;
rtems_status_code rc;
dev_t dev = disk_desc->dev;
/* get MBR sector */
rc = get_sector(dev, 0, &sector);
@@ -398,7 +398,7 @@ read_mbr(disk_desc_t *disk_desc)
* N/A
*/
static void
partition_free(part_desc_t *part_desc)
partition_free(rtems_part_desc_t *part_desc)
{
int part_num;
@@ -429,7 +429,7 @@ partition_free(part_desc_t *part_desc)
* N/A
*/
void
rtems_ide_part_table_free(disk_desc_t *disk_desc)
rtems_ide_part_table_free(rtems_disk_desc_t *disk_desc)
{
int part_num;
@@ -455,7 +455,7 @@ rtems_ide_part_table_free(disk_desc_t *disk_desc)
* RTEMS_INTERNAL_ERROR otherwise
*/
rtems_status_code
rtems_ide_part_table_get(const char *dev_name, disk_desc_t *disk_desc)
rtems_ide_part_table_get(const char *dev_name, rtems_disk_desc_t *disk_desc)
{
struct stat dev_stat;
rtems_status_code rc;
@@ -494,16 +494,16 @@ rtems_ide_part_table_initialize(char *dev_name)
{
int part_num;
dev_t dev;
disk_desc_t *disk_desc;
rtems_disk_desc_t *disk_desc;
rtems_device_major_number major;
rtems_device_minor_number minor;
rtems_status_code rc;
part_desc_t *part_desc;
rtems_part_desc_t *part_desc;
/* logical device name /dev/hdxyy */
char name[RTEMS_IDE_PARTITION_DEV_NAME_LENGTH_MAX];
disk_desc = (disk_desc_t *) calloc(1, sizeof(disk_desc_t));
disk_desc = (rtems_disk_desc_t *) calloc(1, sizeof(rtems_disk_desc_t));
if (disk_desc == NULL)
{
return RTEMS_NO_MEMORY;

View File

@@ -51,7 +51,7 @@
* footprint targets. Leave in by default.
*/
#if !defined (RTEMS_NVDISK_TRACE)
#define RTEMS_NVDISK_TRACE 1
#define RTEMS_NVDISK_TRACE 0
#endif
/**
@@ -165,7 +165,7 @@ rtems_nvdisk_crc16_gen_factors (uint16_t pattern)
/**
* Print a message to the nvdisk output and flush it.
*
* @param fd The flashdisk control structure.
* @param nvd The nvdisk control structure.
* @param format The format string. See printf for details.
* @param ... The arguments for the format text.
* @return int The number of bytes written to the output.
@@ -189,7 +189,7 @@ rtems_nvdisk_printf (const rtems_nvdisk* nvd, const char *format, ...)
/**
* Print a info message to the nvdisk output and flush it.
*
* @param fd The flashdisk control structure.
* @param nvd The nvdisk control structure.
* @param format The format string. See printf for details.
* @param ... The arguments for the format text.
* @return int The number of bytes written to the output.
@@ -213,7 +213,7 @@ rtems_nvdisk_info (const rtems_nvdisk* nvd, const char *format, ...)
/**
* Print a warning to the nvdisk output and flush it.
*
* @param fd The flashdisk control structure.
* @param nvd The nvdisk control structure.
* @param format The format string. See printf for details.
* @param ... The arguments for the format text.
* @return int The number of bytes written to the output.
@@ -255,24 +255,6 @@ rtems_nvdisk_error (const char *format, ...)
return ret;
}
/**
* Print an abort message, flush it then abort the program.
*
* @param format The format string. See printf for details.
* @param ... The arguments for the format text.
*/
static void
rtems_nvdisk_abort (const char *format, ...)
{
va_list args;
va_start (args, format);
fprintf (stderr, "nvdisk:abort:");
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
fflush (stderr);
exit (1);
}
/**
* Get the descriptor for a device.
*/
@@ -324,6 +306,7 @@ rtems_nvdisk_device_write (const rtems_nvdisk* nvd,
return ops->write (device, dd->flags, dd->base, offset, buffer, size);
}
#if NOT_USED
/**
* Verify the data with the data in a segment.
*/
@@ -344,6 +327,7 @@ rtems_nvdisk_device_verify (const rtems_nvdisk* nvd,
#endif
return ops->verify (device, dd->flags, dd->base, offset, buffer, size);
}
#endif
/**
* Read a page of data from the device.
@@ -373,20 +357,6 @@ rtems_nvdisk_write_page (const rtems_nvdisk* nvd,
buffer, nvd->block_size);
}
/**
* Verify a page of data with the data in the device.
*/
static int
rtems_nvdisk_verify_page (const rtems_nvdisk* nvd,
uint32_t device,
uint32_t page,
const void* buffer)
{
return rtems_nvdisk_device_verify (nvd, device,
page * nvd->block_size,
buffer, nvd->block_size);
}
/**
* Read the checksum from the device.
*/
@@ -532,7 +502,9 @@ rtems_nvdisk_read_block (rtems_nvdisk* nvd, uint32_t block, uint8_t* buffer)
if (crc == 0xffff)
{
#if RTEMS_NVDISK_TRACE
rtems_nvdisk_warning (nvd, "read-block: crc not set: %d", block);
#endif
memset (buffer, 0, nvd->block_size);
return 0;
}
@@ -605,13 +577,12 @@ rtems_nvdisk_write_block (rtems_nvdisk* nvd,
* @retval int The ioctl return value.
*/
static int
rtems_nvdisk_read (rtems_nvdisk* nvd, blkdev_request* req)
rtems_nvdisk_read (rtems_nvdisk* nvd, rtems_blkdev_request* req)
{
blkdev_sg_buffer* sg = req->bufs;
uint32_t block = req->start;
uint32_t b;
int32_t remains;
int ret = 0;
rtems_blkdev_sg_buffer* sg = req->bufs;
uint32_t b;
int32_t remains;
int ret = 0;
#if RTEMS_NVDISK_TRACE
rtems_nvdisk_info (nvd, "read: blocks=%d", req->bufnum);
@@ -619,7 +590,7 @@ rtems_nvdisk_read (rtems_nvdisk* nvd, blkdev_request* req)
remains = req->count * nvd->block_size;
for (b = 0; b < req->bufnum; b++, block++, sg++)
for (b = 0; b < req->bufnum; b++, sg++)
{
uint32_t length = sg->length;
@@ -658,18 +629,17 @@ rtems_nvdisk_read (rtems_nvdisk* nvd, blkdev_request* req)
* @retval int The ioctl return value.
*/
static int
rtems_nvdisk_write (rtems_nvdisk* nvd, blkdev_request* req)
rtems_nvdisk_write (rtems_nvdisk* nvd, rtems_blkdev_request* req)
{
blkdev_sg_buffer* sg = req->bufs;
uint32_t block = req->start;
uint32_t b;
int ret = 0;
rtems_blkdev_sg_buffer* sg = req->bufs;
uint32_t b;
int ret = 0;
#if RTEMS_NVDISK_TRACE
rtems_nvdisk_info (nvd, "write: blocks=%d", req->bufnum);
#endif
for (b = 0; b < req->bufnum; b++, block++, sg++)
for (b = 0; b < req->bufnum; b++, sg++)
{
if (sg->length != nvd->block_size)
{
@@ -720,7 +690,7 @@ rtems_nvdisk_erase_disk (rtems_nvdisk* nvd)
}
/**
* MV disk IOCTL handler.
* NV disk IOCTL handler.
*
* @param dev Device number (major, minor number).
* @param req IOCTL request code.
@@ -731,9 +701,21 @@ static int
rtems_nvdisk_ioctl (dev_t dev, uint32_t req, void* argp)
{
rtems_device_minor_number minor = rtems_filesystem_dev_minor_t (dev);
blkdev_request* r = argp;
rtems_blkdev_request* r = argp;
rtems_status_code sc;
if (minor >= rtems_nvdisk_count)
{
errno = ENODEV;
return -1;
}
if (rtems_nvdisks[minor].device_count == 0)
{
errno = ENODEV;
return -1;
}
errno = 0;
sc = rtems_semaphore_obtain (rtems_nvdisks[minor].lock, RTEMS_WAIT, 0);
@@ -743,28 +725,20 @@ rtems_nvdisk_ioctl (dev_t dev, uint32_t req, void* argp)
{
switch (req)
{
case BLKIO_REQUEST:
if ((minor >= rtems_nvdisk_count) ||
(rtems_nvdisks[minor].device_count == 0))
case RTEMS_BLKIO_REQUEST:
switch (r->req)
{
errno = ENODEV;
}
else
{
switch (r->req)
{
case BLKDEV_REQ_READ:
errno = rtems_nvdisk_read (&rtems_nvdisks[minor], r);
break;
case RTEMS_BLKDEV_REQ_READ:
errno = rtems_nvdisk_read (&rtems_nvdisks[minor], r);
break;
case BLKDEV_REQ_WRITE:
errno = rtems_nvdisk_write (&rtems_nvdisks[minor], r);
break;
case RTEMS_BLKDEV_REQ_WRITE:
errno = rtems_nvdisk_write (&rtems_nvdisks[minor], r);
break;
default:
errno = EBADRQC;
break;
}
default:
errno = EBADRQC;
break;
}
break;

View File

@@ -22,6 +22,14 @@
#include "rtems/diskdevs.h"
#include "rtems/ramdisk.h"
/**
* Control tracing. It can be compiled out of the code for small
* footprint targets. Leave in by default.
*/
#if !defined (RTEMS_RAMDISK_TRACE)
#define RTEMS_RAMDISK_TRACE 0
#endif
#define RAMDISK_DEVICE_BASE_NAME "/dev/ramdisk"
/* Internal RAM disk descriptor */
@@ -32,11 +40,40 @@ struct ramdisk {
rtems_boolean initialized;/* RAM disk is initialized */
rtems_boolean malloced; /* != 0, if memory allocated by malloc for this
RAM disk */
#if RTEMS_RAMDISK_TRACE
int info_level; /* Trace level */
#endif
};
static struct ramdisk *ramdisk;
static int nramdisks;
#if RTEMS_RAMDISK_TRACE
/**
* Print a message to the ramdisk output and flush it.
*
* @param rd The ramdisk control structure.
* @param format The format string. See printf for details.
* @param ... The arguments for the format text.
* @return int The number of bytes written to the output.
*/
static int
rtems_ramdisk_printf (struct ramdisk *rd, const char *format, ...)
{
int ret = 0;
if (rd->info_level >= 1)
{
va_list args;
va_start (args, format);
fprintf (stdout, "ramdisk:");
ret = vfprintf (stdout, format, args);
fprintf (stdout, "\n");
fflush (stdout);
}
return ret;
}
#endif
/* ramdisk_read --
* RAM disk READ request handler. This primitive copies data from RAM
* disk to supplied buffer and invoke the callout function to inform
@@ -49,19 +86,25 @@ static int nramdisks;
* ioctl return value
*/
static int
ramdisk_read(struct ramdisk *rd, blkdev_request *req)
ramdisk_read(struct ramdisk *rd, rtems_blkdev_request *req)
{
char *from;
uint32_t i;
blkdev_sg_buffer *sg;
rtems_blkdev_sg_buffer *sg;
uint32_t remains;
from = (char *)rd->area + (req->start * rd->block_size);
#if RTEMS_RAMDISK_TRACE
rtems_ramdisk_printf (rd, "ramdisk read: start=%d, blocks=%d remains=%d",
req->bufs[0].block, req->bufnum,
rd->block_size * req->count);
#endif
remains = rd->block_size * req->count;
sg = req->bufs;
for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
{
int count = sg->length;
from = ((char *)rd->area + (sg->block * rd->block_size));
if (count > remains)
count = remains;
memcpy(sg->buffer, from, count);
@@ -84,19 +127,24 @@ ramdisk_read(struct ramdisk *rd, blkdev_request *req)
* ioctl return value
*/
static int
ramdisk_write(struct ramdisk *rd, blkdev_request *req)
ramdisk_write(struct ramdisk *rd, rtems_blkdev_request *req)
{
char *to;
uint32_t i;
blkdev_sg_buffer *sg;
rtems_blkdev_sg_buffer *sg;
uint32_t remains;
to = (char *)rd->area + (req->start * rd->block_size);
#if RTEMS_RAMDISK_TRACE
rtems_ramdisk_printf (rd, "ramdisk write: start=%d, blocks=%d remains=%d",
req->bufs[0].block, req->bufnum,
rd->block_size * req->count);
#endif
remains = rd->block_size * req->count;
sg = req->bufs;
for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
{
int count = sg->length;
to = ((char *)rd->area + (sg->block * rd->block_size));
if (count > remains)
count = remains;
memcpy(to, sg->buffer, count);
@@ -123,10 +171,10 @@ ramdisk_ioctl(dev_t dev, uint32_t req, void *argp)
{
switch (req)
{
case BLKIO_REQUEST:
case RTEMS_BLKIO_REQUEST:
{
rtems_device_minor_number minor;
blkdev_request *r = argp;
rtems_blkdev_request *r = argp;
struct ramdisk *rd;
minor = rtems_filesystem_dev_minor_t(dev);
@@ -140,10 +188,10 @@ ramdisk_ioctl(dev_t dev, uint32_t req, void *argp)
switch (r->req)
{
case BLKDEV_REQ_READ:
case RTEMS_BLKDEV_REQ_READ:
return ramdisk_read(rd, r);
case BLKDEV_REQ_WRITE:
case RTEMS_BLKDEV_REQ_WRITE:
return ramdisk_write(rd, r);
default:
@@ -188,7 +236,9 @@ ramdisk_initialize(
r = ramdisk = calloc(rtems_ramdisk_configuration_size,
sizeof(struct ramdisk));
#if RTEMS_RAMDISK_TRACE
r->info_level = 1;
#endif
for (i = 0; i < rtems_ramdisk_configuration_size; i++, c++, r++)
{
dev_t dev = rtems_filesystem_make_dev_t(major, i);

View File

@@ -26,6 +26,137 @@
#include "fat.h"
#include "fat_fat_operations.h"
int
fat_buf_access(fat_fs_info_t *fs_info, uint32_t blk, int op_type,
rtems_bdbuf_buffer **buf)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
uint8_t i;
rtems_boolean sec_of_fat;
if (fs_info->c.state == FAT_CACHE_EMPTY)
{
if (op_type == FAT_OP_TYPE_READ)
sc = rtems_bdbuf_read(fs_info->vol.dev, blk, &fs_info->c.buf);
else
sc = rtems_bdbuf_get(fs_info->vol.dev, blk, &fs_info->c.buf);
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
fs_info->c.blk_num = blk;
fs_info->c.modified = 0;
fs_info->c.state = FAT_CACHE_ACTUAL;
}
sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) &&
(fs_info->c.blk_num < fs_info->vol.rdir_loc));
if (fs_info->c.blk_num != blk)
{
if (fs_info->c.modified)
{
if (sec_of_fat && !fs_info->vol.mirror)
memcpy(fs_info->sec_buf, fs_info->c.buf->buffer,
fs_info->vol.bps);
sc = rtems_bdbuf_release_modified(fs_info->c.buf);
fs_info->c.state = FAT_CACHE_EMPTY;
fs_info->c.modified = 0;
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
if (sec_of_fat && !fs_info->vol.mirror)
{
rtems_bdbuf_buffer *b;
for (i = 1; i < fs_info->vol.fats; i++)
{
sc = rtems_bdbuf_get(fs_info->vol.dev,
fs_info->c.blk_num +
fs_info->vol.fat_length * i,
&b);
if ( sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(ENOMEM);
memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps);
sc = rtems_bdbuf_release_modified(b);
if ( sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(ENOMEM);
}
}
}
else
{
sc = rtems_bdbuf_release(fs_info->c.buf);
fs_info->c.state = FAT_CACHE_EMPTY;
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
}
if (op_type == FAT_OP_TYPE_READ)
sc = rtems_bdbuf_read(fs_info->vol.dev, blk, &fs_info->c.buf);
else
sc = rtems_bdbuf_get(fs_info->vol.dev, blk, &fs_info->c.buf);
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
fs_info->c.blk_num = blk;
fs_info->c.state = FAT_CACHE_ACTUAL;
}
*buf = fs_info->c.buf;
return RC_OK;
}
int
fat_buf_release(fat_fs_info_t *fs_info)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
uint8_t i;
rtems_boolean sec_of_fat;
if (fs_info->c.state == FAT_CACHE_EMPTY)
return RC_OK;
sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) &&
(fs_info->c.blk_num < fs_info->vol.rdir_loc));
if (fs_info->c.modified)
{
if (sec_of_fat && !fs_info->vol.mirror)
memcpy(fs_info->sec_buf, fs_info->c.buf->buffer, fs_info->vol.bps);
sc = rtems_bdbuf_release_modified(fs_info->c.buf);
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
fs_info->c.modified = 0;
if (sec_of_fat && !fs_info->vol.mirror)
{
rtems_bdbuf_buffer *b;
for (i = 1; i < fs_info->vol.fats; i++)
{
sc = rtems_bdbuf_get(fs_info->vol.dev,
fs_info->c.blk_num +
fs_info->vol.fat_length * i,
&b);
if ( sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(ENOMEM);
memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps);
sc = rtems_bdbuf_release_modified(b);
if ( sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(ENOMEM);
}
}
}
else
{
sc = rtems_bdbuf_release(fs_info->c.buf);
if (sc != RTEMS_SUCCESSFUL)
rtems_set_errno_and_return_minus_one(EIO);
}
fs_info->c.state = FAT_CACHE_EMPTY;
return RC_OK;
}
/* _fat_block_read --
* This function reads 'count' bytes from device filesystem is mounted on,
* starts at 'start+offset' position where 'start' computed in sectors
@@ -57,7 +188,7 @@ _fat_block_read(
ssize_t cmpltd = 0;
uint32_t blk = start;
uint32_t ofs = offset;
bdbuf_buffer *block = NULL;
rtems_bdbuf_buffer *block = NULL;
uint32_t c = 0;
while (count > 0)
@@ -102,13 +233,13 @@ _fat_block_write(
uint32_t count,
const void *buff)
{
int rc = RC_OK;
fat_fs_info_t *fs_info = mt_entry->fs_info;
ssize_t cmpltd = 0;
uint32_t blk = start;
uint32_t ofs = offset;
bdbuf_buffer *block = NULL;
uint32_t c = 0;
int rc = RC_OK;
fat_fs_info_t *fs_info = mt_entry->fs_info;
ssize_t cmpltd = 0;
uint32_t blk = start;
uint32_t ofs = offset;
rtems_bdbuf_buffer *block = NULL;
uint32_t c = 0;
while(count > 0)
{
@@ -133,9 +264,6 @@ _fat_block_write(
return cmpltd;
}
/* fat_cluster_read --
* wrapper for reading a whole cluster at once
*
@@ -215,7 +343,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
ssize_t ret = 0;
struct stat stat_buf;
int i = 0;
bdbuf_buffer *block = NULL;
rtems_bdbuf_buffer *block = NULL;
rc = stat(mt_entry->dev, &stat_buf);
if (rc == -1)
@@ -223,12 +351,12 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
/* rtmes feature: no block devices, all are character devices */
if (!S_ISCHR(stat_buf.st_mode))
set_errno_and_return_minus_one(ENOTBLK);
rtems_set_errno_and_return_minus_one(ENOTBLK);
/* check that device is registred as block device and lock it */
vol->dd = rtems_disk_lookup(stat_buf.st_dev);
/* check that device is registred as block device and lock it */
vol->dd = rtems_disk_obtain(stat_buf.st_dev);
if (vol->dd == NULL)
set_errno_and_return_minus_one(ENOTBLK);
rtems_set_errno_and_return_minus_one(ENOTBLK);
vol->dev = stat_buf.st_dev;
@@ -238,7 +366,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
if (sc != RTEMS_SUCCESSFUL)
{
rtems_disk_release(vol->dd);
set_errno_and_return_minus_one( EIO);
rtems_set_errno_and_return_minus_one( EIO);
}
memcpy( boot_rec, block->buffer, FAT_MAX_BPB_SIZE);
@@ -247,7 +375,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
if (sc != RTEMS_SUCCESSFUL)
{
rtems_disk_release(vol->dd);
set_errno_and_return_minus_one( EIO);
rtems_set_errno_and_return_minus_one( EIO );
}
/* Evaluate boot record */
@@ -259,7 +387,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
(vol->bps != 4096))
{
rtems_disk_release(vol->dd);
set_errno_and_return_minus_one( EINVAL );
rtems_set_errno_and_return_minus_one( EINVAL );
}
for (vol->sec_mul = 0, i = (vol->bps >> FAT_SECTOR512_BITS); (i & 1) == 0;
@@ -275,7 +403,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
if (vol->spc == 0)
{
rtems_disk_release(vol->dd);
set_errno_and_return_minus_one(EINVAL);
rtems_set_errno_and_return_minus_one(EINVAL);
}
for (vol->spc_log2 = 0, i = vol->spc; (i & 1) == 0;
@@ -287,7 +415,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
if ((vol->bpc = vol->bps << vol->spc_log2) > MS_BYTES_PER_CLUSTER_LIMIT)
{
rtems_disk_release(vol->dd);
set_errno_and_return_minus_one(EINVAL);
rtems_set_errno_and_return_minus_one(EINVAL);
}
for (vol->bpc_log2 = 0, i = vol->bpc; (i & 1) == 0;
@@ -361,7 +489,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
if( vol->info_sec == 0 )
{
rtems_disk_release(vol->dd);
set_errno_and_return_minus_one( EINVAL );
rtems_set_errno_and_return_minus_one( EINVAL );
}
else
{
@@ -377,7 +505,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
FAT_FSINFO_LEAD_SIGNATURE_VALUE)
{
rtems_disk_release(vol->dd);
set_errno_and_return_minus_one( EINVAL );
rtems_set_errno_and_return_minus_one( EINVAL );
}
else
{
@@ -412,25 +540,25 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
vol->afat_loc = vol->fat_loc + vol->fat_length * vol->afat;
/* set up collection of fat-files fd */
fs_info->vhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control));
fs_info->vhash = calloc(FAT_HASH_SIZE, sizeof(rtems_chain_control));
if ( fs_info->vhash == NULL )
{
rtems_disk_release(vol->dd);
set_errno_and_return_minus_one( ENOMEM );
rtems_set_errno_and_return_minus_one( ENOMEM );
}
for (i = 0; i < FAT_HASH_SIZE; i++)
_Chain_Initialize_empty(fs_info->vhash + i);
rtems_chain_initialize_empty(fs_info->vhash + i);
fs_info->rhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control));
fs_info->rhash = calloc(FAT_HASH_SIZE, sizeof(rtems_chain_control));
if ( fs_info->rhash == NULL )
{
rtems_disk_release(vol->dd);
free(fs_info->vhash);
set_errno_and_return_minus_one( ENOMEM );
rtems_set_errno_and_return_minus_one( ENOMEM );
}
for (i = 0; i < FAT_HASH_SIZE; i++)
_Chain_Initialize_empty(fs_info->rhash + i);
rtems_chain_initialize_empty(fs_info->rhash + i);
fs_info->uino_pool_size = FAT_UINO_POOL_INIT_SIZE;
fs_info->uino_base = (vol->tot_secs << vol->sec_mul) << 4;
@@ -441,7 +569,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
rtems_disk_release(vol->dd);
free(fs_info->vhash);
free(fs_info->rhash);
set_errno_and_return_minus_one( ENOMEM );
rtems_set_errno_and_return_minus_one( ENOMEM );
}
fs_info->sec_buf = (uint8_t *)calloc(vol->bps, sizeof(uint8_t));
if (fs_info->sec_buf == NULL)
@@ -450,7 +578,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
free(fs_info->vhash);
free(fs_info->rhash);
free(fs_info->uino);
set_errno_and_return_minus_one( ENOMEM );
rtems_set_errno_and_return_minus_one( ENOMEM );
}
return RC_OK;
@@ -488,19 +616,19 @@ fat_shutdown_drive(rtems_filesystem_mount_table_entry_t *mt_entry)
for (i = 0; i < FAT_HASH_SIZE; i++)
{
Chain_Node *node = NULL;
Chain_Control *the_chain = fs_info->vhash + i;
rtems_chain_node *node = NULL;
rtems_chain_control *the_chain = fs_info->vhash + i;
while ( (node = _Chain_Get(the_chain)) != NULL )
while ( (node = rtems_chain_get(the_chain)) != NULL )
free(node);
}
for (i = 0; i < FAT_HASH_SIZE; i++)
{
Chain_Node *node = NULL;
Chain_Control *the_chain = fs_info->rhash + i;
rtems_chain_node *node = NULL;
rtems_chain_control *the_chain = fs_info->rhash + i;
while ( (node = _Chain_Get(the_chain)) != NULL )
while ( (node = rtems_chain_get(the_chain)) != NULL )
free(node);
}
@@ -541,7 +669,7 @@ fat_init_clusters_chain(
buf = calloc(fs_info->vol.bpc, sizeof(char));
if ( buf == NULL )
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val)
{

View File

@@ -25,11 +25,6 @@ extern "C" {
#include <rtems/seterr.h>
/* XXX: temporary hack :(( */
#ifndef set_errno_and_return_minus_one
#define set_errno_and_return_minus_one rtems_set_errno_and_return_minus_one
#endif /* set_errno_and_return_minus_one */
#include <rtems/score/cpu.h>
#include <errno.h>
#include <rtems/bdbuf.h>
@@ -297,45 +292,45 @@ extern "C" {
*/
typedef struct fat_vol_s
{
uint16_t bps; /* bytes per sector */
uint8_t sec_log2; /* log2 of bps */
uint8_t sec_mul; /* log2 of 512bts sectors number per sector */
uint8_t spc; /* sectors per cluster */
uint8_t spc_log2; /* log2 of spc */
uint16_t bpc; /* bytes per cluster */
uint8_t bpc_log2; /* log2 of bytes per cluster */
uint8_t fats; /* number of FATs */
uint8_t type; /* FAT type */
uint32_t mask;
uint32_t eoc_val;
uint16_t fat_loc; /* FAT start */
uint32_t fat_length; /* sectors per FAT */
uint32_t rdir_loc; /* root directory start */
uint16_t rdir_entrs; /* files per root directory */
uint32_t rdir_secs; /* sectors per root directory */
uint32_t rdir_size; /* root directory size in bytes */
uint32_t tot_secs; /* total count of sectors */
uint32_t data_fsec; /* first data sector */
uint32_t data_cls; /* count of data clusters */
uint32_t rdir_cl; /* first cluster of the root directory */
uint16_t info_sec; /* FSInfo Sector Structure location */
uint32_t free_cls; /* last known free clusters count */
uint32_t next_cl; /* next free cluster number */
uint8_t mirror; /* mirroring enabla/disable */
uint32_t afat_loc; /* active FAT location */
uint8_t afat; /* the number of active FAT */
dev_t dev; /* device ID */
disk_device *dd; /* disk device (see libblock) */
void *private_data; /* reserved */
uint16_t bps; /* bytes per sector */
uint8_t sec_log2; /* log2 of bps */
uint8_t sec_mul; /* log2 of 512bts sectors number per sector */
uint8_t spc; /* sectors per cluster */
uint8_t spc_log2; /* log2 of spc */
uint16_t bpc; /* bytes per cluster */
uint8_t bpc_log2; /* log2 of bytes per cluster */
uint8_t fats; /* number of FATs */
uint8_t type; /* FAT type */
uint32_t mask;
uint32_t eoc_val;
uint16_t fat_loc; /* FAT start */
uint32_t fat_length; /* sectors per FAT */
uint32_t rdir_loc; /* root directory start */
uint16_t rdir_entrs; /* files per root directory */
uint32_t rdir_secs; /* sectors per root directory */
uint32_t rdir_size; /* root directory size in bytes */
uint32_t tot_secs; /* total count of sectors */
uint32_t data_fsec; /* first data sector */
uint32_t data_cls; /* count of data clusters */
uint32_t rdir_cl; /* first cluster of the root directory */
uint16_t info_sec; /* FSInfo Sector Structure location */
uint32_t free_cls; /* last known free clusters count */
uint32_t next_cl; /* next free cluster number */
uint8_t mirror; /* mirroring enabla/disable */
uint32_t afat_loc; /* active FAT location */
uint8_t afat; /* the number of active FAT */
dev_t dev; /* device ID */
rtems_disk_device *dd; /* disk device (see libblock) */
void *private_data; /* reserved */
} fat_vol_t;
typedef struct fat_cache_s
{
uint32_t blk_num;
rtems_boolean modified;
uint8_t state;
bdbuf_buffer *buf;
uint32_t blk_num;
rtems_boolean modified;
uint8_t state;
rtems_bdbuf_buffer *buf;
} fat_cache_t;
/*
@@ -344,15 +339,15 @@ typedef struct fat_cache_s
*/
typedef struct fat_fs_info_s
{
fat_vol_t vol; /* volume descriptor */
Chain_Control *vhash; /* "vhash" of fat-file descriptors */
Chain_Control *rhash; /* "rhash" of fat-file descriptors */
char *uino; /* array of unique ino numbers */
uint32_t index;
uint32_t uino_pool_size; /* size */
uint32_t uino_base;
fat_cache_t c; /* cache */
uint8_t *sec_buf; /* just placeholder for anything */
fat_vol_t vol; /* volume descriptor */
rtems_chain_control *vhash; /* "vhash" of fat-file descriptors */
rtems_chain_control *rhash; /* "rhash" of fat-file descriptors */
char *uino; /* array of unique ino numbers */
uint32_t index;
uint32_t uino_pool_size; /* size */
uint32_t uino_base;
fat_cache_t c; /* cache */
uint8_t *sec_buf; /* just placeholder for anything */
} fat_fs_info_t;
/*
@@ -415,145 +410,18 @@ fat_cluster_num_to_sector512_num(
fs_info->vol.sec_mul);
}
static inline int
fat_buf_access(fat_fs_info_t *fs_info, uint32_t blk, int op_type,
bdbuf_buffer **buf)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
uint8_t i;
rtems_boolean sec_of_fat;
if (fs_info->c.state == FAT_CACHE_EMPTY)
{
if (op_type == FAT_OP_TYPE_READ)
sc = rtems_bdbuf_read(fs_info->vol.dev, blk, &fs_info->c.buf);
else
sc = rtems_bdbuf_get(fs_info->vol.dev, blk, &fs_info->c.buf);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
fs_info->c.blk_num = blk;
fs_info->c.modified = 0;
fs_info->c.state = FAT_CACHE_ACTUAL;
}
sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) &&
(fs_info->c.blk_num < fs_info->vol.rdir_loc));
if (fs_info->c.blk_num != blk)
{
if (fs_info->c.modified)
{
if (sec_of_fat && !fs_info->vol.mirror)
memcpy(fs_info->sec_buf, fs_info->c.buf->buffer,
fs_info->vol.bps);
sc = rtems_bdbuf_release_modified(fs_info->c.buf);
fs_info->c.state = FAT_CACHE_EMPTY;
fs_info->c.modified = 0;
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
if (sec_of_fat && !fs_info->vol.mirror)
{
bdbuf_buffer *b;
for (i = 1; i < fs_info->vol.fats; i++)
{
sc = rtems_bdbuf_get(fs_info->vol.dev,
fs_info->c.blk_num +
fs_info->vol.fat_length * i,
&b);
if ( sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(ENOMEM);
memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps);
sc = rtems_bdbuf_release_modified(b);
if ( sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(ENOMEM);
}
}
}
else
{
sc = rtems_bdbuf_release(fs_info->c.buf);
fs_info->c.state = FAT_CACHE_EMPTY;
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
}
if (op_type == FAT_OP_TYPE_READ)
sc = rtems_bdbuf_read(fs_info->vol.dev, blk, &fs_info->c.buf);
else
sc = rtems_bdbuf_get(fs_info->vol.dev, blk, &fs_info->c.buf);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
fs_info->c.blk_num = blk;
fs_info->c.state = FAT_CACHE_ACTUAL;
}
*buf = fs_info->c.buf;
return RC_OK;
}
static inline int
fat_buf_release(fat_fs_info_t *fs_info)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
uint8_t i;
rtems_boolean sec_of_fat;
if (fs_info->c.state == FAT_CACHE_EMPTY)
return RC_OK;
sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) &&
(fs_info->c.blk_num < fs_info->vol.rdir_loc));
if (fs_info->c.modified)
{
if (sec_of_fat && !fs_info->vol.mirror)
memcpy(fs_info->sec_buf, fs_info->c.buf->buffer, fs_info->vol.bps);
sc = rtems_bdbuf_release_modified(fs_info->c.buf);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
fs_info->c.modified = 0;
if (sec_of_fat && !fs_info->vol.mirror)
{
bdbuf_buffer *b;
for (i = 1; i < fs_info->vol.fats; i++)
{
sc = rtems_bdbuf_get(fs_info->vol.dev,
fs_info->c.blk_num +
fs_info->vol.fat_length * i,
&b);
if ( sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(ENOMEM);
memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps);
sc = rtems_bdbuf_release_modified(b);
if ( sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(ENOMEM);
}
}
}
else
{
sc = rtems_bdbuf_release(fs_info->c.buf);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
}
fs_info->c.state = FAT_CACHE_EMPTY;
return RC_OK;
}
static inline void
fat_buf_mark_modified(fat_fs_info_t *fs_info)
{
fs_info->c.modified = TRUE;
}
int
fat_buf_access(fat_fs_info_t *fs_info, uint32_t blk, int op_type,
rtems_bdbuf_buffer **buf);
int
fat_buf_release(fat_fs_info_t *fs_info);
ssize_t
_fat_block_read(rtems_filesystem_mount_table_entry_t *mt_entry,

View File

@@ -229,13 +229,13 @@ fat_get_fat_cluster(
{
int rc = RC_OK;
register fat_fs_info_t *fs_info = mt_entry->fs_info;
bdbuf_buffer *block0 = NULL;
rtems_bdbuf_buffer *block0 = NULL;
uint32_t sec = 0;
uint32_t ofs = 0;
/* sanity check */
if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) )
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
sec = (FAT_FAT_OFFSET(fs_info->vol.type, cln) >> fs_info->vol.sec_log2) +
fs_info->vol.afat_loc;
@@ -284,7 +284,7 @@ fat_get_fat_cluster(
break;
default:
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
break;
}
@@ -311,17 +311,17 @@ fat_set_fat_cluster(
uint32_t in_val
)
{
int rc = RC_OK;
fat_fs_info_t *fs_info = mt_entry->fs_info;
uint32_t sec = 0;
uint32_t ofs = 0;
uint16_t fat16_clv = 0;
uint32_t fat32_clv = 0;
bdbuf_buffer *block0 = NULL;
int rc = RC_OK;
fat_fs_info_t *fs_info = mt_entry->fs_info;
uint32_t sec = 0;
uint32_t ofs = 0;
uint16_t fat16_clv = 0;
uint32_t fat32_clv = 0;
rtems_bdbuf_buffer *block0 = NULL;
/* sanity check */
if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) )
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
sec = (FAT_FAT_OFFSET(fs_info->vol.type, cln) >> fs_info->vol.sec_log2) +
fs_info->vol.afat_loc;
@@ -428,7 +428,7 @@ fat_set_fat_cluster(
break;
default:
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
break;
}

View File

@@ -10,6 +10,8 @@
*
*/
#define MSDOS_TRACE 1
#if HAVE_CONFIG_H
#include "config.h"
#endif
@@ -112,7 +114,7 @@ fat_file_open(
lfat_fd = (*fat_fd) = (fat_file_fd_t*)malloc(sizeof(fat_file_fd_t));
if ( lfat_fd == NULL )
set_errno_and_return_minus_one( ENOMEM );
rtems_set_errno_and_return_minus_one( ENOMEM );
lfat_fd->links_num = 1;
lfat_fd->flags &= ~FAT_FILE_REMOVED;
@@ -131,7 +133,7 @@ fat_file_open(
* XXX: kernel resource is unsufficient, but not the memory,
* but there is no suitable errno :(
*/
set_errno_and_return_minus_one( ENOMEM );
rtems_set_errno_and_return_minus_one( ENOMEM );
}
}
_hash_insert(fs_info->vhash, key, lfat_fd->ino, lfat_fd);
@@ -383,11 +385,11 @@ fat_file_write(
return cmpltd;
if ( start > fat_fd->fat_file_size )
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
if ((count > fat_fd->size_limit) ||
(start > fat_fd->size_limit - count))
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
rc = fat_file_extend(mt_entry, fat_fd, start + count, &c);
if (rc != RC_OK)
@@ -493,7 +495,7 @@ fat_file_extend(
if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
(fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
set_errno_and_return_minus_one( ENOSPC );
rtems_set_errno_and_return_minus_one( ENOSPC );
bytes_remain = (fs_info->vol.bpc -
(fat_fd->fat_file_size & (fs_info->vol.bpc - 1))) &
@@ -525,7 +527,7 @@ fat_file_extend(
/* this means that no space left on device */
if ((cls_added == 0) && (bytes_remain == 0))
set_errno_and_return_minus_one(ENOSPC);
rtems_set_errno_and_return_minus_one(ENOSPC);
/* check wether we satisfied request for 'cls2add' clusters */
if (cls2add != cls_added)
@@ -687,7 +689,7 @@ fat_file_ioctl(
/* sanity check */
if ( pos >= fat_fd->fat_file_size )
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
(fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
@@ -759,13 +761,13 @@ fat_file_datasync(
fat_file_fd_t *fat_fd
)
{
int rc = RC_OK;
rtems_status_code sc = RTEMS_SUCCESSFUL;
fat_fs_info_t *fs_info = mt_entry->fs_info;
uint32_t cur_cln = fat_fd->cln;
bdbuf_buffer *block = NULL;
uint32_t sec = 0;
uint32_t i = 0;
int rc = RC_OK;
rtems_status_code sc = RTEMS_SUCCESSFUL;
fat_fs_info_t *fs_info = mt_entry->fs_info;
uint32_t cur_cln = fat_fd->cln;
rtems_bdbuf_buffer *block = NULL;
uint32_t sec = 0;
uint32_t i = 0;
if (fat_fd->fat_file_size == 0)
return RC_OK;
@@ -788,11 +790,11 @@ fat_file_datasync(
/* ... sync it */
sc = rtems_bdbuf_read(fs_info->vol.dev, (sec + i), &block);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
sc = rtems_bdbuf_sync(block);
if ( sc != RTEMS_SUCCESSFUL )
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
}
rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
@@ -947,9 +949,7 @@ fat_file_lseek(
)
{
int rc = RC_OK;
/*
assert(fat_fd->fat_file_size);
*/
if (file_cln == fat_fd->map.file_cln)
*disk_cln = fat_fd->map.disk_cln;
else

View File

@@ -129,9 +129,9 @@ msdos_creat_node(
*MSDOS_DIR_FILE_SIZE(new_node) =*MSDOS_DIR_FILE_SIZE(link_node);
*MSDOS_DIR_FIRST_CLUSTER_LOW(new_node) =
*MSDOS_DIR_FIRST_CLUSTER_LOW(link_node);
*MSDOS_DIR_FIRST_CLUSTER_LOW(link_node);
*MSDOS_DIR_FIRST_CLUSTER_HI(new_node) =
*MSDOS_DIR_FIRST_CLUSTER_HI(link_node);
*MSDOS_DIR_FIRST_CLUSTER_HI(link_node);
/*
* set "archive bit" due to changes
*/
@@ -302,14 +302,14 @@ msdos_file_link(rtems_filesystem_location_info_t *to_loc,
* check spelling and format new node name
*/
if (MSDOS_NAME != msdos_get_token(token, new_name, &len)) {
set_errno_and_return_minus_one(ENAMETOOLONG);
rtems_set_errno_and_return_minus_one(ENAMETOOLONG);
}
/*
* verify, that the existing node can be linked to
* check that nodes are in same FS/volume?
*/
if (to_loc->mt_entry->fs_info != par_loc->mt_entry->fs_info) {
set_errno_and_return_minus_one(EXDEV);
rtems_set_errno_and_return_minus_one(EXDEV);
}
/*
* lock volume
@@ -317,7 +317,7 @@ msdos_file_link(rtems_filesystem_location_info_t *to_loc,
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
/*
@@ -334,7 +334,7 @@ msdos_file_link(rtems_filesystem_location_info_t *to_loc,
to_fat_fd->cln = FAT_EOF;
rc = msdos_set_first_cluster_num(to_loc->mt_entry, to_fat_fd);
if (rc == RC_OK) {
rc = msdos_set_file_size(par_loc->mt_entry, to_fat_fd);
rc = msdos_set_file_size(par_loc->mt_entry, to_fat_fd);
}
}
/*

View File

@@ -56,7 +56,7 @@ msdos_dir_open(rtems_libio_t *iop, const char *pathname, uint32_t flag,
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
rc = fat_file_reopen(fat_fd);
if (rc != RC_OK)
@@ -91,7 +91,7 @@ msdos_dir_close(rtems_libio_t *iop)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd);
if (rc != RC_OK)
@@ -233,7 +233,7 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
while (count > 0)
{
@@ -248,7 +248,7 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
{
rtems_semaphore_release(fs_info->vol_sema);
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
}
for (i = 0; i < ret; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
@@ -377,7 +377,7 @@ msdos_dir_lseek(rtems_libio_t *iop, off_t offset, int whence)
*/
case SEEK_END:
default:
set_errno_and_return_minus_one( EINVAL );
rtems_set_errno_and_return_minus_one( EINVAL );
break;
}
return RC_OK;
@@ -416,7 +416,7 @@ msdos_dir_stat(
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
buf->st_dev = fs_info->fat.vol.dev;
buf->st_ino = fat_fd->ino;
@@ -463,7 +463,7 @@ msdos_dir_sync(rtems_libio_t *iop)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
@@ -495,7 +495,7 @@ msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
/*
* We deny attemp to delete open directory (if directory is current
@@ -504,7 +504,7 @@ msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc)
if (fat_fd->links_num > 1)
{
rtems_semaphore_release(fs_info->vol_sema);
set_errno_and_return_minus_one(EBUSY);
rtems_set_errno_and_return_minus_one(EBUSY);
}
/*
@@ -520,7 +520,7 @@ msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc)
if (!is_empty)
{
rtems_semaphore_release(fs_info->vol_sema);
set_errno_and_return_minus_one(ENOTEMPTY);
rtems_set_errno_and_return_minus_one(ENOTEMPTY);
}
/*
@@ -529,7 +529,7 @@ msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc)
if (pathloc->mt_entry->mt_fs_root.node_access == pathloc->node_access)
{
rtems_semaphore_release(fs_info->vol_sema);
set_errno_and_return_minus_one(EBUSY);
rtems_set_errno_and_return_minus_one(EBUSY);
}
/*

View File

@@ -89,7 +89,7 @@ msdos_eval_path(
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
if (!pathloc->node_access)
{
@@ -271,7 +271,7 @@ msdos_eval4make(
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
if (!pathloc->node_access)
{

View File

@@ -53,7 +53,7 @@ msdos_file_open(rtems_libio_t *iop, const char *pathname, uint32_t flag,
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
rc = fat_file_reopen(fat_fd);
if (rc != RC_OK)
@@ -94,7 +94,7 @@ msdos_file_close(rtems_libio_t *iop)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
/*
* if fat-file descriptor is not marked as "removed", synchronize
@@ -154,7 +154,7 @@ msdos_file_read(rtems_libio_t *iop, void *buffer, size_t count)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
buffer);
@@ -187,7 +187,7 @@ msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
ret = fat_file_write(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
buffer);
@@ -235,7 +235,7 @@ msdos_file_lseek(rtems_libio_t *iop, off_t offset, int whence)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
rc = fat_file_extend(iop->pathinfo.mt_entry, fat_fd, iop->offset,
&real_size);
@@ -276,7 +276,7 @@ msdos_file_stat(
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
buf->st_dev = fs_info->fat.vol.dev;
buf->st_ino = fat_fd->ino;
@@ -315,7 +315,7 @@ msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
rc = fat_file_truncate(iop->pathinfo.mt_entry, fat_fd, length);
if (rc != RC_OK)
@@ -356,7 +356,7 @@ msdos_file_sync(rtems_libio_t *iop)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
/* synchronize file data */
rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
@@ -416,7 +416,7 @@ msdos_file_datasync(rtems_libio_t *iop)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
/* synchronize file data */
rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
@@ -466,7 +466,7 @@ msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
/* mark file removed */
rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln,

View File

@@ -277,7 +277,7 @@ static int msdos_format_eval_sectors_per_cluster
} while (!finished);
if (ret_val != 0) {
set_errno_and_return_minus_one(ret_val);
rtems_set_errno_and_return_minus_one(ret_val);
}
else {
*sectors_per_cluster_adj = sectors_per_cluster;
@@ -298,9 +298,9 @@ static int msdos_format_determine_fmt_params
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
const disk_device *dd, /* disk device structure */
const rtems_disk_device *dd, /* disk device structure */
const msdos_format_request_param_t *rqdata, /* requested fmt parameters */
msdos_format_param_t *fmt_params/* computed fmt parameters */
msdos_format_param_t *fmt_params/* computed fmt parameters */
)
/*-------------------------------------------------------------------------*\
| Return Value: |
@@ -613,7 +613,7 @@ static int msdos_format_determine_fmt_params
* Phuuu.... That's it.
*/
if (ret_val != 0) {
set_errno_and_return_minus_one(ret_val);
rtems_set_errno_and_return_minus_one(ret_val);
}
else {
return 0;
@@ -791,13 +791,13 @@ int msdos_format
| 0, if success, -1 and errno if failed |
\*=========================================================================*/
{
char tmp_sec[FAT_TOTAL_MBR_SIZE];
int rc;
disk_device *dd = NULL;
struct stat stat_buf;
int ret_val = 0;
int fd = -1;
int i;
char tmp_sec[FAT_TOTAL_MBR_SIZE];
int rc;
rtems_disk_device *dd = NULL;
struct stat stat_buf;
int ret_val = 0;
int fd = -1;
int i;
msdos_format_param_t fmt_params;
/*
@@ -817,7 +817,7 @@ int msdos_format
/* check that device is registered as block device and lock it */
if (ret_val == 0) {
dd = rtems_disk_lookup(stat_buf.st_dev);
dd = rtems_disk_obtain(stat_buf.st_dev);
if (dd == NULL) {
errno = ENOTBLK;
ret_val = -1;

View File

@@ -47,7 +47,7 @@ msdos_free_node_info(rtems_filesystem_location_info_t *pathloc)
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
rc = fat_file_close(pathloc->mt_entry, pathloc->node_access);

View File

@@ -61,7 +61,7 @@ msdos_initialize_support(
fs_info = (msdos_fs_info_t *)calloc(1, sizeof(msdos_fs_info_t));
if (!fs_info)
set_errno_and_return_minus_one(ENOMEM);
rtems_set_errno_and_return_minus_one(ENOMEM);
temp_mt_entry->fs_info = fs_info;
@@ -124,7 +124,7 @@ msdos_initialize_support(
fat_file_close(temp_mt_entry, fat_fd);
fat_shutdown_drive(temp_mt_entry);
free(fs_info);
set_errno_and_return_minus_one(ENOMEM);
rtems_set_errno_and_return_minus_one(ENOMEM);
}
sc = rtems_semaphore_create(3,
@@ -138,7 +138,7 @@ msdos_initialize_support(
fat_shutdown_drive(temp_mt_entry);
free(fs_info->cl_buf);
free(fs_info);
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
}
temp_mt_entry->mt_fs_root.node_access = fat_fd;

View File

@@ -11,6 +11,8 @@
* @(#) $Id$
*/
#define MSDOS_TRACE 1
#if HAVE_CONFIG_H
#include "config.h"
#endif
@@ -786,7 +788,7 @@ int msdos_find_name_in_fat_file(
fs_info->cl_buf)) != FAT_EOF)
{
if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
assert(ret == bts2rd);
@@ -903,7 +905,7 @@ int msdos_find_node_by_cluster_num_in_fat_file(
fs_info->cl_buf)) != FAT_EOF)
{
if ( ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE )
set_errno_and_return_minus_one( EIO );
rtems_set_errno_and_return_minus_one( EIO );
assert(ret == bts2rd);

View File

@@ -74,12 +74,12 @@ int msdos_mknod(
type = MSDOS_REGULAR_FILE;
}
else
set_errno_and_return_minus_one(EINVAL);
rtems_set_errno_and_return_minus_one(EINVAL);
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one(EIO);
rtems_set_errno_and_return_minus_one(EIO);
/* Create an MSDOS node */
rc = msdos_creat_node(pathloc, type, new_name, mode, NULL);

View File

@@ -65,7 +65,7 @@ if LIBSHELL
noinst_LIBRARIES += libshell.a
libshell_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/shell
libshell_a_SOURCES = shell/cat_file.c shell/cmds.c shell/internal.h \
shell/main_alias.c shell/main_cat.c shell/main_cd.c \
shell/main_alias.c shell/main_cat.c shell/main_cd.c shell/cmp-ls.c \
shell/main_chdir.c shell/main_chmod.c shell/main_chroot.c \
shell/main_cp.c shell/main_cpuuse.c shell/main_date.c shell/main_dir.c \
shell/main_echo.c shell/main_exit.c shell/main_help.c shell/main_id.c \
@@ -78,8 +78,10 @@ libshell_a_SOURCES = shell/cat_file.c shell/cmds.c shell/internal.h \
shell/main_stackuse.c shell/main_tty.c shell/main_umask.c \
shell/main_unmount.c shell/main_blksync.c shell/main_whoami.c \
shell/shell.c shell/shell_cmdset.c shell/shell_getchar.c shell/shellconfig.c \
shell/shellconfig.h shell/shell.h shell/shell_makeargs.c shell/str2int.c \
shell/write_file.c shell/utils-cp.c shell/err.c shell/errx.c shell/verr.c \
shell/shellconfig.h shell/shell.h shell/shell_makeargs.c \
shell/str2int.c shell/filemode.c shell/pwcache.c shell/print-ls.c\
shell/write_file.c shell/utils-cp.c shell/utils-ls.c \
shell/err.c shell/errx.c shell/verr.c shell/vis.c \
shell/verrx.c shell/vwarn.c shell/vwarnx.c shell/warn.c shell/warnx.c \
shell/fts.c shell/print_heapinfo.c shell/main_wkspaceinfo.c \
shell/shell_script.c

View File

@@ -0,0 +1,200 @@
/* $NetBSD: cmp.c,v 1.17 2003/08/07 09:05:14 agc Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Michael Fischbein.
*
* 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. 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 0
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)cmp.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: cmp.c,v 1.17 2003/08/07 09:05:14 agc Exp $");
#endif
#endif /* not lint */
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fts.h>
#include <string.h>
#include "extern-ls.h"
#if defined(__rtems__) || defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || \
defined(_XOPEN_SOURCE) || defined(__NetBSD__)
#define ATIMENSEC_CMP(x, op, y) ((x)->st_atime op (y)->st_atime)
#define CTIMENSEC_CMP(x, op, y) ((x)->st_ctime op (y)->st_ctime)
#define MTIMENSEC_CMP(x, op, y) ((x)->st_mtime op (y)->st_mtime)
#else
#define ATIMENSEC_CMP(x, op, y) \
((x)->st_atime.tv_nsec op (y)->st_atime.tv_nsec)
#define CTIMENSEC_CMP(x, op, y) \
((x)->st_ctime.tv_nsec op (y)->st_ctime.tv_nsec)
#define MTIMENSEC_CMP(x, op, y) \
((x)->st_mtime.tv_nsec op (y)->st_mtime.tv_nsec)
#endif
int
namecmp(const FTSENT *a, const FTSENT *b)
{
return (strcmp(a->fts_name, b->fts_name));
}
int
revnamecmp(const FTSENT *a, const FTSENT *b)
{
return (strcmp(b->fts_name, a->fts_name));
}
int
modcmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_mtime > a->fts_statp->st_mtime)
return (1);
else if (b->fts_statp->st_mtime < a->fts_statp->st_mtime)
return (-1);
else if (MTIMENSEC_CMP(b->fts_statp, >, a->fts_statp))
return (1);
else if (MTIMENSEC_CMP(b->fts_statp, <, a->fts_statp))
return (-1);
else
return (namecmp(a, b));
}
int
revmodcmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_mtime > a->fts_statp->st_mtime)
return (-1);
else if (b->fts_statp->st_mtime < a->fts_statp->st_mtime)
return (1);
else if (MTIMENSEC_CMP(b->fts_statp, >, a->fts_statp))
return (-1);
else if (MTIMENSEC_CMP(b->fts_statp, <, a->fts_statp))
return (1);
else
return (revnamecmp(a, b));
}
int
acccmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_atime > a->fts_statp->st_atime)
return (1);
else if (b->fts_statp->st_atime < a->fts_statp->st_atime)
return (-1);
else if (ATIMENSEC_CMP(b->fts_statp, >, a->fts_statp))
return (1);
else if (ATIMENSEC_CMP(b->fts_statp, <, a->fts_statp))
return (-1);
else
return (namecmp(a, b));
}
int
revacccmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_atime > a->fts_statp->st_atime)
return (-1);
else if (b->fts_statp->st_atime < a->fts_statp->st_atime)
return (1);
else if (ATIMENSEC_CMP(b->fts_statp, >, a->fts_statp))
return (-1);
else if (ATIMENSEC_CMP(b->fts_statp, <, a->fts_statp))
return (1);
else
return (revnamecmp(a, b));
}
int
statcmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_ctime > a->fts_statp->st_ctime)
return (1);
else if (b->fts_statp->st_ctime < a->fts_statp->st_ctime)
return (-1);
else if (CTIMENSEC_CMP(b->fts_statp, >, a->fts_statp))
return (1);
else if (CTIMENSEC_CMP(b->fts_statp, <, a->fts_statp))
return (-1);
else
return (namecmp(a, b));
}
int
revstatcmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_ctime > a->fts_statp->st_ctime)
return (-1);
else if (b->fts_statp->st_ctime < a->fts_statp->st_ctime)
return (1);
else if (CTIMENSEC_CMP(b->fts_statp, >, a->fts_statp))
return (-1);
else if (CTIMENSEC_CMP(b->fts_statp, <, a->fts_statp))
return (1);
else
return (revnamecmp(a, b));
}
int
sizecmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_size > a->fts_statp->st_size)
return (1);
if (b->fts_statp->st_size < a->fts_statp->st_size)
return (-1);
else
return (namecmp(a, b));
}
int
revsizecmp(const FTSENT *a, const FTSENT *b)
{
if (b->fts_statp->st_size > a->fts_statp->st_size)
return (-1);
if (b->fts_statp->st_size < a->fts_statp->st_size)
return (1);
else
return (revnamecmp(a, b));
}

View File

@@ -84,7 +84,7 @@ int set_utimes(const char *, struct stat *);
int setfile(rtems_shell_cp_globals* cp_globals, struct stat *, int);
int preserve_dir_acls(struct stat *, char *, char *);
int preserve_fd_acls(int, int);
void usage();
void usage(rtems_shell_cp_globals* cp_globals);
__END_DECLS

View File

@@ -0,0 +1,195 @@
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Michael Fischbein.
*
* 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.
*
* from: @(#)ls.h 8.1 (Berkeley) 5/31/93
* $FreeBSD: src/bin/ls/ls.h,v 1.23 2008/04/04 03:57:46 grog Exp $
*/
#ifndef _EXTERN_LS_H_
#define _EXTERN_LS_H_
#define NO_PRINT 1
//#define COLORLS 1
#include <sys/cdefs.h>
#include <setjmp.h>
#define major(d) rtems_filesystem_dev_major_t(d)
#define minor(d) rtems_filesystem_dev_minor_t(d)
const char *user_from_uid(uid_t uid, int nouser);
typedef struct {
int blocksize;
int termwidth;
int sortkey;
int rval;
int output;
time_t now;
int f_accesstime;
int f_column;
int f_columnacross;
int f_flags;
int f_grouponly;
int f_humanize;
int f_inode;
int f_listdir;
int f_listdot;
int f_longform;
int f_nonprint;
int f_nosort;
int f_numericonly;
int f_octal;
int f_octal_escape;
int f_recursive;
int f_reversesort;
int f_sectime;
int f_singlecol;
int f_size;
int f_statustime;
int f_stream;
int f_type;
int f_typedir;
int f_whiteout;
int exit_code;
jmp_buf exit_jmp;
} rtems_shell_ls_globals;
#define blocksize globals->blocksize
#define termwidth globals->termwidth
#define sortkey globals->sortkey
#define rval globals->rval
#define output globals->output
#define now globals->now
#define f_accesstime globals->f_accesstime
#define f_column globals->f_column
#define f_columnacross globals->f_columnacross
#define f_flags globals->f_flags
#define f_grouponly globals->f_grouponly
#define f_humanize globals->f_humanize
#define f_inode globals->f_inode
#define f_listdir globals->f_listdir
#define f_listdot globals->f_listdot
#define f_longform globals->f_longform
#define f_nonprint globals->f_nonprint
#define f_nosort globals->f_nosort
#define f_numericonly globals->f_numericonly
#define f_octal globals->f_octal
#define f_octal_escape globals->f_octal_escape
#define f_recursive globals->f_recursive
#define f_reversesort globals->f_reversesort
#define f_sectime globals->f_sectime
#define f_singlecol globals->f_singlecol
#define f_size globals->f_size
#define f_statustime globals->f_statustime
#define f_stream globals->f_stream
#define f_type globals->f_type
#define f_typedir globals->f_typedir
#define f_whiteout globals->f_whiteout
#define exit_jump &(globals->exit_jmp)
void rtems_shell_ls_exit(rtems_shell_ls_globals* globals, int code);
#define exit(ec) rtems_shell_ls_exit(globals, ec)
typedef struct {
FTSENT *list;
u_int64_t btotal;
u_int64_t stotal;
int entries;
int maxlen;
int s_block;
int s_flags;
int s_group;
int s_inode;
int s_nlink;
int s_size;
int s_user;
int s_major;
int s_minor;
} DISPLAY;
typedef struct {
char *user;
char *group;
char *flags;
char data[1];
} NAMES;
#define acccmp rtems_shell_ls_acccmp
#define revacccmp rtems_shell_ls_revacccmp
#define modcmp rtems_shell_ls_modcmp
#define revmodcmp rtems_shell_ls_revmodcmp
#define namecmp rtems_shell_ls_namecmp
#define revnamecmp rtems_shell_ls_revnamecmp
#define statcmp rtems_shell_ls_statcmp
#define revstatcmp rtems_shell_ls_revstatcmp
#define sizecmp rtems_shell_ls_sizecmp
#define revsizecmp rtems_shell_ls_revsizecmp
#define printescaped rtems_shell_ls_printescaped
#define printacol rtems_shell_ls_printacol
#define printcol rtems_shell_ls_printcol
#define printlong rtems_shell_ls_printlong
#define printscol rtems_shell_ls_printscol
#define printstream rtems_shell_ls_printstream
#define usage rtems_shell_ls_usage
int acccmp(const FTSENT *, const FTSENT *);
int revacccmp(const FTSENT *, const FTSENT *);
int modcmp(const FTSENT *, const FTSENT *);
int revmodcmp(const FTSENT *, const FTSENT *);
int namecmp(const FTSENT *, const FTSENT *);
int revnamecmp(const FTSENT *, const FTSENT *);
int statcmp(const FTSENT *, const FTSENT *);
int revstatcmp(const FTSENT *, const FTSENT *);
int sizecmp(const FTSENT *, const FTSENT *);
int revsizecmp(const FTSENT *, const FTSENT *);
int printescaped(rtems_shell_ls_globals* globals, const char *);
void printacol(rtems_shell_ls_globals* globals, DISPLAY *);
void printcol(rtems_shell_ls_globals* globals, DISPLAY *);
void printlong(rtems_shell_ls_globals* globals, DISPLAY *);
void printscol(rtems_shell_ls_globals* globals, DISPLAY *);
void printstream(rtems_shell_ls_globals* globals, DISPLAY *);
int safe_print(rtems_shell_ls_globals* globals, const char *);
void usage(rtems_shell_ls_globals* globals);
void strmode(mode_t mode, char *p);
#define DAYSPERNYEAR 365
#define SECSPERDAY (60 * 60 * 24)
#endif /* !_EXTERN_H_ */

View File

@@ -0,0 +1,150 @@
/*-
* Copyright (c) 1990, 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 defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)strmode.c 8.3 (Berkeley) 8/15/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/string/strmode.c,v 1.5 2007/01/09 00:28:12 imp Exp $");
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
void
strmode(mode, p)
mode_t mode;
char *p;
{
/* print type */
switch (mode & S_IFMT) {
case S_IFDIR: /* directory */
*p++ = 'd';
break;
case S_IFCHR: /* character special */
*p++ = 'c';
break;
case S_IFBLK: /* block special */
*p++ = 'b';
break;
case S_IFREG: /* regular */
*p++ = '-';
break;
case S_IFLNK: /* symbolic link */
*p++ = 'l';
break;
case S_IFSOCK: /* socket */
*p++ = 's';
break;
#ifdef S_IFIFO
case S_IFIFO: /* fifo */
*p++ = 'p';
break;
#endif
#ifdef S_IFWHT
case S_IFWHT: /* whiteout */
*p++ = 'w';
break;
#endif
default: /* unknown */
*p++ = '?';
break;
}
/* usr */
if (mode & S_IRUSR)
*p++ = 'r';
else
*p++ = '-';
if (mode & S_IWUSR)
*p++ = 'w';
else
*p++ = '-';
switch (mode & (S_IXUSR | S_ISUID)) {
case 0:
*p++ = '-';
break;
case S_IXUSR:
*p++ = 'x';
break;
case S_ISUID:
*p++ = 'S';
break;
case S_IXUSR | S_ISUID:
*p++ = 's';
break;
}
/* group */
if (mode & S_IRGRP)
*p++ = 'r';
else
*p++ = '-';
if (mode & S_IWGRP)
*p++ = 'w';
else
*p++ = '-';
switch (mode & (S_IXGRP | S_ISGID)) {
case 0:
*p++ = '-';
break;
case S_IXGRP:
*p++ = 'x';
break;
case S_ISGID:
*p++ = 'S';
break;
case S_IXGRP | S_ISGID:
*p++ = 's';
break;
}
/* other */
if (mode & S_IROTH)
*p++ = 'r';
else
*p++ = '-';
if (mode & S_IWOTH)
*p++ = 'w';
else
*p++ = '-';
switch (mode & (S_IXOTH | S_ISVTX)) {
case 0:
*p++ = '-';
break;
case S_IXOTH:
*p++ = 'x';
break;
case S_ISVTX:
*p++ = 'T';
break;
case S_IXOTH | S_ISVTX:
*p++ = 't';
break;
}
*p++ = ' '; /* will be a '+' if ACL's implemented */
*p = '\0';
}

View File

@@ -58,7 +58,7 @@ int rtems_shell_main_blksync(
return 1;
}
if (ioctl (fd, BLKIO_SYNCDEV) < 0) {
if (ioctl (fd, RTEMS_BLKIO_SYNCDEV) < 0) {
fprintf( stderr, "%s: driver sync failed: %s\n", argv[0], strerror (errno));
return 1;
}

View File

@@ -175,14 +175,14 @@ main_cp(rtems_shell_cp_globals* cp_globals, int argc, char *argv[])
vflag = 1;
break;
default:
usage();
usage(cp_globals);
break;
}
argc -= getopt_reent.optind;
argv += getopt_reent.optind;
if (argc < 2)
usage();
usage(cp_globals);
fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
if (Rflag && rflag)

View File

@@ -1,104 +1,758 @@
/* $NetBSD: ls.c,v 1.58 2005/10/26 02:24:22 jschauma Exp $ */
/*
* LS Shell Command Implmentation
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Author: Fernando RUIZ CASAS
* Work: fernando.ruiz@ctv.es
* Home: correo@fernando-ruiz.com
* This code is derived from software contributed to Berkeley by
* Michael Fischbein.
*
* 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.
* 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. 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.
*
* $Id$
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if 0
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1989, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <dirent.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stddef.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)ls.c 8.7 (Berkeley) 8/5/94";
#else
__RCSID("$NetBSD: ls.c,v 1.58 2005/10/26 02:24:22 jschauma Exp $");
#endif
#endif /* not lint */
#endif
#include <rtems.h>
#include <rtems/shell.h>
#include "internal.h"
#include <rtems/shellconfig.h>
#include <getopt.h>
int rtems_shell_main_ls(
int argc,
char *argv[]
)
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fts.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <pwd.h>
#include <grp.h>
#include "extern-ls.h"
static void display(rtems_shell_ls_globals* globals, FTSENT *, FTSENT *);
static int mastercmp_listdir(const FTSENT **, const FTSENT **);
static int mastercmp_no_listdir(const FTSENT **, const FTSENT **);
static void traverse(rtems_shell_ls_globals* globals, int, char **, int);
static void (*printfcn)(rtems_shell_ls_globals* globals, DISPLAY *);
static int (*sortfcn)(const FTSENT *, const FTSENT *);
#define BY_NAME 0
#define BY_SIZE 1
#define BY_TIME 2
#if RTEMS_REMOVED
long blocksize; /* block size units */
int termwidth = 80; /* default terminal width */
int sortkey = BY_NAME;
int rval = EXIT_SUCCESS; /* exit value - set if error encountered */
/* flags */
int f_accesstime; /* use time of last access */
int f_column; /* columnated format */
int f_columnacross; /* columnated format, sorted across */
int f_flags; /* show flags associated with a file */
int f_grouponly; /* long listing without owner */
int f_humanize; /* humanize the size field */
int f_inode; /* print inode */
int f_listdir; /* list actual directory, not contents */
int f_listdot; /* list files beginning with . */
int f_longform; /* long listing format */
int f_nonprint; /* show unprintables as ? */
int f_nosort; /* don't sort output */
int f_numericonly; /* don't convert uid/gid to name */
int f_octal; /* print octal escapes for nongraphic characters */
int f_octal_escape; /* like f_octal but use C escapes if possible */
int f_recursive; /* ls subdirectories also */
int f_reversesort; /* reverse whatever sort is used */
int f_sectime; /* print the real time for all files */
int f_singlecol; /* use single column output */
int f_size; /* list size in short listing */
int f_statustime; /* use time of last mode change */
int f_stream; /* stream format */
int f_type; /* add type character for non-regular files */
int f_typedir; /* add type character for directories */
int f_whiteout; /* show whiteout entries */
#endif
void
rtems_shell_ls_exit (rtems_shell_ls_globals* globals, int code)
{
char *fname;
DIR *dirp;
struct dirent *dp;
struct stat stat_buf;
struct passwd *pwd;
struct group *grp;
char *user;
char *group;
char sbuf[256];
char nbuf[1024];
int n;
int size;
globals->exit_code = code;
longjmp (globals->exit_jmp, 1);
}
fname = ".";
if (argc>1)
fname = argv[1];
static int main_ls(rtems_shell_ls_globals* globals, int argc, char *argv[]);
if ((dirp = opendir(fname)) == NULL) {
fprintf(stderr,"%s: %s: No such file or directory.\n", argv[0], fname);
return errno;
}
n = 0;
size = 0;
while ((dp = readdir(dirp)) != NULL) {
strcpy(nbuf,fname);
if (nbuf[strlen(nbuf)-1]!='/')
strcat(nbuf,"/");
strcat(nbuf,dp->d_name); /* always the fullpathname. Avoid ftpd problem.*/
if (stat(nbuf, &stat_buf) == 0) { /* AWFUL but works...*/
strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M", gmtime(&stat_buf.st_mtime));
pwd = getpwuid(stat_buf.st_uid);
user = pwd?pwd->pw_name:"nouser";
grp = getgrgid(stat_buf.st_gid);
group = grp?grp->gr_name:"nogrp";
printf("%c%c%c%c%c%c%c%c%c%c %3d %6.6s %6.6s %11d %s %s%c\n",
(S_ISLNK(stat_buf.st_mode)?('l'):
(S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
(stat_buf.st_mode & S_IRUSR)?('r'):('-'),
(stat_buf.st_mode & S_IWUSR)?('w'):('-'),
(stat_buf.st_mode & S_IXUSR)?('x'):('-'),
(stat_buf.st_mode & S_IRGRP)?('r'):('-'),
(stat_buf.st_mode & S_IWGRP)?('w'):('-'),
(stat_buf.st_mode & S_IXGRP)?('x'):('-'),
(stat_buf.st_mode & S_IROTH)?('r'):('-'),
(stat_buf.st_mode & S_IWOTH)?('w'):('-'),
(stat_buf.st_mode & S_IXOTH)?('x'):('-'),
(int)stat_buf.st_nlink,
user,group,
(int)stat_buf.st_size,
sbuf,
dp->d_name,
S_ISDIR(stat_buf.st_mode)?'/':' ');
n++;
size += stat_buf.st_size;
int
rtems_shell_main_ls(int argc, char *argv[])
{
rtems_shell_ls_globals ls_globals;
rtems_shell_ls_globals* globals = &ls_globals;
memset (globals, 0, sizeof (ls_globals));
termwidth = 80;
sortkey = BY_NAME;
rval = EXIT_SUCCESS;
ls_globals.exit_code = 1;
if (setjmp (ls_globals.exit_jmp) == 0)
return main_ls (globals, argc, argv);
return ls_globals.exit_code;
}
int
main_ls(rtems_shell_ls_globals* globals, int argc, char *argv[])
{
static char dot[] = ".", *dotav[] = { dot, NULL };
//struct winsize win;
int ch, fts_options;
int kflag = 0;
const char *p;
struct getopt_data getopt_reent;
memset(&getopt_reent, 0, sizeof(getopt_data));
#if RTEMS_REMOVED
setprogname(argv[0]);
#endif
setlocale(LC_ALL, "");
/* Terminal defaults to -Cq, non-terminal defaults to -1. */
if (isatty(STDOUT_FILENO)) {
#if RTEMS_REMOVED
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
win.ws_col > 0)
termwidth = win.ws_col;
f_column = f_nonprint = 1;
#endif
} else
f_singlecol = 1;
/* Root is -A automatically. */
if (!getuid())
f_listdot = 1;
fts_options = FTS_PHYSICAL;
while ((ch = getopt_r(argc, argv,
"1ABCFLRSTWabcdfghiklmnopqrstuwx", &getopt_reent)) != -1) {
switch (ch) {
/*
* The -1, -C, -l, -m and -x options all override each other so
* shell aliasing works correctly.
*/
case '1':
f_singlecol = 1;
f_column = f_columnacross = f_longform = f_stream = 0;
break;
case 'C':
f_column = 1;
f_columnacross = f_longform = f_singlecol = f_stream =
0;
break;
case 'g':
if (f_grouponly != -1)
f_grouponly = 1;
f_longform = 1;
f_column = f_columnacross = f_singlecol = f_stream = 0;
break;
case 'l':
f_longform = 1;
f_column = f_columnacross = f_singlecol = f_stream = 0;
/* Never let -g take precedence over -l. */
f_grouponly = -1;
break;
case 'm':
f_stream = 1;
f_column = f_columnacross = f_longform = f_singlecol =
0;
break;
case 'x':
f_columnacross = 1;
f_column = f_longform = f_singlecol = f_stream = 0;
break;
/* The -c and -u options override each other. */
case 'c':
f_statustime = 1;
f_accesstime = 0;
break;
case 'u':
f_accesstime = 1;
f_statustime = 0;
break;
case 'F':
f_type = 1;
break;
case 'L':
fts_options &= ~FTS_PHYSICAL;
fts_options |= FTS_LOGICAL;
break;
case 'R':
f_recursive = 1;
break;
case 'a':
fts_options |= FTS_SEEDOT;
/* FALLTHROUGH */
case 'A':
f_listdot = 1;
break;
/* The -B option turns off the -b, -q and -w options. */
case 'B':
f_nonprint = 0;
f_octal = 1;
f_octal_escape = 0;
break;
/* The -b option turns off the -B, -q and -w options. */
case 'b':
f_nonprint = 0;
f_octal = 0;
f_octal_escape = 1;
break;
/* The -d option turns off the -R option. */
case 'd':
f_listdir = 1;
f_recursive = 0;
break;
case 'f':
f_nosort = 1;
break;
case 'i':
f_inode = 1;
break;
case 'k':
blocksize = 1024;
kflag = 1;
break;
/* The -h option forces all sizes to be measured in bytes. */
case 'h':
f_humanize = 1;
break;
case 'n':
f_numericonly = 1;
break;
case 'o':
f_flags = 1;
break;
case 'p':
f_typedir = 1;
break;
/* The -q option turns off the -B, -b and -w options. */
case 'q':
f_nonprint = 1;
f_octal = 0;
f_octal_escape = 0;
break;
case 'r':
f_reversesort = 1;
break;
case 'S':
sortkey = BY_SIZE;
break;
case 's':
f_size = 1;
break;
case 'T':
f_sectime = 1;
break;
case 't':
sortkey = BY_TIME;
break;
case 'W':
f_whiteout = 1;
break;
/* The -w option turns off the -B, -b and -q options. */
case 'w':
f_nonprint = 0;
f_octal = 0;
f_octal_escape = 0;
break;
default:
case '?':
usage(globals);
}
}
argc -= getopt_reent.optind;
argv += getopt_reent.optind;
if (f_column || f_columnacross || f_stream) {
if ((p = getenv("COLUMNS")) != NULL)
termwidth = atoi(p);
}
/*
* If both -g and -l options, let -l take precedence.
*/
if (f_grouponly == -1)
f_grouponly = 0;
/*
* If not -F, -i, -l, -p, -S, -s or -t options, don't require stat
* information.
*/
if (!f_inode && !f_longform && !f_size && !f_type && !f_typedir &&
sortkey == BY_NAME)
fts_options |= FTS_NOSTAT;
/*
* If not -F, -d or -l options, follow any symbolic links listed on
* the command line.
*/
if (!f_longform && !f_listdir && !f_type)
fts_options |= FTS_COMFOLLOW;
/*
* If -W, show whiteout entries
*/
#ifdef FTS_WHITEOUT
if (f_whiteout)
fts_options |= FTS_WHITEOUT;
#endif
/* If -l or -s, figure out block size. */
if (f_inode || f_longform || f_size) {
#if RTEMS_REMOVED
if (!kflag)
(void)getbsize(NULL, &blocksize);
#else
blocksize = 1024;
#endif
blocksize /= 512;
}
/* Select a sort function. */
if (f_reversesort) {
switch (sortkey) {
case BY_NAME:
sortfcn = revnamecmp;
break;
case BY_SIZE:
sortfcn = revsizecmp;
break;
case BY_TIME:
if (f_accesstime)
sortfcn = revacccmp;
else if (f_statustime)
sortfcn = revstatcmp;
else /* Use modification time. */
sortfcn = revmodcmp;
break;
}
} else {
switch (sortkey) {
case BY_NAME:
sortfcn = namecmp;
break;
case BY_SIZE:
sortfcn = sizecmp;
break;
case BY_TIME:
if (f_accesstime)
sortfcn = acccmp;
else if (f_statustime)
sortfcn = statcmp;
else /* Use modification time. */
sortfcn = modcmp;
break;
}
}
/* Select a print function. */
if (f_singlecol)
printfcn = printscol;
else if (f_columnacross)
printfcn = printacol;
else if (f_longform)
printfcn = printlong;
else if (f_stream)
printfcn = printstream;
else
printfcn = printcol;
if (argc)
traverse(globals, argc, argv, fts_options);
else
traverse(globals, 1, dotav, fts_options);
exit(rval);
/* NOTREACHED */
return 0;
}
#if RTEMS_REMOVED
static int output; /* If anything output. */
#endif
/*
* Traverse() walks the logical directory structure specified by the argv list
* in the order specified by the mastercmp() comparison function. During the
* traversal it passes linked lists of structures to display() which represent
* a superset (may be exact set) of the files to be displayed.
*/
static void
traverse(rtems_shell_ls_globals* globals, int argc, char *argv[], int options)
{
FTS *ftsp;
FTSENT *p, *chp;
int ch_options;
if ((ftsp =
fts_open(argv, options,
f_nosort ? NULL : f_listdir ?
mastercmp_listdir : mastercmp_no_listdir)) == NULL)
err(exit_jump, EXIT_FAILURE, NULL);
display(globals, NULL, fts_children(ftsp, 0));
if (f_listdir)
{
fts_close(ftsp);
return;
}
}
printf("%d files %d bytes occupied\n",n,size);
closedir(dirp);
return 0;
/*
* If not recursing down this tree and don't need stat info, just get
* the names.
*/
ch_options = !f_recursive && options & FTS_NOSTAT ? FTS_NAMEONLY : 0;
while ((p = fts_read(ftsp)) != NULL)
switch (p->fts_info) {
case FTS_DC:
warnx("%s: directory causes a cycle", p->fts_name);
break;
case FTS_DNR:
case FTS_ERR:
warnx("%s: %s", p->fts_name, strerror(p->fts_errno));
rval = EXIT_FAILURE;
break;
case FTS_D:
if (p->fts_level != FTS_ROOTLEVEL &&
p->fts_name[0] == '.' && !f_listdot)
break;
/*
* If already output something, put out a newline as
* a separator. If multiple arguments, precede each
* directory with its name.
*/
if (output)
(void)printf("\n%s:\n", p->fts_path);
else if (argc > 1) {
(void)printf("%s:\n", p->fts_path);
output = 1;
}
chp = fts_children(ftsp, ch_options);
display(globals, p, chp);
if (!f_recursive && chp != NULL)
(void)fts_set(ftsp, p, FTS_SKIP);
break;
}
fts_close(ftsp);
if (errno)
err(exit_jump, EXIT_FAILURE, "fts_read");
}
/*
* Display() takes a linked list of FTSENT structures and passes the list
* along with any other necessary information to the print function. P
* points to the parent directory of the display list.
*/
static void
display(rtems_shell_ls_globals* globals, FTSENT *p, FTSENT *list)
{
struct stat *sp;
DISPLAY d;
FTSENT *cur;
NAMES *np;
u_int64_t btotal, stotal, maxblock, maxsize;
int maxinode, maxnlink, maxmajor, maxminor;
int bcfile, entries, flen, glen, ulen, maxflags, maxgroup, maxlen;
int maxuser, needstats;
const char *user, *group;
char buf[21]; /* 64 bits == 20 digits, +1 for NUL */
char nuser[12], ngroup[12];
char *flags = NULL;
#ifdef __GNUC__
/* This outrageous construct just to shut up a GCC warning. */
(void) &maxsize;
#endif
/*
* If list is NULL there are two possibilities: that the parent
* directory p has no children, or that fts_children() returned an
* error. We ignore the error case since it will be replicated
* on the next call to fts_read() on the post-order visit to the
* directory p, and will be signalled in traverse().
*/
if (list == NULL)
return;
needstats = f_inode || f_longform || f_size;
flen = 0;
maxinode = maxnlink = 0;
bcfile = 0;
maxuser = maxgroup = maxflags = maxlen = 0;
btotal = stotal = maxblock = maxsize = 0;
maxmajor = maxminor = 0;
for (cur = list, entries = 0; cur; cur = cur->fts_link) {
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
warnx("%s: %s",
cur->fts_name, strerror(cur->fts_errno));
cur->fts_number = NO_PRINT;
rval = EXIT_FAILURE;
continue;
}
/*
* P is NULL if list is the argv list, to which different rules
* apply.
*/
if (p == NULL) {
/* Directories will be displayed later. */
if (cur->fts_info == FTS_D && !f_listdir) {
cur->fts_number = NO_PRINT;
continue;
}
} else {
/* Only display dot file if -a/-A set. */
if (cur->fts_name[0] == '.' && !f_listdot) {
cur->fts_number = NO_PRINT;
continue;
}
}
if (cur->fts_namelen > maxlen)
maxlen = cur->fts_namelen;
if (needstats) {
sp = cur->fts_statp;
if (sp->st_blocks > maxblock)
maxblock = sp->st_blocks;
if (sp->st_ino > maxinode)
maxinode = sp->st_ino;
if (sp->st_nlink > maxnlink)
maxnlink = sp->st_nlink;
if (sp->st_size > maxsize)
maxsize = sp->st_size;
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) {
bcfile = 1;
if (major(sp->st_rdev) > maxmajor)
maxmajor = major(sp->st_rdev);
if (minor(sp->st_rdev) > maxminor)
maxminor = minor(sp->st_rdev);
}
btotal += sp->st_blocks;
stotal += sp->st_size;
if (f_longform) {
if (f_numericonly ||
(user = user_from_uid(sp->st_uid, 0)) ==
NULL) {
(void)snprintf(nuser, sizeof(nuser),
"%u", sp->st_uid);
user = nuser;
}
if (f_numericonly ||
(group = group_from_gid(sp->st_gid, 0)) ==
NULL) {
(void)snprintf(ngroup, sizeof(ngroup),
"%u", sp->st_gid);
group = ngroup;
}
if ((ulen = strlen(user)) > maxuser)
maxuser = ulen;
if ((glen = strlen(group)) > maxgroup)
maxgroup = glen;
#if RTEMS_REMOVED
if (f_flags) {
flags =
flags_to_string(sp->st_flags, "-");
if ((flen = strlen(flags)) > maxflags)
maxflags = flen;
} else
#endif
flen = 0;
if ((np = malloc(sizeof(NAMES) +
ulen + glen + flen + 3)) == NULL)
err(exit_jump, EXIT_FAILURE, NULL);
np->user = &np->data[0];
(void)strcpy(np->user, user);
np->group = &np->data[ulen + 1];
(void)strcpy(np->group, group);
if (f_flags) {
np->flags = &np->data[ulen + glen + 2];
(void)strcpy(np->flags, flags);
}
cur->fts_pointer = np;
}
}
++entries;
}
if (!entries)
return;
d.list = list;
d.entries = entries;
d.maxlen = maxlen;
if (needstats) {
d.btotal = btotal;
d.stotal = stotal;
if (f_humanize) {
d.s_block = 4; /* min buf length for humanize_number */
} else {
(void)snprintf(buf, sizeof(buf), "%llu",
(long long)howmany(maxblock, blocksize));
d.s_block = strlen(buf);
}
d.s_flags = maxflags;
d.s_group = maxgroup;
(void)snprintf(buf, sizeof(buf), "%u", maxinode);
d.s_inode = strlen(buf);
(void)snprintf(buf, sizeof(buf), "%u", maxnlink);
d.s_nlink = strlen(buf);
if (f_humanize) {
d.s_size = 4; /* min buf length for humanize_number */
} else {
(void)snprintf(buf, sizeof(buf), "%llu",
(long long)maxsize);
d.s_size = strlen(buf);
}
d.s_user = maxuser;
if (bcfile) {
(void)snprintf(buf, sizeof(buf), "%u", maxmajor);
d.s_major = strlen(buf);
(void)snprintf(buf, sizeof(buf), "%u", maxminor);
d.s_minor = strlen(buf);
if (d.s_major + d.s_minor + 2 > d.s_size)
d.s_size = d.s_major + d.s_minor + 2;
else if (d.s_size - d.s_minor - 2 > d.s_major)
d.s_major = d.s_size - d.s_minor - 2;
} else {
d.s_major = 0;
d.s_minor = 0;
}
}
printfcn(globals, &d);
output = 1;
if (f_longform)
for (cur = list; cur; cur = cur->fts_link)
free(cur->fts_pointer);
}
/*
* Ordering for mastercmp:
* If ordering the argv (fts_level = FTS_ROOTLEVEL) return non-directories
* as larger than directories. Within either group, use the sort function.
* All other levels use the sort function. Error entries remain unsorted.
*/
static int
mastercmp_no_listdir(const FTSENT **a, const FTSENT **b)
{
int a_info, b_info;
int l_f_listdir = 0;
a_info = (*a)->fts_info;
if (a_info == FTS_ERR)
return (0);
b_info = (*b)->fts_info;
if (b_info == FTS_ERR)
return (0);
if (a_info == FTS_NS || b_info == FTS_NS) {
if (b_info != FTS_NS)
return (1);
else if (a_info != FTS_NS)
return (-1);
else
return (namecmp(*a, *b));
}
if (a_info != b_info && !l_f_listdir &&
(*a)->fts_level == FTS_ROOTLEVEL) {
if (a_info == FTS_D)
return (1);
else if (b_info == FTS_D)
return (-1);
}
return (sortfcn(*a, *b));
}
static int
mastercmp_listdir(const FTSENT **a, const FTSENT **b)
{
int a_info, b_info;
int l_f_listdir = 1;
a_info = (*a)->fts_info;
if (a_info == FTS_ERR)
return (0);
b_info = (*b)->fts_info;
if (b_info == FTS_ERR)
return (0);
if (a_info == FTS_NS || b_info == FTS_NS) {
if (b_info != FTS_NS)
return (1);
else if (a_info != FTS_NS)
return (-1);
else
return (namecmp(*a, *b));
}
if (a_info != b_info && !l_f_listdir &&
(*a)->fts_level == FTS_ROOTLEVEL) {
if (a_info == FTS_D)
return (1);
else if (b_info == FTS_D)
return (-1);
}
return (sortfcn(*a, *b));
}
rtems_shell_cmd_t rtems_shell_LS_Command = {

View File

@@ -1,50 +1,699 @@
/*
* RM Shell Command Implmentation
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Author: Fernando RUIZ CASAS
* Work: fernando.ruiz@ctv.es
* Home: correo@fernando-ruiz.com
* 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.
*
* 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$
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if 0
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1990, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#ifndef lint
static char sccsid[] = "@(#)rm.c 8.5 (Berkeley) 4/18/94";
#endif /* not lint */
#endif
#if 0
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/rm/rm.c,v 1.58 2006/10/31 02:22:36 delphij Exp $");
#endif
#include <rtems.h>
#include <rtems/shell.h>
#include "internal.h"
#include <rtems/shellconfig.h>
#include <getopt.h>
int rtems_shell_main_rm(
int argc,
char *argv[]
)
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fts.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* RTEMS specific changes */
typedef struct {
int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok;
int rflag, Iflag;
uid_t uid;
int exit_code;
jmp_buf exit_jmp;
} rtems_shell_rm_globals;
#define dflag globals->dflag
#define eval globals->eval
#define fflag globals->fflag
#define iflag globals->iflag
#define Pflag globals->Pflag
#define vflag globals->vflag
#define Wflag globals->Wflag
#define stdin_ok globals->stdin_ok
#define rflag globals->rflag
#define Iflag globals->Iflag
#define xuid globals->uid
#define exit_jump &(globals->exit_jmp)
#include <setjmp.h>
#define exit(ec) rtems_shell_rm_exit(globals, ec)
void
rtems_shell_rm_exit (rtems_shell_rm_globals* globals, int code)
{
int n = 1;
globals->exit_code = code;
longjmp (globals->exit_jmp, 1);
}
while ( n<argc ) {
if (unlink(argv[n])) {
fprintf(stderr,"%s: %s: %s\n", argv[0], argv[n], strerror(errno));
return -1;
}
n++;
}
return 0;
static int main_rm(rtems_shell_rm_globals* globals, int argc, char *argv[]);
int
rtems_shell_main_rm(int argc, char *argv[])
{
rtems_shell_rm_globals rm_globals;
memset (&rm_globals, 0, sizeof (rm_globals));
rm_globals.exit_code = 1;
if (setjmp (rm_globals.exit_jmp) == 0)
return main_rm (&rm_globals, argc, argv);
return rm_globals.exit_code;
}
#define check(a1, a2, a3) check_rm(globals, a1, a2, a3)
#define check2(a1) check2_rm(globals, a1)
#define checkdot(a1) checkdot_rm(globals, a1)
#define checkslash(a1) checkslash_rm(globals, a1)
#define rm_file(a1) rm_file_rm(globals, a1)
#define rm_overwrite(a1, a2) rm_overwrite_rm(globals, a1, a2)
#define rm_tree(a1) rm_tree_rm(globals, a1)
#define usage() usage_rm(globals)
/* RTEMS changes */
static int check_rm(rtems_shell_rm_globals* globals, char *, char *, struct stat *);
static int check2_rm(rtems_shell_rm_globals* globals, char **);
static void checkdot_rm(rtems_shell_rm_globals* globals, char **);
static void checkslash_rm(rtems_shell_rm_globals* globals, char **);
static void rm_file_rm(rtems_shell_rm_globals* globals, char **);
static int rm_overwrite_rm(rtems_shell_rm_globals* globals, char *, struct stat *);
static void rm_tree_rm(rtems_shell_rm_globals* globals, char **);
static void usage_rm(rtems_shell_rm_globals* globals);
/*
* rm --
* This rm is different from historic rm's, but is expected to match
* POSIX 1003.2 behavior. The most visible difference is that -f
* has two specific effects now, ignore non-existent files and force
* file removal.
*/
int
main_rm(rtems_shell_rm_globals* globals, int argc, char *argv[])
{
int ch;
char *p;
struct getopt_data getopt_reent;
memset(&getopt_reent, 0, sizeof(getopt_data));
/*
* Test for the special case where the utility is called as
* "unlink", for which the functionality provided is greatly
* simplified.
*/
if ((p = rindex(argv[0], '/')) == NULL)
p = argv[0];
else
++p;
if (strcmp(p, "unlink") == 0) {
while (getopt_r(argc, argv, "", &getopt_reent) != -1)
usage();
argc -= getopt_reent.optind;
argv += getopt_reent.optind;
if (argc != 1)
usage();
rm_file(&argv[0]);
exit(eval);
}
Pflag = rflag = 0;
while ((ch = getopt_r(argc, argv, "dfiIPRrvW", &getopt_reent)) != -1)
switch(ch) {
case 'd':
dflag = 1;
break;
case 'f':
fflag = 1;
iflag = 0;
break;
case 'i':
fflag = 0;
iflag = 1;
break;
case 'I':
Iflag = 1;
break;
case 'P':
Pflag = 1;
break;
case 'R':
case 'r': /* Compatibility. */
rflag = 1;
break;
case 'v':
vflag = 1;
break;
case 'W':
Wflag = 1;
break;
default:
usage();
}
argc -= getopt_reent.optind;
argv += getopt_reent.optind;
if (argc < 1) {
if (fflag)
return (0);
usage();
}
checkdot(argv);
if (getenv("POSIXLY_CORRECT") == NULL)
checkslash(argv);
xuid = geteuid();
if (*argv) {
stdin_ok = isatty(STDIN_FILENO);
if (Iflag) {
if (check2(argv) == 0)
exit (1);
}
if (rflag)
rm_tree(argv);
else
rm_file(argv);
}
exit (eval);
return 0;
}
void
rm_tree_rm(rtems_shell_rm_globals* globals, char **argv)
{
FTS *fts;
FTSENT *p;
int needstat;
int flags;
int rval;
/*
* Remove a file hierarchy. If forcing removal (-f), or interactive
* (-i) or can't ask anyway (stdin_ok), don't stat the file.
*/
needstat = !xuid || (!fflag && !iflag && stdin_ok);
/*
* If the -i option is specified, the user can skip on the pre-order
* visit. The fts_number field flags skipped directories.
*/
#define SKIPPED 1
flags = FTS_PHYSICAL;
if (!needstat)
flags |= FTS_NOSTAT;
if (Wflag)
flags |= FTS_WHITEOUT;
if (!(fts = fts_open(argv, flags, NULL))) {
if (fflag && errno == ENOENT)
return;
err(exit_jump, 1, "fts_open");
}
while ((p = fts_read(fts)) != NULL) {
switch (p->fts_info) {
case FTS_DNR:
if (!fflag || p->fts_errno != ENOENT) {
warnx("%s: %s",
p->fts_path, strerror(p->fts_errno));
eval = 1;
}
continue;
case FTS_ERR:
errx(exit_jump, 1, "%s: %s", p->fts_path, strerror(p->fts_errno));
case FTS_NS:
/*
* Assume that since fts_read() couldn't stat the
* file, it can't be unlinked.
*/
if (!needstat)
break;
if (!fflag || p->fts_errno != ENOENT) {
warnx("%s: %s",
p->fts_path, strerror(p->fts_errno));
eval = 1;
}
continue;
case FTS_D:
/* Pre-order: give user chance to skip. */
if (!fflag && !check(p->fts_path, p->fts_accpath,
p->fts_statp)) {
(void)fts_set(fts, p, FTS_SKIP);
p->fts_number = SKIPPED;
}
#if RTEMS_REMOVED
else if (!xuid &&
(p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
!(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
chflags(p->fts_accpath,
p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0)
goto err;
#endif
continue;
case FTS_DP:
/* Post-order: see if user skipped. */
if (p->fts_number == SKIPPED)
continue;
break;
default:
if (!fflag &&
!check(p->fts_path, p->fts_accpath, p->fts_statp))
continue;
}
rval = 0;
#if RTEMS_REMOVED
if (!xuid &&
(p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
!(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)))
rval = chflags(p->fts_accpath,
p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE));
#endif
if (rval == 0) {
/*
* If we can't read or search the directory, may still be
* able to remove it. Don't print out the un{read,search}able
* message unless the remove fails.
*/
switch (p->fts_info) {
case FTS_DP:
case FTS_DNR:
rval = rmdir(p->fts_accpath);
if (rval == 0 || (fflag && errno == ENOENT)) {
if (rval == 0 && vflag)
(void)printf("%s\n",
p->fts_path);
continue;
}
break;
#if RTEMS_REMOVED
case FTS_W:
rval = undelete(p->fts_accpath);
if (rval == 0 && (fflag && errno == ENOENT)) {
if (vflag)
(void)printf("%s\n",
p->fts_path);
continue;
}
break;
#endif
case FTS_NS:
/*
* Assume that since fts_read() couldn't stat
* the file, it can't be unlinked.
*/
if (fflag)
continue;
/* FALLTHROUGH */
default:
if (Pflag)
if (!rm_overwrite(p->fts_accpath, NULL))
continue;
rval = unlink(p->fts_accpath);
if (rval == 0 || (fflag && errno == ENOENT)) {
if (rval == 0 && vflag)
(void)printf("%s\n",
p->fts_path);
continue;
}
}
}
#if RTEMS_REMOVED
err:
#endif
warn("%s", p->fts_path);
eval = 1;
}
if (errno)
err(exit_jump, 1, "fts_read");
fts_close(fts);
}
#define S_ISWHT(m) (0)
void
rm_file_rm(rtems_shell_rm_globals* globals, char **argv)
{
struct stat sb;
int rval;
char *f;
/*
* Remove a file. POSIX 1003.2 states that, by default, attempting
* to remove a directory is an error, so must always stat the file.
*/
while ((f = *argv++) != NULL) {
/* Assume if can't stat the file, can't unlink it. */
if (lstat(f, &sb)) {
#if RTEMS_REMOVED
if (Wflag) {
sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR;
} else {
#endif
if (!fflag || errno != ENOENT) {
warn("%s", f);
eval = 1;
}
continue;
#if RTEMS_REMOVED
}
#endif
} else if (Wflag) {
warnx("%s: %s", f, strerror(EEXIST));
eval = 1;
continue;
}
if (S_ISDIR(sb.st_mode) && !dflag) {
warnx("%s: is a directory", f);
eval = 1;
continue;
}
if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb))
continue;
rval = 0;
#if RTEMS_REMOVED
if (!xuid && !S_ISWHT(sb.st_mode) &&
(sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
!(sb.st_flags & (SF_APPEND|SF_IMMUTABLE)))
rval = chflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE));
#endif
if (rval == 0) {
if (S_ISWHT(sb.st_mode))
#if RTEMS_REMOVED
rval = undelete(f);
#endif
;
else if (S_ISDIR(sb.st_mode))
rval = rmdir(f);
else {
if (Pflag)
if (!rm_overwrite(f, &sb))
continue;
rval = unlink(f);
}
}
if (rval && (!fflag || errno != ENOENT)) {
warn("%s", f);
eval = 1;
}
if (vflag && rval == 0)
(void)printf("%s\n", f);
}
}
/*
* rm_overwrite --
* Overwrite the file 3 times with varying bit patterns.
*
* XXX
* This is a cheap way to *really* delete files. Note that only regular
* files are deleted, directories (and therefore names) will remain.
* Also, this assumes a fixed-block file system (like FFS, or a V7 or a
* System V file system). In a logging file system, you'll have to have
* kernel support.
*/
int
rm_overwrite_rm(rtems_shell_rm_globals* globals, char *file, struct stat *sbp)
{
struct stat sb;
#if RTEMS_REMOVED
struct statfs fsb;
#endif
off_t len;
int bsize, fd, wlen;
char *buf = NULL;
fd = -1;
if (sbp == NULL) {
if (lstat(file, &sb))
goto err;
sbp = &sb;
}
if (!S_ISREG(sbp->st_mode))
return (1);
if (sbp->st_nlink > 1 && !fflag) {
warnx("%s (inode %lu): not overwritten due to multiple links",
file, sbp->st_ino);
return (0);
}
if ((fd = open(file, O_WRONLY, 0)) == -1)
goto err;
#if RTEMS_REMOVED
if (fstatfs(fd, &fsb) == -1)
goto err;
bsize = MAX(fsb.f_iosize, 1024);
#endif
bsize = 1024;
if ((buf = malloc(bsize)) == NULL)
err(exit_jump, 1, "%s: malloc", file);
#define PASS(byte) { \
memset(buf, byte, bsize); \
for (len = sbp->st_size; len > 0; len -= wlen) { \
wlen = len < bsize ? len : bsize; \
if (write(fd, buf, wlen) != wlen) \
goto err; \
} \
}
PASS(0xff);
if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
goto err;
PASS(0x00);
if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
goto err;
PASS(0xff);
if (!fsync(fd) && !close(fd)) {
free(buf);
return (1);
}
err: eval = 1;
if (buf)
free(buf);
if (fd != -1)
close(fd);
warn("%s", file);
return (0);
}
void strmode(mode_t mode, char *p);
char *fflagstostr(u_long flags);
const char *user_from_uid(uid_t uid, int nouser);
int
check_rm(rtems_shell_rm_globals* globals, char *path, char *name, struct stat *sp)
{
int ch, first;
char modep[15], *flagsp;
/* Check -i first. */
if (iflag)
(void)fprintf(stderr, "remove %s? ", path);
else {
/*
* If it's not a symbolic link and it's unwritable and we're
* talking to a terminal, ask. Symbolic links are excluded
* because their permissions are meaningless. Check stdin_ok
* first because we may not have stat'ed the file.
*/
#if RTEMS_REMOVED
if (!stdin_ok || S_ISLNK(sp->st_mode) ||
(!access(name, W_OK) &&
!(sp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
(!(sp->st_flags & (UF_APPEND|UF_IMMUTABLE)) || !xuid)))
#endif
if (!stdin_ok || S_ISLNK(sp->st_mode) ||
(!access(name, W_OK)))
return (1);
strmode(sp->st_mode, modep);
#if RTEMS_REMOVED
if ((flagsp = fflagstostr(sp->st_flags)) == NULL)
err(exit_jump, 1, "fflagstostr");
#else
flagsp = "no supported";
#endif
if (Pflag)
errx(exit_jump, 1,
"%s: -P was specified, but file is not writable",
path);
(void)fprintf(stderr, "override %s%s%s/%s %s%sfor %s? ",
modep + 1, modep[9] == ' ' ? "" : " ",
user_from_uid(sp->st_uid, 0),
group_from_gid(sp->st_gid, 0),
*flagsp ? flagsp : "", *flagsp ? " " : "",
path);
free(flagsp);
}
(void)fflush(stderr);
first = ch = getchar();
while (ch != '\n' && ch != EOF)
ch = getchar();
return (first == 'y' || first == 'Y');
}
#define ISSLASH(a) ((a)[0] == '/' && (a)[1] == '\0')
void
checkslash_rm(rtems_shell_rm_globals* globals, char **argv)
{
char **t, **u;
int complained;
complained = 0;
for (t = argv; *t;) {
if (ISSLASH(*t)) {
if (!complained++)
warnx("\"/\" may not be removed");
eval = 1;
for (u = t; u[0] != NULL; ++u)
u[0] = u[1];
} else {
++t;
}
}
}
int
check2_rm(rtems_shell_rm_globals* globals, char **argv)
{
struct stat st;
int first;
int ch;
int fcount = 0;
int dcount = 0;
int i;
const char *dname = NULL;
for (i = 0; argv[i]; ++i) {
if (lstat(argv[i], &st) == 0) {
if (S_ISDIR(st.st_mode)) {
++dcount;
dname = argv[i]; /* only used if 1 dir */
} else {
++fcount;
}
}
}
first = 0;
while (first != 'n' && first != 'N' && first != 'y' && first != 'Y') {
if (dcount && rflag) {
fprintf(stderr, "recursively remove");
if (dcount == 1)
fprintf(stderr, " %s", dname);
else
fprintf(stderr, " %d dirs", dcount);
if (fcount == 1)
fprintf(stderr, " and 1 file");
else if (fcount > 1)
fprintf(stderr, " and %d files", fcount);
} else if (dcount + fcount > 3) {
fprintf(stderr, "remove %d files", dcount + fcount);
} else {
return(1);
}
fprintf(stderr, "? ");
fflush(stderr);
first = ch = getchar();
while (ch != '\n' && ch != EOF)
ch = getchar();
if (ch == EOF)
break;
}
return (first == 'y' || first == 'Y');
}
#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
void
checkdot_rm(rtems_shell_rm_globals* globals, char **argv)
{
char *p, **save, **t;
int complained;
complained = 0;
for (t = argv; *t;) {
if ((p = strrchr(*t, '/')) != NULL)
++p;
else
p = *t;
if (ISDOT(p)) {
if (!complained++)
warnx("\".\" and \"..\" may not be removed");
eval = 1;
for (save = t; (t[0] = t[1]) != NULL; ++t)
continue;
t = save;
} else
++t;
}
}
void
usage_rm(rtems_shell_rm_globals* globals)
{
(void)fprintf(stderr, "%s\n%s\n",
"usage: rm [-f | -i] [-dIPRrvW] file ...",
" unlink file");
exit(1);
}
rtems_shell_cmd_t rtems_shell_RM_Command = {
"rm", /* name */
"rm n1 [n2 [n3...]] # remove files", /* usage */
"[-f | -i] [-dIPRrvW] file ...", /* usage */
"files", /* topic */
rtems_shell_main_rm, /* command */
NULL, /* alias */

View File

@@ -0,0 +1,480 @@
/* $NetBSD: print.c,v 1.40 2004/11/17 17:00:00 mycroft Exp $ */
/*
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Michael Fischbein.
*
* 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. 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 0
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)print.c 8.5 (Berkeley) 7/28/94";
#else
__RCSID("$NetBSD: print.c,v 1.40 2004/11/17 17:00:00 mycroft Exp $");
#endif
#endif /* not lint */
#endif
#include <rtems.h>
#include <rtems/libio.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <err.h>
#include <errno.h>
#include <fts.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
//#include <tzfile.h>
#include <unistd.h>
//#include <util.h>
#include "extern-ls.h"
#if RTEMS_REMOVED
extern int termwidth;
#endif
static int printaname(rtems_shell_ls_globals* globals, FTSENT *, int, int);
static void printlink(rtems_shell_ls_globals* globals, FTSENT *);
static void printtime(rtems_shell_ls_globals* globals, time_t);
static int printtype(u_int);
#if RTEMS_REMOVED
static time_t now;
#endif
#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
void
printscol(rtems_shell_ls_globals* globals, DISPLAY *dp)
{
FTSENT *p;
for (p = dp->list; p; p = p->fts_link) {
if (IS_NOPRINT(p))
continue;
(void)printaname(globals, p, dp->s_inode, dp->s_block);
(void)putchar('\n');
}
}
void
printlong(rtems_shell_ls_globals* globals, DISPLAY *dp)
{
struct stat *sp;
FTSENT *p;
NAMES *np;
char buf[20]; //, szbuf[5];
now = time(NULL);
if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
#if RTEMS_REMOVED
if (f_humanize) {
if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
"", HN_AUTOSCALE,
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
err(exit_jump, 1, "humanize_number");
(void)printf("total %s\n", szbuf);
} else {
#endif
(void)printf("total %llu\n",
(long long)(howmany(dp->btotal, blocksize)));
#if RTEMS_REMOVED
}
#endif
}
for (p = dp->list; p; p = p->fts_link) {
if (IS_NOPRINT(p))
continue;
sp = p->fts_statp;
if (f_inode)
(void)printf("%*lu ", dp->s_inode,
(unsigned long)sp->st_ino);
if (f_size && !f_humanize) {
(void)printf("%*llu ", dp->s_block,
(long long)howmany(sp->st_blocks, blocksize));
}
(void)strmode(sp->st_mode, buf);
np = p->fts_pointer;
(void)printf("%s %*lu ", buf, dp->s_nlink,
(unsigned long)sp->st_nlink);
if (!f_grouponly)
(void)printf("%-*s ", dp->s_user, np->user);
(void)printf("%-*s ", dp->s_group, np->group);
if (f_flags)
(void)printf("%-*s ", dp->s_flags, np->flags);
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
(void)printf("%*lu, %*lu ",
dp->s_major, major(sp->st_rdev), dp->s_minor,
minor(sp->st_rdev));
else
#if RTEMS_REMOVED
if (f_humanize) {
if ((humanize_number(szbuf, sizeof(szbuf),
sp->st_size, "", HN_AUTOSCALE,
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
err(1, "humanize_number");
(void)printf("%*s ", dp->s_size, szbuf);
} else {
#endif
(void)printf("%*llu ", dp->s_size,
(long long)sp->st_size);
#if RTEMS_REMOVED
}
#endif
if (f_accesstime)
printtime(globals, sp->st_atime);
else if (f_statustime)
printtime(globals, sp->st_ctime);
else
printtime(globals, sp->st_mtime);
if (f_octal || f_octal_escape)
(void)safe_print(globals, p->fts_name);
else if (f_nonprint)
(void)printescaped(globals, p->fts_name);
else
(void)printf("%s", p->fts_name);
if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
(void)printtype(sp->st_mode);
if (S_ISLNK(sp->st_mode))
printlink(globals, p);
(void)putchar('\n');
}
}
void
printcol(rtems_shell_ls_globals* globals, DISPLAY *dp)
{
static FTSENT **array;
static int lastentries = -1;
FTSENT *p;
int base, chcnt, col, colwidth, num;
int numcols, numrows, row;
//char szbuf[5];
colwidth = dp->maxlen;
if (f_inode)
colwidth += dp->s_inode + 1;
if (f_size) {
if (f_humanize)
colwidth += dp->s_size + 1;
else
colwidth += dp->s_block + 1;
}
if (f_type || f_typedir)
colwidth += 1;
colwidth += 1;
if (termwidth < 2 * colwidth) {
printscol(globals, dp);
return;
}
/*
* Have to do random access in the linked list -- build a table
* of pointers.
*/
if (dp->entries > lastentries) {
lastentries = dp->entries;
if ((array =
realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
warn(NULL);
printscol(globals, dp);
}
}
for (p = dp->list, num = 0; p; p = p->fts_link)
if (p->fts_number != NO_PRINT)
array[num++] = p;
numcols = termwidth / colwidth;
colwidth = termwidth / numcols; /* spread out if possible */
numrows = num / numcols;
if (num % numcols)
++numrows;
if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
#if RTEMS_REMOVED
if (f_humanize) {
if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
"", HN_AUTOSCALE,
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
err(1, "humanize_number");
(void)printf("total %s\n", szbuf);
} else {
#endif
(void)printf("total %llu\n",
(long long)(howmany(dp->btotal, blocksize)));
#if RTEMS_REMOVED
}
#endif
}
for (row = 0; row < numrows; ++row) {
for (base = row, chcnt = col = 0; col < numcols; ++col) {
chcnt = printaname(globals, array[base], dp->s_inode,
f_humanize && 0 ? dp->s_size : dp->s_block);
if ((base += numrows) >= num)
break;
while (chcnt++ < colwidth)
(void)putchar(' ');
}
(void)putchar('\n');
}
}
void
printacol(rtems_shell_ls_globals* globals, DISPLAY *dp)
{
FTSENT *p;
int chcnt, col, colwidth;
int numcols;
//char szbuf[5];
colwidth = dp->maxlen;
if (f_inode)
colwidth += dp->s_inode + 1;
if (f_size) {
if (f_humanize)
colwidth += dp->s_size + 1;
else
colwidth += dp->s_block + 1;
}
if (f_type || f_typedir)
colwidth += 1;
colwidth += 1;
if (termwidth < 2 * colwidth) {
printscol(globals, dp);
return;
}
numcols = termwidth / colwidth;
colwidth = termwidth / numcols; /* spread out if possible */
if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
#if RTEMS_REMOVED
if (f_humanize) {
if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
"", HN_AUTOSCALE,
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
err(1, "humanize_number");
(void)printf("total %s\n", szbuf);
} else {
#endif
(void)printf("total %llu\n",
(long long)(howmany(dp->btotal, blocksize)));
#if RTEMS_REMOVED
}
#endif
}
chcnt = col = 0;
for (p = dp->list; p; p = p->fts_link) {
if (IS_NOPRINT(p))
continue;
if (col >= numcols) {
chcnt = col = 0;
(void)putchar('\n');
}
chcnt = printaname(globals, p, dp->s_inode,
f_humanize && 0 ? dp->s_size : dp->s_block);
while (chcnt++ < colwidth)
(void)putchar(' ');
col++;
}
(void)putchar('\n');
}
void
printstream(rtems_shell_ls_globals* globals, DISPLAY *dp)
{
FTSENT *p;
int col;
int extwidth;
extwidth = 0;
if (f_inode)
extwidth += dp->s_inode + 1;
if (f_size) {
if (f_humanize)
extwidth += dp->s_size + 1;
else
extwidth += dp->s_block + 1;
}
if (f_type)
extwidth += 1;
for (col = 0, p = dp->list; p != NULL; p = p->fts_link) {
if (IS_NOPRINT(p))
continue;
if (col > 0) {
(void)putchar(','), col++;
if (col + 1 + extwidth + p->fts_namelen >= termwidth)
(void)putchar('\n'), col = 0;
else
(void)putchar(' '), col++;
}
col += printaname(globals, p, dp->s_inode,
f_humanize && 0 ? dp->s_size : dp->s_block);
}
(void)putchar('\n');
}
/*
* print [inode] [size] name
* return # of characters printed, no trailing characters.
*/
static int
printaname(rtems_shell_ls_globals* globals,
FTSENT *p, int inodefield, int sizefield)
{
struct stat *sp;
int chcnt;
//char szbuf[5];
sp = p->fts_statp;
chcnt = 0;
if (f_inode)
chcnt += printf("%*lu ", inodefield, (unsigned long)sp->st_ino);
if (f_size) {
#if RTEMS_REMOVED
if (f_humanize) {
if ((humanize_number(szbuf, sizeof(szbuf), sp->st_size,
"", HN_AUTOSCALE,
(HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
err(1, "humanize_number");
chcnt += printf("%*s ", sizefield, szbuf);
} else {
#endif
chcnt += printf("%*llu ", sizefield,
(long long)howmany(sp->st_blocks, blocksize));
#if RTEMS_REMOVED
}
#endif
}
if (f_octal || f_octal_escape)
chcnt += safe_print(globals, p->fts_name);
else if (f_nonprint)
chcnt += printescaped(globals, p->fts_name);
else
chcnt += printf("%s", p->fts_name);
if (f_type || (f_typedir && S_ISDIR(sp->st_mode)))
chcnt += printtype(sp->st_mode);
return (chcnt);
}
static void
printtime(rtems_shell_ls_globals* globals, time_t ftime)
{
int i;
char *longstring;
longstring = ctime(&ftime);
for (i = 4; i < 11; ++i)
(void)putchar(longstring[i]);
#define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY)
if (f_sectime)
for (i = 11; i < 24; i++)
(void)putchar(longstring[i]);
else if (ftime + SIXMONTHS > now && ftime - SIXMONTHS < now)
for (i = 11; i < 16; ++i)
(void)putchar(longstring[i]);
else {
(void)putchar(' ');
for (i = 20; i < 24; ++i)
(void)putchar(longstring[i]);
}
(void)putchar(' ');
}
static int
printtype(u_int mode)
{
switch (mode & S_IFMT) {
case S_IFDIR:
(void)putchar('/');
return (1);
case S_IFIFO:
(void)putchar('|');
return (1);
case S_IFLNK:
(void)putchar('@');
return (1);
case S_IFSOCK:
(void)putchar('=');
return (1);
#if RTEMS_REMOVED
case S_IFWHT:
(void)putchar('%');
return (1);
#endif
}
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
(void)putchar('*');
return (1);
}
return (0);
}
static void
printlink(rtems_shell_ls_globals* globals, FTSENT *p)
{
int lnklen;
char name[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
if (p->fts_level == FTS_ROOTLEVEL)
(void)snprintf(name, sizeof(name), "%s", p->fts_name);
else
(void)snprintf(name, sizeof(name),
"%s/%s", p->fts_parent->fts_accpath, p->fts_name);
if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
(void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
return;
}
path[lnklen] = '\0';
(void)printf(" -> ");
if (f_octal || f_octal_escape)
(void)safe_print(globals, path);
else if (f_nonprint)
(void)printescaped(globals, path);
else
(void)printf("%s", path);
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 1989, 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 defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)pwcache.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/gen/pwcache.c,v 1.11 2007/01/09 00:27:55 imp Exp $");
#include <sys/types.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
//#include <utmp.h>
#define UT_NAMESIZE 64
#define NCACHE 64 /* power of 2 */
#define MASK (NCACHE - 1) /* bits to store with */
const char *
user_from_uid(uid_t uid, int nouser)
{
static struct ncache {
uid_t uid;
int found;
char name[UT_NAMESIZE + 1];
} c_uid[NCACHE];
static int pwopen;
struct passwd *pw;
struct ncache *cp;
cp = c_uid + (uid & MASK);
if (cp->uid != uid || !*cp->name) {
if (pwopen == 0) {
//setpassent(1);
pwopen = 1;
}
pw = getpwuid(uid);
cp->uid = uid;
if (pw != NULL) {
cp->found = 1;
(void)strncpy(cp->name, pw->pw_name, UT_NAMESIZE);
cp->name[UT_NAMESIZE] = '\0';
} else {
cp->found = 0;
(void)snprintf(cp->name, UT_NAMESIZE, "%u", uid);
if (nouser)
return (NULL);
}
}
return ((nouser && !cp->found) ? NULL : cp->name);
}
char *
group_from_gid(gid_t gid, int nogroup)
{
static struct ncache {
gid_t gid;
int found;
char name[UT_NAMESIZE + 1];
} c_gid[NCACHE];
static int gropen;
struct group *gr;
struct ncache *cp;
cp = c_gid + (gid & MASK);
if (cp->gid != gid || !*cp->name) {
if (gropen == 0) {
//setgroupent(1);
gropen = 1;
}
gr = getgrgid(gid);
cp->gid = gid;
if (gr != NULL) {
cp->found = 1;
(void)strncpy(cp->name, gr->gr_name, UT_NAMESIZE);
cp->name[UT_NAMESIZE] = '\0';
} else {
cp->found = 0;
(void)snprintf(cp->name, UT_NAMESIZE, "%u", gid);
if (nogroup)
return (NULL);
}
}
return ((nogroup && !cp->found) ? NULL : cp->name);
}

View File

@@ -980,7 +980,7 @@ static rtems_status_code rtems_shell_run (
name,
task_priority,
task_stacksize,
RTEMS_DEFAULT_MODES,
RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
RTEMS_LOCAL | RTEMS_FLOATING_POINT,
&task_id
);

View File

@@ -465,11 +465,11 @@ preserve_dir_acls(struct stat *fs, char *source_dir, char *dest_dir)
}
void
usage(void)
usage(rtems_shell_cp_globals* cp_globals)
{
(void)fprintf(stderr, "%s\n%s\n",
"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-alpv] source_file target_file",
" cp [-R [-H | -L | -P]] [-f | -i | -n] [-alpv] source_file ... "
"target_directory");
longjmp (cp_globals->exit_jmp, 1);
}

View File

@@ -0,0 +1,113 @@
/* $NetBSD: util.c,v 1.28 2005/06/17 14:36:16 hira Exp $ */
/*
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Michael Fischbein.
*
* 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. 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 0
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)util.c 8.5 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: util.c,v 1.28 2005/06/17 14:36:16 hira Exp $");
#endif
#endif /* not lint */
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
#include <fts.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vis.h>
#include "extern-ls.h"
#define SIZE_T_MAX 255
int
safe_print(rtems_shell_ls_globals* globals, const char *src)
{
size_t len;
char *name;
int flags;
flags = VIS_NL | VIS_OCTAL;
if (f_octal_escape)
flags |= VIS_CSTYLE;
len = strlen(src);
if (len != 0 && SIZE_T_MAX/len <= 4) {
errx(exit_jump, EXIT_FAILURE, "%s: name too long", src);
/* NOTREACHED */
}
name = (char *)malloc(4*len+1);
if (name != NULL) {
len = strvis(name, src, flags);
printf("%s", name);
free(name);
return len;
} else
errx(exit_jump, EXIT_FAILURE, "out of memory!");
/* NOTREACHED */
}
int
printescaped(rtems_shell_ls_globals* globals, const char *src)
{
unsigned char c;
int n;
for (n = 0; (c = *src) != '\0'; ++src, ++n)
if (isprint(c))
(void)putchar(c);
else
(void)putchar('?');
return n;
}
void
usage(rtems_shell_ls_globals* globals)
{
(void)fprintf(stderr,
"usage: %s [-AaBbCcdFfghikLlmnopqRrSsTtuWwx1] [file ...]\n",
"ls");
exit(EXIT_FAILURE);
/* NOTREACHED */
}

384
cpukit/libmisc/shell/vis.c Normal file
View File

@@ -0,0 +1,384 @@
/* $NetBSD: vis.c,v 1.33 2005/05/28 13:11:14 lukem Exp $ */
/*-
* Copyright (c) 1989, 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. 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.
*/
/*-
* Copyright (c) 1999, 2005 The NetBSD Foundation, Inc.
* 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 NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#define _DIAGASSERT(a)
#if 0
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: vis.c,v 1.33 2005/05/28 13:11:14 lukem Exp $");
#endif /* LIBC_SCCS and not lint */
#endif
#include <sys/types.h>
#include <assert.h>
#include <vis.h>
#include <stdlib.h>
#if !HAVE_VIS || !HAVE_SVIS
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#undef BELL
#define BELL '\a'
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
#define issafe(c) (c == '\b' || c == BELL || c == '\r')
#define xtoa(c) "0123456789abcdef"[c]
#define MAXEXTRAS 5
#define MAKEEXTRALIST(flag, extra, orig) \
do { \
const char *o = orig; \
char *e; \
while (*o++) \
continue; \
extra = malloc((size_t)((o - orig) + MAXEXTRAS)); \
if (!extra) break; \
for (o = orig, e = extra; (*e++ = *o++) != '\0';) \
continue; \
e--; \
if (flag & VIS_SP) *e++ = ' '; \
if (flag & VIS_TAB) *e++ = '\t'; \
if (flag & VIS_NL) *e++ = '\n'; \
if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \
*e = '\0'; \
} while (/*CONSTCOND*/0)
/*
* This is HVIS, the macro of vis used to HTTP style (RFC 1808)
*/
#define HVIS(dst, c, flag, nextc, extra) \
do \
if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \
*dst++ = '%'; \
*dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \
*dst++ = xtoa((unsigned int)c & 0xf); \
} else { \
SVIS(dst, c, flag, nextc, extra); \
} \
while (/*CONSTCOND*/0)
/*
* This is SVIS, the central macro of vis.
* dst: Pointer to the destination buffer
* c: Character to encode
* flag: Flag word
* nextc: The character following 'c'
* extra: Pointer to the list of extra characters to be
* backslash-protected.
*/
#define SVIS(dst, c, flag, nextc, extra) \
do { \
int isextra; \
isextra = strchr(extra, c) != NULL; \
if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \
((flag & VIS_SAFE) && issafe(c)))) { \
*dst++ = c; \
break; \
} \
if (flag & VIS_CSTYLE) { \
switch (c) { \
case '\n': \
*dst++ = '\\'; *dst++ = 'n'; \
continue; \
case '\r': \
*dst++ = '\\'; *dst++ = 'r'; \
continue; \
case '\b': \
*dst++ = '\\'; *dst++ = 'b'; \
continue; \
case BELL: \
*dst++ = '\\'; *dst++ = 'a'; \
continue; \
case '\v': \
*dst++ = '\\'; *dst++ = 'v'; \
continue; \
case '\t': \
*dst++ = '\\'; *dst++ = 't'; \
continue; \
case '\f': \
*dst++ = '\\'; *dst++ = 'f'; \
continue; \
case ' ': \
*dst++ = '\\'; *dst++ = 's'; \
continue; \
case '\0': \
*dst++ = '\\'; *dst++ = '0'; \
if (isoctal(nextc)) { \
*dst++ = '0'; \
*dst++ = '0'; \
} \
continue; \
default: \
if (isgraph(c)) { \
*dst++ = '\\'; *dst++ = c; \
continue; \
} \
} \
} \
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
*dst++ = '\\'; \
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \
*dst++ = (c & 07) + '0'; \
} else { \
if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \
if (c & 0200) { \
c &= 0177; *dst++ = 'M'; \
} \
if (iscntrl(c)) { \
*dst++ = '^'; \
if (c == 0177) \
*dst++ = '?'; \
else \
*dst++ = c + '@'; \
} else { \
*dst++ = '-'; *dst++ = c; \
} \
} \
} while (/*CONSTCOND*/0)
/*
* svis - visually encode characters, also encoding the characters
* pointed to by `extra'
*/
char *
svis(char *dst, int c, int flag, int nextc, const char *extra)
{
char *nextra = NULL;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra);
if (!nextra) {
*dst = '\0'; /* can't create nextra, return "" */
return dst;
}
if (flag & VIS_HTTPSTYLE)
HVIS(dst, c, flag, nextc, nextra);
else
SVIS(dst, c, flag, nextc, nextra);
free(nextra);
*dst = '\0';
return dst;
}
/*
* strsvis, strsvisx - visually encode characters from src into dst
*
* Extra is a pointer to a \0-terminated list of characters to
* be encoded, too. These functions are useful e. g. to
* encode strings in such a way so that they are not interpreted
* by a shell.
*
* Dst must be 4 times the size of src to account for possible
* expansion. The length of dst, not including the trailing NULL,
* is returned.
*
* Strsvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data.
*/
int
strsvis(char *dst, const char *csrc, int flag, const char *extra)
{
int c;
char *start;
char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra);
if (!nextra) {
*dst = '\0'; /* can't create nextra, return "" */
return 0;
}
if (flag & VIS_HTTPSTYLE) {
for (start = dst; (c = *src++) != '\0'; /* empty */)
HVIS(dst, c, flag, *src, nextra);
} else {
for (start = dst; (c = *src++) != '\0'; /* empty */)
SVIS(dst, c, flag, *src, nextra);
}
free(nextra);
*dst = '\0';
return (dst - start);
}
int
strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
{
unsigned char c;
char *start;
char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra);
if (! nextra) {
*dst = '\0'; /* can't create nextra, return "" */
return 0;
}
if (flag & VIS_HTTPSTYLE) {
for (start = dst; len > 0; len--) {
c = *src++;
HVIS(dst, c, flag, len ? *src : '\0', nextra);
}
} else {
for (start = dst; len > 0; len--) {
c = *src++;
SVIS(dst, c, flag, len ? *src : '\0', nextra);
}
}
free(nextra);
*dst = '\0';
return (dst - start);
}
#endif
#if !HAVE_VIS
/*
* vis - visually encode characters
*/
char *
vis(char *dst, int c, int flag, int nextc)
{
char *extra = NULL;
unsigned char uc = (unsigned char)c;
_DIAGASSERT(dst != NULL);
MAKEEXTRALIST(flag, extra, "");
if (! extra) {
*dst = '\0'; /* can't create extra, return "" */
return dst;
}
if (flag & VIS_HTTPSTYLE)
HVIS(dst, uc, flag, nextc, extra);
else
SVIS(dst, uc, flag, nextc, extra);
free(extra);
*dst = '\0';
return dst;
}
/*
* strvis, strvisx - visually encode characters from src into dst
*
* Dst must be 4 times the size of src to account for possible
* expansion. The length of dst, not including the trailing NULL,
* is returned.
*
* Strvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data.
*/
int
strvis(char *dst, const char *src, int flag)
{
char *extra = NULL;
int rv;
MAKEEXTRALIST(flag, extra, "");
if (!extra) {
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
rv = strsvis(dst, src, flag, extra);
free(extra);
return rv;
}
int
strvisx(char *dst, const char *src, size_t len, int flag)
{
char *extra = NULL;
int rv;
MAKEEXTRALIST(flag, extra, "");
if (!extra) {
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
rv = strsvisx(dst, src, len, flag, extra);
free(extra);
return rv;
}
#endif

View File

@@ -0,0 +1,91 @@
/* $NetBSD: vis.h,v 1.16 2005/09/13 01:44:32 christos Exp $ */
/*-
* Copyright (c) 1990, 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. 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.
*
* @(#)vis.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _VIS_H_
#define _VIS_H_
#include <sys/types.h>
/*
* to select alternate encoding format
*/
#define VIS_OCTAL 0x01 /* use octal \ddd format */
#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */
/*
* to alter set of characters encoded (default is to encode all
* non-graphic except space, tab, and newline).
*/
#define VIS_SP 0x04 /* also encode space */
#define VIS_TAB 0x08 /* also encode tab */
#define VIS_NL 0x10 /* also encode newline */
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
/*
* other
*/
#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */
/*
* unvis return codes
*/
#define UNVIS_VALID 1 /* character valid */
#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */
#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */
#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */
#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */
/*
* unvis flags
*/
#define UNVIS_END 1 /* no more characters */
#include <sys/cdefs.h>
__BEGIN_DECLS
char *vis(char *, int, int, int);
char *svis(char *, int, int, int, const char *);
int strvis(char *, const char *, int);
int strsvis(char *, const char *, int, const char *);
int strvisx(char *, const char *, size_t, int);
int strsvisx(char *, const char *, size_t, int, const char *);
int strunvis(char *, const char *);
int strunvisx(char *, const char *, int);
#ifndef __LIBC12_SOURCE__
//int unvis(char *, int, int *, int) __RENAME(__unvis13);
#endif
__END_DECLS
#endif /* !_VIS_H_ */

View File

@@ -587,7 +587,7 @@ extern rtems_configuration_table Configuration;
#define CONFIGURE_ATA_DRIVER_TASK_PRIORITY ATA_DRIVER_TASK_DEFAULT_PRIORITY
#endif
#ifdef CONFIGURE_INIT
rtems_task_priority ata_driver_task_priority
rtems_task_priority rtems_ata_driver_task_priority
= CONFIGURE_ATA_DRIVER_TASK_PRIORITY;
#endif /* CONFIGURE_INIT */
#endif
@@ -598,13 +598,36 @@ extern rtems_configuration_table Configuration;
#ifdef CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
#include <rtems/bdbuf.h>
/*
* configure the priority of the bdbuf swapout task
* configure the bdbuf cache parameters
*/
#ifndef CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS
#define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS \
RTEMS_BDBUF_MAX_READ_AHEAD_BLOCKS_DEFAULT
#endif
#ifndef CONFIGURE_BDBUF_MAX_WRITE_BLOCKS
#define CONFIGURE_BDBUF_MAX_WRITE_BLOCKS \
RTEMS_BDBUF_MAX_WRITE_BLOCKS_DEFAULT
#endif
#ifndef CONFIGURE_SWAPOUT_TASK_PRIORITY
#define CONFIGURE_SWAPOUT_TASK_PRIORITY SWAPOUT_TASK_DEFAULT_PRIORITY
#define CONFIGURE_SWAPOUT_TASK_PRIORITY \
RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT
#endif
#ifndef CONFIGURE_SWAPOUT_SWAP_PERIOD
#define CONFIGURE_SWAPOUT_SWAP_PERIOD \
RTEMS_BDBUF_SWAPOUT_TASK_SWAP_PERIOD_DEFAULT
#endif
#ifndef CONFIGURE_SWAPOUT_BLOCK_HOLD
#define CONFIGURE_SWAPOUT_BLOCK_HOLD \
RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT
#endif
#ifdef CONFIGURE_INIT
rtems_task_priority swapout_task_priority = CONFIGURE_SWAPOUT_TASK_PRIORITY;
rtems_bdbuf_config rtems_bdbuf_configuration = {
CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS,
CONFIGURE_BDBUF_MAX_WRITE_BLOCKS,
CONFIGURE_SWAPOUT_TASK_PRIORITY,
CONFIGURE_SWAPOUT_SWAP_PERIOD,
CONFIGURE_SWAPOUT_BLOCK_HOLD
};
#endif
#ifndef CONFIGURE_HAS_OWN_BDBUF_TABLE
#ifndef CONFIGURE_BDBUF_BUFFER_COUNT
@@ -615,11 +638,12 @@ extern rtems_configuration_table Configuration;
#define CONFIGURE_BDBUF_BUFFER_SIZE 512
#endif
#ifdef CONFIGURE_INIT
rtems_bdbuf_config rtems_bdbuf_configuration[] = {
rtems_bdbuf_pool_config rtems_bdbuf_pool_configuration[] = {
{CONFIGURE_BDBUF_BUFFER_SIZE, CONFIGURE_BDBUF_BUFFER_COUNT, NULL}
};
int rtems_bdbuf_configuration_size =( sizeof(rtems_bdbuf_configuration)
/sizeof(rtems_bdbuf_configuration[0]));
int rtems_bdbuf_pool_configuration_size =
(sizeof(rtems_bdbuf_pool_configuration) /
sizeof(rtems_bdbuf_pool_configuration[0]));
#endif /* CONFIGURE_INIT */
#endif /* CONFIGURE_HAS_OWN_BDBUF_TABLE */
#endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */

View File

@@ -66,9 +66,9 @@ void _CORE_mutex_Initialize(
_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
#ifdef __RTEMS_STRICT_ORDER_MUTEX__
_Chain_Prepend_unprotected( &executing->lock_mutex,
_Chain_Prepend_unprotected( &_Thread_Executing->lock_mutex,
&the_mutex->queue.lock_queue );
the_mutex->queue.priority_before = executing->current_priority;
the_mutex->queue.priority_before = _Thread_Executing->current_priority;
#endif
_Thread_Executing->resource_count++;

View File

@@ -61,4 +61,5 @@ void _Internal_error_Occurred(
_CPU_Fatal_halt( the_error );
/* will not return from this routine */
while (TRUE);
}