fileio.c
来自「开放源码实时操作系统源码.」· C语言 代码 · 共 767 行 · 第 1/2 页
C
767 行
//==========================================================================
//
// fileio.c
//
// RedBoot fileio support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002, 2003, 2004 Gary Thomas
// Copyright (C) 2004, 2005, 2006 eCosCentric Limited.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: dwmw2, msalter
// Date: 2004-11-21
// Purpose:
// Description:
//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
//
//==========================================================================
// Shoot me. But I don't want struct timeval because redboot provides it.
#define _POSIX_SOURCE
#include <time.h>
#undef _POSIX_SOURCE
#include <redboot.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#ifdef CYGPKG_IO_FLASH
#include <pkgconf/io_flash.h>
#include <cyg/io/io.h>
#include <cyg/io/flash.h>
#include <cyg/io/config_keys.h>
#endif
#include <cyg/io/devtab.h>
#include <cyg/fileio/fileio.h>
#include <cyg/infra/cyg_ass.h> // assertion macros
//==========================================================================
// Define table boundaries
CYG_HAL_TABLE_BEGIN( __FS_cmds_TAB__, FS_cmds);
CYG_HAL_TABLE_END( __FS_cmds_TAB_END__, FS_cmds);
extern struct cmd __FS_cmds_TAB__[], __FS_cmds_TAB_END__;
//==========================================================================
static void
fs_usage(char *why)
{
diag_printf("*** invalid 'fs' command: %s\n", why);
cmd_usage(__FS_cmds_TAB__, &__FS_cmds_TAB_END__, "fs ");
}
//==========================================================================
#define MAX_MOUNTS 4
static int mount_count = 0;
static struct
{
char dev_str[PATH_MAX];
char mp_str[PATH_MAX];
char type_str[PATH_MAX];
} mounts[MAX_MOUNTS];
//==========================================================================
static void do_mount(int argc, char *argv[]);
static void do_umount(int argc, char *argv[]);
/* Temporary hack until flashv2 merged to trunk. We can't tell whether we're
* working with flash v1 or v2 from the package version. So if legacy device isn't
* defined we check whether, if there is a block device, there's a tell-tale define
* that only exists with the v1 version.
*/
#if !defined(CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY) && \
defined(CYGPKG_IO_FLASH_BLOCK_DEVICE) && \
defined(CYGINT_IO_FLASH_BLOCK_CFG_1)
# define CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY 1
#endif
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY
#define FLASHPART "[-f <partition>] "
#else
#define FLASHPART
#endif
local_cmd_entry("mount",
"Mount file system",
FLASHPART "[-d <device>] -t <fstype> [<mountpoint>]",
do_mount,
FS_cmds
);
local_cmd_entry("umount",
"Unmount file system",
"<mountpoint>",
do_umount,
FS_cmds
);
//==========================================================================
// Mount disk/filesystem
static void
do_mount(int argc, char *argv[])
{
char *dev_str = "<undefined>", *type_str, *mp_str;
bool dev_set = false, type_set = false;
struct option_info opts[3];
int err, num_opts = 2;
int i,m=0; /* Set to 0 to silence warning */
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY
char *part_str;
bool part_set = false;
#endif
init_opts(&opts[0], 'd', true, OPTION_ARG_TYPE_STR,
(void *)&dev_str, &dev_set, "device");
init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_STR,
(void *)&type_str, &type_set, "fstype");
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY
init_opts(&opts[2], 'f', true, OPTION_ARG_TYPE_STR,
(void *)&part_str, &part_set, "partition");
num_opts++;
#endif
CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options");
if (!scan_opts(argc, argv, 1, opts, num_opts, &mp_str, OPTION_ARG_TYPE_STR, "mountpoint"))
return;
if (!type_set) {
err_printf("fs mount: Must specify file system type\n");
return;
}
if( mp_str == 0 )
mp_str = "/";
if( mount_count >= MAX_MOUNTS )
{
err_printf("fs mount: Maximum number of mounts exceeded\n");
return;
}
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY
if (part_set) {
cyg_uint32 len;
cyg_io_handle_t h;
if (dev_set && strcmp(dev_str, CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1)) {
err_printf("fs mount: May only set one of <device> or <partition>\n");
return;
}
dev_str = CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1;
len = (cyg_uint32)strlen(part_str);
err = cyg_io_lookup(dev_str, &h);
if (err < 0) {
err_printf("fs mount: cyg_io_lookup of \"%s\" returned %d\n", dev_str, err);
return;
}
err = cyg_io_set_config(h, CYG_IO_SET_CONFIG_FLASH_FIS_NAME,
part_str, &len);
if (err < 0) {
diag_printf("fs mount: FIS partition \"%s\" not found\n",
part_str);
return;
}
}
#endif
for( i = 0; i < MAX_MOUNTS; i++ )
{
if( mounts[i].mp_str[0] != '\0' )
{
if( strcmp(mounts[i].dev_str, dev_str ) == 0 )
{
err_printf("fs mount: Device %s already mounted\n",dev_str);
return;
}
}
else
m = i;
}
strcpy( mounts[m].mp_str, mp_str );
strcpy( mounts[m].dev_str, dev_str );
strcpy( mounts[m].type_str, type_str );
err = mount(mounts[m].dev_str, mounts[m].mp_str, mounts[m].type_str);
if (err)
{
err_printf("fs mount: mount(%s,%s,%s) failed %d\n", dev_str, mp_str, type_str, errno);
mounts[m].mp_str[0] = '\0'; // mount failed so don't let it appear mounted
}
else
{
if( mount_count == 0 )
chdir( "/" );
mount_count++;
}
}
//==========================================================================
static void
do_umount(int argc, char *argv[])
{
char *dir_str;
int err;
int i;
if( mount_count == 0 )
{
err_printf("fs: No filesystems mounted\n");
return;
}
if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "mountpoint"))
return;
if( dir_str == 0 )
dir_str = "/";
for( i = 0; i < MAX_MOUNTS; i++ )
{
if( strcmp(mounts[i].mp_str, dir_str ) == 0 )
break;
}
if( i == MAX_MOUNTS )
{
err_printf("fs unmount: unknown mountpoint %s\n",dir_str);
return;
}
err = umount (dir_str);
if (err)
err_printf("fs umount: unmount failed %d\n", errno);
else
{
mounts[i].mp_str[0] = '\0';
mount_count--;
if( mount_count == 0 )
chdir( "/" );
}
}
//==========================================================================
#include <dirent.h>
static char rwx[8][4] = { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" };
static void
do_list(int argc, char * argv[])
{
char * dir_str;
DIR *dirp;
char filename[PATH_MAX];
char cwd[PATH_MAX];
struct stat sbuf;
int err;
if( mount_count == 0 )
{
err_printf("fs: No filesystems mounted\n");
return;
}
if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory"))
return;
if( dir_str == 0 )
{
dir_str = getcwd(cwd, sizeof(cwd));
}
dirp = opendir(dir_str);
if (dirp==NULL) {
err_printf("fs list: no such directory %s\n",dir_str);
return;
}
for (;;) {
struct dirent *entry = readdir(dirp);
if( entry == NULL )
break;
strcpy(filename, dir_str);
strcat(filename, "/");
strcat(filename, entry->d_name);
err = stat(filename, &sbuf);
if (err < 0) {
diag_printf("Unable to stat file %s\n", filename);
continue;
}
diag_printf("%4d ", sbuf.st_ino);
if (S_ISDIR(sbuf.st_mode)) diag_printf("d");
if (S_ISCHR(sbuf.st_mode)) diag_printf("c");
if (S_ISBLK(sbuf.st_mode)) diag_printf("b");
if (S_ISREG(sbuf.st_mode)) diag_printf("-");
if (S_ISLNK(sbuf.st_mode)) diag_printf("l");
diag_printf("%s%s%s", // Ho, humm, have to hard code the shifts
rwx[(sbuf.st_mode & S_IRWXU) >> 16],
rwx[(sbuf.st_mode & S_IRWXG) >> 19],
rwx[(sbuf.st_mode & S_IRWXO) >> 22]);
diag_printf(" %2d size %6d %s\n",
sbuf.st_nlink,(int)sbuf.st_size,
entry->d_name);
}
closedir(dirp);
return;
}
local_cmd_entry("list",
"list directory contents",
"[<directory>]",
do_list,
FS_cmds
);
//==========================================================================
static void
do_mkdir(int argc, char * argv[])
{
char *dir_str;
int err;
if( mount_count == 0 )
{
err_printf("fs: No filesystems mounted\n");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?