/********************************************************************************************************* ** 函数名称: __buildinRtPrint ** 功能描述: 打印 lwip 内建路由信息 ** 输 入 : rt aodv 路由条目 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __buildinRtPrint (PCHAR pcBuffer, size_t stSize, size_t *pstOffset) { struct netif *netif; ip_addr_t ipaddr; CHAR cIpDest[INET_ADDRSTRLEN]; CHAR cGateway[INET_ADDRSTRLEN] = "*"; CHAR cMask[INET_ADDRSTRLEN]; CHAR cFlag[6]; CHAR cIfName[IF_NAMESIZE] = "\0"; for (netif = netif_list; netif != NULL; netif = netif->next) { if (netif->flags & NETIF_FLAG_POINTTOPOINT) { /* PPP / SLIP 连接 */ ipaddr.addr = netif->gw.addr; ipaddr_ntoa_r(&ipaddr, cIpDest, INET_ADDRSTRLEN); ipaddr_ntoa_r(&netif->netmask, cMask, INET_ADDRSTRLEN); if_indextoname(netif->num, cIfName); lib_strcpy(cFlag, "UH"); } else { /* 普通链接 */ ipaddr.addr = netif->ip_addr.addr & netif->netmask.addr; ipaddr_ntoa_r(&ipaddr, cIpDest, INET_ADDRSTRLEN); ipaddr_ntoa_r(&netif->netmask, cMask, INET_ADDRSTRLEN); if_indextoname(netif->num, cIfName); lib_strcpy(cFlag, "U"); } *pstOffset = bnprintf(pcBuffer, stSize, *pstOffset, "%-18s %-18s %-18s %-8s %-3s\n", cIpDest, cGateway, cMask, cFlag, cIfName); ipaddr_ntoa_r(&netif->ip_addr, cIpDest, INET_ADDRSTRLEN); lib_strcpy(cFlag, "UH"); *pstOffset = bnprintf(pcBuffer, stSize, *pstOffset, "%-18s %-18s %-18s %-8s %-3s\n", cIpDest, cGateway, cMask, cFlag, cIfName); } if (netif_default) { ipaddr_ntoa_r(&netif_default->gw, cGateway, INET_ADDRSTRLEN); ipaddr_ntoa_r(&netif_default->netmask, cMask, INET_ADDRSTRLEN); if_indextoname(netif_default->num, cIfName); lib_strcpy(cFlag, "UG"); *pstOffset = bnprintf(pcBuffer, stSize, *pstOffset, "%-18s %-18s %-18s %-8s %-3s\n", "default", cGateway, cMask, cFlag, cIfName); } }
VOID _HeapKernelInit (VOID) #endif /* LW_CFG_MEMORY_HEAP_... */ { #if LW_CFG_MEMORY_HEAP_CONFIG_TYPE > 0 _K_pheapKernel = _HeapCreate(pvKernelHeapMem, stKernelHeapSize); #else #if LW_CFG_MEMORY_KERNEL_HEAP_ADDRESS == 0 _K_pheapKernel = _HeapCreate((PVOID)_K_stkKernelHeap, LW_CFG_MEMORY_KERNEL_HEAP_SIZE_BYTE); #else _K_pheapKernel = _HeapCreate((PVOID)(LW_CFG_MEMORY_KERNEL_HEAP_ADDRESS), LW_CFG_MEMORY_KERNEL_HEAP_SIZE_BYTE); #endif #endif /* LW_CFG_MEMORY_HEAP_... */ #if (LW_CFG_DEVICE_EN > 0) && (LW_CFG_FIO_LIB_EN > 0) #if LW_CFG_ERRORMESSAGE_EN > 0 || LW_CFG_LOGMESSAGE_EN > 0 #if LW_CFG_MEMORY_HEAP_CONFIG_TYPE > 0 _DebugFormat(__LOGMESSAGE_LEVEL, "kernel heap has been create 0x%lx (%zd Bytes).\r\n", (addr_t)pvKernelHeapMem, stKernelHeapSize); #else _DebugFormat(__LOGMESSAGE_LEVEL, "kernel heap has been create 0x%lx (%zd Bytes).\r\n", (LW_CFG_MEMORY_KERNEL_HEAP_ADDRESS == 0) ? (addr_t)_K_stkKernelHeap : (addr_t)LW_CFG_MEMORY_KERNEL_HEAP_ADDRESS, (size_t)LW_CFG_MEMORY_KERNEL_HEAP_SIZE_BYTE); #endif /* LW_CFG_MEMORY_HEAP_... */ #endif /* LW_CFG_ERRORMESSAGE_EN... */ #endif /* LW_CFG_DEVICE_EN... */ lib_strcpy(_K_pheapKernel->HEAP_cHeapName, "kernel"); }
static VOID __rtEntryPrint (PLW_RT_ENTRY prte, PCHAR pcBuffer, size_t stSize, size_t *pstOffset) { CHAR cIpDest[INET_ADDRSTRLEN]; CHAR cGateway[INET_ADDRSTRLEN] = "*"; CHAR cMask[INET_ADDRSTRLEN] = "*"; CHAR cFlag[6] = "\0"; ipaddr_ntoa_r(&prte->RTE_ipaddrDest, cIpDest, INET_ADDRSTRLEN); if (prte->RTE_pnetif) { ipaddr_ntoa_r(&prte->RTE_pnetif->gw, cGateway, INET_ADDRSTRLEN); ipaddr_ntoa_r(&prte->RTE_pnetif->netmask, cMask, INET_ADDRSTRLEN); } if (prte->RTE_uiFlag & LW_RT_FLAG_U) { lib_strcat(cFlag, "U"); } if (prte->RTE_uiFlag & LW_RT_FLAG_G) { lib_strcat(cFlag, "G"); } else { lib_strcpy(cGateway, "*"); /* 直接路由 (不需要打印网关) */ } if (prte->RTE_uiFlag & LW_RT_FLAG_H) { lib_strcat(cFlag, "H"); } if (prte->RTE_uiFlag & LW_RT_FLAG_D) { lib_strcat(cFlag, "D"); } if (prte->RTE_uiFlag & LW_RT_FLAG_M) { lib_strcat(cFlag, "M"); } *pstOffset = bnprintf(pcBuffer, stSize, *pstOffset, "%-18s %-18s %-18s %-8s %-3s\n", cIpDest, cGateway, cMask, cFlag, prte->RTE_cNetifName); }
/********************************************************************************************************* ** 函数名称: __ram_move ** 功能描述: ramfs 移动或者重命名一个文件 ** 输 入 : pramn 文件节点 ** pcNewName 新的名字 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT __ram_move (PRAM_NODE pramn, PCHAR pcNewName) { PRAM_VOLUME pramfs; PRAM_NODE pramnTemp; PRAM_NODE pramnFather; PRAM_NODE pramnNewFather; BOOL bRoot; BOOL bLast; PCHAR pcTail; PCHAR pcTemp; PCHAR pcFileName; pramfs = pramn->RAMN_pramfs; pramnFather = pramn->RAMN_pramnFather; pramnTemp = __ram_open(pramfs, pcNewName, &pramnNewFather, &bRoot, &bLast, &pcTail); if (pramnTemp) { _ErrorHandle(EEXIST); return (PX_ERROR); } if (bRoot || (bLast == LW_FALSE)) { /* 新名字指向根或者没有目录 */ _ErrorHandle(EINVAL); return (PX_ERROR); } if (pramnFather != pramnNewFather) { /* 目录发生改变 */ if (pramnFather) { _List_Line_Del(&pramn->RAMN_lineBrother, &pramnFather->RAMN_plineSon); } else { _List_Line_Del(&pramn->RAMN_lineBrother, &pramfs->RAMFS_plineSon); } if (pramnNewFather) { _List_Line_Add_Ahead(&pramn->RAMN_lineBrother, &pramnNewFather->RAMN_plineSon); } else { _List_Line_Add_Ahead(&pramn->RAMN_lineBrother, &pramfs->RAMFS_plineSon); } } pcFileName = lib_rindex(pcNewName, PX_DIVIDER); if (pcFileName) { pcFileName++; } else { pcFileName = pcNewName; } pcTemp = (PCHAR)__SHEAP_ALLOC(lib_strlen(pcFileName) + 1); if (pcTemp == LW_NULL) { _ErrorHandle(ENOMEM); return (PX_ERROR); } lib_strcpy(pcTemp, pcFileName); __SHEAP_FREE(pramn->RAMN_pcName); pramn->RAMN_pcName = pcTemp; return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_TShellFormatAdd ** 功能描述: 为一个关键字添加格式字串信息 ** 输 入 : pcKeyword 关键字 ** pcFormat 格式字串 ** 输 出 : 错误代码. ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_TShellFormatAdd (CPCHAR pcKeyword, CPCHAR pcFormat) { __PTSHELL_KEYWORD pskwNode = LW_NULL; REGISTER size_t stStrLen; if (__PROC_GET_PID_CUR() != 0) { /* 进程中不允许操作 */ _ErrorHandle(ENOTSUP); return (ENOTSUP); } if (!pcKeyword) { _DebugHandle(__ERRORMESSAGE_LEVEL, "pcKeyword invalidate.\r\n"); _ErrorHandle(ERROR_TSHELL_EPARAM); return (ERROR_TSHELL_EPARAM); } if (!pcFormat) { _DebugHandle(__ERRORMESSAGE_LEVEL, "pcHelp invalidate.\r\n"); _ErrorHandle(ERROR_TSHELL_EPARAM); return (ERROR_TSHELL_EPARAM); } stStrLen = lib_strnlen(pcKeyword, LW_CFG_SHELL_MAX_KEYWORDLEN); if (stStrLen >= (LW_CFG_SHELL_MAX_KEYWORDLEN + 1)) { _DebugHandle(__ERRORMESSAGE_LEVEL, "pcKeyword is too long.\r\n"); _ErrorHandle(ERROR_TSHELL_EPARAM); return (ERROR_TSHELL_EPARAM); } if (ERROR_NONE == __tshellKeywordFind(pcKeyword, &pskwNode)) { /* 查找关键字 */ __TTINY_SHELL_LOCK(); /* 互斥访问 */ if (pskwNode->SK_pcFormatString) { __TTINY_SHELL_UNLOCK(); /* 释放资源 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "format string overlap.\r\n"); _ErrorHandle(ERROR_TSHELL_OVERLAP); return (ERROR_TSHELL_OVERLAP); } stStrLen = lib_strlen(pcFormat); /* 为帮助字串开辟空间 */ pskwNode->SK_pcFormatString = (PCHAR)__SHEAP_ALLOC(stStrLen + 1); if (!pskwNode->SK_pcFormatString) { _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\r\n"); _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); return (ERROR_SYSTEM_LOW_MEMORY); } lib_strcpy(pskwNode->SK_pcFormatString, pcFormat); __TTINY_SHELL_UNLOCK(); /* 释放资源 */ return (ERROR_NONE); } else { _ErrorHandle(ERROR_TSHELL_EKEYWORD); return (ERROR_TSHELL_EKEYWORD); /* 关键字错误 */ } }
VOID _HeapSystemInit (VOID) #endif /* LW_CFG_MEMORY_HEAP_... */ { #if LW_CFG_MEMORY_HEAP_CONFIG_TYPE > 0 if (pvSystemHeapMem && stSystemHeapSize) { _K_pheapSystem = _HeapCreate(pvSystemHeapMem, stSystemHeapSize); } else #else #if LW_CFG_MEMORY_SYSTEM_HEAP_ADDRESS == 0 if (LW_CFG_MEMORY_SYSTEM_HEAP_SIZE_BYTE) { _K_pheapSystem = _HeapCreate((PVOID)_K_stkSystemHeap, LW_CFG_MEMORY_SYSTEM_HEAP_SIZE_BYTE); } else #else if (LW_CFG_MEMORY_SYSTEM_HEAP_SIZE_BYTE) { _K_pheapSystem = _HeapCreate((PVOID)LW_CFG_MEMORY_SYSTEM_HEAP_ADDRESS, LW_CFG_MEMORY_SYSTEM_HEAP_SIZE_BYTE); } else #endif #endif /* LW_CFG_MEMORY_HEAP_... */ { _K_pheapSystem = _K_pheapKernel; /* 只使用 kernel heap */ } #if (LW_CFG_DEVICE_EN > 0) && (LW_CFG_FIO_LIB_EN > 0) #if (LW_CFG_ERRORMESSAGE_EN > 0) || (LW_CFG_LOGMESSAGE_EN > 0) #if LW_CFG_MEMORY_HEAP_CONFIG_TYPE > 0 _DebugFormat(__LOGMESSAGE_LEVEL, "system heap has been create 0x%lx (%zd Bytes).\r\n", (addr_t)pvSystemHeapMem, stSystemHeapSize); #else _DebugFormat(__LOGMESSAGE_LEVEL, "system heap has been create 0x%lx (%zd Bytes).\r\n", (LW_CFG_MEMORY_SYSTEM_HEAP_ADDRESS == 0) ? (addr_t)_K_stkSystemHeap : (addr_t)LW_CFG_MEMORY_SYSTEM_HEAP_ADDRESS, (size_t)LW_CFG_MEMORY_SYSTEM_HEAP_SIZE_BYTE); #endif /* LW_CFG_MEMORY_HEAP_... */ #endif /* LW_CFG_ERRORMESSAGE_EN... */ #endif /* LW_CFG_DEVICE_EN... */ if (_K_pheapSystem == _K_pheapKernel) { lib_strcpy(_K_pheapSystem->HEAP_cHeapName, "kersys"); } else { lib_strcpy(_K_pheapSystem->HEAP_cHeapName, "system"); } }
/********************************************************************************************************* ** 函数名称: __tshellTtyInputHistorySave ** 功能描述: shell 记录一条输入. ** 输 入 : psicContext 输入上下文 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __tshellHistorySave (__PSHELL_INPUT_CTX psicContext) { PLW_CLASS_TCB ptcbCur; __PSHELL_HISTORY_CTX psihc; __PSHELL_HISTORY psihHistory; PLW_LIST_RING pring; LW_TCB_GET_CUR_SAFE(ptcbCur); psihc = __TTINY_SHELL_GET_HIS(ptcbCur); pring = psihc->SIHC_pringHeader; while (pring) { /* 循环查找是否与以前的相同 */ psihHistory = _LIST_ENTRY(pring, __SHELL_HISTORY, SIH_ringManage); if (lib_strcmp(psihHistory->SIH_cInputSave, CTX_BUFFER) == 0) { /* 如果相同 */ if (pring == psihc->SIHC_pringHeader) { return; /* 如果是表头, 则不需要处理 */ } else { _List_Ring_Del(&psihHistory->SIH_ringManage, &psihc->SIHC_pringHeader); _List_Ring_Add_Ahead(&psihHistory->SIH_ringManage, &psihc->SIHC_pringHeader); /* 放在表头位置 */ return; } } pring = _list_ring_get_next(pring); if (pring == psihc->SIHC_pringHeader) { break; } } psihHistory = (__PSHELL_HISTORY)__SHEAP_ALLOC(sizeof(__SHELL_HISTORY) + lib_strlen(CTX_BUFFER)); if (psihHistory) { lib_strcpy(psihHistory->SIH_cInputSave, CTX_BUFFER); _List_Ring_Add_Ahead(&psihHistory->SIH_ringManage, &psihc->SIHC_pringHeader); /* 加入新的输入 */ psihc->SIHC_uiCounter++; if (psihc->SIHC_uiCounter > __INPUT_SAVE_MAX) { /* 需要删除最老的一条 */ PLW_LIST_RING pringPrev = _list_ring_get_prev(psihc->SIHC_pringHeader); psihHistory = _LIST_ENTRY(pringPrev, __SHELL_HISTORY, SIH_ringManage); _List_Ring_Del(&psihHistory->SIH_ringManage, &psihc->SIHC_pringHeader); __SHEAP_FREE(psihHistory); psihc->SIHC_uiCounter--; } } }
LW_API ULONG API_RmsGetName (LW_OBJECT_HANDLE ulId, PCHAR pcName) { REGISTER PLW_CLASS_RMS prms; REGISTER UINT16 usIndex; usIndex = _ObjectGetIndex(ulId); if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n"); _ErrorHandle(ERROR_KERNEL_IN_ISR); return (ERROR_KERNEL_IN_ISR); } #if LW_CFG_ARG_CHK_EN > 0 if (!pcName) { _DebugHandle(__ERRORMESSAGE_LEVEL, "name invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_PNAME_NULL); return (ERROR_KERNEL_PNAME_NULL); } if (!_ObjectClassOK(ulId, _OBJECT_RMS)) { /* 对象类型检查 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } if (_Rms_Index_Invalid(usIndex)) { /* 缓冲区索引检查 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n"); _ErrorHandle(ERROR_KERNEL_HANDLE_NULL); return (ERROR_KERNEL_HANDLE_NULL); } __KERNEL_ENTER(); /* 进入内核 */ if (_Rms_Type_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "RMS handle invalidate.\r\n"); _ErrorHandle(ERROR_RMS_NULL); return (ERROR_RMS_NULL); } #else __KERNEL_ENTER(); /* 进入内核 */ #endif prms = &_K_rmsBuffer[usIndex]; lib_strcpy(pcName, prms->RMS_cRmsName); __KERNEL_EXIT(); /* 退出内核 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __procFssupRootfsRead ** 功能描述: procfs 读一个根文件系统支持信息 proc 文件 ** 输 入 : p_pfsn 节点控制块 ** pcBuffer 缓冲区 ** stMaxBytes 缓冲区大小 ** oft 文件指针 ** 输 出 : 实际读取的数目 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static ssize_t __procFssupRead (PLW_PROCFS_NODE p_pfsn, PCHAR pcBuffer, size_t stMaxBytes, off_t oft) { REGISTER PCHAR pcFileBuffer; size_t stRealSize; /* 实际的文件内容大小 */ size_t stCopeBytes; /* * 程序运行到这里, 文件缓冲一定已经分配了预置的内存大小(创建节点时预置大小为 64 字节). */ pcFileBuffer = (PCHAR)API_ProcFsNodeBuffer(p_pfsn); if (pcFileBuffer == LW_NULL) { _ErrorHandle(ENOMEM); return (0); } stRealSize = API_ProcFsNodeGetRealFileSize(p_pfsn); if (stRealSize == 0) { /* 需要生成文件 */ lib_strcpy(pcFileBuffer, "rootfs procfs ramfs romfs "); #if LW_CFG_FATFS_EN > 0 lib_strlcat(pcFileBuffer, "vfat ", __PROCFS_BUFFER_SIZE_FSSUP); #endif /* LW_CFG_FATFS_EN */ #if LW_CFG_NFS_EN > 0 lib_strlcat(pcFileBuffer, "nfs ", __PROCFS_BUFFER_SIZE_FSSUP); #endif /* LW_CFG_NFS_EN */ #if LW_CFG_YAFFS_EN > 0 lib_strlcat(pcFileBuffer, "yaffs ", __PROCFS_BUFFER_SIZE_FSSUP); #endif /* LW_CFG_YAFFS_EN */ stRealSize = lib_strlen(pcFileBuffer); API_ProcFsNodeSetRealFileSize(p_pfsn, stRealSize); } if (oft >= stRealSize) { _ErrorHandle(ENOSPC); return (0); } stCopeBytes = __MIN(stMaxBytes, (size_t)(stRealSize - oft)); /* 计算实际拷贝的字节数 */ lib_memcpy(pcBuffer, (CPVOID)(pcFileBuffer + oft), (UINT)stCopeBytes); return ((ssize_t)stCopeBytes); }
/********************************************************************************************************* ** 函数名称: API_OemDiskMountEx2 ** 功能描述: 自动挂载一个磁盘的所有分区. 可以使用指定的文件系统类型挂载 ** 输 入 : pcVolName 根节点名字 (当前 API 将根据分区情况在末尾加入数字) ** pblkdDisk 物理磁盘控制块 (必须是直接操作物理磁盘) ** pvDiskCacheMem 磁盘 CACHE 缓冲区的内存起始地址 (为零表示动态分配磁盘缓冲) ** stMemSize 磁盘 CACHE 缓冲区大小 (为零表示不需要 DISK CACHE) ** iMaxRBurstSector 磁盘猝发读的最大扇区数 ** iMaxWBurstSector 磁盘猝发写的最大扇区数 ** pcFsName 文件系统类型, 例如: "vfat" "tpsfs" "iso9660" "ntfs" ... ** bForceFsType 是否强制使用指定的文件系统类型 ** 输 出 : OEM 磁盘控制块 ** 全局变量: ** 调用模块: ** 注 意 : 挂载的文件系统不包含 yaffs 文件系统, yaffs 属于静态文件系统. API 函数 *********************************************************************************************************/ LW_API PLW_OEMDISK_CB API_OemDiskMountEx2 (CPCHAR pcVolName, PLW_BLK_DEV pblkdDisk, PVOID pvDiskCacheMem, size_t stMemSize, INT iMaxRBurstSector, INT iMaxWBurstSector, CPCHAR pcFsName, BOOL bForceFsType) { INT i; INT iErrLevel = 0; REGISTER ULONG ulError; CHAR cFullVolName[MAX_FILENAME_LENGTH]; /* 完整卷标名 */ INT iBlkIo; INT iBlkIoErr; PCHAR pcTail; INT iVolSeq; REGISTER INT iNPart; DISKPART_TABLE dptPart; /* 分区表 */ PLW_OEMDISK_CB poemd; FUNCPTR pfuncFsCreate; /* * 挂载节点名检查 */ if (pcVolName == LW_NULL || *pcVolName != PX_ROOT) { /* 名字错误 */ _ErrorHandle(EINVAL); return (LW_NULL); } i = (INT)lib_strnlen(pcVolName, (PATH_MAX - __OEM_DISK_TAIL_LEN)); if (i >= (PATH_MAX - __OEM_DISK_TAIL_LEN)) { /* 名字过长 */ _ErrorHandle(ERROR_IO_NAME_TOO_LONG); return (LW_NULL); } /* * 分配 OEM 磁盘控制块内存 */ poemd = (PLW_OEMDISK_CB)__SHEAP_ALLOC(sizeof(LW_OEMDISK_CB) + (size_t)i); if (poemd == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\r\n"); _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); return (LW_NULL); } lib_bzero(poemd, sizeof(LW_OEMDISK_CB) + i); /* 清空 */ poemd->OEMDISK_pblkdDisk = pblkdDisk; /* * 分配磁盘缓冲内存 */ if ((pvDiskCacheMem == LW_NULL) && (stMemSize > 0)) { /* 是否需要动态分配磁盘缓冲 */ poemd->OEMDISK_pvCache = __SHEAP_ALLOC(stMemSize); if (poemd->OEMDISK_pvCache == LW_NULL) { _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); /* 系统缺少内存 */ goto __error_handle; } pvDiskCacheMem = poemd->OEMDISK_pvCache; } /* * 创建物理磁盘缓冲, 同时会初始化磁盘 */ if (stMemSize) { ulError = API_DiskCacheCreateEx(pblkdDisk, pvDiskCacheMem, stMemSize, iMaxRBurstSector, iMaxWBurstSector, &poemd->OEMDISK_pblkdCache); if (ulError) { iErrLevel = 1; goto __error_handle; } } else { poemd->OEMDISK_pblkdCache = pblkdDisk; /* 不需要磁盘缓冲 */ } /* * 创建 blk io 设备 */ pcTail = lib_rindex(pcVolName, PX_DIVIDER); if (pcTail == LW_NULL) { pcTail = (PCHAR)pcVolName; } else { pcTail++; } for (iBlkIo = 0; iBlkIo < 64; iBlkIo++) { snprintf(cFullVolName, MAX_FILENAME_LENGTH, "%s%s%d", LW_BLKIO_PERFIX, pcTail, iBlkIo); if (API_IosDevMatchFull(cFullVolName) == LW_NULL) { iBlkIoErr = API_OemBlkIoCreate(cFullVolName, poemd->OEMDISK_pblkdCache); if (iBlkIoErr == ERROR_NONE) { break; } else if (errno != ERROR_IOS_DUPLICATE_DEVICE_NAME) { iErrLevel = 2; goto __error_handle; } } } /* * 扫面磁盘所有分区信息 */ iNPart = API_DiskPartitionScan(poemd->OEMDISK_pblkdCache, &dptPart); /* 扫描分区表 */ if (iNPart < 1) { iErrLevel = 3; goto __error_handle; } poemd->OEMDISK_uiNPart = (UINT)iNPart; /* 记录分区数量 */ /* * 初始化所有的分区挂载失败 */ for (i = 0; i < iNPart; i++) { poemd->OEMDISK_iVolSeq[i] = PX_ERROR; /* 默认为挂载失败 */ } /* * 分别挂载各个分区 */ iVolSeq = 0; for (i = 0; i < iNPart; i++) { /* 装载各个分区 */ if (API_DiskPartitionGet(&dptPart, i, &poemd->OEMDISK_pblkdPart[i]) < 0) { /* 获得分区 logic device */ break; } __refined_seq: sprintf(cFullVolName, "%s%d", pcVolName, iVolSeq); /* 获得完整卷名 */ if (API_IosDevMatchFull(cFullVolName)) { /* 设备名重名预判 */ iVolSeq++; goto __refined_seq; /* 重新确定卷序号 */ } pfuncFsCreate = LW_NULL; switch (dptPart.DPT_dpoLogic[i].DPO_dpnEntry.DPN_ucPartType) { /* 判断文件系统分区类型 */ case LW_DISK_PART_TYPE_FAT12: /* FAT 文件系统类型 */ case LW_DISK_PART_TYPE_FAT16: case LW_DISK_PART_TYPE_FAT16_BIG: case LW_DISK_PART_TYPE_WIN95_FAT32: case LW_DISK_PART_TYPE_WIN95_FAT32LBA: case LW_DISK_PART_TYPE_WIN95_FAT16LBA: if (bForceFsType) { /* 是否强制指定文件系统类型 */ pfuncFsCreate = __fsCreateFuncGet(pcFsName); } else { pfuncFsCreate = __fsCreateFuncGet("vfat"); } break; case LW_DISK_PART_TYPE_TPS: if (bForceFsType) { /* 是否强制指定文件系统类型 */ pfuncFsCreate = __fsCreateFuncGet(pcFsName); } else { pfuncFsCreate = __fsCreateFuncGet("tpsfs"); } break; default: /* 默认使用指定文件系统类型 */ if (bForceFsType) { /* 是否强制指定文件系统类型 */ pfuncFsCreate = __fsCreateFuncGet(pcFsName); } break; } if (pfuncFsCreate) { /* 存在支持的文件系统 */ if (pfuncFsCreate(cFullVolName, poemd->OEMDISK_pblkdPart[i]) < 0) { /* 挂载文件系统 */ if (API_GetLastError() == ERROR_IOS_DUPLICATE_DEVICE_NAME) { iVolSeq++; goto __refined_seq; /* 重新确定卷序号 */ } else { goto __mount_over; /* 挂载失败 */ } } poemd->OEMDISK_pdevhdr[i] = API_IosDevMatchFull(cFullVolName); poemd->OEMDISK_iVolSeq[i] = iVolSeq; /* 记录卷序号 */ } else { continue; /* 此分区无法加载 */ } if (poemd->OEMDISK_iVolSeq[i] >= 0) { __oemDiskForceDeleteEn(cFullVolName); /* 默认为强制删除 */ } iVolSeq++; /* 已处理完当前卷 */ } __mount_over: /* 所有分区挂载完毕 */ lib_strcpy(poemd->OEMDISK_cVolName, pcVolName); /* 拷贝名字 */ return (poemd); __error_handle: if (iErrLevel > 2) { if (poemd->OEMDISK_pblkdCache) { API_OemBlkIoDelete(poemd->OEMDISK_pblkdCache); } } if (iErrLevel > 1) { if (poemd->OEMDISK_pblkdCache != pblkdDisk) { API_DiskCacheDelete(poemd->OEMDISK_pblkdCache); } } if (iErrLevel > 0) { if (poemd->OEMDISK_pvCache) { __SHEAP_FREE(poemd->OEMDISK_pvCache); } } __SHEAP_FREE(poemd); return (LW_NULL); }
/* * Open a network file */ CVmNetFile *CVmNetFile::open(VMG_ const vm_val_t *val, const vm_rcdesc *rc, int mode, os_filetype_t typ, const char *mime_type) { vm_val_t filespec; /* check for a TadsObject implementing getFilename */ if (G_predef->filespec_getFilename != VM_INVALID_PROP && val->typ == VM_OBJ && CVmObjTads::is_tadsobj_obj(vmg_ val->val.obj)) { /* call getFilename - the return value is the file spec */ G_interpreter->get_prop( vmg_ 0, val, G_predef->filespec_getFilename, val, 0, rc); /* the result is the real file spec */ filespec = *G_interpreter->get_r0(); } else { /* it's not a TadsObject, so it must directly have the file name */ filespec = *val; } /* check the argument type */ CVmNetFile *nf = 0; if (filespec.typ == VM_OBJ && CVmObjTemporaryFile::is_tmpfil_obj(vmg_ filespec.val.obj)) { /* temporary file object - get the object, properly cast */ CVmObjTemporaryFile *tmp = (CVmObjTemporaryFile *)vm_objp( vmg_ filespec.val.obj); /* if the temporary file object is invalid, it's an error */ if (tmp->get_fname() == 0) err_throw(VMERR_CREATE_FILE); /* create the local file descriptor for the temp file path */ nf = open_local(vmg_ tmp->get_fname(), 0, mode, typ); /* mark it as a temp file */ nf->is_temp = TRUE; } else { /* anything else has to be a string */ char fname[OSFNMAX]; CVmBif::get_str_val_fname(vmg_ fname, sizeof(fname), CVmBif::get_str_val(vmg_ &filespec)); /* * if it's a local file, and it has a relative path, explicitly * apply the image file path as the default working directory */ if (!os_is_file_absolute(fname) && !is_net_mode(vmg0_)) { /* build the full, absolute name based on the image file path */ char fname_abs[OSFNMAX]; os_build_full_path(fname_abs, sizeof(fname_abs), G_image_loader->get_path(), fname); /* replace the relative path with the new absolute path */ lib_strcpy(fname, sizeof(fname), fname_abs); } /* create the regular network file descriptor */ nf = open(vmg_ fname, 0, mode, typ, mime_type); } /* if they gave us an object as our file spec, remember it */ if (nf != 0 && val->typ == VM_OBJ) nf->filespec = val->val.obj; /* return the network file descriptor */ return nf; }
/* * Open a network file */ CVmNetFile *CVmNetFile::open(VMG_ const vm_val_t *val, const vm_rcdesc *rc, int mode, os_filetype_t typ, const char *mime_type) { vm_val_t filespec; /* check for a TadsObject implementing getFilename */ if (G_predef->filespec_getFilename != VM_INVALID_PROP && vm_val_cast_ok(CVmObjTads, val)) { /* call getFilename - the return value is the file spec */ G_interpreter->get_prop( vmg_ 0, val, G_predef->filespec_getFilename, val, 0, rc); /* the result is the real file spec */ filespec = *G_interpreter->get_r0(); } else { /* it's not a TadsObject, so it must directly have the file name */ filespec = *val; } /* check the file spec argument type */ CVmNetFile *nf = 0; CVmObjTemporaryFile *tmp = 0; CVmObjFileName *ofn = 0; if ((tmp = vm_val_cast(CVmObjTemporaryFile, &filespec)) != 0) { /* if the temporary file object is invalid, it's an error */ if (tmp->get_fname() == 0) err_throw(VMERR_CREATE_FILE); /* create the local file descriptor for the temp file path */ nf = open_local(vmg_ tmp->get_fname(), 0, mode, typ); /* mark it as a temp file */ nf->is_temp = TRUE; } else if (filespec.is_numeric(vmg0_) || ((ofn = vm_val_cast(CVmObjFileName, &filespec)) != 0 && ofn->is_special_file())) { /* * It's a special file ID, either as an integer or as a FileName * wrapping a special file int. Get the value. */ int32_t sfid = (ofn != 0 ? ofn->get_sfid() : filespec.num_to_int(vmg0_)); /* resolve the file system path for the given special file ID */ char fname[OSFNMAX] = { '\0' }; if (!CVmObjFile::sfid_to_path(vmg_ fname, sizeof(fname), sfid)) err_throw(VMERR_BAD_VAL_BIF); /* create the special file descriptor */ nf = open(vmg_ fname, sfid, mode, typ, mime_type); } else { /* anything else has to be a string */ char fname[OSFNMAX]; CVmBif::get_fname_val(vmg_ fname, sizeof(fname), &filespec); /* * if it's a local file, and it has a relative path, explicitly * apply the image file path as the default working directory */ if (!os_is_file_absolute(fname) && !is_net_mode(vmg0_)) { /* build the full, absolute name based on the file base path */ char fnabs[OSFNMAX]; os_build_full_path(fnabs, sizeof(fnabs), G_file_path, fname); /* replace the relative path with the new absolute path */ lib_strcpy(fname, sizeof(fname), fnabs); } /* create the regular network file descriptor */ nf = open(vmg_ fname, 0, mode, typ, mime_type); } /* if they gave us an object as our file spec, remember it */ if (nf != 0 && val->typ == VM_OBJ) nf->filespec = val->val.obj; /* return the network file descriptor */ return nf; }
/********************************************************************************************************* ** 函数名称: __romFsReadDir ** 功能描述: romFs 获得指定目录信息 ** 输 入 : pfdentry 文件控制块 ** dir 目录结构 ** 输 出 : < 0 表示错误 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __romFsReadDir (PLW_FD_ENTRY pfdentry, DIR *dir) { PLW_FD_NODE pfdnode = (PLW_FD_NODE)pfdentry->FDENTRY_pfdnode; PROM_FILE promfile = (PROM_FILE)pfdnode->FDNODE_pvFile; ROMFS_DIRENT romfsdnt; INT iError; if (!dir) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (promfile->ROMFIL_iFileType == __ROMFS_FILE_TYPE_NODE) { _ErrorHandle(ENOTDIR); return (PX_ERROR); } if (dir->dir_pos == 0) { if (promfile->ROMFIL_iFileType == __ROMFS_FILE_TYPE_DEV) { promfile->ROMFIL_ulCookieDir = promfile->ROMFIL_promfs->ROMFS_uiRootAddr; } else if (promfile->ROMFIL_iFileType == __ROMFS_FILE_TYPE_DIR) { if (promfile->ROMFIL_romfsdnt.ROMFSDNT_uiSpec == promfile->ROMFIL_romfsdnt.ROMFSDNT_uiMe) { promfile->ROMFIL_ulCookieDir = 0; /* 此目录下没有文件 */ } else { promfile->ROMFIL_ulCookieDir = promfile->ROMFIL_romfsdnt.ROMFSDNT_uiSpec; } } else { _ErrorHandle(ENOTDIR); return (PX_ERROR); } } __get_next: if (promfile->ROMFIL_ulCookieDir == 0) { /* 遍历结束 */ _ErrorHandle(ENOENT); return (PX_ERROR); } if (__ROMFS_FILE_LOCK(promfile) != ERROR_NONE) { _ErrorHandle(ENXIO); return (PX_ERROR); } if (__rfs_getfile(promfile->ROMFIL_promfs, promfile->ROMFIL_ulCookieDir, &romfsdnt)) { __ROMFS_FILE_UNLOCK(promfile); return (PX_ERROR); } __ROMFS_FILE_UNLOCK(promfile); if ((lib_strcmp(romfsdnt.ROMFSDNT_cName, ".") == 0) || (lib_strcmp(romfsdnt.ROMFSDNT_cName, "..") == 0)) { /* 忽略 . 和 .. */ promfile->ROMFIL_ulCookieDir = romfsdnt.ROMFSDNT_uiNext; /* 记录下一个位置 */ goto __get_next; } lib_strcpy(dir->dir_dirent.d_name, romfsdnt.ROMFSDNT_cName); dir->dir_dirent.d_shortname[0] = PX_EOS; /* 不支持短文件名 */ dir->dir_dirent.d_type = IFTODT(romfsdnt.ROMFSDNT_stat.st_mode); dir->dir_pos++; iError = ERROR_NONE; promfile->ROMFIL_ulCookieDir = romfsdnt.ROMFSDNT_uiNext; /* 记录下一个位置 */ return (iError); }
/********************************************************************************************************* ** 函数名称: __romFsOpen ** 功能描述: 打开或者创建文件 ** 输 入 : promfs romfs 文件系统 ** pcName 文件名 ** iFlags 方式 ** iMode mode_t ** 输 出 : < 0 错误 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static LONG __romFsOpen (PROM_VOLUME promfs, PCHAR pcName, INT iFlags, INT iMode) { INT iError; PROM_FILE promfile; PLW_FD_NODE pfdnode; size_t stSize; BOOL bIsNew; struct stat *pstat; INT iFollowLinkType; PCHAR pcTail, pcSymfile, pcPrefix; if (pcName == LW_NULL) { /* 无文件名 */ _ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH); return (PX_ERROR); } else { stSize = sizeof(ROM_FILE) + lib_strlen(pcName); promfile = (PROM_FILE)__SHEAP_ALLOC(stSize); if (promfile == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\r\n"); _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); return (PX_ERROR); } lib_bzero(promfile, stSize); lib_strcpy(promfile->ROMFIL_cName, pcName); /* 记录文件名 */ promfile->ROMFIL_promfs = promfs; if (__ROMFS_VOL_LOCK(promfs) != ERROR_NONE) { _ErrorHandle(ENXIO); return (PX_ERROR); } if (__STR_IS_ROOT(promfile->ROMFIL_cName)) { promfile->ROMFIL_iFileType = __ROMFS_FILE_TYPE_DEV; goto __file_open_ok; /* 设备打开正常 */ } if (promfs->ROMFS_bValid == LW_FALSE) { __ROMFS_VOL_UNLOCK(promfs); __SHEAP_FREE(promfile); _ErrorHandle(ERROR_IOS_DEVICE_NOT_FOUND); return (PX_ERROR); } iError = __rfs_open(promfs, pcName, &pcTail, &pcSymfile, &promfile->ROMFIL_romfsdnt); if (iError) { __ROMFS_VOL_UNLOCK(promfs); __SHEAP_FREE(promfile); if (iFlags & O_CREAT) { _ErrorHandle(EROFS); /* 只读文件系统 */ } return (PX_ERROR); } /* * 首先处理符号链接文件情况 */ if (S_ISLNK(promfile->ROMFIL_romfsdnt.ROMFSDNT_stat.st_mode)) { pcSymfile--; /* 从 / 开始 */ if (pcSymfile == pcName) { pcPrefix = LW_NULL; /* 没有前缀 */ } else { pcPrefix = pcName; *pcSymfile = PX_EOS; } if (pcTail && lib_strlen(pcTail)) { iFollowLinkType = FOLLOW_LINK_TAIL; /* 连接目标内部文件 */ } else { iFollowLinkType = FOLLOW_LINK_FILE; /* 链接文件本身 */ } if (__rfs_path_build_link(promfs, &promfile->ROMFIL_romfsdnt, pcName, PATH_MAX + 1, pcPrefix, pcTail) == ERROR_NONE) { /* 构造链接目标 */ __ROMFS_VOL_UNLOCK(promfs); __SHEAP_FREE(promfile); return (iFollowLinkType); } else { /* 构造连接失败 */ __ROMFS_VOL_UNLOCK(promfs); __SHEAP_FREE(promfile); return (PX_ERROR); } } else if (S_ISDIR(promfile->ROMFIL_romfsdnt.ROMFSDNT_stat.st_mode)) { promfile->ROMFIL_iFileType = __ROMFS_FILE_TYPE_DIR; } else { promfile->ROMFIL_iFileType = __ROMFS_FILE_TYPE_NODE; } __file_open_ok: pstat = &promfile->ROMFIL_romfsdnt.ROMFSDNT_stat; pfdnode = API_IosFdNodeAdd(&promfs->ROMFS_plineFdNodeHeader, pstat->st_dev, (ino64_t)pstat->st_ino, iFlags, iMode, pstat->st_uid, pstat->st_gid, pstat->st_size, (PVOID)promfile, &bIsNew); /* 添加文件节点 */ if (pfdnode == LW_NULL) { /* 无法创建 fd_node 节点 */ __ROMFS_VOL_UNLOCK(promfs); __SHEAP_FREE(promfile); return (PX_ERROR); } LW_DEV_INC_USE_COUNT(&promfs->ROMFS_devhdrHdr); /* 更新计数器 */ __ROMFS_VOL_UNLOCK(promfs); if (bIsNew == LW_FALSE) { /* 有重复打开 */ __SHEAP_FREE(promfile); } return ((LONG)pfdnode); /* 返回文件节点 */ } return (PX_ERROR); }
LW_API INT API_HotplugEventMessage (INT iMsg, BOOL bInsert, CPCHAR pcPath, UINT32 uiArg0, UINT32 uiArg1, UINT32 uiArg2, UINT32 uiArg3) { size_t i; UCHAR ucBuffer[LW_HOTPLUG_DEV_MAX_MSGSIZE]; if (pcPath == LW_NULL) { i = 0; } else { i = lib_strlen(pcPath); if (i > PATH_MAX) { _ErrorHandle(ENAMETOOLONG); return (PX_ERROR); } } ucBuffer[0] = (UCHAR)((iMsg >> 24) & 0xff); ucBuffer[1] = (UCHAR)((iMsg >> 16) & 0xff); ucBuffer[2] = (UCHAR)((iMsg >> 8) & 0xff); ucBuffer[3] = (UCHAR)((iMsg) & 0xff); ucBuffer[4] = (UCHAR)bInsert; if (pcPath) { lib_strcpy((PCHAR)&ucBuffer[5], pcPath); } else { ucBuffer[5] = PX_EOS; } i += 6; /* 包含最后的 \0 */ ucBuffer[i++] = (UCHAR)((uiArg0 >> 24) & 0xff); /* MSB */ ucBuffer[i++] = (UCHAR)((uiArg0 >> 16) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg0 >> 8) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg0) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg1 >> 24) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg1 >> 16) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg1 >> 8) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg1) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg2 >> 24) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg2 >> 16) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg2 >> 8) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg2) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg3 >> 24) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg3 >> 16) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg3 >> 8) & 0xff); ucBuffer[i++] = (UCHAR)((uiArg3) & 0xff); _hotplugDevPutMsg(iMsg, ucBuffer, i); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __tshellFileMatch ** 功能描述: shell 根据当前输入情况进行匹配. ** 输 入 : iFd 文件描述符 ** pcDir 文件夹 ** pcFileName 文件名 ** psicContext 当前输入上下文 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __tshellFileMatch (INT iFd, PCHAR pcDir, PCHAR pcFileName, __PSHELL_INPUT_CTX psicContext) { #define __TSHELL_BYTES_PERLINE 80 /* 单行 80 字符 */ #define __TSHELL_BYTES_PERFILE 16 /* 每个文件名显示格长度 */ UINT uiMath = 0; BOOL bMathPrint = LW_FALSE; INT iError; size_t stPrintLen; size_t stTotalLen = 0; size_t stPad; size_t stFileNameLen = lib_strlen(pcFileName); CHAR cStat[MAX_FILENAME_LENGTH]; struct stat statGet; struct winsize winsz; struct dirent direntcMatch; struct dirent *pdirent; DIR *pdir = opendir(pcDir); /* 无法打开目录 */ size_t stDirLen; size_t stMinSimilar = 0; size_t stSimilar; if (pdir == LW_NULL) { return; } if (ioctl(STD_OUT, TIOCGWINSZ, &winsz)) { /* 获得窗口信息 */ winsz.ws_col = __TSHELL_BYTES_PERLINE; } else { winsz.ws_col = (unsigned short)ROUND_DOWN(winsz.ws_col, __TSHELL_BYTES_PERFILE); } stDirLen = lib_strlen(pcDir); do { pdirent = readdir(pdir); if (pdirent) { if ((stFileNameLen == 0) || (lib_strncmp(pcFileName, pdirent->d_name, stFileNameLen) == 0)) { uiMath++; if (uiMath > 1) { /* 只打印匹配结果 */ if (uiMath == 2) { printf("\n"); /* 换行 */ } stSimilar = __similarLen(direntcMatch.d_name, pdirent->d_name); if (stSimilar < stMinSimilar) { stMinSimilar = stSimilar; /* 保存最小相似度 */ } __print_dirent: if (pcDir[stDirLen - 1] != PX_DIVIDER) { snprintf(cStat, MAX_FILENAME_LENGTH, "%s/%s", pcDir, pdirent->d_name); } else { snprintf(cStat, MAX_FILENAME_LENGTH, "%s%s", pcDir, pdirent->d_name); } iError = stat(cStat, &statGet); if (iError < 0) { statGet.st_mode = DEFAULT_FILE_PERM | S_IFCHR; /* 默认属性 */ } if (S_ISDIR(statGet.st_mode)) { lib_strlcat(pdirent->d_name, PX_STR_DIVIDER, MAX_FILENAME_LENGTH); } API_TShellColorStart(pdirent->d_name, "", statGet.st_mode, STD_OUT); stPrintLen = printf("%-15s ", pdirent->d_name); /* 打印文件名 */ if (stPrintLen > __TSHELL_BYTES_PERFILE) { stPad = ROUND_UP(stPrintLen, __TSHELL_BYTES_PERFILE) - stPrintLen; /* 计算填充数量 */ __fillWhite(stPad); } else { stPad = 0; } stTotalLen += stPrintLen + stPad; API_TShellColorEnd(STD_OUT); if (stTotalLen >= winsz.ws_col) { printf("\n"); /* 换行 */ stTotalLen = 0; } if (bMathPrint == LW_FALSE) { /* 是否也需要把第一次匹配的打印*/ bMathPrint = LW_TRUE; pdirent = &direntcMatch; goto __print_dirent; } else { /* 否则记录上一次的结果 */ lib_strcpy(direntcMatch.d_name, pdirent->d_name); } } else { direntcMatch = *pdirent; /* 记录第一次 math 的节点 */ stMinSimilar = lib_strlen(pdirent->d_name); } } } } while (pdirent); closedir(pdir); if (uiMath > 1) { /* 多个匹配 */ if (stTotalLen) { printf("\n"); /* 结束本行 */ } __tshellShowPrompt(); /* 显示命令提示符 */ if (stMinSimilar > stFileNameLen) { direntcMatch.d_name[stMinSimilar] = PX_EOS; /* 自动匹配输入至相似处 */ lib_strlcat(CTX_BUFFER, &direntcMatch.d_name[stFileNameLen], LW_CFG_SHELL_MAX_COMMANDLEN); CTX_TOTAL = lib_strlen(CTX_BUFFER); CTX_CURSOR = CTX_TOTAL; } write(iFd, CTX_BUFFER, CTX_TOTAL); } else if (uiMath == 1) { /* 仅有一个匹配 */ size_t stCatLen; if (pcDir[stDirLen - 1] != PX_DIVIDER) { snprintf(cStat, MAX_FILENAME_LENGTH, "%s/%s", pcDir, direntcMatch.d_name); } else { snprintf(cStat, MAX_FILENAME_LENGTH, "%s%s", pcDir, direntcMatch.d_name); } iError = stat(cStat, &statGet); if (iError < 0) { statGet.st_mode = DEFAULT_FILE_PERM | S_IFCHR; /* 默认属性 */ } if (S_ISDIR(statGet.st_mode)) { /* 如果是目录 */ lib_strlcat(direntcMatch.d_name, PX_STR_DIVIDER, MAX_FILENAME_LENGTH); /* 加一个目录结束符 */ } stCatLen = lib_strlen(direntcMatch.d_name) - stFileNameLen; write(iFd, &direntcMatch.d_name[stFileNameLen], stCatLen); lib_strlcat(CTX_BUFFER, &direntcMatch.d_name[stFileNameLen], LW_CFG_SHELL_MAX_COMMANDLEN); CTX_TOTAL += (UINT)stCatLen; CTX_CURSOR = CTX_TOTAL; } }
/********************************************************************************************************* ** 函数名称: __ram_maken ** 功能描述: ramfs 创建一个文件 ** 输 入 : pramfs 文件系统 ** pcName 文件名 ** pramnFather 父亲, NULL 表示根目录 ** mode mode_t ** pcLink 如果为连接文件, 这里指明连接目标. ** 输 出 : 创建结果 ** 全局变量: ** 调用模块: *********************************************************************************************************/ PRAM_NODE __ram_maken (PRAM_VOLUME pramfs, CPCHAR pcName, PRAM_NODE pramnFather, mode_t mode, CPCHAR pcLink) { PRAM_NODE pramn = (PRAM_NODE)__SHEAP_ALLOC(sizeof(RAM_NODE)); CPCHAR pcFileName; if (pramn == LW_NULL) { _ErrorHandle(ENOMEM); return (LW_NULL); } lib_bzero(pramn, sizeof(RAM_NODE)); pcFileName = lib_rindex(pcName, PX_DIVIDER); if (pcFileName) { pcFileName++; } else { pcFileName = pcName; } pramn->RAMN_pcName = (PCHAR)__SHEAP_ALLOC(lib_strlen(pcFileName) + 1); if (pramn->RAMN_pcName == LW_NULL) { __SHEAP_FREE(pramn); _ErrorHandle(ENOMEM); return (LW_NULL); } lib_strcpy(pramn->RAMN_pcName, pcFileName); if (S_ISLNK(mode)) { pramn->RAMN_pcLink = (PCHAR)__SHEAP_ALLOC(lib_strlen(pcLink) + 1); if (pramn->RAMN_pcLink == LW_NULL) { __SHEAP_FREE(pramn->RAMN_pcName); __SHEAP_FREE(pramn); _ErrorHandle(ENOMEM); return (LW_NULL); } lib_strcpy(pramn->RAMN_pcLink, pcLink); } else { if ((mode & S_IFMT) == 0) { mode |= S_IFREG; } pramn->RAMN_pcLink = LW_NULL; } pramn->RAMN_pramnFather = pramnFather; pramn->RAMN_pramfs = pramfs; pramn->RAMN_mode = mode; pramn->RAMN_timeCreate = lib_time(LW_NULL); pramn->RAMN_timeAccess = pramn->RAMN_timeCreate; pramn->RAMN_timeChange = pramn->RAMN_timeCreate; pramn->RAMN_uid = getuid(); pramn->RAMN_gid = getgid(); pramn->RAMN_prambCookie = LW_NULL; if (pramnFather) { _List_Line_Add_Ahead(&pramn->RAMN_lineBrother, &pramnFather->RAMN_plineSon); } else { _List_Line_Add_Ahead(&pramn->RAMN_lineBrother, &pramfs->RAMFS_plineSon); } return (pramn); }
/********************************************************************************************************* ** 函数名称: API_InterVectorConnectEx ** 功能描述: 设置系统指定向量中断服务 ** 输 入 : ulVector 中断向量号 ** pfuncIsr 服务函数 ** pfuncClear 附加中断清除函数(可为 NULL) ** pvArg 服务函数参数 ** pcName 中断服务名称 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ULONG API_InterVectorConnectEx (ULONG ulVector, PINT_SVR_ROUTINE pfuncIsr, VOIDFUNCPTR pfuncClear, PVOID pvArg, CPCHAR pcName) { INTREG iregInterLevel; BOOL bNeedFree; PLW_LIST_LINE plineTemp; PLW_CLASS_INTACT piactionOld; PLW_CLASS_INTACT piaction; PLW_CLASS_INTDESC pidesc; if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中断中调用 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n"); _ErrorHandle(ERROR_KERNEL_IN_ISR); return (ERROR_KERNEL_IN_ISR); } INTER_SHOWLOCK_CREATE(); if (_Object_Name_Invalid(pcName)) { /* 检查名字有效性 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "name too long.\r\n"); _ErrorHandle(ERROR_KERNEL_PNAME_TOO_LONG); return (ERROR_KERNEL_PNAME_TOO_LONG); } if (_Inter_Vector_Invalid(ulVector)) { _ErrorHandle(ERROR_KERNEL_VECTOR_NULL); return (ERROR_KERNEL_VECTOR_NULL); } if (pfuncIsr == LW_NULL) { _ErrorHandle(ERROR_KERNEL_VECTOR_NULL); return (ERROR_KERNEL_VECTOR_NULL); } piaction = (PLW_CLASS_INTACT)__KHEAP_ALLOC(sizeof(LW_CLASS_INTACT)); if (piaction == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "kernel low memory.\r\n"); _ErrorHandle(ERROR_KERNEL_LOW_MEMORY); return (ERROR_KERNEL_LOW_MEMORY); } lib_bzero(piaction, sizeof(LW_CLASS_INTACT)); piaction->IACT_pfuncIsr = pfuncIsr; piaction->IACT_pfuncClear = pfuncClear; piaction->IACT_pvArg = pvArg; if (pcName) { lib_strcpy(piaction->IACT_cInterName, pcName); } else { piaction->IACT_cInterName[0] = PX_EOS; } pidesc = LW_IVEC_GET_IDESC(ulVector); LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel); /* 关闭中断同时锁住 spinlock */ if (LW_IVEC_GET_FLAG(ulVector) & LW_IRQ_FLAG_QUEUE) { /* 队列服务类型向量 */ for (plineTemp = pidesc->IDESC_plineAction; plineTemp != LW_NULL; plineTemp = _list_line_get_next(plineTemp)) { piactionOld = _LIST_ENTRY(plineTemp, LW_CLASS_INTACT, IACT_plineManage); if ((piactionOld->IACT_pfuncIsr == pfuncIsr) && (piactionOld->IACT_pvArg == pvArg)) { /* 中断处理函数是否被重复安装 */ break; } } if (plineTemp) { /* 此中断被重复安装 */ bNeedFree = LW_TRUE; } else { _List_Line_Add_Ahead(&piaction->IACT_plineManage, &pidesc->IDESC_plineAction); bNeedFree = LW_FALSE; } } else { /* 非队列服务式中断向量 */ if (pidesc->IDESC_plineAction) { piactionOld = _LIST_ENTRY(pidesc->IDESC_plineAction, LW_CLASS_INTACT, IACT_plineManage); piactionOld->IACT_pfuncIsr = piaction->IACT_pfuncIsr; piactionOld->IACT_pfuncClear = piaction->IACT_pfuncClear; piactionOld->IACT_pvArg = piaction->IACT_pvArg; lib_strcpy(piactionOld->IACT_cInterName, piaction->IACT_cInterName); bNeedFree = LW_TRUE; } else { _List_Line_Add_Ahead(&piaction->IACT_plineManage, &pidesc->IDESC_plineAction); bNeedFree = LW_FALSE; } } LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel); /* 打开中断, 同时打开 spinlock */ if (bNeedFree) { __KHEAP_FREE(piaction); } _DebugFormat(__LOGMESSAGE_LEVEL, "IRQ %d : %s connect : 0x%p\r\n", (INT)ulVector, (pcName ? pcName : ""), (PVOID)pfuncIsr); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __tshellReadline ** 功能描述: shell 从终端读取一条命令. ** 输 入 : iFd 文件描述符 ** pvBuffer 接收缓冲区 ** stMaxBytes 接收缓冲区大小 ** 输 出 : 读取个数 ** 全局变量: ** 调用模块: *********************************************************************************************************/ ssize_t __tshellReadline (INT iFd, PVOID pcBuffer, size_t stSize) { #define __CHK_READ_OUT(res) if (sstReadNum <= 0) { \ goto __out; \ } LONG lOldOption = OPT_TERMINAL; LONG lNewOption; ssize_t sstReadNum; __SHELL_INPUT_CTX sicContext; CHAR cRead; PVOID pvCookie = LW_NULL; if (__tshellReadlineInit() < ERROR_NONE) { /* 初始化当前线程 Readline相关 */ return (0); } sicContext.SIC_uiCursor = 0; sicContext.SIC_uiTotalLen = 0; sicContext.SIC_cInputBuffer[0] = PX_EOS; ioctl(iFd, FIOGETOPTIONS, &lOldOption); lNewOption = lOldOption & ~(OPT_ECHO | OPT_LINE); /* no echo no line mode */ ioctl(iFd, FIOSETOPTIONS, lNewOption); while (sicContext.SIC_uiTotalLen < LW_CFG_SHELL_MAX_COMMANDLEN) { sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); __re_check_key: if (__KEY_IS_ESC(cRead)) { /* 功能键起始 */ sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); if (cRead == 91) { /* 方向键中间键 */ sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); switch (cRead) { case __FUNC_KEY_LEFT: /* ← */ __tshellCharLeft(iFd, &sicContext); break; case __FUNC_KEY_UP: /* ↑ */ __tshellCharUp(iFd, &pvCookie, &sicContext); break; case __FUNC_KEY_RIGHT: /* → */ __tshellCharRight(iFd, &sicContext); break; case __FUNC_KEY_DOWN: /* ↓ */ __tshellCharDown(iFd, &pvCookie, &sicContext); break; case __FUNC_KEY_HOME: /* home key */ __tshellCharHome(iFd, &sicContext); sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); if (cRead != 126) { goto __re_check_key; } break; case __FUNC_KEY_DELETE: /* delete key */ __tshellCharDelete(iFd, &sicContext); sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); if (cRead != 126) { goto __re_check_key; } break; case __FUNC_KEY_END: /* end key */ __tshellCharEnd(iFd, &sicContext); sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); if (cRead != 126) { goto __re_check_key; } break; } } else { goto __re_check_key; } } else if (__KEY_IS_TAB(cRead)) { /* tab */ __tshellCharTab(iFd, &sicContext); } else if (__KEY_IS_BS(cRead)) { /* backspace */ __tshellCharBackspace(iFd, cRead, &sicContext); } else if (__KEY_IS_LF(cRead)) { /* 结束 */ write(iFd, &cRead, 1); /* echo */ break; } else if (__KEY_IS_EOT(cRead)) { /* CTL+D 强制退出 */ lib_strcpy(sicContext.SIC_cInputBuffer, __TTINY_SHELL_FORCE_ABORT); sicContext.SIC_uiTotalLen = (UINT)lib_strlen(__TTINY_SHELL_FORCE_ABORT); break; } else { __tshellCharInster(iFd, cRead, &sicContext); } } sicContext.SIC_cInputBuffer[sicContext.SIC_uiTotalLen] = PX_EOS; /* 命令结束 */ if (lib_strlen(sicContext.SIC_cInputBuffer)) { __tshellHistorySave(&sicContext); /* 记录历史命令 */ } __out: ioctl(iFd, FIOSETOPTIONS, lOldOption); /* 恢复以前终端状态 */ lib_strlcpy((PCHAR)pcBuffer, sicContext.SIC_cInputBuffer, stSize); return ((ssize_t)sicContext.SIC_uiTotalLen); }
VOID archTaskCtxShow (INT iFd, PLW_STACK pstkTop) { CHAR cCpsr[32 + 1] = "\0"; LW_STACK stkCpsr = pstkTop[0]; if (stkCpsr & 0x80000000) { cCpsr[0] = 'N'; } else { cCpsr[0] = 'n'; } if (stkCpsr & 0x40000000) { cCpsr[1] = 'Z'; } else { cCpsr[1] = 'z'; } if (stkCpsr & 0x20000000) { cCpsr[2] = 'C'; } else { cCpsr[2] = 'c'; } if (stkCpsr & 0x10000000) { cCpsr[3] = 'V'; } else { cCpsr[3] = 'v'; } if (stkCpsr & 0x08000000) { cCpsr[4] = 'Q'; } else { cCpsr[4] = 'q'; } if (stkCpsr & 0x80) { cCpsr[5] = 'I'; } else { cCpsr[5] = 'i'; } if (stkCpsr & 0x40) { cCpsr[6] = 'F'; } else { cCpsr[6] = 'f'; } if (stkCpsr & 0x20) { cCpsr[7] = 'T'; } else { cCpsr[7] = 't'; } cCpsr[8] = 0; stkCpsr &= 0x1F; switch (stkCpsr) { case ARCH_ARM_USR32MODE: lib_strcpy(&cCpsr[8], "_USER"); break; case ARCH_ARM_FIQ32MODE: lib_strcpy(&cCpsr[8], "_FIQ"); break; case ARCH_ARM_IRQ32MODE: lib_strcpy(&cCpsr[8], "_IRQ"); break; case ARCH_ARM_SVC32MODE: lib_strcpy(&cCpsr[8], "_SVC"); break; case ARCH_ARM_ABT32MODE: lib_strcpy(&cCpsr[8], "_ABT"); break; case ARCH_ARM_UND32MODE: lib_strcpy(&cCpsr[8], "_UND"); break; case ARCH_ARM_SYS32MODE: lib_strcpy(&cCpsr[8], "_SYS"); break; default: lib_strcpy(&cCpsr[8], "_!!!"); break; } fdprintf(iFd, "cpsr = %s\n", cCpsr); fdprintf(iFd, "r0 = 0x%08x ", pstkTop[1]); fdprintf(iFd, "r1 = 0x%08x\n", pstkTop[2]); fdprintf(iFd, "r2 = 0x%08x ", pstkTop[3]); fdprintf(iFd, "r3 = 0x%08x\n", pstkTop[4]); fdprintf(iFd, "r4 = 0x%08x ", pstkTop[5]); fdprintf(iFd, "r5 = 0x%08x\n", pstkTop[6]); fdprintf(iFd, "r6 = 0x%08x ", pstkTop[7]); fdprintf(iFd, "r7 = 0x%08x\n", pstkTop[8]); fdprintf(iFd, "r8 = 0x%08x ", pstkTop[9]); fdprintf(iFd, "r9 = 0x%08x\n", pstkTop[10]); fdprintf(iFd, "r10 = 0x%08x ", pstkTop[11]); fdprintf(iFd, "fp = 0x%08x\n", pstkTop[12]); fdprintf(iFd, "ip = 0x%08x ", pstkTop[13]); fdprintf(iFd, "sp = 0x%08x\n", (ARCH_REG_T)pstkTop); fdprintf(iFd, "lr = 0x%08x ", pstkTop[14]); fdprintf(iFd, "pc = 0x%08x\n", pstkTop[15]); }