📄 zfschdir.c
字号:
/*
* File : ZFSChdir.c
* Description: This file contains the implementation of ZFSChdir API
* Author : Mahadev K C
* Created on : 30-APR-2003
*
* Copyright 2004 ZiLOG Inc. ALL RIGHTS RESERVED.
*
* This file contains unpublished confidential and proprietary information
* of ZiLOG, Inc.
* NO PART OF THIS WORK MAY BE DUPLICATED, STORED, PUBLISHED OR DISCLOSED
* IN ANY FORM WITHOUT THE PRIOR WRITTEN CONSENT OF ZiLOG, INC.
* This is not a license and no use of any kind of this work is authorized
* in the absence of a written license granted by ZiLOG, Inc. in ZiLOG's
* sole discretion
*/
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZSemaphore.h"
#include "glextern.h"
extern RZK_SEMAPHOREHANDLE_t hSem_FS;
INT GetCwdLenForNode( PZFS_DIR_LIST_t pdir_node )
{
UINT len ;
UINT ttl_len = 0 ;
PZFS_DIR_LIST_t proot_node ;
UINT8 begin = ZFS_TRUE ;
for( proot_node = pdir_node ; proot_node->up_list != NULL ; proot_node = proot_node->up_list ) ;
while ( pdir_node != NULL )
{
// get the pdir_node and get the length of the name.
len = strlen( ( const INT8 *) pdir_node->dir_name ) ;
ttl_len += len ;
if( pdir_node == proot_node && begin == ZFS_TRUE )
{
ttl_len += 3 ;
goto end_GetCwdLenForNode ;
}
else
begin = ZFS_FALSE ;
if( pdir_node == proot_node )
ttl_len += 2 ; // needed for :/
else
ttl_len++ ;
pdir_node = pdir_node->up_list ;
}
end_GetCwdLenForNode:
return ttl_len ;
}
VOID GetCwdStringForDirNode( PZFS_DIR_LIST_t pdir_node, INT8 *pcwd_path)
{
UINT len = 0 ;
UINT idx ;
UINT ttl_len = 0 ;
PZFS_DIR_LIST_t proot_node ;
INT8 *pend, *pcur ;
UINT8 begin = ZFS_TRUE ;
for( proot_node = pdir_node ; proot_node->up_list != NULL ; proot_node = proot_node->up_list ) ;
while( pdir_node != NULL )
{
len = strlen( (const INT8 * ) pdir_node->dir_name ) ;
// if this is the first time, just copy the data onto the buffer.
if( begin == ZFS_TRUE )
{
if( pdir_node != proot_node )
memcpy( &pcwd_path[1], pdir_node->dir_name, len ) ;
else
{
memcpy( &pcwd_path[0], pdir_node->dir_name, len ) ;
pcwd_path[len]=':' ;
pcwd_path[len+1]='/' ; // to support '/'
// pcwd_path[len+1]='\\' ; // to support '\'
ttl_len += len + 2 ;
goto end_GetCwdStringForDirNode ;
}
begin = ZFS_FALSE ;
ttl_len = len + 1;
}
else
{
// shift the bytes to right.
pend = pcwd_path + ttl_len + len ;
pcur = pcwd_path + ttl_len - 1;
for( idx = 0 ; idx < ttl_len ; idx++ )
{
*pend = *pcur ;
pend-- ;
pcur-- ;
}
if( proot_node == pdir_node )
memcpy( &pcwd_path[0], pdir_node->dir_name, len ) ;
else
memcpy( &pcwd_path[1], pdir_node->dir_name, len ) ;
ttl_len += len + 1;
}
if( proot_node == pdir_node )
pcwd_path[len] = ':';
else
{
pcwd_path[0]='/' ; // to support '/'
// pcwd_path[0]='\\' ; // to support '\'
}
pdir_node = pdir_node->up_list ;
}
end_GetCwdStringForDirNode:
pcwd_path[ ttl_len ] = '\0' ;
}
extern RZK_SEMAPHOREHANDLE_t hSem_FS;
//Function Name: ZFSChdir
//Decription: This API changes the current working directory to a new directory provided in
// the arguments
ZFS_STATUS_t ZFSChdir( IN INT8 *dir )
{
UINT off = 0 ;
UINT len = 0 ;
PZFS_DIR_LIST_t pdir_node, pcwd_dir_node ;
PZFS_VOL_INFO_t pvol_info ;
UINT8 status ;
INT8 *pcwd_path ;
ZFS_STATUS_t ret_status = ZFSERR_SUCCESS ;
// if ZFS is not initialized, return error
if( !IsZFSInited() )
return ZFSERR_NOT_INITIALIZED ;
// now check the validity of the dir path given in the argument
if( !ValidatePath( dir ) )
return ZFSERR_INVALID_FILEDIR_PATH ;
// get the length of the dir name
len = strlen( ( const INT8 * ) dir ) ;
// disable preemption
// preempt_status = DisablePreemption() ;
RZKAcquireSemaphore(hSem_FS,INFINITE_SUSPEND);
if( GetCwdInfoForCurThread( &pvol_info, &pcwd_dir_node ) != ZFS_TRUE )
{
ret_status = ZFSERR_INVALID_VOLUME ;
goto err_label_ZFS_Chdir ;
}
// now validated, disable preemption, find the absolute path
status = IsAbsPath( dir, &pvol_info, &off, &pdir_node ) ;
if( status != ZFS_TRUE )
{
ret_status = ZFSERR_INVALID_FILEDIR_PATH ;
goto err_label_ZFS_Chdir ;
}
if( !IsVolumeValid(pvol_info) )
{
ret_status = ZFSERR_INVALID_VOLUME ;
goto err_label_ZFS_Chdir ;
}
if( pdir_node == NULL )
{
pdir_node = pcwd_dir_node ;
}
// this is relative path, get the directory node of the relative path
pdir_node = GetNodeForPath( pdir_node, dir + off, ( len - off ) ) ;
if( pdir_node == NULL )
{
ret_status = ZFSERR_INVALID_FILEDIR_PATH ;
goto err_label_ZFS_Chdir ;
}
// Now Need to check the length of the new directory path. If it is less
// than the max_dir_length, then only set otherwise return an error.
if( GetCwdLenForNode( pdir_node ) > g_max_cwd_len )
{
ret_status = ZFSERR_CWD_PATH_LENGTH_MORE ;
goto err_label_ZFS_Chdir ;
}
// prepare the CWD string and store it in the thread TCB
pcwd_path = GetCwdPathForHandle( GetCurrentThread() ) ;
GetCwdStringForDirNode( pdir_node, pcwd_path ) ;
// now set the path in the string
SetCwdPath( pcwd_path ) ;
err_label_ZFS_Chdir:
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ret_status ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -