forked from Imagelibrary/rtems
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:
@@ -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>
|
2008-07-24 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
* libcsupport/include/rtems/libcsupport.h: Moved declaration of
|
* libcsupport/include/rtems/libcsupport.h: Moved declaration of
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ include $(top_srcdir)/automake/compile.am
|
|||||||
if !UNIX
|
if !UNIX
|
||||||
noinst_LIBRARIES = libblock.a
|
noinst_LIBRARIES = libblock.a
|
||||||
libblock_a_SOURCES = src/bdbuf.c src/blkdev.c src/diskdevs.c src/flashdisk.c \
|
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 \
|
src/nvdisk-sram.c \
|
||||||
include/rtems/bdbuf.h include/rtems/blkdev.h \
|
include/rtems/bdbuf.h include/rtems/blkdev.h \
|
||||||
include/rtems/diskdevs.h include/rtems/flashdisk.h \
|
include/rtems/diskdevs.h include/rtems/flashdisk.h \
|
||||||
|
|||||||
@@ -25,116 +25,143 @@ extern "C" {
|
|||||||
#include "rtems/blkdev.h"
|
#include "rtems/blkdev.h"
|
||||||
#include "rtems/diskdevs.h"
|
#include "rtems/diskdevs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
* State of a buffer in the cache.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
typedef enum
|
||||||
/* 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
|
|
||||||
{
|
{
|
||||||
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) */
|
struct rtems_bdbuf_avl_node
|
||||||
int nblks; /* Number of blocks in this pool */
|
{
|
||||||
rtems_id bufget_sema; /* Buffer obtain counting semaphore */
|
signed char cache; /* Cache */
|
||||||
void *mallocd_bufs; /* Pointer to the malloc'd buffer memory,
|
struct rtems_bdbuf_buffer* left; /* Left Child */
|
||||||
or NULL, if buffer memory provided in
|
struct rtems_bdbuf_buffer* right; /* Right Child */
|
||||||
buffer configuration */
|
signed char bal; /* The balance of the sub-tree */
|
||||||
bdbuf_buffer *bdbufs; /* Pointer to table of buffer descriptors
|
} avl;
|
||||||
allocated for this buffer pool. */
|
|
||||||
} bdbuf_pool;
|
|
||||||
|
|
||||||
/* Buffering layer context definition */
|
dev_t dev; /* device number */
|
||||||
struct bdbuf_context {
|
rtems_blkdev_bnum block; /* block number on the device */
|
||||||
bdbuf_pool *pool; /* Table of buffer pools */
|
|
||||||
int npools; /* Number of entries in pool table */
|
|
||||||
|
|
||||||
Chain_Control mod; /* Modified buffers list */
|
unsigned char* buffer; /* Pointer to the buffer memory area */
|
||||||
rtems_id flush_sema; /* Buffer flush semaphore; counting
|
int error; /* If not 0 indicate an error value (errno)
|
||||||
semaphore; incremented when buffer
|
* which can be used by user later */
|
||||||
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;
|
|
||||||
|
|
||||||
/* bdbuf_config structure describes block configuration (size,
|
volatile rtems_bdbuf_buf_state state; /* State of the buffer. */
|
||||||
* amount, memory location) for buffering layer
|
|
||||||
|
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 {
|
typedef struct rtems_bdbuf_config {
|
||||||
int size; /* Size of block */
|
int max_read_ahead_blocks; /*<< Number of blocks to read ahead. */
|
||||||
int num; /* Number of blocks of appropriate size */
|
int max_write_blocks; /*<< Number of blocks to write at once. */
|
||||||
unsigned char *mem_area;
|
rtems_task_priority swapout_priority; /*<< Priority of the swap out task. */
|
||||||
/* Pointer to the blocks location or NULL, in this
|
uint32_t swapout_period; /*<< Period swapout checks buf timers. */
|
||||||
case memory for blocks will be allocated by
|
uint32_t swap_block_hold; /*<< Period a buffer is held. */
|
||||||
Buffering Layer with the help of RTEMS partition
|
|
||||||
manager */
|
|
||||||
} rtems_bdbuf_config;
|
} 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 --
|
/* rtems_bdbuf_init --
|
||||||
* Prepare buffering layer to work - initialize buffer descritors
|
* 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
|
* amount requested. After initialization all blocks is placed into
|
||||||
* free elements lists.
|
* free elements lists.
|
||||||
*
|
*
|
||||||
* PARAMETERS:
|
|
||||||
* conf_table - pointer to the buffers configuration table
|
|
||||||
* size - number of entries in configuration table
|
|
||||||
*
|
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
||||||
* or error code if error is occured)
|
* or error code if error is occured)
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size);
|
rtems_bdbuf_init ();
|
||||||
|
|
||||||
|
|
||||||
/* rtems_bdbuf_get --
|
/* rtems_bdbuf_get --
|
||||||
* Obtain block buffer. If specified block already cached (i.e. there's
|
* 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:
|
* SIDE EFFECTS:
|
||||||
* bufget_sema semaphore obtained by this primitive.
|
* bufget_sema semaphore obtained by this primitive.
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_get(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
|
rtems_bdbuf_get(dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd);
|
||||||
|
|
||||||
/* rtems_bdbuf_read --
|
/* rtems_bdbuf_read --
|
||||||
* (Similar to the rtems_bdbuf_get, except reading data from media)
|
* (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:
|
* SIDE EFFECTS:
|
||||||
* bufget_sema and transfer_sema semaphores obtained by this primitive.
|
* bufget_sema and transfer_sema semaphores obtained by this primitive.
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_read(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
|
rtems_bdbuf_read(dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd);
|
||||||
|
|
||||||
/* rtems_bdbuf_release --
|
/* rtems_bdbuf_release --
|
||||||
* Release buffer allocated before. This primitive decrease the
|
* 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:
|
* SIDE EFFECTS:
|
||||||
* flush_sema and bufget_sema semaphores may be released by this primitive.
|
* flush_sema and bufget_sema semaphores may be released by this primitive.
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_release(bdbuf_buffer *bd_buf);
|
rtems_bdbuf_release(rtems_bdbuf_buffer* bd);
|
||||||
|
|
||||||
/* rtems_bdbuf_release_modified --
|
/* rtems_bdbuf_release_modified --
|
||||||
* Release buffer allocated before, assuming that it is _modified_ by
|
* Release buffer allocated before, assuming that it is _modified_ by
|
||||||
@@ -244,8 +266,8 @@ rtems_bdbuf_release(bdbuf_buffer *bd_buf);
|
|||||||
* SIDE EFFECTS:
|
* SIDE EFFECTS:
|
||||||
* flush_sema semaphore may be released by this primitive.
|
* flush_sema semaphore may be released by this primitive.
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_release_modified(bdbuf_buffer *bd_buf);
|
rtems_bdbuf_release_modified(rtems_bdbuf_buffer* bd);
|
||||||
|
|
||||||
/* rtems_bdbuf_sync --
|
/* rtems_bdbuf_sync --
|
||||||
* Wait until specified buffer synchronized with disk. Invoked on exchanges
|
* Wait until specified buffer synchronized with disk. Invoked on exchanges
|
||||||
@@ -265,8 +287,8 @@ rtems_bdbuf_release_modified(bdbuf_buffer *bd_buf);
|
|||||||
* SIDE EFFECTS:
|
* SIDE EFFECTS:
|
||||||
* Primitive may be blocked on transfer_sema semaphore.
|
* Primitive may be blocked on transfer_sema semaphore.
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_sync(bdbuf_buffer *bd_buf);
|
rtems_bdbuf_sync(rtems_bdbuf_buffer* bd);
|
||||||
|
|
||||||
/* rtems_bdbuf_syncdev --
|
/* rtems_bdbuf_syncdev --
|
||||||
* Synchronize with disk all buffers containing the blocks belonging to
|
* 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
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
||||||
* or error code if error is occured)
|
* or error code if error is occured)
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_syncdev(dev_t dev);
|
rtems_bdbuf_syncdev(dev_t dev);
|
||||||
|
|
||||||
/* rtems_bdbuf_find_pool --
|
/* rtems_bdbuf_find_pool --
|
||||||
* Find first appropriate buffer pool. This primitive returns the index
|
* 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
|
* of 2), RTEMS_NOT_DEFINED if buffer pool for this or greater block size
|
||||||
* is not configured.
|
* is not configured.
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool);
|
rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool);
|
||||||
|
|
||||||
/* rtems_bdbuf_get_pool_info --
|
/* rtems_bdbuf_get_pool_info --
|
||||||
* Obtain characteristics of buffer pool with specified number.
|
* Obtain characteristics of buffer pool with specified number.
|
||||||
@@ -316,8 +338,8 @@ rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool);
|
|||||||
* NOTE:
|
* NOTE:
|
||||||
* Buffer pools enumerated contiguously starting from 0.
|
* Buffer pools enumerated contiguously starting from 0.
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size, int *blocks);
|
rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size, int *blocks);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,67 +20,92 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Interface with device drivers
|
/*
|
||||||
* Block device looks, initialized and behaves like traditional RTEMS device
|
* Interface with device drivers Block device looks, initialized and behaves
|
||||||
* driver. Heart of the block device driver is in BIOREQUEST ioctl. This call
|
* like traditional RTEMS device driver. Heart of the block device driver is in
|
||||||
* puts I/O request to the block device queue, in priority order, for
|
* BIOREQUEST ioctl. This call puts I/O request to the block device queue, in
|
||||||
* asynchronous processing. When driver executes request, req_done
|
* priority order, for asynchronous processing. When driver executes request,
|
||||||
* function invoked, so callee knows about it. Look for details below.
|
* req_done function invoked, so callee knows about it. Look for details below.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
/* Block device block number datatype */
|
* Block device block number datatype
|
||||||
typedef uint32_t blkdev_bnum;
|
*/
|
||||||
|
typedef uint32_t rtems_blkdev_bnum;
|
||||||
|
|
||||||
/* Block device request type */
|
/* Block device request type */
|
||||||
typedef enum blkdev_request_op {
|
typedef enum rtems_blkdev_request_op {
|
||||||
BLKDEV_REQ_READ, /* Read operation */
|
RTEMS_BLKDEV_REQ_READ, /* Read operation */
|
||||||
BLKDEV_REQ_WRITE /* Write operation */
|
RTEMS_BLKDEV_REQ_WRITE, /* Write operation */
|
||||||
} blkdev_request_op;
|
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:
|
* Type for block device request done callback function.
|
||||||
* arg - argument supplied in blkdev_request
|
*
|
||||||
* status - rtems status code for this operation
|
* @param arg Argument supplied in blkdev_request
|
||||||
* errno - errno value to be passed to the user when
|
* @param status RTEMS status code for this operation
|
||||||
|
* @param errno errno value to be passed to the user when
|
||||||
* status != RTEMS_SUCCESSFUL
|
* status != RTEMS_SUCCESSFUL
|
||||||
*/
|
*/
|
||||||
typedef void (* blkdev_request_cb)(void *arg,
|
typedef void (* rtems_blkdev_request_cb)(void *arg,
|
||||||
rtems_status_code status,
|
rtems_status_code status,
|
||||||
int error);
|
int error);
|
||||||
|
|
||||||
/* blkdev_sg_buffer
|
/**
|
||||||
|
* @struct rtems_blkdev_sg_buffer
|
||||||
* Block device scatter/gather buffer structure
|
* 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 */
|
uint32_t length; /* Buffer length */
|
||||||
void *buffer; /* Buffer pointer */
|
void *buffer; /* Buffer pointer */
|
||||||
} blkdev_sg_buffer;
|
void *user; /* User pointer */
|
||||||
|
} rtems_blkdev_sg_buffer;
|
||||||
|
|
||||||
/* blkdev_request (Block Device Request) structure is
|
/* blkdev_request (Block Device Request) structure is
|
||||||
* used to read/write a number of blocks from/to device.
|
* used to read/write a number of blocks from/to device.
|
||||||
*/
|
*/
|
||||||
typedef struct blkdev_request {
|
typedef struct rtems_blkdev_request {
|
||||||
blkdev_request_op req; /* Block device operation (read or write) */
|
/* Block device operation (read or write) */
|
||||||
blkdev_request_cb req_done; /* Callback function */
|
rtems_blkdev_request_op req;
|
||||||
void *done_arg; /* Argument to be passed to callback function*/
|
/* Callback function */
|
||||||
rtems_status_code status; /* Last I/O operation completion status */
|
rtems_blkdev_request_cb req_done;
|
||||||
int error; /* If status != RTEMS_SUCCESSFUL, this field
|
/* Argument to be passed to callback function*/
|
||||||
* contains error code
|
void *done_arg;
|
||||||
*/
|
/* Last I/O operation completion status */
|
||||||
blkdev_bnum start; /* Start block number */
|
rtems_status_code status;
|
||||||
uint32_t count; /* Number of blocks to be exchanged */
|
/* If status != RTEMS_SUCCESSFUL, this field contains error code */
|
||||||
uint32_t bufnum; /* Number of buffers provided */
|
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 */
|
/* The task requesting the IO operation. */
|
||||||
} blkdev_request;
|
rtems_id io_task;
|
||||||
|
|
||||||
|
/* List of scatter/gather buffers */
|
||||||
|
rtems_blkdev_sg_buffer bufs[0];
|
||||||
|
} rtems_blkdev_request;
|
||||||
|
|
||||||
/* Block device IOCTL request codes */
|
/* Block device IOCTL request codes */
|
||||||
#define BLKIO_REQUEST _IOWR('B', 1, blkdev_request)
|
#define RTEMS_BLKIO_REQUEST _IOWR('B', 1, rtems_blkdev_request)
|
||||||
#define BLKIO_GETBLKSIZE _IO('B', 2)
|
#define RTEMS_BLKIO_GETBLKSIZE _IO('B', 2)
|
||||||
#define BLKIO_GETSIZE _IO('B', 3)
|
#define RTEMS_BLKIO_GETSIZE _IO('B', 3)
|
||||||
#define BLKIO_SYNCDEV _IO('B', 4)
|
#define RTEMS_BLKIO_SYNCDEV _IO('B', 4)
|
||||||
|
|
||||||
/* Device driver interface conventions suppose that driver may
|
/* Device driver interface conventions suppose that driver may
|
||||||
* contain initialize/open/close/read/write/ioctl entry points. These
|
* 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.
|
* 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_open, rtems_blkdev_generic_close, \
|
||||||
rtems_blkdev_generic_read, rtems_blkdev_generic_write, \
|
rtems_blkdev_generic_read, rtems_blkdev_generic_write, \
|
||||||
rtems_blkdev_generic_ioctl
|
rtems_blkdev_generic_ioctl
|
||||||
|
|||||||
@@ -21,44 +21,47 @@ extern "C" {
|
|||||||
#include <rtems/libio.h>
|
#include <rtems/libio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "rtems/blkdev.h"
|
|
||||||
|
|
||||||
/* Buffer pool identifier */
|
/* Buffer pool identifier */
|
||||||
typedef int rtems_bdpool_id;
|
typedef int rtems_bdpool_id;
|
||||||
|
|
||||||
/* Block device ioctl handler */
|
#include "rtems/blkdev.h"
|
||||||
typedef int (* block_device_ioctl) (dev_t dev, uint32_t req, void *argp);
|
|
||||||
|
|
||||||
/* disk_device: Entry of this type created for every disk device (both for
|
/* Driver capabilities. */
|
||||||
* logical and physical disks).
|
|
||||||
|
/* 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
|
* Array of arrays of pointers to disk_device structures maintained. First
|
||||||
* table indexed by major number and second table indexed by minor number.
|
* table indexed by major number and second table indexed by minor number.
|
||||||
* Such data organization allow quick lookup using data structure of
|
* Such data organization allow quick lookup using data structure of
|
||||||
* moderated size.
|
* moderated size.
|
||||||
*/
|
*/
|
||||||
typedef struct disk_device {
|
typedef struct rtems_disk_device {
|
||||||
dev_t dev; /* Device ID (major + minor) */
|
dev_t dev; /* Device ID (major + minor) */
|
||||||
struct disk_device *phys_dev; /* Physical device ID (the same
|
struct rtems_disk_device *phys_dev; /* Physical device ID (the same
|
||||||
as dev if this entry specifies
|
as dev if this entry specifies
|
||||||
the physical device) */
|
the physical device) */
|
||||||
char *name; /* Disk device name */
|
uint32_t capabilities; /* Driver capabilities. */
|
||||||
int uses; /* Use counter. Device couldn't be
|
char *name; /* Disk device name */
|
||||||
removed if it is in use. */
|
int uses; /* Use counter. Device couldn't be
|
||||||
int start; /* Starting block number (0 for
|
removed if it is in use. */
|
||||||
physical devices, block offset
|
int start; /* Starting block number (0 for
|
||||||
on the related physical device
|
physical devices, block offset
|
||||||
for logical device) */
|
on the related physical device
|
||||||
int size; /* Size of physical or logical disk
|
for logical device) */
|
||||||
in disk blocks */
|
int size; /* Size of physical or logical disk
|
||||||
int block_size; /* Size of device block (minimum
|
in disk blocks */
|
||||||
transfer unit) in bytes
|
int block_size; /* Size of device block (minimum
|
||||||
(must be power of 2) */
|
transfer unit) in bytes
|
||||||
int block_size_log2; /* log2 of block_size */
|
(must be power of 2) */
|
||||||
rtems_bdpool_id pool; /* Buffer pool assigned to this
|
int block_size_log2; /* log2 of block_size */
|
||||||
device */
|
rtems_bdpool_id pool; /* Buffer pool assigned to this
|
||||||
block_device_ioctl ioctl; /* ioctl handler for this block
|
device */
|
||||||
device */
|
rtems_block_device_ioctl ioctl; /* ioctl handler for this block
|
||||||
} disk_device;
|
device */
|
||||||
|
} rtems_disk_device;
|
||||||
|
|
||||||
/* rtems_disk_create_phys --
|
/* rtems_disk_create_phys --
|
||||||
* Create physical disk entry. This function usually invoked from
|
* Create physical disk entry. This function usually invoked from
|
||||||
@@ -84,7 +87,7 @@ typedef struct disk_device {
|
|||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_disk_create_phys(dev_t dev, int block_size, int disk_size,
|
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);
|
const char *name);
|
||||||
|
|
||||||
/* rtems_disk_create_log --
|
/* 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_status_code
|
||||||
rtems_disk_delete(dev_t dev);
|
rtems_disk_delete(dev_t dev);
|
||||||
|
|
||||||
/* rtems_disk_lookup --
|
/* rtems_disk_obtain --
|
||||||
* Find block device descriptor by its device identifier. This function
|
* Find block device descriptor by its device identifier. This function
|
||||||
* increment usage counter to 1. User should release disk_device structure
|
* increment usage counter to 1. User should release disk_device structure
|
||||||
* by invoking rtems_disk_release primitive.
|
* 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
|
* pointer to the block device descriptor, or NULL if no such device
|
||||||
* exists.
|
* exists.
|
||||||
*/
|
*/
|
||||||
disk_device *
|
rtems_disk_device *
|
||||||
rtems_disk_lookup(dev_t dev);
|
rtems_disk_obtain(dev_t dev);
|
||||||
|
|
||||||
/* rtems_disk_release --
|
/* rtems_disk_release --
|
||||||
* Release disk_device structure (decrement usage counter to 1).
|
* 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.
|
* It should be implemented as inline function.
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_disk_release(disk_device *dd);
|
rtems_disk_release(rtems_disk_device *dd);
|
||||||
|
|
||||||
/* rtems_disk_next --
|
/* rtems_disk_next --
|
||||||
* Disk device enumerator. Looking for device having device number larger
|
* Disk device enumerator. Looking for device having device number larger
|
||||||
@@ -172,7 +175,7 @@ rtems_disk_release(disk_device *dd);
|
|||||||
* RETURNS:
|
* RETURNS:
|
||||||
* Pointer to the disk descriptor for next disk device, or NULL if all
|
* Pointer to the disk descriptor for next disk device, or NULL if all
|
||||||
* devices enumerated. */
|
* devices enumerated. */
|
||||||
disk_device *
|
rtems_disk_device *
|
||||||
rtems_disk_next(dev_t dev);
|
rtems_disk_next(dev_t dev);
|
||||||
|
|
||||||
/* rtems_diskio_initialize --
|
/* rtems_diskio_initialize --
|
||||||
|
|||||||
@@ -77,16 +77,18 @@
|
|||||||
* sector_data_t --
|
* sector_data_t --
|
||||||
* corresponds to the sector on the device
|
* 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 */
|
uint32_t sector_num; /* sector number on the device */
|
||||||
uint8_t data[0]; /* raw sector data */
|
uint8_t data[0]; /* raw sector data */
|
||||||
} sector_data_t;
|
} rtems_sector_data_t;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enum partition types
|
* Enum partition types
|
||||||
* see list at http://ata-atapi.com/hiwtab.htm
|
* see list at http://ata-atapi.com/hiwtab.htm
|
||||||
|
*
|
||||||
|
* @todo Should these have RTEMS before them.
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
EMPTY_PARTITION = 0x00,
|
EMPTY_PARTITION = 0x00,
|
||||||
@@ -108,29 +110,32 @@ enum {
|
|||||||
|
|
||||||
|
|
||||||
/* Forward declaration */
|
/* Forward declaration */
|
||||||
struct disk_desc_s;
|
struct rtems_disk_desc_s;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* part_desc_t --
|
* part_desc_t --
|
||||||
* contains all neccessary information about partition
|
* 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 bootable; /* is the partition active */
|
||||||
uint8_t sys_type; /* type of partition */
|
uint8_t sys_type; /* type of partition */
|
||||||
uint8_t log_id; /* logical number 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 size; /* size in sectors */
|
||||||
uint32_t end; /* last partition sector, end = start + size - 1 */
|
uint32_t end; /* last partition sector, end = start + size - 1 */
|
||||||
struct disk_desc_s *disk_desc; /* descriptor of disk, partition contains in */
|
struct rtems_disk_desc_s *disk_desc; /* descriptor of disk, partition
|
||||||
struct part_desc_s *ext_part; /* extended partition containing this one */
|
* contains in */
|
||||||
|
struct rtems_part_desc_s *ext_part; /* extended partition containing this
|
||||||
|
* one */
|
||||||
|
|
||||||
/* partitions, containing in this one */
|
/* partitions, containing in this one */
|
||||||
struct part_desc_s *sub_part[RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER];
|
struct rtems_part_desc_s *sub_part[RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER];
|
||||||
} part_desc_t;
|
} rtems_part_desc_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct disk_desc_s {
|
typedef struct rtems_disk_desc_s {
|
||||||
dev_t dev; /* device number */
|
dev_t dev; /* device number */
|
||||||
|
|
||||||
/* device name in /dev filesystem */
|
/* device name in /dev filesystem */
|
||||||
@@ -142,8 +147,8 @@ typedef struct disk_desc_s {
|
|||||||
int last_log_id; /* used for logical disks enumerating */
|
int last_log_id; /* used for logical disks enumerating */
|
||||||
|
|
||||||
/* primary partition descriptors */
|
/* primary partition descriptors */
|
||||||
part_desc_t *partitions[RTEMS_IDE_PARTITION_MAX_PARTITION_NUMBER];
|
rtems_part_desc_t *partitions[RTEMS_IDE_PARTITION_MAX_PARTITION_NUMBER];
|
||||||
} disk_desc_t;
|
} rtems_disk_desc_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -160,7 +165,7 @@ extern "C" {
|
|||||||
* N/A
|
* N/A
|
||||||
*/
|
*/
|
||||||
void
|
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_SUCCESSFUL if success, or -1 and corresponding errno else
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
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);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ typedef struct rtems_nvdisk_config
|
|||||||
const rtems_nvdisk_device_desc* devices; /**< The device descriptions. */
|
const rtems_nvdisk_device_desc* devices; /**< The device descriptions. */
|
||||||
uint32_t flags; /**< Set of flags to control
|
uint32_t flags; /**< Set of flags to control
|
||||||
driver. */
|
driver. */
|
||||||
uint32_t info_level; /**< Default info level. */
|
uint32_t info_level; /**< Default info level. */
|
||||||
} rtems_nvdisk_config;
|
} rtems_nvdisk_config;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ ramdisk_initialize(
|
|||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
#define RAMDISK_DRIVER_TABLE_ENTRY \
|
#define RAMDISK_DRIVER_TABLE_ENTRY \
|
||||||
{ ramdisk_initialize, GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES }
|
{ ramdisk_initialize, RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES }
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -38,10 +38,10 @@ rtems_blkdev_generic_read(
|
|||||||
unsigned int block;
|
unsigned int block;
|
||||||
unsigned int blkofs;
|
unsigned int blkofs;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
disk_device *dd;
|
rtems_disk_device *dd;
|
||||||
|
|
||||||
dev = rtems_filesystem_make_dev_t(major, minor);
|
dev = rtems_filesystem_make_dev_t(major, minor);
|
||||||
dd = rtems_disk_lookup(dev);
|
dd = rtems_disk_obtain(dev);
|
||||||
if (dd == NULL)
|
if (dd == NULL)
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ rtems_blkdev_generic_read(
|
|||||||
|
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
bdbuf_buffer *diskbuf;
|
rtems_bdbuf_buffer *diskbuf;
|
||||||
int copy;
|
int copy;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
|
|
||||||
@@ -99,10 +99,10 @@ rtems_blkdev_generic_write(
|
|||||||
unsigned int blkofs;
|
unsigned int blkofs;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
disk_device *dd;
|
rtems_disk_device *dd;
|
||||||
|
|
||||||
dev = rtems_filesystem_make_dev_t(major, minor);
|
dev = rtems_filesystem_make_dev_t(major, minor);
|
||||||
dd = rtems_disk_lookup(dev);
|
dd = rtems_disk_obtain(dev);
|
||||||
if (dd == NULL)
|
if (dd == NULL)
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ rtems_blkdev_generic_write(
|
|||||||
|
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
bdbuf_buffer *diskbuf;
|
rtems_bdbuf_buffer *diskbuf;
|
||||||
int copy;
|
int copy;
|
||||||
|
|
||||||
if ((blkofs == 0) && (count >= block_size))
|
if ((blkofs == 0) && (count >= block_size))
|
||||||
@@ -156,10 +156,10 @@ rtems_blkdev_generic_open(
|
|||||||
void * arg)
|
void * arg)
|
||||||
{
|
{
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
disk_device *dd;
|
rtems_disk_device *dd;
|
||||||
|
|
||||||
dev = rtems_filesystem_make_dev_t(major, minor);
|
dev = rtems_filesystem_make_dev_t(major, minor);
|
||||||
dd = rtems_disk_lookup(dev);
|
dd = rtems_disk_obtain(dev);
|
||||||
if (dd == NULL)
|
if (dd == NULL)
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
|
||||||
@@ -181,10 +181,10 @@ rtems_blkdev_generic_close(
|
|||||||
void * arg)
|
void * arg)
|
||||||
{
|
{
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
disk_device *dd;
|
rtems_disk_device *dd;
|
||||||
|
|
||||||
dev = rtems_filesystem_make_dev_t(major, minor);
|
dev = rtems_filesystem_make_dev_t(major, minor);
|
||||||
dd = rtems_disk_lookup(dev);
|
dd = rtems_disk_obtain(dev);
|
||||||
if (dd == NULL)
|
if (dd == NULL)
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
|
||||||
@@ -206,32 +206,32 @@ rtems_blkdev_generic_ioctl(
|
|||||||
{
|
{
|
||||||
rtems_libio_ioctl_args_t *args = arg;
|
rtems_libio_ioctl_args_t *args = arg;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
disk_device *dd;
|
rtems_disk_device *dd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
dev = rtems_filesystem_make_dev_t(major, minor);
|
dev = rtems_filesystem_make_dev_t(major, minor);
|
||||||
dd = rtems_disk_lookup(dev);
|
dd = rtems_disk_obtain(dev);
|
||||||
if (dd == NULL)
|
if (dd == NULL)
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
|
||||||
switch (args->command)
|
switch (args->command)
|
||||||
{
|
{
|
||||||
case BLKIO_GETBLKSIZE:
|
case RTEMS_BLKIO_GETBLKSIZE:
|
||||||
args->ioctl_return = dd->block_size;
|
args->ioctl_return = dd->block_size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLKIO_GETSIZE:
|
case RTEMS_BLKIO_GETSIZE:
|
||||||
args->ioctl_return = dd->size;
|
args->ioctl_return = dd->size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLKIO_SYNCDEV:
|
case RTEMS_BLKIO_SYNCDEV:
|
||||||
rc = rtems_bdbuf_syncdev(dd->dev);
|
rc = rtems_bdbuf_syncdev(dd->dev);
|
||||||
args->ioctl_return = (rc == RTEMS_SUCCESSFUL ? 0 : -1);
|
args->ioctl_return = (rc == RTEMS_SUCCESSFUL ? 0 : -1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLKIO_REQUEST:
|
case RTEMS_BLKIO_REQUEST:
|
||||||
{
|
{
|
||||||
blkdev_request *req = args->buffer;
|
rtems_blkdev_request *req = args->buffer;
|
||||||
req->start += dd->start;
|
req->start += dd->start;
|
||||||
args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
|
args->ioctl_return = dd->ioctl(dd->phys_dev->dev, args->command,
|
||||||
req);
|
req);
|
||||||
|
|||||||
@@ -23,13 +23,13 @@
|
|||||||
#define DISKTAB_INITIAL_SIZE 32
|
#define DISKTAB_INITIAL_SIZE 32
|
||||||
|
|
||||||
/* Table of disk devices having the same major number */
|
/* Table of disk devices having the same major number */
|
||||||
struct disk_device_table {
|
typedef struct rtems_disk_device_table {
|
||||||
disk_device **minor; /* minor-indexed disk device table */
|
rtems_disk_device **minor; /* minor-indexed disk device table */
|
||||||
int size; /* Number of entries in the table */
|
int size; /* Number of entries in the table */
|
||||||
};
|
} rtems_disk_device_table;
|
||||||
|
|
||||||
/* Pointer to [major].minor[minor] indexed array of disk devices */
|
/* 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 */
|
/* Number of allocated entries in disktab table */
|
||||||
static int disktab_size;
|
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
|
* pointer to the disk device descriptor entry, or NULL if no memory
|
||||||
* available for its creation.
|
* available for its creation.
|
||||||
*/
|
*/
|
||||||
static disk_device *
|
static rtems_disk_device *
|
||||||
create_disk_entry(dev_t dev)
|
create_disk_entry(dev_t dev)
|
||||||
{
|
{
|
||||||
rtems_device_major_number major;
|
rtems_device_major_number major;
|
||||||
rtems_device_minor_number minor;
|
rtems_device_minor_number minor;
|
||||||
struct disk_device **d;
|
rtems_disk_device **d;
|
||||||
|
|
||||||
rtems_filesystem_split_dev_t (dev, major, minor);
|
rtems_filesystem_split_dev_t (dev, major, minor);
|
||||||
|
|
||||||
if (major >= disktab_size)
|
if (major >= disktab_size)
|
||||||
{
|
{
|
||||||
struct disk_device_table *p;
|
rtems_disk_device_table *p;
|
||||||
int newsize;
|
int newsize;
|
||||||
int i;
|
int i;
|
||||||
newsize = disktab_size * 2;
|
newsize = disktab_size * 2;
|
||||||
if (major >= newsize)
|
if (major >= newsize)
|
||||||
newsize = major + 1;
|
newsize = major + 1;
|
||||||
p = realloc(disktab, sizeof(struct disk_device_table) * newsize);
|
p = realloc(disktab, sizeof(rtems_disk_device_table) * newsize);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
p += disktab_size;
|
p += disktab_size;
|
||||||
@@ -97,7 +97,7 @@ create_disk_entry(dev_t dev)
|
|||||||
(minor >= disktab[major].size))
|
(minor >= disktab[major].size))
|
||||||
{
|
{
|
||||||
int newsize;
|
int newsize;
|
||||||
disk_device **p;
|
rtems_disk_device **p;
|
||||||
int i;
|
int i;
|
||||||
int s = disktab[major].size;
|
int s = disktab[major].size;
|
||||||
|
|
||||||
@@ -108,7 +108,8 @@ create_disk_entry(dev_t dev)
|
|||||||
if (minor >= newsize)
|
if (minor >= newsize)
|
||||||
newsize = minor + 1;
|
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)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
disktab[major].minor = p;
|
disktab[major].minor = p;
|
||||||
@@ -121,7 +122,7 @@ create_disk_entry(dev_t dev)
|
|||||||
d = disktab[major].minor + minor;
|
d = disktab[major].minor + minor;
|
||||||
if (*d == NULL)
|
if (*d == NULL)
|
||||||
{
|
{
|
||||||
*d = calloc(1, sizeof(disk_device));
|
*d = calloc(1, sizeof(rtems_disk_device));
|
||||||
}
|
}
|
||||||
return *d;
|
return *d;
|
||||||
}
|
}
|
||||||
@@ -136,12 +137,12 @@ create_disk_entry(dev_t dev)
|
|||||||
* Pointer to the disk device descriptor corresponding to the specified
|
* Pointer to the disk device descriptor corresponding to the specified
|
||||||
* device number, or NULL if disk device with such number not exists.
|
* 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)
|
get_disk_entry(dev_t dev)
|
||||||
{
|
{
|
||||||
rtems_device_major_number major;
|
rtems_device_major_number major;
|
||||||
rtems_device_minor_number minor;
|
rtems_device_minor_number minor;
|
||||||
struct disk_device_table *dtab;
|
rtems_disk_device_table *dtab;
|
||||||
|
|
||||||
rtems_filesystem_split_dev_t (dev, major, minor);
|
rtems_filesystem_split_dev_t (dev, major, minor);
|
||||||
|
|
||||||
@@ -171,9 +172,9 @@ get_disk_entry(dev_t dev)
|
|||||||
* no memory available).
|
* no memory available).
|
||||||
*/
|
*/
|
||||||
static rtems_status_code
|
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;
|
char *n;
|
||||||
|
|
||||||
dd = get_disk_entry(dev);
|
dd = get_disk_entry(dev);
|
||||||
@@ -234,12 +235,12 @@ create_disk(dev_t dev, const char *name, disk_device **diskdev)
|
|||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_disk_create_phys(dev_t dev, int block_size, int disk_size,
|
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)
|
const char *name)
|
||||||
{
|
{
|
||||||
int bs_log2;
|
int bs_log2;
|
||||||
int i;
|
int i;
|
||||||
disk_device *dd;
|
rtems_disk_device *dd;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
rtems_bdpool_id pool;
|
rtems_bdpool_id pool;
|
||||||
rtems_device_major_number major;
|
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);
|
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;
|
diskdevs_protected = FALSE;
|
||||||
rtems_semaphore_release(diskdevs_mutex);
|
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_status_code
|
||||||
rtems_disk_create_log(dev_t dev, dev_t phys, int start, int size, char *name)
|
rtems_disk_create_log(dev_t dev, dev_t phys, int start, int size, char *name)
|
||||||
{
|
{
|
||||||
disk_device *dd;
|
rtems_disk_device *dd;
|
||||||
disk_device *pdd;
|
rtems_disk_device *pdd;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
rtems_device_major_number major;
|
rtems_device_major_number major;
|
||||||
rtems_device_minor_number minor;
|
rtems_device_minor_number minor;
|
||||||
@@ -393,12 +399,12 @@ rtems_disk_delete(dev_t dev)
|
|||||||
used = 0;
|
used = 0;
|
||||||
for (maj = 0; maj < disktab_size; maj++)
|
for (maj = 0; maj < disktab_size; maj++)
|
||||||
{
|
{
|
||||||
struct disk_device_table *dtab = disktab + maj;
|
rtems_disk_device_table *dtab = disktab + maj;
|
||||||
if (dtab != NULL)
|
if (dtab != NULL)
|
||||||
{
|
{
|
||||||
for (min = 0; min < dtab->size; min++)
|
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))
|
if ((dd != NULL) && (dd->phys_dev->dev == dev))
|
||||||
used += dd->uses;
|
used += dd->uses;
|
||||||
}
|
}
|
||||||
@@ -415,12 +421,12 @@ rtems_disk_delete(dev_t dev)
|
|||||||
/* Delete this device and all of its logical devices */
|
/* Delete this device and all of its logical devices */
|
||||||
for (maj = 0; maj < disktab_size; maj++)
|
for (maj = 0; maj < disktab_size; maj++)
|
||||||
{
|
{
|
||||||
struct disk_device_table *dtab = disktab +maj;
|
rtems_disk_device_table *dtab = disktab +maj;
|
||||||
if (dtab != NULL)
|
if (dtab != NULL)
|
||||||
{
|
{
|
||||||
for (min = 0; min < dtab->size; min++)
|
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))
|
if ((dd != NULL) && (dd->phys_dev->dev == dev))
|
||||||
{
|
{
|
||||||
unlink(dd->name);
|
unlink(dd->name);
|
||||||
@@ -437,7 +443,7 @@ rtems_disk_delete(dev_t dev)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rtems_disk_lookup --
|
/* rtems_disk_obtain --
|
||||||
* Find block device descriptor by its device identifier.
|
* Find block device descriptor by its device identifier.
|
||||||
*
|
*
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
@@ -447,11 +453,11 @@ rtems_disk_delete(dev_t dev)
|
|||||||
* pointer to the block device descriptor, or NULL if no such device
|
* pointer to the block device descriptor, or NULL if no such device
|
||||||
* exists.
|
* exists.
|
||||||
*/
|
*/
|
||||||
disk_device *
|
rtems_disk_device *
|
||||||
rtems_disk_lookup(dev_t dev)
|
rtems_disk_obtain(dev_t dev)
|
||||||
{
|
{
|
||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
disk_device *dd;
|
rtems_disk_device *dd;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
|
|
||||||
rtems_interrupt_disable(level);
|
rtems_interrupt_disable(level);
|
||||||
@@ -480,7 +486,7 @@ rtems_disk_lookup(dev_t dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* rtems_disk_release --
|
/* rtems_disk_release --
|
||||||
* Release disk_device structure (decrement usage counter to 1).
|
* Release rtems_disk_device structure (decrement usage counter to 1).
|
||||||
*
|
*
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
* dd - pointer to disk device structure
|
* dd - pointer to disk device structure
|
||||||
@@ -489,7 +495,7 @@ rtems_disk_lookup(dev_t dev)
|
|||||||
* RTEMS_SUCCESSFUL
|
* RTEMS_SUCCESSFUL
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
rtems_status_code
|
||||||
rtems_disk_release(disk_device *dd)
|
rtems_disk_release(rtems_disk_device *dd)
|
||||||
{
|
{
|
||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
rtems_interrupt_disable(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
|
* Pointer to the disk descriptor for next disk device, or NULL if all
|
||||||
* devices enumerated.
|
* devices enumerated.
|
||||||
*/
|
*/
|
||||||
disk_device *
|
rtems_disk_device *
|
||||||
rtems_disk_next(dev_t dev)
|
rtems_disk_next(dev_t dev)
|
||||||
{
|
{
|
||||||
rtems_device_major_number major;
|
rtems_device_major_number major;
|
||||||
rtems_device_minor_number minor;
|
rtems_device_minor_number minor;
|
||||||
struct disk_device_table *dtab;
|
rtems_disk_device_table *dtab;
|
||||||
|
|
||||||
dev++;
|
dev++;
|
||||||
rtems_filesystem_split_dev_t (dev, major, minor);
|
rtems_filesystem_split_dev_t (dev, major, minor);
|
||||||
@@ -562,7 +568,7 @@ rtems_disk_io_initialize(void)
|
|||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
|
|
||||||
disktab_size = DISKTAB_INITIAL_SIZE;
|
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)
|
if (disktab == NULL)
|
||||||
return RTEMS_NO_MEMORY;
|
return RTEMS_NO_MEMORY;
|
||||||
|
|
||||||
@@ -578,8 +584,7 @@ rtems_disk_io_initialize(void)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = rtems_bdbuf_init(rtems_bdbuf_configuration,
|
rc = rtems_bdbuf_init();
|
||||||
rtems_bdbuf_configuration_size);
|
|
||||||
|
|
||||||
if (rc != RTEMS_SUCCESSFUL)
|
if (rc != RTEMS_SUCCESSFUL)
|
||||||
{
|
{
|
||||||
@@ -612,12 +617,12 @@ rtems_disk_io_done(void)
|
|||||||
/* Free data structures */
|
/* Free data structures */
|
||||||
for (maj = 0; maj < disktab_size; maj++)
|
for (maj = 0; maj < disktab_size; maj++)
|
||||||
{
|
{
|
||||||
struct disk_device_table *dtab = disktab + maj;
|
rtems_disk_device_table *dtab = disktab + maj;
|
||||||
if (dtab != NULL)
|
if (dtab != NULL)
|
||||||
{
|
{
|
||||||
for (min = 0; min < dtab->size; min++)
|
for (min = 0; min < dtab->size; min++)
|
||||||
{
|
{
|
||||||
disk_device *dd = dtab->minor[min];
|
rtems_disk_device *dd = dtab->minor[min];
|
||||||
unlink(dd->name);
|
unlink(dd->name);
|
||||||
free(dd->name);
|
free(dd->name);
|
||||||
free(dd);
|
free(dd);
|
||||||
|
|||||||
@@ -2057,14 +2057,13 @@ rtems_fdisk_write_block (rtems_flashdisk* fd,
|
|||||||
* @retval int The ioctl return value.
|
* @retval int The ioctl return value.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
rtems_blkdev_sg_buffer* sg = req->bufs;
|
||||||
uint32_t block = req->start;
|
uint32_t b;
|
||||||
uint32_t b;
|
int ret = 0;
|
||||||
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;
|
uint32_t length = sg->length;
|
||||||
|
|
||||||
@@ -2077,7 +2076,7 @@ rtems_fdisk_read (rtems_flashdisk* fd, blkdev_request* req)
|
|||||||
length = fd->block_size;
|
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)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
@@ -2098,14 +2097,13 @@ rtems_fdisk_read (rtems_flashdisk* fd, blkdev_request* req)
|
|||||||
* @retval int The ioctl return value.
|
* @retval int The ioctl return value.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
rtems_blkdev_sg_buffer* sg = req->bufs;
|
||||||
uint32_t block = req->start;
|
uint32_t b;
|
||||||
uint32_t b;
|
int ret = 0;
|
||||||
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)
|
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);
|
"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)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
@@ -2356,7 +2354,7 @@ static int
|
|||||||
rtems_fdisk_ioctl (dev_t dev, uint32_t req, void* argp)
|
rtems_fdisk_ioctl (dev_t dev, uint32_t req, void* argp)
|
||||||
{
|
{
|
||||||
rtems_device_minor_number minor = rtems_filesystem_dev_minor_t (dev);
|
rtems_device_minor_number minor = rtems_filesystem_dev_minor_t (dev);
|
||||||
blkdev_request* r = argp;
|
rtems_blkdev_request* r = argp;
|
||||||
rtems_status_code sc;
|
rtems_status_code sc;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
@@ -2368,7 +2366,7 @@ rtems_fdisk_ioctl (dev_t dev, uint32_t req, void* argp)
|
|||||||
{
|
{
|
||||||
switch (req)
|
switch (req)
|
||||||
{
|
{
|
||||||
case BLKIO_REQUEST:
|
case RTEMS_BLKIO_REQUEST:
|
||||||
if ((minor >= rtems_flashdisk_count) ||
|
if ((minor >= rtems_flashdisk_count) ||
|
||||||
(rtems_flashdisks[minor].device_count == 0))
|
(rtems_flashdisks[minor].device_count == 0))
|
||||||
{
|
{
|
||||||
@@ -2378,11 +2376,11 @@ rtems_fdisk_ioctl (dev_t dev, uint32_t req, void* argp)
|
|||||||
{
|
{
|
||||||
switch (r->req)
|
switch (r->req)
|
||||||
{
|
{
|
||||||
case BLKDEV_REQ_READ:
|
case RTEMS_BLKDEV_REQ_READ:
|
||||||
errno = rtems_fdisk_read (&rtems_flashdisks[minor], r);
|
errno = rtems_fdisk_read (&rtems_flashdisks[minor], r);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLKDEV_REQ_WRITE:
|
case RTEMS_BLKDEV_REQ_WRITE:
|
||||||
errno = rtems_fdisk_write (&rtems_flashdisks[minor], r);
|
errno = rtems_fdisk_write (&rtems_flashdisks[minor], r);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -46,18 +46,18 @@
|
|||||||
* and does not support devices with sector size other than 512 bytes
|
* and does not support devices with sector size other than 512 bytes
|
||||||
*/
|
*/
|
||||||
static rtems_status_code
|
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;
|
rtems_sector_data_t *s;
|
||||||
bdbuf_buffer *buf;
|
rtems_bdbuf_buffer *buf;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
|
|
||||||
if (sector == NULL)
|
if (sector == NULL)
|
||||||
{
|
{
|
||||||
return RTEMS_INTERNAL_ERROR;
|
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)
|
if (s == NULL)
|
||||||
{
|
{
|
||||||
return RTEMS_NO_MEMORY;
|
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
|
* TRUE if sector has msdos signature, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
static rtems_boolean
|
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;
|
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.
|
* RTEMS_INTERNAL_ERROR, if other error occurs.
|
||||||
*/
|
*/
|
||||||
static rtems_status_code
|
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;
|
rtems_part_desc_t *part_desc;
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
|
|
||||||
if (new_part_desc == NULL)
|
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;
|
*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;
|
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.
|
* RTEMS_INTERNAL_ERROR if other error occurs.
|
||||||
*/
|
*/
|
||||||
static rtems_status_code
|
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;
|
int i;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
sector_data_t *sector;
|
rtems_sector_data_t *sector;
|
||||||
uint32_t here;
|
uint32_t here;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
part_desc_t *new_part_desc;
|
rtems_part_desc_t *new_part_desc;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
|
|
||||||
if ((ext_part == NULL) || (ext_part->disk_desc == NULL))
|
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
|
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;
|
disk_desc->partitions[disk_desc->last_log_id] = new_part_desc;
|
||||||
new_part_desc->log_id = ++disk_desc->last_log_id;
|
new_part_desc->log_id = ++disk_desc->last_log_id;
|
||||||
new_part_desc->start += here;
|
new_part_desc->start += here;
|
||||||
@@ -314,14 +314,14 @@ read_extended_partition(uint32_t start, part_desc_t *ext_part)
|
|||||||
* RTEMS_INTERNAL_ERROR otherwise
|
* RTEMS_INTERNAL_ERROR otherwise
|
||||||
*/
|
*/
|
||||||
static rtems_status_code
|
static rtems_status_code
|
||||||
read_mbr(disk_desc_t *disk_desc)
|
read_mbr(rtems_disk_desc_t *disk_desc)
|
||||||
{
|
{
|
||||||
int part_num;
|
int part_num;
|
||||||
sector_data_t *sector;
|
rtems_sector_data_t *sector;
|
||||||
part_desc_t *part_desc;
|
rtems_part_desc_t *part_desc;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
dev_t dev = disk_desc->dev;
|
dev_t dev = disk_desc->dev;
|
||||||
|
|
||||||
/* get MBR sector */
|
/* get MBR sector */
|
||||||
rc = get_sector(dev, 0, §or);
|
rc = get_sector(dev, 0, §or);
|
||||||
@@ -398,7 +398,7 @@ read_mbr(disk_desc_t *disk_desc)
|
|||||||
* N/A
|
* N/A
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
partition_free(part_desc_t *part_desc)
|
partition_free(rtems_part_desc_t *part_desc)
|
||||||
{
|
{
|
||||||
int part_num;
|
int part_num;
|
||||||
|
|
||||||
@@ -429,7 +429,7 @@ partition_free(part_desc_t *part_desc)
|
|||||||
* N/A
|
* N/A
|
||||||
*/
|
*/
|
||||||
void
|
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;
|
int part_num;
|
||||||
|
|
||||||
@@ -455,7 +455,7 @@ rtems_ide_part_table_free(disk_desc_t *disk_desc)
|
|||||||
* RTEMS_INTERNAL_ERROR otherwise
|
* RTEMS_INTERNAL_ERROR otherwise
|
||||||
*/
|
*/
|
||||||
rtems_status_code
|
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;
|
struct stat dev_stat;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
@@ -494,16 +494,16 @@ rtems_ide_part_table_initialize(char *dev_name)
|
|||||||
{
|
{
|
||||||
int part_num;
|
int part_num;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
disk_desc_t *disk_desc;
|
rtems_disk_desc_t *disk_desc;
|
||||||
rtems_device_major_number major;
|
rtems_device_major_number major;
|
||||||
rtems_device_minor_number minor;
|
rtems_device_minor_number minor;
|
||||||
rtems_status_code rc;
|
rtems_status_code rc;
|
||||||
part_desc_t *part_desc;
|
rtems_part_desc_t *part_desc;
|
||||||
|
|
||||||
/* logical device name /dev/hdxyy */
|
/* logical device name /dev/hdxyy */
|
||||||
char name[RTEMS_IDE_PARTITION_DEV_NAME_LENGTH_MAX];
|
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)
|
if (disk_desc == NULL)
|
||||||
{
|
{
|
||||||
return RTEMS_NO_MEMORY;
|
return RTEMS_NO_MEMORY;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
* footprint targets. Leave in by default.
|
* footprint targets. Leave in by default.
|
||||||
*/
|
*/
|
||||||
#if !defined (RTEMS_NVDISK_TRACE)
|
#if !defined (RTEMS_NVDISK_TRACE)
|
||||||
#define RTEMS_NVDISK_TRACE 1
|
#define RTEMS_NVDISK_TRACE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,7 +165,7 @@ rtems_nvdisk_crc16_gen_factors (uint16_t pattern)
|
|||||||
/**
|
/**
|
||||||
* Print a message to the nvdisk output and flush it.
|
* 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 format The format string. See printf for details.
|
||||||
* @param ... The arguments for the format text.
|
* @param ... The arguments for the format text.
|
||||||
* @return int The number of bytes written to the output.
|
* @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.
|
* 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 format The format string. See printf for details.
|
||||||
* @param ... The arguments for the format text.
|
* @param ... The arguments for the format text.
|
||||||
* @return int The number of bytes written to the output.
|
* @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.
|
* 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 format The format string. See printf for details.
|
||||||
* @param ... The arguments for the format text.
|
* @param ... The arguments for the format text.
|
||||||
* @return int The number of bytes written to the output.
|
* @return int The number of bytes written to the output.
|
||||||
@@ -255,24 +255,6 @@ rtems_nvdisk_error (const char *format, ...)
|
|||||||
return ret;
|
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.
|
* 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);
|
return ops->write (device, dd->flags, dd->base, offset, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NOT_USED
|
||||||
/**
|
/**
|
||||||
* Verify the data with the data in a segment.
|
* Verify the data with the data in a segment.
|
||||||
*/
|
*/
|
||||||
@@ -344,6 +327,7 @@ rtems_nvdisk_device_verify (const rtems_nvdisk* nvd,
|
|||||||
#endif
|
#endif
|
||||||
return ops->verify (device, dd->flags, dd->base, offset, buffer, size);
|
return ops->verify (device, dd->flags, dd->base, offset, buffer, size);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a page of data from the device.
|
* Read a page of data from the device.
|
||||||
@@ -373,20 +357,6 @@ rtems_nvdisk_write_page (const rtems_nvdisk* nvd,
|
|||||||
buffer, nvd->block_size);
|
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.
|
* 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 (crc == 0xffff)
|
||||||
{
|
{
|
||||||
|
#if RTEMS_NVDISK_TRACE
|
||||||
rtems_nvdisk_warning (nvd, "read-block: crc not set: %d", block);
|
rtems_nvdisk_warning (nvd, "read-block: crc not set: %d", block);
|
||||||
|
#endif
|
||||||
memset (buffer, 0, nvd->block_size);
|
memset (buffer, 0, nvd->block_size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -605,13 +577,12 @@ rtems_nvdisk_write_block (rtems_nvdisk* nvd,
|
|||||||
* @retval int The ioctl return value.
|
* @retval int The ioctl return value.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
rtems_blkdev_sg_buffer* sg = req->bufs;
|
||||||
uint32_t block = req->start;
|
uint32_t b;
|
||||||
uint32_t b;
|
int32_t remains;
|
||||||
int32_t remains;
|
int ret = 0;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
#if RTEMS_NVDISK_TRACE
|
#if RTEMS_NVDISK_TRACE
|
||||||
rtems_nvdisk_info (nvd, "read: blocks=%d", req->bufnum);
|
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;
|
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;
|
uint32_t length = sg->length;
|
||||||
|
|
||||||
@@ -658,18 +629,17 @@ rtems_nvdisk_read (rtems_nvdisk* nvd, blkdev_request* req)
|
|||||||
* @retval int The ioctl return value.
|
* @retval int The ioctl return value.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
rtems_blkdev_sg_buffer* sg = req->bufs;
|
||||||
uint32_t block = req->start;
|
uint32_t b;
|
||||||
uint32_t b;
|
int ret = 0;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
#if RTEMS_NVDISK_TRACE
|
#if RTEMS_NVDISK_TRACE
|
||||||
rtems_nvdisk_info (nvd, "write: blocks=%d", req->bufnum);
|
rtems_nvdisk_info (nvd, "write: blocks=%d", req->bufnum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (b = 0; b < req->bufnum; b++, block++, sg++)
|
for (b = 0; b < req->bufnum; b++, sg++)
|
||||||
{
|
{
|
||||||
if (sg->length != nvd->block_size)
|
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 dev Device number (major, minor number).
|
||||||
* @param req IOCTL request code.
|
* @param req IOCTL request code.
|
||||||
@@ -731,9 +701,21 @@ static int
|
|||||||
rtems_nvdisk_ioctl (dev_t dev, uint32_t req, void* argp)
|
rtems_nvdisk_ioctl (dev_t dev, uint32_t req, void* argp)
|
||||||
{
|
{
|
||||||
rtems_device_minor_number minor = rtems_filesystem_dev_minor_t (dev);
|
rtems_device_minor_number minor = rtems_filesystem_dev_minor_t (dev);
|
||||||
blkdev_request* r = argp;
|
rtems_blkdev_request* r = argp;
|
||||||
rtems_status_code sc;
|
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;
|
errno = 0;
|
||||||
|
|
||||||
sc = rtems_semaphore_obtain (rtems_nvdisks[minor].lock, RTEMS_WAIT, 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)
|
switch (req)
|
||||||
{
|
{
|
||||||
case BLKIO_REQUEST:
|
case RTEMS_BLKIO_REQUEST:
|
||||||
if ((minor >= rtems_nvdisk_count) ||
|
switch (r->req)
|
||||||
(rtems_nvdisks[minor].device_count == 0))
|
|
||||||
{
|
{
|
||||||
errno = ENODEV;
|
case RTEMS_BLKDEV_REQ_READ:
|
||||||
}
|
errno = rtems_nvdisk_read (&rtems_nvdisks[minor], r);
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
switch (r->req)
|
|
||||||
{
|
|
||||||
case BLKDEV_REQ_READ:
|
|
||||||
errno = rtems_nvdisk_read (&rtems_nvdisks[minor], r);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLKDEV_REQ_WRITE:
|
case RTEMS_BLKDEV_REQ_WRITE:
|
||||||
errno = rtems_nvdisk_write (&rtems_nvdisks[minor], r);
|
errno = rtems_nvdisk_write (&rtems_nvdisks[minor], r);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errno = EBADRQC;
|
errno = EBADRQC;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,14 @@
|
|||||||
#include "rtems/diskdevs.h"
|
#include "rtems/diskdevs.h"
|
||||||
#include "rtems/ramdisk.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"
|
#define RAMDISK_DEVICE_BASE_NAME "/dev/ramdisk"
|
||||||
|
|
||||||
/* Internal RAM disk descriptor */
|
/* Internal RAM disk descriptor */
|
||||||
@@ -32,11 +40,40 @@ struct ramdisk {
|
|||||||
rtems_boolean initialized;/* RAM disk is initialized */
|
rtems_boolean initialized;/* RAM disk is initialized */
|
||||||
rtems_boolean malloced; /* != 0, if memory allocated by malloc for this
|
rtems_boolean malloced; /* != 0, if memory allocated by malloc for this
|
||||||
RAM disk */
|
RAM disk */
|
||||||
|
#if RTEMS_RAMDISK_TRACE
|
||||||
|
int info_level; /* Trace level */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ramdisk *ramdisk;
|
static struct ramdisk *ramdisk;
|
||||||
static int nramdisks;
|
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 --
|
/* ramdisk_read --
|
||||||
* RAM disk READ request handler. This primitive copies data from RAM
|
* RAM disk READ request handler. This primitive copies data from RAM
|
||||||
* disk to supplied buffer and invoke the callout function to inform
|
* disk to supplied buffer and invoke the callout function to inform
|
||||||
@@ -49,19 +86,25 @@ static int nramdisks;
|
|||||||
* ioctl return value
|
* ioctl return value
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ramdisk_read(struct ramdisk *rd, blkdev_request *req)
|
ramdisk_read(struct ramdisk *rd, rtems_blkdev_request *req)
|
||||||
{
|
{
|
||||||
char *from;
|
char *from;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
blkdev_sg_buffer *sg;
|
rtems_blkdev_sg_buffer *sg;
|
||||||
uint32_t remains;
|
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;
|
remains = rd->block_size * req->count;
|
||||||
sg = req->bufs;
|
sg = req->bufs;
|
||||||
for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
|
for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
|
||||||
{
|
{
|
||||||
int count = sg->length;
|
int count = sg->length;
|
||||||
|
from = ((char *)rd->area + (sg->block * rd->block_size));
|
||||||
if (count > remains)
|
if (count > remains)
|
||||||
count = remains;
|
count = remains;
|
||||||
memcpy(sg->buffer, from, count);
|
memcpy(sg->buffer, from, count);
|
||||||
@@ -84,19 +127,24 @@ ramdisk_read(struct ramdisk *rd, blkdev_request *req)
|
|||||||
* ioctl return value
|
* ioctl return value
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ramdisk_write(struct ramdisk *rd, blkdev_request *req)
|
ramdisk_write(struct ramdisk *rd, rtems_blkdev_request *req)
|
||||||
{
|
{
|
||||||
char *to;
|
char *to;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
blkdev_sg_buffer *sg;
|
rtems_blkdev_sg_buffer *sg;
|
||||||
uint32_t remains;
|
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;
|
remains = rd->block_size * req->count;
|
||||||
sg = req->bufs;
|
sg = req->bufs;
|
||||||
for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
|
for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
|
||||||
{
|
{
|
||||||
int count = sg->length;
|
int count = sg->length;
|
||||||
|
to = ((char *)rd->area + (sg->block * rd->block_size));
|
||||||
if (count > remains)
|
if (count > remains)
|
||||||
count = remains;
|
count = remains;
|
||||||
memcpy(to, sg->buffer, count);
|
memcpy(to, sg->buffer, count);
|
||||||
@@ -123,10 +171,10 @@ ramdisk_ioctl(dev_t dev, uint32_t req, void *argp)
|
|||||||
{
|
{
|
||||||
switch (req)
|
switch (req)
|
||||||
{
|
{
|
||||||
case BLKIO_REQUEST:
|
case RTEMS_BLKIO_REQUEST:
|
||||||
{
|
{
|
||||||
rtems_device_minor_number minor;
|
rtems_device_minor_number minor;
|
||||||
blkdev_request *r = argp;
|
rtems_blkdev_request *r = argp;
|
||||||
struct ramdisk *rd;
|
struct ramdisk *rd;
|
||||||
|
|
||||||
minor = rtems_filesystem_dev_minor_t(dev);
|
minor = rtems_filesystem_dev_minor_t(dev);
|
||||||
@@ -140,10 +188,10 @@ ramdisk_ioctl(dev_t dev, uint32_t req, void *argp)
|
|||||||
|
|
||||||
switch (r->req)
|
switch (r->req)
|
||||||
{
|
{
|
||||||
case BLKDEV_REQ_READ:
|
case RTEMS_BLKDEV_REQ_READ:
|
||||||
return ramdisk_read(rd, r);
|
return ramdisk_read(rd, r);
|
||||||
|
|
||||||
case BLKDEV_REQ_WRITE:
|
case RTEMS_BLKDEV_REQ_WRITE:
|
||||||
return ramdisk_write(rd, r);
|
return ramdisk_write(rd, r);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -188,7 +236,9 @@ ramdisk_initialize(
|
|||||||
|
|
||||||
r = ramdisk = calloc(rtems_ramdisk_configuration_size,
|
r = ramdisk = calloc(rtems_ramdisk_configuration_size,
|
||||||
sizeof(struct ramdisk));
|
sizeof(struct ramdisk));
|
||||||
|
#if RTEMS_RAMDISK_TRACE
|
||||||
|
r->info_level = 1;
|
||||||
|
#endif
|
||||||
for (i = 0; i < rtems_ramdisk_configuration_size; i++, c++, r++)
|
for (i = 0; i < rtems_ramdisk_configuration_size; i++, c++, r++)
|
||||||
{
|
{
|
||||||
dev_t dev = rtems_filesystem_make_dev_t(major, i);
|
dev_t dev = rtems_filesystem_make_dev_t(major, i);
|
||||||
|
|||||||
@@ -26,6 +26,137 @@
|
|||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
#include "fat_fat_operations.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 --
|
/* _fat_block_read --
|
||||||
* This function reads 'count' bytes from device filesystem is mounted on,
|
* This function reads 'count' bytes from device filesystem is mounted on,
|
||||||
* starts at 'start+offset' position where 'start' computed in sectors
|
* starts at 'start+offset' position where 'start' computed in sectors
|
||||||
@@ -57,7 +188,7 @@ _fat_block_read(
|
|||||||
ssize_t cmpltd = 0;
|
ssize_t cmpltd = 0;
|
||||||
uint32_t blk = start;
|
uint32_t blk = start;
|
||||||
uint32_t ofs = offset;
|
uint32_t ofs = offset;
|
||||||
bdbuf_buffer *block = NULL;
|
rtems_bdbuf_buffer *block = NULL;
|
||||||
uint32_t c = 0;
|
uint32_t c = 0;
|
||||||
|
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
@@ -102,13 +233,13 @@ _fat_block_write(
|
|||||||
uint32_t count,
|
uint32_t count,
|
||||||
const void *buff)
|
const void *buff)
|
||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
fat_fs_info_t *fs_info = mt_entry->fs_info;
|
fat_fs_info_t *fs_info = mt_entry->fs_info;
|
||||||
ssize_t cmpltd = 0;
|
ssize_t cmpltd = 0;
|
||||||
uint32_t blk = start;
|
uint32_t blk = start;
|
||||||
uint32_t ofs = offset;
|
uint32_t ofs = offset;
|
||||||
bdbuf_buffer *block = NULL;
|
rtems_bdbuf_buffer *block = NULL;
|
||||||
uint32_t c = 0;
|
uint32_t c = 0;
|
||||||
|
|
||||||
while(count > 0)
|
while(count > 0)
|
||||||
{
|
{
|
||||||
@@ -133,9 +264,6 @@ _fat_block_write(
|
|||||||
return cmpltd;
|
return cmpltd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* fat_cluster_read --
|
/* fat_cluster_read --
|
||||||
* wrapper for reading a whole cluster at once
|
* 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;
|
ssize_t ret = 0;
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bdbuf_buffer *block = NULL;
|
rtems_bdbuf_buffer *block = NULL;
|
||||||
|
|
||||||
rc = stat(mt_entry->dev, &stat_buf);
|
rc = stat(mt_entry->dev, &stat_buf);
|
||||||
if (rc == -1)
|
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 */
|
/* rtmes feature: no block devices, all are character devices */
|
||||||
if (!S_ISCHR(stat_buf.st_mode))
|
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 */
|
/* check that device is registred as block device and lock it */
|
||||||
vol->dd = rtems_disk_lookup(stat_buf.st_dev);
|
vol->dd = rtems_disk_obtain(stat_buf.st_dev);
|
||||||
if (vol->dd == NULL)
|
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;
|
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)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
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);
|
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)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
rtems_disk_release(vol->dd);
|
||||||
set_errno_and_return_minus_one( EIO);
|
rtems_set_errno_and_return_minus_one( EIO );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Evaluate boot record */
|
/* Evaluate boot record */
|
||||||
@@ -259,7 +387,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
|
|||||||
(vol->bps != 4096))
|
(vol->bps != 4096))
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
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;
|
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)
|
if (vol->spc == 0)
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
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;
|
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)
|
if ((vol->bpc = vol->bps << vol->spc_log2) > MS_BYTES_PER_CLUSTER_LIMIT)
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
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;
|
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 )
|
if( vol->info_sec == 0 )
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
rtems_disk_release(vol->dd);
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -377,7 +505,7 @@ fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
|
|||||||
FAT_FSINFO_LEAD_SIGNATURE_VALUE)
|
FAT_FSINFO_LEAD_SIGNATURE_VALUE)
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
rtems_disk_release(vol->dd);
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
else
|
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;
|
vol->afat_loc = vol->fat_loc + vol->fat_length * vol->afat;
|
||||||
|
|
||||||
/* set up collection of fat-files fd */
|
/* 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 )
|
if ( fs_info->vhash == NULL )
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
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++)
|
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 )
|
if ( fs_info->rhash == NULL )
|
||||||
{
|
{
|
||||||
rtems_disk_release(vol->dd);
|
rtems_disk_release(vol->dd);
|
||||||
free(fs_info->vhash);
|
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++)
|
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_pool_size = FAT_UINO_POOL_INIT_SIZE;
|
||||||
fs_info->uino_base = (vol->tot_secs << vol->sec_mul) << 4;
|
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);
|
rtems_disk_release(vol->dd);
|
||||||
free(fs_info->vhash);
|
free(fs_info->vhash);
|
||||||
free(fs_info->rhash);
|
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));
|
fs_info->sec_buf = (uint8_t *)calloc(vol->bps, sizeof(uint8_t));
|
||||||
if (fs_info->sec_buf == NULL)
|
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->vhash);
|
||||||
free(fs_info->rhash);
|
free(fs_info->rhash);
|
||||||
free(fs_info->uino);
|
free(fs_info->uino);
|
||||||
set_errno_and_return_minus_one( ENOMEM );
|
rtems_set_errno_and_return_minus_one( ENOMEM );
|
||||||
}
|
}
|
||||||
|
|
||||||
return RC_OK;
|
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++)
|
for (i = 0; i < FAT_HASH_SIZE; i++)
|
||||||
{
|
{
|
||||||
Chain_Node *node = NULL;
|
rtems_chain_node *node = NULL;
|
||||||
Chain_Control *the_chain = fs_info->vhash + i;
|
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);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < FAT_HASH_SIZE; i++)
|
for (i = 0; i < FAT_HASH_SIZE; i++)
|
||||||
{
|
{
|
||||||
Chain_Node *node = NULL;
|
rtems_chain_node *node = NULL;
|
||||||
Chain_Control *the_chain = fs_info->rhash + i;
|
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);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +669,7 @@ fat_init_clusters_chain(
|
|||||||
|
|
||||||
buf = calloc(fs_info->vol.bpc, sizeof(char));
|
buf = calloc(fs_info->vol.bpc, sizeof(char));
|
||||||
if ( buf == NULL )
|
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)
|
while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,11 +25,6 @@ extern "C" {
|
|||||||
|
|
||||||
#include <rtems/seterr.h>
|
#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 <rtems/score/cpu.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <rtems/bdbuf.h>
|
#include <rtems/bdbuf.h>
|
||||||
@@ -297,45 +292,45 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
typedef struct fat_vol_s
|
typedef struct fat_vol_s
|
||||||
{
|
{
|
||||||
uint16_t bps; /* bytes per sector */
|
uint16_t bps; /* bytes per sector */
|
||||||
uint8_t sec_log2; /* log2 of bps */
|
uint8_t sec_log2; /* log2 of bps */
|
||||||
uint8_t sec_mul; /* log2 of 512bts sectors number per sector */
|
uint8_t sec_mul; /* log2 of 512bts sectors number per sector */
|
||||||
uint8_t spc; /* sectors per cluster */
|
uint8_t spc; /* sectors per cluster */
|
||||||
uint8_t spc_log2; /* log2 of spc */
|
uint8_t spc_log2; /* log2 of spc */
|
||||||
uint16_t bpc; /* bytes per cluster */
|
uint16_t bpc; /* bytes per cluster */
|
||||||
uint8_t bpc_log2; /* log2 of bytes per cluster */
|
uint8_t bpc_log2; /* log2 of bytes per cluster */
|
||||||
uint8_t fats; /* number of FATs */
|
uint8_t fats; /* number of FATs */
|
||||||
uint8_t type; /* FAT type */
|
uint8_t type; /* FAT type */
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
uint32_t eoc_val;
|
uint32_t eoc_val;
|
||||||
uint16_t fat_loc; /* FAT start */
|
uint16_t fat_loc; /* FAT start */
|
||||||
uint32_t fat_length; /* sectors per FAT */
|
uint32_t fat_length; /* sectors per FAT */
|
||||||
uint32_t rdir_loc; /* root directory start */
|
uint32_t rdir_loc; /* root directory start */
|
||||||
uint16_t rdir_entrs; /* files per root directory */
|
uint16_t rdir_entrs; /* files per root directory */
|
||||||
uint32_t rdir_secs; /* sectors per root directory */
|
uint32_t rdir_secs; /* sectors per root directory */
|
||||||
uint32_t rdir_size; /* root directory size in bytes */
|
uint32_t rdir_size; /* root directory size in bytes */
|
||||||
uint32_t tot_secs; /* total count of sectors */
|
uint32_t tot_secs; /* total count of sectors */
|
||||||
uint32_t data_fsec; /* first data sector */
|
uint32_t data_fsec; /* first data sector */
|
||||||
uint32_t data_cls; /* count of data clusters */
|
uint32_t data_cls; /* count of data clusters */
|
||||||
uint32_t rdir_cl; /* first cluster of the root directory */
|
uint32_t rdir_cl; /* first cluster of the root directory */
|
||||||
uint16_t info_sec; /* FSInfo Sector Structure location */
|
uint16_t info_sec; /* FSInfo Sector Structure location */
|
||||||
uint32_t free_cls; /* last known free clusters count */
|
uint32_t free_cls; /* last known free clusters count */
|
||||||
uint32_t next_cl; /* next free cluster number */
|
uint32_t next_cl; /* next free cluster number */
|
||||||
uint8_t mirror; /* mirroring enabla/disable */
|
uint8_t mirror; /* mirroring enabla/disable */
|
||||||
uint32_t afat_loc; /* active FAT location */
|
uint32_t afat_loc; /* active FAT location */
|
||||||
uint8_t afat; /* the number of active FAT */
|
uint8_t afat; /* the number of active FAT */
|
||||||
dev_t dev; /* device ID */
|
dev_t dev; /* device ID */
|
||||||
disk_device *dd; /* disk device (see libblock) */
|
rtems_disk_device *dd; /* disk device (see libblock) */
|
||||||
void *private_data; /* reserved */
|
void *private_data; /* reserved */
|
||||||
} fat_vol_t;
|
} fat_vol_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct fat_cache_s
|
typedef struct fat_cache_s
|
||||||
{
|
{
|
||||||
uint32_t blk_num;
|
uint32_t blk_num;
|
||||||
rtems_boolean modified;
|
rtems_boolean modified;
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
bdbuf_buffer *buf;
|
rtems_bdbuf_buffer *buf;
|
||||||
} fat_cache_t;
|
} fat_cache_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -344,15 +339,15 @@ typedef struct fat_cache_s
|
|||||||
*/
|
*/
|
||||||
typedef struct fat_fs_info_s
|
typedef struct fat_fs_info_s
|
||||||
{
|
{
|
||||||
fat_vol_t vol; /* volume descriptor */
|
fat_vol_t vol; /* volume descriptor */
|
||||||
Chain_Control *vhash; /* "vhash" of fat-file descriptors */
|
rtems_chain_control *vhash; /* "vhash" of fat-file descriptors */
|
||||||
Chain_Control *rhash; /* "rhash" of fat-file descriptors */
|
rtems_chain_control *rhash; /* "rhash" of fat-file descriptors */
|
||||||
char *uino; /* array of unique ino numbers */
|
char *uino; /* array of unique ino numbers */
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
uint32_t uino_pool_size; /* size */
|
uint32_t uino_pool_size; /* size */
|
||||||
uint32_t uino_base;
|
uint32_t uino_base;
|
||||||
fat_cache_t c; /* cache */
|
fat_cache_t c; /* cache */
|
||||||
uint8_t *sec_buf; /* just placeholder for anything */
|
uint8_t *sec_buf; /* just placeholder for anything */
|
||||||
} fat_fs_info_t;
|
} fat_fs_info_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -415,145 +410,18 @@ fat_cluster_num_to_sector512_num(
|
|||||||
fs_info->vol.sec_mul);
|
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
|
static inline void
|
||||||
fat_buf_mark_modified(fat_fs_info_t *fs_info)
|
fat_buf_mark_modified(fat_fs_info_t *fs_info)
|
||||||
{
|
{
|
||||||
fs_info->c.modified = TRUE;
|
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
|
ssize_t
|
||||||
_fat_block_read(rtems_filesystem_mount_table_entry_t *mt_entry,
|
_fat_block_read(rtems_filesystem_mount_table_entry_t *mt_entry,
|
||||||
|
|||||||
@@ -229,13 +229,13 @@ fat_get_fat_cluster(
|
|||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
register fat_fs_info_t *fs_info = mt_entry->fs_info;
|
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 sec = 0;
|
||||||
uint32_t ofs = 0;
|
uint32_t ofs = 0;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) )
|
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) +
|
sec = (FAT_FAT_OFFSET(fs_info->vol.type, cln) >> fs_info->vol.sec_log2) +
|
||||||
fs_info->vol.afat_loc;
|
fs_info->vol.afat_loc;
|
||||||
@@ -284,7 +284,7 @@ fat_get_fat_cluster(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,17 +311,17 @@ fat_set_fat_cluster(
|
|||||||
uint32_t in_val
|
uint32_t in_val
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
fat_fs_info_t *fs_info = mt_entry->fs_info;
|
fat_fs_info_t *fs_info = mt_entry->fs_info;
|
||||||
uint32_t sec = 0;
|
uint32_t sec = 0;
|
||||||
uint32_t ofs = 0;
|
uint32_t ofs = 0;
|
||||||
uint16_t fat16_clv = 0;
|
uint16_t fat16_clv = 0;
|
||||||
uint32_t fat32_clv = 0;
|
uint32_t fat32_clv = 0;
|
||||||
bdbuf_buffer *block0 = NULL;
|
rtems_bdbuf_buffer *block0 = NULL;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) )
|
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) +
|
sec = (FAT_FAT_OFFSET(fs_info->vol.type, cln) >> fs_info->vol.sec_log2) +
|
||||||
fs_info->vol.afat_loc;
|
fs_info->vol.afat_loc;
|
||||||
@@ -428,7 +428,7 @@ fat_set_fat_cluster(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define MSDOS_TRACE 1
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#if HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -112,7 +114,7 @@ fat_file_open(
|
|||||||
|
|
||||||
lfat_fd = (*fat_fd) = (fat_file_fd_t*)malloc(sizeof(fat_file_fd_t));
|
lfat_fd = (*fat_fd) = (fat_file_fd_t*)malloc(sizeof(fat_file_fd_t));
|
||||||
if ( lfat_fd == NULL )
|
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->links_num = 1;
|
||||||
lfat_fd->flags &= ~FAT_FILE_REMOVED;
|
lfat_fd->flags &= ~FAT_FILE_REMOVED;
|
||||||
@@ -131,7 +133,7 @@ fat_file_open(
|
|||||||
* XXX: kernel resource is unsufficient, but not the memory,
|
* XXX: kernel resource is unsufficient, but not the memory,
|
||||||
* but there is no suitable errno :(
|
* 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);
|
_hash_insert(fs_info->vhash, key, lfat_fd->ino, lfat_fd);
|
||||||
@@ -383,11 +385,11 @@ fat_file_write(
|
|||||||
return cmpltd;
|
return cmpltd;
|
||||||
|
|
||||||
if ( start > fat_fd->fat_file_size )
|
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) ||
|
if ((count > fat_fd->size_limit) ||
|
||||||
(start > fat_fd->size_limit - count))
|
(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);
|
rc = fat_file_extend(mt_entry, fat_fd, start + count, &c);
|
||||||
if (rc != RC_OK)
|
if (rc != RC_OK)
|
||||||
@@ -493,7 +495,7 @@ fat_file_extend(
|
|||||||
|
|
||||||
if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
|
if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
|
||||||
(fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
|
(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 -
|
bytes_remain = (fs_info->vol.bpc -
|
||||||
(fat_fd->fat_file_size & (fs_info->vol.bpc - 1))) &
|
(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 */
|
/* this means that no space left on device */
|
||||||
if ((cls_added == 0) && (bytes_remain == 0))
|
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 */
|
/* check wether we satisfied request for 'cls2add' clusters */
|
||||||
if (cls2add != cls_added)
|
if (cls2add != cls_added)
|
||||||
@@ -687,7 +689,7 @@ fat_file_ioctl(
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if ( pos >= fat_fd->fat_file_size )
|
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)) &&
|
if ((FAT_FD_OF_ROOT_DIR(fat_fd)) &&
|
||||||
(fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
|
(fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)))
|
||||||
@@ -759,13 +761,13 @@ fat_file_datasync(
|
|||||||
fat_file_fd_t *fat_fd
|
fat_file_fd_t *fat_fd
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
fat_fs_info_t *fs_info = mt_entry->fs_info;
|
fat_fs_info_t *fs_info = mt_entry->fs_info;
|
||||||
uint32_t cur_cln = fat_fd->cln;
|
uint32_t cur_cln = fat_fd->cln;
|
||||||
bdbuf_buffer *block = NULL;
|
rtems_bdbuf_buffer *block = NULL;
|
||||||
uint32_t sec = 0;
|
uint32_t sec = 0;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
if (fat_fd->fat_file_size == 0)
|
if (fat_fd->fat_file_size == 0)
|
||||||
return RC_OK;
|
return RC_OK;
|
||||||
@@ -788,11 +790,11 @@ fat_file_datasync(
|
|||||||
/* ... sync it */
|
/* ... sync it */
|
||||||
sc = rtems_bdbuf_read(fs_info->vol.dev, (sec + i), &block);
|
sc = rtems_bdbuf_read(fs_info->vol.dev, (sec + i), &block);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
set_errno_and_return_minus_one( EIO );
|
rtems_set_errno_and_return_minus_one( EIO );
|
||||||
|
|
||||||
sc = rtems_bdbuf_sync(block);
|
sc = rtems_bdbuf_sync(block);
|
||||||
if ( sc != RTEMS_SUCCESSFUL )
|
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);
|
rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
|
||||||
@@ -947,9 +949,7 @@ fat_file_lseek(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
int rc = RC_OK;
|
int rc = RC_OK;
|
||||||
/*
|
|
||||||
assert(fat_fd->fat_file_size);
|
|
||||||
*/
|
|
||||||
if (file_cln == fat_fd->map.file_cln)
|
if (file_cln == fat_fd->map.file_cln)
|
||||||
*disk_cln = fat_fd->map.disk_cln;
|
*disk_cln = fat_fd->map.disk_cln;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -129,9 +129,9 @@ msdos_creat_node(
|
|||||||
*MSDOS_DIR_FILE_SIZE(new_node) =*MSDOS_DIR_FILE_SIZE(link_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(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(new_node) =
|
||||||
*MSDOS_DIR_FIRST_CLUSTER_HI(link_node);
|
*MSDOS_DIR_FIRST_CLUSTER_HI(link_node);
|
||||||
/*
|
/*
|
||||||
* set "archive bit" due to changes
|
* 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
|
* check spelling and format new node name
|
||||||
*/
|
*/
|
||||||
if (MSDOS_NAME != msdos_get_token(token, new_name, &len)) {
|
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
|
* verify, that the existing node can be linked to
|
||||||
* check that nodes are in same FS/volume?
|
* check that nodes are in same FS/volume?
|
||||||
*/
|
*/
|
||||||
if (to_loc->mt_entry->fs_info != par_loc->mt_entry->fs_info) {
|
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
|
* 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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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;
|
to_fat_fd->cln = FAT_EOF;
|
||||||
rc = msdos_set_first_cluster_num(to_loc->mt_entry, to_fat_fd);
|
rc = msdos_set_first_cluster_num(to_loc->mt_entry, to_fat_fd);
|
||||||
if (rc == RC_OK) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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);
|
rc = fat_file_reopen(fat_fd);
|
||||||
if (rc != RC_OK)
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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);
|
rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd);
|
||||||
if (rc != RC_OK)
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
|
|
||||||
while (count > 0)
|
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)
|
if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
|
||||||
{
|
{
|
||||||
rtems_semaphore_release(fs_info->vol_sema);
|
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)
|
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:
|
case SEEK_END:
|
||||||
default:
|
default:
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
rtems_set_errno_and_return_minus_one( EINVAL );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return RC_OK;
|
return RC_OK;
|
||||||
@@ -416,7 +416,7 @@ msdos_dir_stat(
|
|||||||
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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_dev = fs_info->fat.vol.dev;
|
||||||
buf->st_ino = fat_fd->ino;
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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);
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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
|
* 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)
|
if (fat_fd->links_num > 1)
|
||||||
{
|
{
|
||||||
rtems_semaphore_release(fs_info->vol_sema);
|
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)
|
if (!is_empty)
|
||||||
{
|
{
|
||||||
rtems_semaphore_release(fs_info->vol_sema);
|
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)
|
if (pathloc->mt_entry->mt_fs_root.node_access == pathloc->node_access)
|
||||||
{
|
{
|
||||||
rtems_semaphore_release(fs_info->vol_sema);
|
rtems_semaphore_release(fs_info->vol_sema);
|
||||||
set_errno_and_return_minus_one(EBUSY);
|
rtems_set_errno_and_return_minus_one(EBUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ msdos_eval_path(
|
|||||||
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
|
|
||||||
if (!pathloc->node_access)
|
if (!pathloc->node_access)
|
||||||
{
|
{
|
||||||
@@ -271,7 +271,7 @@ msdos_eval4make(
|
|||||||
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
|
|
||||||
if (!pathloc->node_access)
|
if (!pathloc->node_access)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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);
|
rc = fat_file_reopen(fat_fd);
|
||||||
if (rc != RC_OK)
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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
|
* 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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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,
|
ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
|
||||||
buffer);
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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,
|
ret = fat_file_write(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
|
||||||
buffer);
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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,
|
rc = fat_file_extend(iop->pathinfo.mt_entry, fat_fd, iop->offset,
|
||||||
&real_size);
|
&real_size);
|
||||||
@@ -276,7 +276,7 @@ msdos_file_stat(
|
|||||||
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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_dev = fs_info->fat.vol.dev;
|
||||||
buf->st_ino = fat_fd->ino;
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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);
|
rc = fat_file_truncate(iop->pathinfo.mt_entry, fat_fd, length);
|
||||||
if (rc != RC_OK)
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
|
|
||||||
/* synchronize file data */
|
/* synchronize file data */
|
||||||
rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
|
|
||||||
/* synchronize file data */
|
/* synchronize file data */
|
||||||
rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
|
|
||||||
/* mark file removed */
|
/* mark file removed */
|
||||||
rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln,
|
rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln,
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ static int msdos_format_eval_sectors_per_cluster
|
|||||||
} while (!finished);
|
} while (!finished);
|
||||||
|
|
||||||
if (ret_val != 0) {
|
if (ret_val != 0) {
|
||||||
set_errno_and_return_minus_one(ret_val);
|
rtems_set_errno_and_return_minus_one(ret_val);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*sectors_per_cluster_adj = sectors_per_cluster;
|
*sectors_per_cluster_adj = sectors_per_cluster;
|
||||||
@@ -298,9 +298,9 @@ static int msdos_format_determine_fmt_params
|
|||||||
+---------------------------------------------------------------------------+
|
+---------------------------------------------------------------------------+
|
||||||
| Input Parameters: |
|
| 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 */
|
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: |
|
| Return Value: |
|
||||||
@@ -613,7 +613,7 @@ static int msdos_format_determine_fmt_params
|
|||||||
* Phuuu.... That's it.
|
* Phuuu.... That's it.
|
||||||
*/
|
*/
|
||||||
if (ret_val != 0) {
|
if (ret_val != 0) {
|
||||||
set_errno_and_return_minus_one(ret_val);
|
rtems_set_errno_and_return_minus_one(ret_val);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -791,13 +791,13 @@ int msdos_format
|
|||||||
| 0, if success, -1 and errno if failed |
|
| 0, if success, -1 and errno if failed |
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
{
|
{
|
||||||
char tmp_sec[FAT_TOTAL_MBR_SIZE];
|
char tmp_sec[FAT_TOTAL_MBR_SIZE];
|
||||||
int rc;
|
int rc;
|
||||||
disk_device *dd = NULL;
|
rtems_disk_device *dd = NULL;
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int i;
|
int i;
|
||||||
msdos_format_param_t fmt_params;
|
msdos_format_param_t fmt_params;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -817,7 +817,7 @@ int msdos_format
|
|||||||
|
|
||||||
/* check that device is registered as block device and lock it */
|
/* check that device is registered as block device and lock it */
|
||||||
if (ret_val == 0) {
|
if (ret_val == 0) {
|
||||||
dd = rtems_disk_lookup(stat_buf.st_dev);
|
dd = rtems_disk_obtain(stat_buf.st_dev);
|
||||||
if (dd == NULL) {
|
if (dd == NULL) {
|
||||||
errno = ENOTBLK;
|
errno = ENOTBLK;
|
||||||
ret_val = -1;
|
ret_val = -1;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ msdos_free_node_info(rtems_filesystem_location_info_t *pathloc)
|
|||||||
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
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);
|
rc = fat_file_close(pathloc->mt_entry, pathloc->node_access);
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ msdos_initialize_support(
|
|||||||
|
|
||||||
fs_info = (msdos_fs_info_t *)calloc(1, sizeof(msdos_fs_info_t));
|
fs_info = (msdos_fs_info_t *)calloc(1, sizeof(msdos_fs_info_t));
|
||||||
if (!fs_info)
|
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;
|
temp_mt_entry->fs_info = fs_info;
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ msdos_initialize_support(
|
|||||||
fat_file_close(temp_mt_entry, fat_fd);
|
fat_file_close(temp_mt_entry, fat_fd);
|
||||||
fat_shutdown_drive(temp_mt_entry);
|
fat_shutdown_drive(temp_mt_entry);
|
||||||
free(fs_info);
|
free(fs_info);
|
||||||
set_errno_and_return_minus_one(ENOMEM);
|
rtems_set_errno_and_return_minus_one(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
sc = rtems_semaphore_create(3,
|
sc = rtems_semaphore_create(3,
|
||||||
@@ -138,7 +138,7 @@ msdos_initialize_support(
|
|||||||
fat_shutdown_drive(temp_mt_entry);
|
fat_shutdown_drive(temp_mt_entry);
|
||||||
free(fs_info->cl_buf);
|
free(fs_info->cl_buf);
|
||||||
free(fs_info);
|
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;
|
temp_mt_entry->mt_fs_root.node_access = fat_fd;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
* @(#) $Id$
|
* @(#) $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define MSDOS_TRACE 1
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#if HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -786,7 +788,7 @@ int msdos_find_name_in_fat_file(
|
|||||||
fs_info->cl_buf)) != FAT_EOF)
|
fs_info->cl_buf)) != FAT_EOF)
|
||||||
{
|
{
|
||||||
if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
|
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);
|
assert(ret == bts2rd);
|
||||||
|
|
||||||
@@ -903,7 +905,7 @@ int msdos_find_node_by_cluster_num_in_fat_file(
|
|||||||
fs_info->cl_buf)) != FAT_EOF)
|
fs_info->cl_buf)) != FAT_EOF)
|
||||||
{
|
{
|
||||||
if ( ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE )
|
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);
|
assert(ret == bts2rd);
|
||||||
|
|
||||||
|
|||||||
@@ -74,12 +74,12 @@ int msdos_mknod(
|
|||||||
type = MSDOS_REGULAR_FILE;
|
type = MSDOS_REGULAR_FILE;
|
||||||
}
|
}
|
||||||
else
|
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,
|
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
|
||||||
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
|
||||||
if (sc != RTEMS_SUCCESSFUL)
|
if (sc != RTEMS_SUCCESSFUL)
|
||||||
set_errno_and_return_minus_one(EIO);
|
rtems_set_errno_and_return_minus_one(EIO);
|
||||||
|
|
||||||
/* Create an MSDOS node */
|
/* Create an MSDOS node */
|
||||||
rc = msdos_creat_node(pathloc, type, new_name, mode, NULL);
|
rc = msdos_creat_node(pathloc, type, new_name, mode, NULL);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ if LIBSHELL
|
|||||||
noinst_LIBRARIES += libshell.a
|
noinst_LIBRARIES += libshell.a
|
||||||
libshell_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/shell
|
libshell_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/shell
|
||||||
libshell_a_SOURCES = shell/cat_file.c shell/cmds.c shell/internal.h \
|
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_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_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 \
|
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_stackuse.c shell/main_tty.c shell/main_umask.c \
|
||||||
shell/main_unmount.c shell/main_blksync.c shell/main_whoami.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/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/shellconfig.h shell/shell.h shell/shell_makeargs.c \
|
||||||
shell/write_file.c shell/utils-cp.c shell/err.c shell/errx.c shell/verr.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/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/fts.c shell/print_heapinfo.c shell/main_wkspaceinfo.c \
|
||||||
shell/shell_script.c
|
shell/shell_script.c
|
||||||
|
|||||||
200
cpukit/libmisc/shell/cmp-ls.c
Normal file
200
cpukit/libmisc/shell/cmp-ls.c
Normal 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));
|
||||||
|
}
|
||||||
@@ -84,7 +84,7 @@ int set_utimes(const char *, struct stat *);
|
|||||||
int setfile(rtems_shell_cp_globals* cp_globals, struct stat *, int);
|
int setfile(rtems_shell_cp_globals* cp_globals, struct stat *, int);
|
||||||
int preserve_dir_acls(struct stat *, char *, char *);
|
int preserve_dir_acls(struct stat *, char *, char *);
|
||||||
int preserve_fd_acls(int, int);
|
int preserve_fd_acls(int, int);
|
||||||
void usage();
|
void usage(rtems_shell_cp_globals* cp_globals);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|||||||
195
cpukit/libmisc/shell/extern-ls.h
Normal file
195
cpukit/libmisc/shell/extern-ls.h
Normal 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_ */
|
||||||
150
cpukit/libmisc/shell/filemode.c
Normal file
150
cpukit/libmisc/shell/filemode.c
Normal 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';
|
||||||
|
}
|
||||||
@@ -58,7 +58,7 @@ int rtems_shell_main_blksync(
|
|||||||
return 1;
|
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));
|
fprintf( stderr, "%s: driver sync failed: %s\n", argv[0], strerror (errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,14 +175,14 @@ main_cp(rtems_shell_cp_globals* cp_globals, int argc, char *argv[])
|
|||||||
vflag = 1;
|
vflag = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(cp_globals);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
argc -= getopt_reent.optind;
|
argc -= getopt_reent.optind;
|
||||||
argv += getopt_reent.optind;
|
argv += getopt_reent.optind;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
usage();
|
usage(cp_globals);
|
||||||
|
|
||||||
fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
|
fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
|
||||||
if (Rflag && rflag)
|
if (Rflag && rflag)
|
||||||
|
|||||||
@@ -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
|
* This code is derived from software contributed to Berkeley by
|
||||||
* Work: fernando.ruiz@ctv.es
|
* Michael Fischbein.
|
||||||
* Home: correo@fernando-ruiz.com
|
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* found in the file LICENSE in this distribution or at
|
* modification, are permitted provided that the following conditions
|
||||||
* http://www.rtems.com/license/LICENSE.
|
* 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
|
#if 0
|
||||||
#include "config.h"
|
#include <sys/cdefs.h>
|
||||||
#endif
|
#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>
|
#ifndef lint
|
||||||
#include <string.h>
|
#if 0
|
||||||
#include <stdlib.h>
|
static char sccsid[] = "@(#)ls.c 8.7 (Berkeley) 8/5/94";
|
||||||
#include <ctype.h>
|
#else
|
||||||
#include <dirent.h>
|
__RCSID("$NetBSD: ls.c,v 1.58 2005/10/26 02:24:22 jschauma Exp $");
|
||||||
#include <time.h>
|
#endif
|
||||||
#include <fcntl.h>
|
#endif /* not lint */
|
||||||
#include <unistd.h>
|
#endif
|
||||||
#include <pwd.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
#include <rtems/shell.h>
|
#include <rtems/shell.h>
|
||||||
#include "internal.h"
|
#include <rtems/shellconfig.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
int rtems_shell_main_ls(
|
#include <sys/types.h>
|
||||||
int argc,
|
#include <sys/stat.h>
|
||||||
char *argv[]
|
#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;
|
globals->exit_code = code;
|
||||||
DIR *dirp;
|
longjmp (globals->exit_jmp, 1);
|
||||||
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;
|
|
||||||
|
|
||||||
fname = ".";
|
static int main_ls(rtems_shell_ls_globals* globals, int argc, char *argv[]);
|
||||||
if (argc>1)
|
|
||||||
fname = argv[1];
|
|
||||||
|
|
||||||
if ((dirp = opendir(fname)) == NULL) {
|
int
|
||||||
fprintf(stderr,"%s: %s: No such file or directory.\n", argv[0], fname);
|
rtems_shell_main_ls(int argc, char *argv[])
|
||||||
return errno;
|
{
|
||||||
}
|
rtems_shell_ls_globals ls_globals;
|
||||||
n = 0;
|
rtems_shell_ls_globals* globals = &ls_globals;
|
||||||
size = 0;
|
memset (globals, 0, sizeof (ls_globals));
|
||||||
while ((dp = readdir(dirp)) != NULL) {
|
termwidth = 80;
|
||||||
strcpy(nbuf,fname);
|
sortkey = BY_NAME;
|
||||||
if (nbuf[strlen(nbuf)-1]!='/')
|
rval = EXIT_SUCCESS;
|
||||||
strcat(nbuf,"/");
|
ls_globals.exit_code = 1;
|
||||||
strcat(nbuf,dp->d_name); /* always the fullpathname. Avoid ftpd problem.*/
|
if (setjmp (ls_globals.exit_jmp) == 0)
|
||||||
if (stat(nbuf, &stat_buf) == 0) { /* AWFUL but works...*/
|
return main_ls (globals, argc, argv);
|
||||||
strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M", gmtime(&stat_buf.st_mtime));
|
return ls_globals.exit_code;
|
||||||
pwd = getpwuid(stat_buf.st_uid);
|
}
|
||||||
user = pwd?pwd->pw_name:"nouser";
|
|
||||||
grp = getgrgid(stat_buf.st_gid);
|
int
|
||||||
group = grp?grp->gr_name:"nogrp";
|
main_ls(rtems_shell_ls_globals* globals, int argc, char *argv[])
|
||||||
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'):
|
static char dot[] = ".", *dotav[] = { dot, NULL };
|
||||||
(S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
|
//struct winsize win;
|
||||||
(stat_buf.st_mode & S_IRUSR)?('r'):('-'),
|
int ch, fts_options;
|
||||||
(stat_buf.st_mode & S_IWUSR)?('w'):('-'),
|
int kflag = 0;
|
||||||
(stat_buf.st_mode & S_IXUSR)?('x'):('-'),
|
const char *p;
|
||||||
(stat_buf.st_mode & S_IRGRP)?('r'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IWGRP)?('w'):('-'),
|
struct getopt_data getopt_reent;
|
||||||
(stat_buf.st_mode & S_IXGRP)?('x'):('-'),
|
memset(&getopt_reent, 0, sizeof(getopt_data));
|
||||||
(stat_buf.st_mode & S_IROTH)?('r'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IWOTH)?('w'):('-'),
|
#if RTEMS_REMOVED
|
||||||
(stat_buf.st_mode & S_IXOTH)?('x'):('-'),
|
setprogname(argv[0]);
|
||||||
(int)stat_buf.st_nlink,
|
#endif
|
||||||
user,group,
|
setlocale(LC_ALL, "");
|
||||||
(int)stat_buf.st_size,
|
|
||||||
sbuf,
|
/* Terminal defaults to -Cq, non-terminal defaults to -1. */
|
||||||
dp->d_name,
|
if (isatty(STDOUT_FILENO)) {
|
||||||
S_ISDIR(stat_buf.st_mode)?'/':' ');
|
#if RTEMS_REMOVED
|
||||||
n++;
|
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
|
||||||
size += stat_buf.st_size;
|
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);
|
* If not recursing down this tree and don't need stat info, just get
|
||||||
return 0;
|
* 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 = {
|
rtems_shell_cmd_t rtems_shell_LS_Command = {
|
||||||
|
|||||||
@@ -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
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* Work: fernando.ruiz@ctv.es
|
* modification, are permitted provided that the following conditions
|
||||||
* Home: correo@fernando-ruiz.com
|
* 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
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
* found in the file LICENSE in this distribution or at
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* http://www.rtems.com/license/LICENSE.
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
*
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
* $Id$
|
* 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
|
#if 0
|
||||||
#include "config.h"
|
#ifndef lint
|
||||||
#endif
|
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>
|
#ifndef lint
|
||||||
#include <unistd.h>
|
static char sccsid[] = "@(#)rm.c 8.5 (Berkeley) 4/18/94";
|
||||||
#include <string.h>
|
#endif /* not lint */
|
||||||
#include <errno.h>
|
#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.h>
|
||||||
#include <rtems/shell.h>
|
#include <rtems/shell.h>
|
||||||
#include "internal.h"
|
#include <rtems/shellconfig.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
int rtems_shell_main_rm(
|
#include <sys/stat.h>
|
||||||
int argc,
|
#include <sys/param.h>
|
||||||
char *argv[]
|
#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 ) {
|
static int main_rm(rtems_shell_rm_globals* globals, int argc, char *argv[]);
|
||||||
if (unlink(argv[n])) {
|
|
||||||
fprintf(stderr,"%s: %s: %s\n", argv[0], argv[n], strerror(errno));
|
int
|
||||||
return -1;
|
rtems_shell_main_rm(int argc, char *argv[])
|
||||||
}
|
{
|
||||||
n++;
|
rtems_shell_rm_globals rm_globals;
|
||||||
}
|
memset (&rm_globals, 0, sizeof (rm_globals));
|
||||||
return 0;
|
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 = {
|
rtems_shell_cmd_t rtems_shell_RM_Command = {
|
||||||
"rm", /* name */
|
"rm", /* name */
|
||||||
"rm n1 [n2 [n3...]] # remove files", /* usage */
|
"[-f | -i] [-dIPRrvW] file ...", /* usage */
|
||||||
"files", /* topic */
|
"files", /* topic */
|
||||||
rtems_shell_main_rm, /* command */
|
rtems_shell_main_rm, /* command */
|
||||||
NULL, /* alias */
|
NULL, /* alias */
|
||||||
|
|||||||
480
cpukit/libmisc/shell/print-ls.c
Normal file
480
cpukit/libmisc/shell/print-ls.c
Normal 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);
|
||||||
|
}
|
||||||
116
cpukit/libmisc/shell/pwcache.c
Normal file
116
cpukit/libmisc/shell/pwcache.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -980,7 +980,7 @@ static rtems_status_code rtems_shell_run (
|
|||||||
name,
|
name,
|
||||||
task_priority,
|
task_priority,
|
||||||
task_stacksize,
|
task_stacksize,
|
||||||
RTEMS_DEFAULT_MODES,
|
RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
|
||||||
RTEMS_LOCAL | RTEMS_FLOATING_POINT,
|
RTEMS_LOCAL | RTEMS_FLOATING_POINT,
|
||||||
&task_id
|
&task_id
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -465,11 +465,11 @@ preserve_dir_acls(struct stat *fs, char *source_dir, char *dest_dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(void)
|
usage(rtems_shell_cp_globals* cp_globals)
|
||||||
{
|
{
|
||||||
|
|
||||||
(void)fprintf(stderr, "%s\n%s\n",
|
(void)fprintf(stderr, "%s\n%s\n",
|
||||||
"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-alpv] source_file target_file",
|
"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 ... "
|
" cp [-R [-H | -L | -P]] [-f | -i | -n] [-alpv] source_file ... "
|
||||||
"target_directory");
|
"target_directory");
|
||||||
|
longjmp (cp_globals->exit_jmp, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
113
cpukit/libmisc/shell/utils-ls.c
Normal file
113
cpukit/libmisc/shell/utils-ls.c
Normal 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
384
cpukit/libmisc/shell/vis.c
Normal 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
|
||||||
91
cpukit/libmisc/shell/vis.h
Normal file
91
cpukit/libmisc/shell/vis.h
Normal 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_ */
|
||||||
@@ -587,7 +587,7 @@ extern rtems_configuration_table Configuration;
|
|||||||
#define CONFIGURE_ATA_DRIVER_TASK_PRIORITY ATA_DRIVER_TASK_DEFAULT_PRIORITY
|
#define CONFIGURE_ATA_DRIVER_TASK_PRIORITY ATA_DRIVER_TASK_DEFAULT_PRIORITY
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIGURE_INIT
|
#ifdef CONFIGURE_INIT
|
||||||
rtems_task_priority ata_driver_task_priority
|
rtems_task_priority rtems_ata_driver_task_priority
|
||||||
= CONFIGURE_ATA_DRIVER_TASK_PRIORITY;
|
= CONFIGURE_ATA_DRIVER_TASK_PRIORITY;
|
||||||
#endif /* CONFIGURE_INIT */
|
#endif /* CONFIGURE_INIT */
|
||||||
#endif
|
#endif
|
||||||
@@ -598,13 +598,36 @@ extern rtems_configuration_table Configuration;
|
|||||||
#ifdef CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
|
#ifdef CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
|
||||||
#include <rtems/bdbuf.h>
|
#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
|
#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
|
#endif
|
||||||
#ifdef CONFIGURE_INIT
|
#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
|
#endif
|
||||||
#ifndef CONFIGURE_HAS_OWN_BDBUF_TABLE
|
#ifndef CONFIGURE_HAS_OWN_BDBUF_TABLE
|
||||||
#ifndef CONFIGURE_BDBUF_BUFFER_COUNT
|
#ifndef CONFIGURE_BDBUF_BUFFER_COUNT
|
||||||
@@ -615,11 +638,12 @@ extern rtems_configuration_table Configuration;
|
|||||||
#define CONFIGURE_BDBUF_BUFFER_SIZE 512
|
#define CONFIGURE_BDBUF_BUFFER_SIZE 512
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIGURE_INIT
|
#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}
|
{CONFIGURE_BDBUF_BUFFER_SIZE, CONFIGURE_BDBUF_BUFFER_COUNT, NULL}
|
||||||
};
|
};
|
||||||
int rtems_bdbuf_configuration_size =( sizeof(rtems_bdbuf_configuration)
|
int rtems_bdbuf_pool_configuration_size =
|
||||||
/sizeof(rtems_bdbuf_configuration[0]));
|
(sizeof(rtems_bdbuf_pool_configuration) /
|
||||||
|
sizeof(rtems_bdbuf_pool_configuration[0]));
|
||||||
#endif /* CONFIGURE_INIT */
|
#endif /* CONFIGURE_INIT */
|
||||||
#endif /* CONFIGURE_HAS_OWN_BDBUF_TABLE */
|
#endif /* CONFIGURE_HAS_OWN_BDBUF_TABLE */
|
||||||
#endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */
|
#endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ void _CORE_mutex_Initialize(
|
|||||||
_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
|
_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
|
||||||
|
|
||||||
#ifdef __RTEMS_STRICT_ORDER_MUTEX__
|
#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.lock_queue );
|
||||||
the_mutex->queue.priority_before = executing->current_priority;
|
the_mutex->queue.priority_before = _Thread_Executing->current_priority;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_Thread_Executing->resource_count++;
|
_Thread_Executing->resource_count++;
|
||||||
|
|||||||
@@ -61,4 +61,5 @@ void _Internal_error_Occurred(
|
|||||||
_CPU_Fatal_halt( the_error );
|
_CPU_Fatal_halt( the_error );
|
||||||
|
|
||||||
/* will not return from this routine */
|
/* will not return from this routine */
|
||||||
|
while (TRUE);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user