📄 others.c
字号:
/* *---------------------------------------------------------------------- * 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 + -