📄 uroot.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. * *---------------------------------------------------------------------- *//* * @(#)uroot.c (seio) * * Standard input-output * ROOT File system */#include "sfmgr.h"LOCAL ER rtGetAttr( struct stat *sb );#define TSD_RGD_VAL_3 3#define TSD_RGA_POS_0 0#define TSD_RGD_POS_0 0#define TSD_RGA_POS_1 1#define TSD_RGD_POS_1 1#define TSD_RGD_POS_2 2#define TSD_RGA_SZ_2 2#define TSD_RGA_BSZ_512 512#define TSD_RGD_MAX_16 16#define TSD_RGD_MSK_5_3 (5U &~ 3U)#define TSD_RGD_MSK_6_3 (6U &~ 3U)#define TSD_RGD_LEN_2 2#define TSD_RGD_VAL_2 2#define TSD_RGD_MSK_3 3U#define TSD_RLS_FPS_2 2/* * ROOT File system connection information */EXPORT RTFS ROOT_FS;/* * ROOT File information acquisition common part */LOCAL ER rtGetAttr( struct stat *sb ){ UW size = TSD_RGA_SZ_2; W cnt; F_ATTACH att; QUEUE *q; ER err; /* Root directory size */ cnt = tkse_lst_fls(&att, 1); if ( cnt < E_OK ) { err = cnt; goto err_ret; } size += (UW)cnt; for ( q = FSQue.next, cnt = 0; q != &FSQue; q = q->next, cnt++ ) { ; } size += (UW)cnt; sb->st_dev = ROOT_DEV; sb->st_ino = ROOT_INO; sb->st_mode = (S_IFDIR|S_IRUSR|S_IRGRP|S_IROTH|S_IXUSR|S_IXGRP|S_IXOTH); sb->st_nlink = 1; sb->st_uid = 0; sb->st_gid = 0; sb->st_rdev = 0; (sb->st_atimespec).tv_sec = 0; (sb->st_mtimespec).tv_sec = 0; (sb->st_ctimespec).tv_sec = 0; (sb->st_atimespec).tv_nsec = 0; (sb->st_mtimespec).tv_nsec = 0; (sb->st_ctimespec).tv_nsec = 0; sb->st_size = (off_t)size; sb->st_blocks = 0; sb->st_blksize = TSD_RGA_BSZ_512; sb->st_flags = 0; sb->st_gen = 0; /* Others */ sb->st_lspare = sb->st_qspare[TSD_RGA_POS_0] = sb->st_qspare[TSD_RGA_POS_1] = 0; return E_OK;err_ret: DEBUG_PRINT(("rtGetAttr err=%#x\n", err)); return err;}/* * ROOT file information acquisition */EXPORT ER rt_stat( struct stat *sb ){ ER err; err = rtGetAttr(sb); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("rt_stat err=%#x\n", err)); return err;}EXPORT ER rt_lstat( struct stat *sb ){ ER err; err = rtGetAttr(sb); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("rt_lstat err=%#x\n", err)); return err;}EXPORT ER rt_fstat( FDPkt *fdp, struct stat *sb ){ ER err; err = rtGetAttr(sb); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("rt_fstat err=%#x\n", err)); return err;}/* * Fetch of ROOT directory entry */EXPORT WER rt_getdents( FDPkt *fdp, struct dirent *buf, size_t nbyte ){ RTFD *fd = (RTFD*)fdp->fd; struct dirent dent; F_ATTACH *bbuf, *temp; TC connm[L_CONNM + 1]; UW fpos = (UW)fd->c.fpos; W i, cnt, max = TSD_RGD_MAX_16, rdsize = 0; FS *fs; QUEUE *q; ER err; /* "." and ".." indicating ROOT directory itself */ if ( fpos == 0U ) { dent.d_fileno = ROOT_INO; dent.d_type = DT_DIR; dent.d_reclen = (sizeof(struct dirent) - (MAXNAMLEN + 1) + TSD_RGD_MSK_5_3); dent.d_name[TSD_RGD_POS_0] = '.'; dent.d_name[TSD_RGD_POS_1] = '\0'; dent.d_namlen = 1; if ( dent.d_reclen > nbyte ) { err = E_PAR; goto err_ret1; } /* Writing of buffer record */ memcpy((UB*)buf, &dent, (size_t)dent.d_reclen); rdsize += dent.d_reclen; fpos++; } if ( fpos == 1U ) { dent.d_fileno = ROOT_INO; dent.d_type = DT_DIR; dent.d_reclen = (sizeof(struct dirent) - (MAXNAMLEN + 1) + TSD_RGD_MSK_6_3); dent.d_name[TSD_RGD_POS_0] = '.'; dent.d_name[TSD_RGD_POS_1] = '.'; dent.d_name[TSD_RGD_POS_2] = '\0'; dent.d_namlen = TSD_RGD_LEN_2; if (( rdsize + (W)dent.d_reclen )> (W)nbyte ) { if ( rdsize > 0 ) { fd->c.fpos = fpos; return rdsize; } else { err = E_PAR; goto err_ret1; } } /* Writing of buffer record */ memcpy((UB*)buf + rdsize, &dent, (size_t)dent.d_reclen); rdsize += dent.d_reclen; fpos++; } /* Acquisition of standard file system buffer */ bbuf = malloc(sizeof(F_ATTACH) * (UW)max); if ( bbuf == NULL ) { err = E_NOMEM; goto err_ret1; } for ( ;; ) { /* Acquisition of standard file system */ cnt = tkse_lst_fls(bbuf, max); if ( cnt < E_OK ) { err = cnt; goto err_ret2; } /* All connected file systems */ if ( cnt <= max ) { break; } /* Re-trial by expanding buffer */ max = cnt; temp = realloc(bbuf, sizeof(F_ATTACH) * (UW)max); if ( temp == NULL ) { free(bbuf); err = E_NOMEM; goto err_ret1; } bbuf = temp; } for ( i = 0; i < cnt; i++ ) { /* Skip reading till the location of file pointer */ if ( (W)fpos > (i + TSD_RGD_VAL_2 )) { continue; } dent.d_fileno = SROOT_INO; dent.d_type = DT_DIR; /* Connection name conversion */ tc_strncpy(connm, bbuf[i].a_name, L_CONNM); connm[L_CONNM] = TNULL; err = tcstoeucs((UB*)dent.d_name, bbuf[i].a_name); if ( err < E_OK ) { goto err_ret2; } dent.d_namlen = (UB)strlen(dent.d_name); dent.d_reclen = (sizeof(struct dirent) - (unsigned short)(MAXNAMLEN + 1)) + (((unsigned short)(dent.d_namlen + 1 + TSD_RGD_VAL_3) &~ TSD_RGD_MSK_3)); /* Check the remaining buffer size */ if (( rdsize + (W)dent.d_reclen) > (W)nbyte ) { if ( rdsize > 0 ) { break; } else { err = E_PAR; goto err_ret2; } } /* Writing of record into buffer */ memcpy((UB*)buf + rdsize, &dent, (size_t)dent.d_reclen); rdsize += dent.d_reclen; } /* Release the standard file system buffer */ free(bbuf); fd->c.fpos = (rdsize > 0)? (UW)(i + TSD_RGD_VAL_2): fd->c.fpos; if ( i < cnt ) { return rdsize; } /* Acquire the other connected file systems */ for ( q = FSQue.next; q != &FSQue; q = q->next, i++ ) { /* Skip reading till the location of file pointer*/ if ( (W)fpos >( i + TSD_RGD_VAL_2 )) { continue; } /* Acquisition of file system information */ fs = (FS*)q; dent.d_fileno = fs->rootino; dent.d_type = DT_DIR; strcpy(dent.d_name, fs->connm); dent.d_namlen = (UB)strlen(fs->connm); dent.d_reclen = (sizeof(struct dirent) - (unsigned short)(MAXNAMLEN + 1)) + (((unsigned short)(dent.d_namlen + 1 + TSD_RGD_VAL_3) &~ TSD_RGD_MSK_3)); /* Check the remaining buffer size */ if ( (rdsize + (W)dent.d_reclen) > (W)nbyte ) { if ( rdsize > 0 ) { break; } else { err = E_PAR; goto err_ret1; } } memcpy((UB*)buf + rdsize, &dent, (size_t)dent.d_reclen); rdsize += dent.d_reclen; } /* File pointer transfer */ fd->c.fpos = (rdsize > 0)? (UW)(i + TSD_RGD_VAL_2): fd->c.fpos; return rdsize;err_ret2: free(bbuf);err_ret1: DEBUG_PRINT(("rt_getdents err=%#x\n", err)); return err;}/* * ROOT file pointer transfer */EXPORT WER rt_lseek( FDPkt *fdp, long offset, int whence ){ RTFD *fd = (RTFD*)fdp->fd; F_ATTACH att; QUEUE *q; W fpos, ux, bt; ER err; switch ( whence ) { case SEEK_SET: fpos = offset; break; case SEEK_CUR: fpos = (W)(fd->c.fpos + (UW)offset); break; case SEEK_END: /* Count the number of file systems */ /* Standard file system */ bt = tkse_lst_fls(&att, 1); if ( bt < E_OK ) { err = bt; goto err_ret; } /* Others */ for ( q = FSQue.next, ux = 0; q != &FSQue; q = q->next, ux++) { ; } /* File size */ fpos = TSD_RLS_FPS_2 + bt + ux; break; default: err = E_PAR; goto err_ret; } if ( fpos < 0 ) { err = E_PAR; goto err_ret; } return (WER)(fd->c.fpos = (UW)fpos);err_ret: DEBUG_PRINT(("rt_lseek err=%#x\n", err)); return err;}/* * ROOT file open */EXPORT WER rt_open( FDPkt *fdp, int oflag, mode_t mode ){ RTFD *fd = (RTFD*)fdp->fd; ER err; /* Parameter check ( Read only) */ fd->c.omode = (UB)((UW)oflag & O_ACCMODE); if ( fd->c.omode != O_RDONLY ) { err = E_RONLY; goto err_ret; } if ( (((UW)oflag & O_CREAT) != 0) && (((UW)oflag & O_EXCL) != 0) ) { err = E_OBJ; goto err_ret; } return fdp->fdno;err_ret: DEBUG_PRINT(("rt_open err=%#x\n", err)); return err;}/* * ROOT file close */EXPORT ER rt_close( FDPkt *fdp ){ /* Do nothing */ return E_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -