⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 others.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	others.c (file) * *	File management *	Other various system call processings */#include "fileio.h"#include "others.h"#include "filesys.h"#include "diskio.h"LOCAL ER changeWorkFile( PINFO *pinfo, LINK *lnk, FsInfo *fsinfo );LOCAL WER getFileType( FID fid, FsInfo *fsinfo );LOCAL WER searchFile( LINK *lnk, TC **path, PINFO *pinfo, FsInfo *fsinfo );LOCAL void getFileStateInfo( DfFileHeader *fh, FileName name, F_STATE *stat, FsInfo *fsinfo );LOCAL ER getLocateInfo( F_LOCATE *locat, FsInfo *fsinfo );LOCAL void getLinkFileInfo( DfFileHeaderBlock *fh, F_LINK *stat, FsInfo *fsinfo );#define TSD_FGL_VAL_1	1#define TSD_FGL_VAL_2	2#define TSD_FGL_VAL_0	0#define TSD_FGN_CNT_255	255/* * Change the work file. *	Change the work file of pinfo into new. *	It is assumed that new is already checked to be valid. *	When new == NULL, make the work file unregistered. *	When new != NULL, it should be called from the file system that new belongs, *	and fsinfo must indicate the the file system of new. *	When called from other than the file system task, *	fsinfo = NULL. */EXPORT ER fmChangeWorkFile( PINFO *pinfo, LINK *new, FsInfo *fsinfo ){	FINFO	*finfo = &pinfo->file;	LINK	old;	FsInfo	*fs;	LOCK_PINFO_SECTION( old = finfo->workFile );	/* Find the file system of current work file. */	fs = fmSelectFileSystemOfLink(&old);	if ( fs != NULL ) {		/* Deregister from the file system of current work file. */		if ( fs == fsinfo ) {			LOCK_PINFO_SECTION( QueRemove(&finfo->q) );		} else {			Lock(&fs->lock);			LOCK_PINFO_SECTION( QueRemove(&finfo->q) );			Unlock(&fs->lock);		}	}	/* Register new work file. */	if ( new != NULL ) {		LOCK_PINFO_SECTION(			finfo->workFile = *new;			QueInsert(&finfo->q, &fsinfo->wrkFilLst);		);	} else {		/* Work file undefined. */		LOCK_PINFO_SECTION( setUndefLink(&finfo->workFile) );	}	return E_OK;}/* * Change the work file. *	Change the work file of the process of *pinfo into *lnk. */LOCAL ER changeWorkFile( PINFO *pinfo, LINK *lnk, FsInfo *fsinfo ){	FileAccMode		amode;	DfFileHeaderBlock	*fh;	ID			mid;	UH			ftype;	ER			err;	/* Map the file header. */	fh = fmpMapFileHeader(lnk->f_id, NULL, &mid, fsinfo);	if ( fh == NULL ) {		err = (ER)mid;		goto err_ret1;	}	/* Check the file type. */	ftype = fmpConvEndianH(fh->head.ftype, fsinfo);	if ( isLinkFile(ftype) != 0 ) {		LINK	ref;		/* Fetch the access mode from the file being linked to. */		(void)fmpConvEndianTC(ref.fs_name, (TC*)fh->f.link.fsnm, FsNameLen,								fsinfo);		ref.f_id = fmpConvEndianH(fh->f.link.fid, fsinfo);		if ( isSameFS(ref.fs_name, fsinfo) != 0 ) {			err = E_ILFMT;			goto err_ret2;		}		err = fmIGetFileInfo(&ref, NULL, NULL, &amode);		if ( err < E_OK ) {			goto err_ret2;		}	} else {		/* Fetch the access mode of the file. */		err = fmpGetFileAccMode(&amode, &fh->head, fsinfo);		if ( err < E_OK ) {			goto err_ret2;		}	}	fmpUnmapDisk(mid, MD_RDONLY);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	/* Access right check */	err = fmpCheckFileAccMode(pinfo, &amode, F_EXCUTE, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	/* Change the work file. */	err = fmChangeWorkFile(pinfo, lnk, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	return E_OK;err_ret2:	fmpUnmapDisk(mid, MD_RDONLY);err_ret1:	DEBUG_PRINT(("changeWorkFile err = %d\n", err));	return err;}/* * chg_wrk: Change the work file. */EXPORT void fmpChangeWorkFile( FmCmdPkt *pkt, FsInfo *fsinfo ){	FM_CHG_WRK_PARA		*cmdPara = (FM_CHG_WRK_PARA*)pkt->cmd.para;	ER			err;	/* Change the work file. */	err = changeWorkFile(pkt->wrk.pinfo, cmdPara->lnk, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	pkt->cmd.ret = E_OK;	return;err_ret:	DEBUG_PRINT(("fmpChangeWorkFile err = %d\n", err));	pkt->cmd.ret = err;	return;}/* ------------------------------------------------------------------------ *//* * get_lnk: Select a file system from the path name. */EXPORT FwdID fmcGetLink( FmCmdPkt *pkt ){	FM_GET_LNK_PARA	*cmdPara = (FM_GET_LNK_PARA*)pkt->cmd.para;	TC		*path;	PathToken	name;	PTYPE		type;	FsInfo		*fs;	ER		err;	/* Parameter check */	err = CheckSpaceRW(cmdPara->lnk, sizeof(LINK));	if ( err < E_OK ) {		goto err_ret;	}	if ( ((UW)cmdPara->mode & ~(UW)(F_BASED|F_DIRECT)) != 0U ) {		err = E_PAR;		goto err_ret;	}	path = cmdPara->path;	if ( path != NULL ) {		/* Obtain the path name. */		err = CheckStrSpaceR(path, PathNameLen + 1);		if ( err < E_OK ) {			goto err_ret;		}		if ( (W)err > PathNameLen ) {			err = E_FNAME;			goto err_ret;		}		err = fmCheckPathName(path);		if ( err < E_OK ) {			goto err_ret;		}		/* Cut out the first token from the path name. */		type = fmGetPathToken(&path, name);	} else {		static TC null_path = TNULL;		/* The work file is the target. */		type = PT_OWN;		path = &null_path;	}	pkt->wrk.pathp = path; /* Analyze the path from next token.  */	switch ( type ) {	  case PT_CON:	/* Connection name. */		fs = fmSelectFileSystemOfConName(name);		pkt->wrk.lnk = RootFile(fs);		break;	  case PT_NAM:	/* File name */		pkt->wrk.pathp = cmdPara->path; /* From the first token again.  */		/* no break */	  case PT_OWN:	/* Work file */		if ( ((UW)cmdPara->mode & (UW)F_BASED) != 0U ) {			pkt->wrk.lnk = *cmdPara->lnk;		} else {			LOCK_PINFO_SECTION(				pkt->wrk.lnk = (pkt->wrk.pinfo)->file.workFile			);			if ( isUndefLink(&pkt->wrk.lnk) != 0 ) {				err = E_NOEXS;				goto err_ret;			}		}		fs = fmSelectFileSystemOfLink(&pkt->wrk.lnk);		break;	  default:		err = E_FNAME;		goto err_ret;	}	if ( fs == NULL ) {		err = E_NOFS;		goto err_ret;	}	/* It is not a forwarding from the file system task. */	resetCmdForward(pkt);	return fs->port;err_ret:	DEBUG_PRINT(("fmcSelectPath err = %d\n", err));	pkt->cmd.ret = err;	return NoForward;}/* * Obtain the file type. */LOCAL WER getFileType( FID fid, FsInfo *fsinfo ){	UH			ftype;	DfFileHeaderBlock	*fh;	ID			mid;	ER			err;	/* Obtain the file header. */	fh = fmpMapFileHeader(fid, NULL, &mid, fsinfo);	if ( fh == NULL ) {		err = (ER)mid;		goto err_ret;	}	/* Fetch the file type. */	ftype = fmpConvEndianH(fh->head.ftype, fsinfo);	fmpUnmapDisk(mid, MD_RDONLY);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return (W)ftype;err_ret:	DEBUG_PRINT(("getFileType err = %d\n", err));	return err;}/* * Retrieve the file name. *	Fetch one path name token from path (Advance path to the start of the next token), *	and find the file that matches with its file name from the link records *	of the file of lnk. Return the found file to lnk. *	When lnk is a link file, the token is not fetched from path, *	and the retrieval is also not performed. Return the file referred to to lnk. *	The following return values are returned. *	* When lnk is a link file:	1 *	* When the file is found:	0 *	* When the file is not found:	E_NOEXS *	* When no search access right of lnk is found:	E_FACV */LOCAL WER searchFile( LINK *lnk, TC **path, PINFO *pinfo, FsInfo *fsinfo ){	PathToken	fname;	W		n;	OFCB		*ofcb;	OpenPara	opara;	UH		ftype;	ID		mid;	ER		err;	/* Prepare to open (Map the file header) */	mid = fmpGetOpenPara(&opara, lnk->f_id, fsinfo);	if ( mid < E_OK ) {		err = (ER)mid;		goto err_ret1;	}	/* Check the file type. */	ftype = fmpConvEndianH(opara.fhd->head.ftype, fsinfo);	if ( isLinkFile(ftype) != 0 ) {		/* Obtain the reference. */		(void)fmpConvEndianTC(lnk->fs_name, (TC*)opara.fhd->f.link.fsnm,							FsNameLen, fsinfo);		lnk->f_id = fmpConvEndianH(opara.fhd->f.link.fid, fsinfo);	} else {		/* File open (Search access right check) */		ofcb = fmpIOpenFile(&opara, F_EXCUTE, pinfo, fsinfo, &err);		if ( ofcb == NULL ) {			goto err_ret2;		}		/* Fetch the next path name token, and divide it between file name and occurrence order. */		(void)fmGetPathToken(path, fname);		n = fmGetFileName(fname);		/* Retrieve the link record, and find the file. */		err = fmpISearchFile(ofcb, fname, n + 1, lnk);		if ( err < E_OK ) {			goto err_ret3;		}		err = fmpICloseFile(ofcb, F_EXCUTE);		if ( err < E_OK ) {			goto err_ret2;		}	}	fmpUnmapDisk(mid, MD_RDONLY);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	return isLinkFile(ftype);err_ret3:	(void)fmpICloseFile(ofcb, F_EXCUTE);err_ret2:	fmpUnmapDisk(mid, MD_RDONLY);err_ret1:	DEBUG_PRINT(("searchFile err = %d\n", err));	return err;}/* * get_lnk: Fetch the link to the file. */EXPORT FwdID fmpGetLink( FmCmdPkt *pkt, FsInfo *fsinfo ){	FM_GET_LNK_PARA	*cmdPara = (FM_GET_LNK_PARA*)pkt->cmd.para;	LINK		curf;	TC		*path = pkt->wrk.pathp;	W		ftype;	FwdID		fwd;	W		lnkKind = 0;	ER		err;	curf  = pkt->wrk.lnk;	while ( *path != TNULL ) {		/* Retrieve the file name. */		err = searchFile(&curf, &path, pkt->wrk.pinfo, fsinfo);		if ( err < E_OK ) {			goto err_ret;		}		if ( err > 0 ) {	/* Link file. */			break;		}	}	if ( *path != TNULL ) {		/* The path name continues: Forward */		fwd = ForwardMgr;	} else {		/* Obtain the file type. */		ftype = getFileType(curf.f_id, fsinfo);		if ( ftype < E_OK ) {			err = (ER)ftype;			goto err_ret;		}		if ( isLinkFile(ftype) != 0 ) {			if ( ((UW)cmdPara->mode & (UH)F_DIRECT) != 0U ) {				/* Obtain the reference of the link file. */				err = searchFile(&curf, NULL, NULL, fsinfo);				if ( err < E_OK ) {					goto err_ret;				}				fwd = ForwardMgr;			} else {				lnkKind = TSD_FGL_VAL_1;				fwd = NoForward;			}		} else {			if ( (*pkt->wrk.pathp == TNULL) && isCmdForward(pkt) ) {				/* The reference file was found when F_DIRECT. */				lnkKind = TSD_FGL_VAL_2;			} else {				lnkKind = TSD_FGL_VAL_0;			}			fwd = NoForward;		}	}	if ( fwd == NoForward ) {		/* Store the link. */		tc_strncpy(curf.fs_name, fsinfo->fsName, FsNameLen);		*cmdPara->lnk = curf;		pkt->cmd.ret = lnkKind;	} else {		if ( (path == pkt->wrk.pathp) && isCmdForward(pkt) ) {			/* Multiplex indirect reference */			err = E_NOEXS;			goto err_ret;		}		/* Forward */		pkt->wrk.lnk = curf;		pkt->wrk.pathp = path;	}	return fwd;err_ret:	DEBUG_PRINT(("fmpGetLink err = %d\n", err));	pkt->cmd.ret = err;	return NoForward;}/* ------------------------------------------------------------------------ *//* * Obtain the file name and management information. */LOCAL void getFileStateInfo( DfFileHeader *fh, FileName name, F_STATE *stat,							FsInfo *fsinfo ){	BOOL	big = fsinfo->bigEndian;	if ( name != NULL ) {		/* Obtain the file name. */		(void)fmConvEndianTC(name, (TC*)fh->name, FileNameLen, big);		name[FileNameLen] = TNULL;	}	if ( stat != NULL ) {		/* Obtain the file management information. */		stat->f_type	= fmConvEndianH(fh->ftype, big);		stat->f_atype	= fmConvEndianH(fh->atype, big);		fmConvEndianHs((UH*)stat->f_owner, (UH*)fh->own,						UserNameLen, big);		fmConvEndianHs((UH*)stat->f_group, (UH*)fh->grp,						UserNameLen, big);		stat->f_grpacc	= fmConvEndianH(fh->gacclv, big);		stat->f_pubacc	= fmConvEndianH(fh->pacclv, big);		stat->f_nlink	= (H)fmConvEndianH((UH)fh->nlnk, big);		stat->f_index	= (H)fmConvEndianH((UH)fh->idxlv, big);		stat->f_size	= (W)fmConvEndianW((UW)fh->size, big);		stat->f_nblk	= (W)fmConvEndianW((UW)fh->nblk, big);		stat->f_nrec	= (W)fmConvEndianW((UW)fh->nrec, big);		stat->f_ltime	= (STIME)fmConvEndianW((UW)fh->ltime, big);		stat->f_atime	= (STIME)fmConvEndianW((UW)fh->atime, big);		stat->f_mtime	= (STIME)fmConvEndianW((UW)fh->mtime, big);		stat->f_ctime	= (STIME)fmConvEndianW((UW)fh->ctime, big);	}}/* * Obtain the file location information. */LOCAL ER getLocateInfo( F_LOCATE *locat, FsInfo *fsinfo ){	DfSystemHeader	*sh;	ID		mid;	ER		err;	if ( locat == NULL ) {		return E_OK;	}	/* Map the system header. */	sh = fmpMapDskAdrS(fsinfo->shead, sizeof(DfSystemHeader),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -