📄 fstouser.c
字号:
/*
* asixos/fs/FCB.c
*
* Copyright (C) 2002 Asic Center
*
* 2002-08-05 Created by Julias
* 2002-08-30 Modify the function fdelete. Add delete a empty directory.
* 2002-09-03 Add the check in function fopen.
*
*/
/*
* 'FCB.c' is the file of FCB module .
* It contains functions(find_FCB, get_FCB, read_FCB,
* del_RAMFCB, del_FCB) which needn't check input-parameter.
*/
//#include <stdio.h>//for simulation
#include <stdlib.h>//for simulation
#include <string.h>
#include <math.h>
#include <filesys\fs.h>
#include "parse.h"
#include "fcb.h"
#include "filebuf.h"
#include "file.h"
#include "iobuf.h"
#include "block.h"
#include "multsk.h"
/*
* Function Prototype
*/
FILE_S *fopen( char *fname, char *mode );
int fclose( FILE_S *fp );
int fseek( FILE_S *fp, long offset, int base );
int fwrite( void *buf, int size, int count, FILE_S *fp );
int fread( void *buf, int size, int count, FILE_S *fp );
int fcreate( char *path );
int fdelete( char *path );
/*
* fopen :
* function: Open the file user wants, if this file does't exist, create it.
* Here we only support two open types: 'rb+' and 'wb+'.
* parameter:
* fname : file name user wants to open
* mode : mode user wants to open( here this parameter we reserve )
* return value:
* ERROR: fail
* OK: success
*/
FILE_S *fopen( char *fname, char *mode )
{
PATH_NODE_S *path_node;
FILE_S *fp;
unsigned long openmode;
if( check_opened_file_num() < 0 )//02-8-24 13:47
// return (FILE_S *)FS_ERROR;
return NULL;
if ( fname == NULL && mode == NULL )
// return (FILE_S *)FS_ERR_PAR;
return NULL;
if ( ( path_node = (PATH_NODE_S *)FS_MALLOC( sizeof(PATH_NODE_S) ) ) == NULL )
// return (FILE_S *)FS_ERROR;
return NULL;
if ( (int)parse_path( fname, path_node ) < 0 )
// return (FILE_S *)FS_ERROR;
return NULL;
if ( path_node->magic != PATH_NODE_MAGIC )
// return (FILE_S *)FS_ERR_MAGIC;
return NULL;
FS_FREE( path_node );
/*
* check the parameter 'mode' and change it to the type
* we use inside filesystem.2002-9-3 17:30
*/
/* Here we use if-else instead of switch, because the machine
* doesn't recegnize character in switch.
*/
/*
switch ( mode )
{
case "rb+":
openmode = FS_OPEN_FILE;
break;
case "wb+":
openmode = FS_CREATE_FILE;
break;
default:
return (FILE_S *)FS_ERROR;
}*/
if( strcmp( mode, "rb+" ) == 0 )
openmode = FS_OPEN_FILE;
else
if( strcmp( mode, "wb+" ) == 0 ) openmode = FS_CREATE_FILE;
// else
// return (FILE_S *)FS_ERROR;
else
return NULL;
if ( (int)( fp = get_FILE( fname, openmode ) ) < 0 )
// return (FILE_S *)FS_ERROR;
return NULL;
return fp;
}
/*
* fclose :
* function: Close the file user wants
* parameter:
* fp : FILE pointer points the file user wants to close.
* return value:
* FS_ERROR: fail
* FS_OK: success
*/
int fclose( FILE_S *fp )
{
if ( fp == NULL )
return FS_ERR_PAR;
if ( fp->magic != FILE_MAGIC )
return FS_ERR_MAGIC;
if ( (int)remove_FILE( fp ) < 0 )
return FS_ERROR;
if( remove_fscb_item( (unsigned int)fp ) < 0 )
return FS_ERROR;//02-8-24 13:52
return FS_OK;
}
/*
* add by dsa 2002/11/04
* close file immediately and use --
*
*/
int fclosenow( FILE_S *fp )
{
if ( fp == NULL )
return FS_ERR_PAR;
if ( fp->magic != FILE_MAGIC )
return FS_ERR_MAGIC;
if ( (int)remove_FILEnow( fp ) < 0 )
return FS_ERROR;
if( remove_fscb_item( (unsigned int)fp ) < 0 )
return FS_ERROR;//02-8-24 13:52
return FS_OK;
}
/*
* fseek :
* function: Move the pointer to specified position.
* parameter:
* fp : pointer points to the file will be written to.
* offset : offset to move from specified position.
* base : jumping-off point.
* return value:
* FS_ERROR: fail
* FS_OK: success
*/
int fseek( FILE_S *fp, long offset, int base )
{
unsigned long curp, end;
// long i, length;//the number of subfcb from head to current pointer
// register SUBFCB_S *subfcb, *tempsub;
/*
* check fp
*/
if ( fp == NULL )
return FS_ERR_PAR;
if ( fp->magic != FILE_MAGIC )
return FS_ERR_MAGIC;
/*check offset*/
if ( fabs(offset) > fp->fcb->file_length )
return FS_ERROR;
switch( base )
{
case SEEK_SET:
/*check offset whether it's beyond the file*/
if ( offset < 0 )
return FS_ERROR;
end = offset;
break;
case SEEK_CUR:
curp = get_curp( (unsigned int)fp );
if ( offset < 0 )
if ( fabs(offset) > curp )
return FS_ERROR;
else if ( curp + offset > fp->fcb->file_length )
return FS_ERROR;
end = curp + offset;
break;
case SEEK_END:
if ( offset > 0 )
return FS_ERROR;
end = fp->fcb->file_length + offset;
break;
}
#if 0
length = ( (end - FCB_BLK_NUM) + (SUBFCB_BLK_NUM - 1) ) / SUBFCB_BLK_NUM;
if ( length > 0 )
{
/*
* read subfcb to ram
*/
for ( subfcb = (SUBFCB_S *)fp->fcb, i = 0; i < length; i++ )
{
if ( subfcb->nextfcb == NULL )
{
if ( (tempsub = (SUBFCB_S *)read_FCB( subfcb->nextblk, &fp->link )) == FS_ERROR )
return FS_ERROR;
subfcb->nextfcb = tempsub;
subfcb->flag = 1;
}
subfcb = subfcb->nextfcb;
}
}
#endif
set_curp( (unsigned int)fp, end );
return FS_OK;
}
/*
* fwrite :
* function: Write data from buf to file.
* parameter:
* buf : pointer points to the buffer stors data that will be written to file.
* size : the size of a unit be written.
* count : the number of unit.
* fp : pointer points to the file will be written to.
* return value:
* FS_ERROR: fail
* FS_OK: success
*/
int fwrite( void *buf, int size, int count, FILE_S *fp )
{
unsigned int length;
if ( buf == NULL || fp == NULL )
return FS_ERR_PAR;
if ( fp->magic != FILE_MAGIC )
return FS_ERR_MAGIC;
length = size * count;
if ( (int)write_file( fp, buf, length ) < 0 )
return FS_ERROR;
return FS_OK;
}
/*
* fread :
* function: Read data from file to buf.
* parameter:
* buf : pointer points to the buffer will stor data that be read from file.
* size : the size of a unit be read.
* count : the number of unit.
* fp : pointer points to the file will be read from.
* return value:
* FS_ERROR: fail
* FS_OK: success
*/
int fread( void *buf, int size, int count, FILE_S *fp )
{
unsigned int length;
if ( buf == NULL || fp == NULL )
return FS_ERR_PAR;
if ( fp->magic != FILE_MAGIC )
return FS_ERR_MAGIC;
length = size * count;
if ( (int)read_file( fp, buf, length ) < 0 )
return FS_ERROR;
return FS_OK;
}
/*
* fcreate :
* function: Create a file according to the path user gives
* and not open it.
* parameter:
* path : the absulote path
* return value:
* FS_ERROR: fail
* fS_OK: success
*/
/*
int fcreate( char *path )
{
FILE_S *fp;
PATH_NODE_S *path_node;
if ( path == NULL )
return FS_ERR_PAR;
if ( parse_path( path, path_node ) != FS_OK )
return FS_ERROR;
if ( path_node->magic != PATH_NODE_MAGIC )
return FS_ERR_MAGIC;
if ( path_node->node[0][0] != '/' )
return FS_ERROR;
if ( (int)(fp = get_FILE( path, FS_CREATE_FILE )) < 0 )
return FS_ERROR;
return FS_OK;
}
*/
/*
* fdelete :
* function: Delete a file not be used or a empty directory.
* parameter:
* path : the absulote path
* return value:
* FS_ERROR: fail
* fS_OK: success
*/
int fdelete( char *path )
{
register PATH_NODE_S *path_node;
register DIR_S *dir;
register DCB_S *dcb;
register char *p, *block;
int i;
unsigned long j;
unsigned int blkid;
unsigned int *data;
/*
* Check the path
*/
if ( path == NULL )
return FS_ERR_PAR;
path_node = (PATH_NODE_S *)FS_MALLOC(sizeof(PATH_NODE_S));
if ( (int)parse_path( path, path_node ) < 0 )
goto EXIT_ENTRY;
if ( path_node->magic != PATH_NODE_MAGIC )
goto EXIT_ENTRY;
/*
* Check whether the file is open.
*/
for ( i = 0; i < MAX_OPEN_FILE; i++ )
{
if ( !strcmp(filebuf[i].path, path) )
goto EXIT_ENTRY;
}
dir = &RootDir[0];
dcb = dir->subdir;
p = (char *)path_node->node;
p += NODE_LEN;
/* We should lock this file */
FS_LOCK( FILE_S_LOCK_ID );
/*
* Search the father directory of given file/directory.
* All is done in rom.
*/
for ( i = 1; i < path_node->depth - 1; i++ )
{
for ( j = 0; j < dir->curdir.file_length; j++, dcb++ )
if ( dcb->dirtype == FS_DIR )
if ( !strcmp( p, dcb->dirname ) )
break;
/*the dirctory doesn't exist*/
if ( j == dir->curdir.file_length )
goto ERROR_EXIT;
/* We find the father directory */
dir = (DIR_S *)dcb->blkid;
dcb = dir->subdir;
p += NODE_LEN;
}/*end of search father directory*/
/* we search the DCB_S of given file/directory in father directory */
for ( i = 0; i < dir->curdir.file_length; i++, dcb++ )
if ( dcb->dirtype != FS_FREE_FILE )
if ( !strcmp( p, dcb->dirname ) )
break;
if ( *(path + strlen(path) - 1) == '/' )//what we will delete is a dirctory
{
/* check whether this directory is empty */
if ( ((FCB_S *)(dcb->blkid))->file_length != 0 )
goto ERROR_EXIT;
if ( ((FCB_S *)(dcb->blkid))->magic != FILE_MAGIC )
goto ERROR_EXIT;
/*
* Here we assume that a directory uses a block.
*/
if ( free_block( dcb->blkid, &blkid, &data ) < 0 )
goto ERROR_EXIT;
write_block( NULL, blkid, 0, BLOCKSIZE, data, IMMEDIATE_WRITE );
}
else//what we will delete is a file
{
if ( ((FCB_S *)dcb->blkid)->magic != FCB_MAGIC )
goto ERROR_EXIT;
if ( (int)del_FCB( dcb->blkid ) < 0 )
goto ERROR_EXIT;
}
/*
* Modify the infomation in father diretory.
* Here we read the block of father directory from rom,
* then find the DCB_S of the file/directory we operating
* and free it.
*/
block = FS_MALLOC( BLOCKSIZE );
if ( block == NULL )
goto ERROR_EXIT;
read_block( NULL, (unsigned int)dir, 0, BLOCKSIZE, block );
dcb = ((DIR_S *)block)->subdir;
for ( j = 0; j < ((DIR_S *)block)->curdir.file_length; j++, dcb++ )
if ( !strcmp( p, dcb->dirname ) )
break;
memset( dcb, 0, sizeof(DCB_S) );
((DIR_S *)block)->curdir.file_length--;
write_block( NULL, (unsigned int)dir, 0, BLOCKSIZE, block, IMMEDIATE_WRITE );
FS_FREE(block);
FS_FREE(path_node);
FS_UNLOCK( FILE_S_LOCK_ID );
return FS_OK;
ERROR_EXIT:
FS_UNLOCK( FILE_S_LOCK_ID );
EXIT_ENTRY:
FS_FREE(path_node);
return FS_ERROR;
/*
EXIT_ENTRY:
FS_FREE(path_node);
return FS_ERROR;
*/
}
/*
* freaddir :
* function: read all the files and the directories of given directory.
* parameter:
* path : the absulote path
* return value:
* FS_ERROR: fail
* fS_OK: success
*/
int freaddir( char *path, DIRINFO_S *dirinfo )
{
char *p;
int i, j;
DIR_S *dir;
register DCB_S *dcb;
// char name[DIR_TREE_MAX_DEPTH][NAME_MAX];
register PATH_NODE_S *path_node;
if ( path == NULL )
return FS_ERR_PAR;
/*parst the path*/
if ( ( path_node = (PATH_NODE_S *)FS_MALLOC
( sizeof(PATH_NODE_S) ) ) == NULL )
return (FCB_S *)FS_ERROR;
if ( parse_path( path, path_node ) != FS_OK )
return (FCB_S *)FS_ERROR;
dir = &RootDir[0];
dcb = dir->subdir;
p = (char *)path_node->node;
p += NODE_LEN;
/* We should lock this file */
// FS_LOCK( FILE_S_LOCK_ID );
/*
* Search the father directory of given file/directory.
* All is done in rom.
*/
for ( i = 1; i < path_node->depth; i++ )
{
for ( j = 0; j < dir->curdir.file_length; j++, dcb++ )
if ( dcb->dirtype == FS_DIR )
if ( !strcmp( p, dcb->dirname ) )
break;
/*the dirctory doesn't exist*/
if ( j == dir->curdir.file_length )
goto ERROR_EXIT;
/* We find the father directory */
dir = (DIR_S *)dcb->blkid;
dcb = dir->subdir;
p += NODE_LEN;
}/*end of search father directory*/
/* Read all the files and the directories in this directory. */
memset ( dirinfo, 0, sizeof(DIRINFO_S) );
dirinfo->allnum = dir->curdir.file_length;
for( i = 0; i < dir->curdir.file_length; i++, dcb++ )
if ( dcb->dirtype != FS_FREE_FILE )
{
dirinfo->siminfo[i].type = dcb->dirtype;
memcpy( dirinfo->siminfo[i].name, dcb->dirname, NAME_MAX );
}
// FS_UNLOCK( FILE_S_LOCK_ID );
return FS_OK;
ERROR_EXIT:
// FS_UNLOCK( FILE_S_LOCK_ID );
return FS_ERROR;
}
//add by dsa 2002.10.25
long GetFileLength( FILE_S *fp )
{
long fl;
fl = fp->fcb->file_length;
return fl;
}
#if 0
void main()
{
dir_init();
fdelete( "/pessia/music/kitaro" );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -