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

📄 stdfs.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *---------------------------------------------------------------------- *    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 + -