📄 stdfs.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. * *---------------------------------------------------------------------- *//* * @(#)stdfs.c (seio) * * Standard input-output * Standard file system */#include <tcode.h>#include <tlang.h>#include "sfmgr.h"LOCAL TC* btGetApprOrder( SFFD *fd, TC *tcname );LOCAL WER btConvName_toTC( UB *name, W nlen, TC *tcname, W tcsz, BOOL pkascii );LOCAL BOOL btCanChgAscii( TC tc );LOCAL WER btConvName_fromTC( TC *tcname, UB *name, W nlen );LOCAL WER btTruncateFile( SFNODE *inode, W sffd, off_t length, BOOL currec );LOCAL ER btGetAttr( SFNODE *inode, W sffd, struct stat *sb );/* * File system connection information */EXPORT SFFS STD_FS;#define ATYPE_REG 3 /* Regular file designation */#define ATYPE_DIR 6 /* Directory designation *//* Buffer memory acquisition size unit */#define NM_ALLOC_UNIT 1024#define TSD_STD_SNC_2 2#define TSD_STD_FPS_2 2#define TSD_FDE_VAL_3 3#define TSD_BCF_VAL_5 5#define TSD_SGF_VAL_5 5#define TSD_SGF_VAL_5U 5U#define TSD_FDE_VAL_6U 6U#define TSD_BCF_VAL_0X60 0x60U#define TSD_BCF_MSK_0X00FF 0x00ffU#define TSD_BCT_SFT_8 8#define TSD_BCF_SFT_8 8#define TSD_SFO_VAL_0X80000000 0x80000000U#define TSD_STD_TSR_M1 (-1)#define TSD_STD_TWR_M1 (-1)#define TSD_SGF_FFR_M1 (-1)#define TSD_BCF_BUF_2 2#define TSD_BCF_NLE_2 2#define TSD_SUT_TIM_2 2#define TSD_STD_LEN_2 2#define TSD_BCT_I_3 3#define TSD_STD_POS_0 0#define TSD_STD_POS_1 1#define TSD_STD_POS_2 2#define TSD_FDE_POS_0 0#define TSD_FDE_POS_1 1#define TSD_FDE_POS_2 2#define TSD_BGA_VA1_2 2#define TSD_STD_ASC_0X20 0x20#define TSD_STD_ASC_0X7E 0x7e#define TSD_BCT_J_2 2#define TSD_BCT_MCY_2 2#define TSD_BCT_VAL_0X6060 0x6060#define TSD_BCC_BUF_4 4#define TSD_BCC_VAL_0X7F 0x7f#define TSD_BCF_TCB_128 128#define TSD_BCF_I_3 3#define TSD_BCF_VAL_0X8080 0x8080U#define TSD_BCF_VAL_128 128#define TSD_BCF_PTC_5 5#define TSD_BCF_MCY_5U 5U#define TSD_SGF_TTE_5 5#define TSD_SLU_VA1_2 2#define TSD_SLU_VA2_2 2#define TSD_SRD_VA1_2 2#define TSD_SRD_VA2_2 2#define TSD_BGA_VA2_2 2#define TSD_SOP_VAL_2 2#define TSD_STD_TFR_0X80000000 0x80000000U#define TSD_STD_TAR_31 31#define TSD_GBA_MSK_0X8000 0x8000U#define TSD_FDE_MSK_3 3U#define TSD_SOP_MSK_2 3U#define TSD_STD_NLN_2 2U#define TSD_FDE_DNL_2 2#define TSD_FDE_FPO_2 2U#define TSD_FDE_VAL_10 10/* * Acquisition of the appearance order of file name */LOCAL TC* btGetApprOrder( SFFD *fd, TC *tcname ){ W len; B *temp; TC *nm; /* File name length */ len = tc_strlen(tcname); /* Count buffer in appearance order */ if ( fd->nmbuf != NULL ) { for ( nm = (TC*)fd->nmbuf; nm < fd->bufend; ) { if ( tc_strcmp(nm + 1, tcname) == 0 ) { break; } nm += tc_strlen(nm + 1) + TSD_BGA_VA1_2; } /* Determination of appearance order */ if ( nm < fd->bufend ) { (*nm)++; return nm; } } else { /* No information on the appearance order */ fd->bufsz = 0; } /* Confirmation of buffer size */ if (( fd->bufsz <= 0 )|| ((fd->bufend + len + 1) >= (TC*)(fd->nmbuf + fd->bufsz))) { /* Buffer expansion */ fd->bufsz += NM_ALLOC_UNIT; temp = (B*)realloc(fd->nmbuf, (UW)fd->bufsz); if ( temp == NULL ) { if ( fd->nmbuf != NULL ) { free(fd->nmbuf); } fd->nmbuf = NULL; goto err_ret; } /* Buffer and present location */ if ( fd->nmbuf == NULL ) { fd->bufend = (VP)temp; fd->nmbuf = (B*)fd->bufend; } else { fd->bufend = (VP)(temp + ((B*)fd->bufend - fd->nmbuf)); fd->nmbuf = temp; } } /* An order of appearance information position */ nm = fd->bufend; /* Addition of order of appearance information */ *nm = 1; tc_strcpy(nm + 1, tcname); fd->bufend += (len + 1 + 1); return nm;err_ret: DEBUG_PRINT(("btGetApprOrder NULL\n")); return NULL;}/* * Convert the Japanese language EUC file name into "TC" * Convert the half-width character of file name into the supported full-width character. * Return the number of conversion result characters to return value. */LOCAL WER btConvName_toTC( UB *name, W nlen, TC *tcname, W tcsz, BOOL pkascii ){ W i, j, len, srclen, tclen, tctotal = 0, tcbufsz; UB *src; TC *tcbuf = NULL, *tcdst; ER err; /* Lock of conversion environment */ Lock(&EtoTLock); if( name == NULL){ err = E_PAR; goto err_ret1; } /* ASCII code check */ for ( j = 0; j < nlen; j++ ) { if ( (name[j] < TSD_STD_ASC_0X20) || (TSD_STD_ASC_0X7E < name[j]) ) { pkascii = FALSE; break; } } /* File name conversion */ if (( nlen > (tcsz - 1)) && pkascii ) { /* Only ASCII area */ tcname[TSD_STD_POS_0] = TK_U; tcname[TSD_STD_POS_1] = TK_X; tcname[TSD_STD_POS_2] = TK_EXTEND_FNM_MARK; /* Pack every 2 characters in the D-zone */ for ( i = TSD_BCT_I_3, j = 0; (i < (tcsz - 1)) && ((j + 1) < nlen); i++, j += TSD_BCT_J_2 ) { tcname[i] = (((UH)name[j] << TSD_BCT_SFT_8) | (UH)name[j + 1]) + TSD_BCT_VAL_0X6060; } /* The last extra 1 character in the A zone*/ if (( i < (tcsz - 1)) &&( j < nlen )) { (void)euctotc( &tcname[i], &name[j]); len = i + 1; } else { len = i; } } else { /* ASCII include a cord out of ASCII area */ /* Buffer size required for conversion */ src = name; srclen = nlen; for ( err = 1; 0 < err; ) { err = tf_strtotcs(tf_euctotc_ctx, src, srclen, TF_ATTR_START | TF_ATTR_SUPPRESS_FUSEN, NULL, &tclen); if ( err < E_OK ) { goto err_ret1; } if ( tctotal == 0 ) { tctotal += tclen; } src = NULL; } /* Buffer obtain */ tcbufsz = (W)sizeof(TC) * (tctotal + 1); tcbuf = (TC*)malloc((UW)tcbufsz); if ( tcbuf == NULL ) { err = E_NOMEM; goto err_ret1; } /* File name conversion */ src = name; tcdst = tcbuf; tctotal = 0; for ( err = 1; 0 < err; ) { tclen = tcbufsz; err = tf_strtotcs(tf_euctotc_ctx, src, srclen, TF_ATTR_START | TF_ATTR_SUPPRESS_FUSEN, tcdst, &tclen); if ( err < E_OK ) { goto err_ret2; } if ( tcdst != 0 ) { tctotal += tclen; } src = NULL; tcdst = NULL; } /* Conversion result */ if ( tctotal <= (tcsz - 1) ) { memcpy((UB*)tcname, (UB*)tcbuf, (size_t)(tctotal * TSD_BCT_MCY_2)); len = tctotal; } else { memcpy((UB*)tcname, (UB*)tcbuf, (size_t)((tcsz - 1) * TSD_BCT_MCY_2)); len = tcsz; } free(tcbuf); } tcname[len] = TNULL; /* Unlock of conversion environment */ Unlock(&EtoTLock); return len;err_ret2: free(tcbuf);err_ret1: Unlock(&EtoTLock); DEBUG_PRINT(("btConvName_toTC err=%#x\n", err)); return err;}/* * ASCII character check */LOCAL BOOL btCanChgAscii( TC tc ){ UB buf[TSD_BCC_BUF_4]; W ret; ret = tctoeuc(buf, tc); if (( ret == 1 )&&((*buf >= TSD_STD_ASC_0X20 )&&( *buf < TSD_BCC_VAL_0X7F)) && (*buf != ':' )&&( *buf != '/' )) { return TRUE; } return FALSE;}/* * Character expansion / Reduction */TC ptcHalf[] = { 0xffa2, 0x0006, 0x0300, 0x0000, 0x0102 };TC ptcFull[] = { 0xffa2, 0x0006, 0x0300, 0x0000, 0x0000 };/* * Convert "TC" file name into Japanese language EUC * of the supported half-width character other than ":" and "/" . * Return the number of bytes of conversion result to return value. */LOCAL WER btConvName_fromTC( TC *tcname, UB *name, W nlen ){ TC *tcp, tcbuf[TSD_BCF_TCB_128]; W i, j, tclen, len, bytes = 0; UB *p, buf[TSD_BCF_BUF_2]; TC tcpack, *ptc, *ptcn, *ptcb, *ptcbe; TLANG lang = TSC_SYS; BOOL half = TRUE, hwidth = FALSE; ER err; Lock(&TtoELock); if (( (tcname[TSD_STD_POS_0] == TK_U) && (tcname[TSD_STD_POS_1] == TK_X) )&& ( tcname[TSD_STD_POS_2] == TK_EXTEND_FNM_MARK )) { /* Unpack in ASCII character string. */ for ( i = TSD_BCF_I_3, p = name; i < L_FNM; i++ ) { tcpack = tcname[i]; if ( tcpack == 0 ) { break; } if ( (tcpack & TSD_BCF_VAL_0X8080) == TSD_BCF_VAL_0X8080 ) { if ( nlen < TSD_BCF_NLE_2 ) { break; } *(p++) = (UB)((tcpack >> TSD_BCF_SFT_8) - TSD_BCF_VAL_0X60); nlen--; if (nlen < TSD_BCF_NLE_2) { break; } *(p++) = (UB)((tcpack & TSD_BCF_MSK_0X00FF) - TSD_BCF_VAL_0X60); nlen--; } else { /* The last 1 character */ err = tctoeuc(buf, tcpack); if ( err >= E_OK ) { if ( err < nlen ) { for ( j = 0; j < err; j++ ) { *(p++) = buf[j]; nlen--; } } else { for( j = 0; j < (nlen - 1); j++ ) { *(p++) = buf[j]; nlen--; } } if ( nlen <= 1 ) { break; } } } } *p = NULL; bytes = p - name; } else { /* Half cornification of ASCII supported character */ ptcn = tcname; ptcbe = tcbuf + TSD_BCF_VAL_128; ptcb = tcbuf; for ( ; *ptcn && (ptcb < ptcbe); ) { err = isTLANG(ptcn, 0, &ptc); if ( err < E_OK ) { half = FALSE; break; } if ( err > 0 ) { lang = (UH)err; for ( ; (ptcn < ptc) && (ptcb < ptcbe); ) { *(ptcb++) = *ptcn; } if ( ptcn != ptc ) { half = FALSE; break; } continue; } if (( lang != TSC_SYS )|| !btCanChgAscii(*ptcn)) { if ( ptcbe <= (ptcb + TSD_BCF_PTC_5) ) { half = FALSE; break; } memcpy(ptcb, ptcFull, (size_t)(sizeof(TC) * TSD_BCF_MCY_5U)); ptcb += TSD_BCF_VAL_5; hwidth = FALSE; } else { if ( !hwidth ) { if ( ptcbe <= (ptcb + TSD_BCF_PTC_5) ) { half = FALSE; break; } memcpy(ptcb, ptcHalf, (size_t)(sizeof(TC) * TSD_BCF_MCY_5U)); ptcb += TSD_BCF_PTC_5; hwidth = TRUE; } } *(ptcb++) = *(ptcn++); } /* Conversion object file name */ if ( half != 0 ) { if ( ptcb < ptcbe ) { *ptcb = TNULL; } tclen = ptcb - tcbuf; tcp = tcbuf; } else { tclen = tc_strlen(tcname); tcp = tcname; } /* File name conversion */ p = name; len = nlen - 1; for ( err = 1; err > 0; ) { err = tf_tcstostr(tf_tctoeuc_ctx, tcp, tclen, 0, TF_ATTR_START, p, &len); if ( err < E_OK ) { goto err_ret; } if ( bytes == 0 ) { bytes += len; } tcp = NULL; p = NULL; } name[bytes] = NULL; } /* Unlock of conversion environment */ Unlock(&TtoELock); return bytes;err_ret: Unlock(&TtoELock); DEBUG_PRINT(("btConvName_fromTC err=%#x\n", err)); return err;}/* --------------------------------------------------------------------------- *//* * Path name analysis */#define LINKBUF_UNIT 16U /* LINK array acquisition unit */EXPORT ER sf_lookup( CDINF *curdir, LPINF *lp ){ SFNODE *inode; F_STATE stat; LINK lnk; B *p = lp->path, *np, *sp, *wsp; W len, mode; TC tname[L_FNM + 1]; UH *link, *temp; UW maxlnk, nl; UB type = DT_DIR; ER err = E_OK; /* Location of search start */ if (( *p != '/' )&&( curdir->fs != (FS*)&ROOT_FS )) { /* Relative path */ /* Start from working file */ inode = (SFNODE*)curdir->inode; for ( maxlnk = 0; maxlnk < inode->nlnk; maxlnk += LINKBUF_UNIT) { ; } /* Link buffer of directory path */ link = Vmalloc(maxlnk * sizeof(UH)); if ( link == NULL ) { err = E_NOMEM; goto err_ret1; } memcpy(link, inode->c.exinf, (size_t)(maxlnk * sizeof(UH))); nl = inode->nlnk; lnk = inode->link; /* File name top location */ np = p; } else { /* Absolute path */ /* Start from root file */ maxlnk = LINKBUF_UNIT; link = Vmalloc(maxlnk * sizeof(UH)); if ( link == NULL ) { err = E_NOMEM; goto err_ret1; } nl = 0; /* Connection name top location */ for ( np = p; *np == '/'; np++ ) { ; } } while ( *np != '\0' ) { /* Error if it is not directory */ if ( type != DT_DIR ) { err = E_FNAME; goto err_ret1; } /* Fetch of file name */ np = strchr(p = np, '/'); if ( np == NULL ) { np = strchr(p, '\0'); } /* Directory "." and ".." special handling */ if ( ((np - p) == 1) && (strncmp(p, ".", (size_t)1) == 0) ) { /* Skip reading the directory "." */ for ( ; *np == '/'; np++ ) { ; } continue; } else if ( ((np - p) == TSD_SLU_VA1_2) && (strncmp(p, "..", (size_t)TSD_SLU_VA2_2) == 0) ) { if ( nl <= 1U ) { /* Parent directory is the root of system*/ lp->path = np; lp->flag = LOOKUP_ROOT; Vfree(link); return E_OK; } /* Return the present link location */ --nl; lnk.f_id = link[nl - 1U]; /* Restart the search from parent directory */ for ( ; *np == '/'; np++ ) { ; } continue; } /* Check of appearance order */ for ( sp = p; sp < np; sp++ ) { if (( *sp == ':' )&&( (sp + 1) != np )) { for ( wsp = sp + 1; wsp < np; wsp++ ) { /* The character continued to ':' */ if (( *wsp < '0' )||( *wsp > '9' )) { break; } } if ( wsp >= np ) { break; } } } /* Search path name */ if ( nl > 0U ) { /* File name */ /* Conversion */ len = btConvName_toTC((UB*)p, sp - p, tname, L_FNM + 1, TRUE); if ( len < E_OK ) { err = len; goto err_ret2; } /* Parent file designation */ mode = F_BASED; } else { /* Connection name */ /* Conversion */ len = btConvName_toTC((UB*)p, sp - p, &tname[1], L_FNM + 1, TRUE); if ( len < E_OK ) { err = len; goto err_ret2; } tname[0] = TC_FDLM; len++; /* Absolute path */ mode = F_NORM; } /* Addition of apperance order */ if ( sp < np ) { tname[len] = TC_FSEP; len++; sp++; while (( sp < np )&&( len < L_FNM )) { err = euctotc(&tname[len++], (UB*)sp++); if ( err < E_OK ) { goto err_ret2; } } tname[len] = TNULL; } /* Acqusition of Link */ err = tkse_get_lnk(tname, &lnk, mode); if (( err < E_OK )&& ( err != E_NOEXS )&&( err !=E_NOFS )) { goto err_ret2; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -