_WCRTLINK CHAR_TYPE *__F_NAME(getcwd,_wgetcwd)( CHAR_TYPE *buf, size_t size ) /***************************************************************************/ { int len; #ifdef __WIDECHAR__ char cwd[MB_CUR_MAX * _MAX_PATH]; /* multi-byte chars */ #else char cwd[_MAX_PATH]; /* single-byte chars */ #endif __null_check( buf, 1 ); if( __getdcwd( &cwd[3], 0 ) ) { _RWD_errno = ENOENT; /* noent? */ return( NULL ); } /* get current drive and insert into cwd[0] */ cwd[0] = TinyGetCurrDrive() + 'A'; cwd[1] = ':'; cwd[2] = '\\'; #ifdef __WIDECHAR__ len = _mbslen( (unsigned char *)cwd ) + 1; #else len = strlen( cwd ) + 1; #endif if( buf == NULL ) { if( (buf = lib_malloc( max( size, len ) * CHARSIZE )) == NULL ) { _RWD_errno = ENOMEM; return( NULL ); } size = len; } /*** Copy the pathname into a buffer and quit ***/ #ifdef __WIDECHAR__ if( mbstowcs( buf, cwd, size ) == -1 ) { return( NULL ); } return( buf ); #else return( strncpy( buf, cwd, size ) ); #endif }
_WCRTLINK CHAR_TYPE *__F_NAME(_sys_fullpath,_sys_wfullpath) ( CHAR_TYPE *buff, const CHAR_TYPE *path, size_t size ) /*********************************************************************/ { #if defined(__NT__) CHAR_TYPE *filepart; DWORD rc; if( __F_NAME(stricmp,_wcsicmp)( path, STRING( "con" ) ) == 0 ) { _WILL_FIT( 3 ); return( __F_NAME(strcpy,wcscpy)( buff, STRING( "con" ) ) ); } /*** Get the full pathname ***/ rc = __lib_GetFullPathName( path, size, buff, &filepart ); // If the buffer is too small, the return value is the size of // the buffer, in TCHARs, required to hold the path. // If the function fails, the return value is zero. To get extended error // information, call GetLastError. if( ( rc == 0 ) || ( rc > size ) ) { __set_errno_nt(); return( NULL ); } return( buff ); #elif defined(__WARP__) APIRET rc; char root[ 4 ]; /* SBCS: room for drive, ':', '\\', and null */ #ifdef __WIDECHAR__ char mbBuff[ _MAX_PATH * MB_CUR_MAX ]; char mbPath[ _MAX_PATH * MB_CUR_MAX ]; #endif if( __F_NAME(isalpha,iswalpha)( path[ 0 ] ) && ( path[ 1 ] == STRING( ':' ) ) && ( path[ 2 ] == STRING( '\\' ) ) ) { int i; i = __F_NAME(strlen,wcslen)( path ); _WILL_FIT( i ); __F_NAME(strcpy,wcscpy)( buff, path ); return( buff ); } /* * Check for x:filename.ext when drive x doesn't exist. In this * case, return x:\filename.ext, not NULL, to be consistent with * MS and with the NT version of _fullpath. */ if( __F_NAME(isalpha,iswalpha)( path[ 0 ] ) && path[ 1 ] == STRING( ':' ) ) { /*** We got this far, so path can't start with letter:\ ***/ root[ 0 ] = (char)path[ 0 ]; root[ 1 ] = ':'; root[ 2 ] = '\\'; root[ 3 ] = '\0'; rc = DosQueryPathInfo( root, FIL_QUERYFULLNAME, buff, size ); if( rc != NO_ERROR ) { /*** Drive does not exist; return x:\filename.ext ***/ _WILL_FIT( __F_NAME(strlen,wcslen)( &path[ 2 ] ) + 3 ); buff[ 0 ] = root[ 0 ]; buff[ 1 ] = STRING( ':' ); buff[ 2 ] = STRING( '\\' ); __F_NAME(strcpy,wcscpy)( &buff[ 3 ], &path[ 2 ] ); return( buff ); } } #ifdef __WIDECHAR__ if( wcstombs( mbPath, path, sizeof( mbPath ) ) == (size_t)-1 ) { return( NULL ); } rc = DosQueryPathInfo( (PSZ)mbPath, FIL_QUERYFULLNAME, mbBuff, sizeof( mbBuff ) ); #else rc = DosQueryPathInfo( (PSZ)path, FIL_QUERYFULLNAME, buff, size ); #endif if( rc != 0 ) { __set_errno_dos( rc ); return( NULL ); } #ifdef __WIDECHAR__ if( mbstowcs( buff, mbBuff, size ) != (size_t)-1 ) { return( buff ); } else { return( NULL ); } #else return( buff ); #endif #elif defined(__QNX__) || defined( __NETWARE__ ) size_t len; char temp_dir[ _MAX_PATH ]; #if defined(__NETWARE__) if( ConvertNameToFullPath( path, temp_dir ) != 0 ) { return( NULL ); } #else if( __qnx_fullpath( temp_dir, path ) == NULL ) { return( NULL ); } #endif len = strlen( temp_dir ); if( len >= size ) { __set_errno( ERANGE ); return( NULL ); } return( strcpy( buff, temp_dir ) ); #elif defined(__UNIX__) const char *p; char *q; size_t len; char curr_dir[ _MAX_PATH ]; p = path; q = buff; if( ! _IS_SLASH( p[ 0 ] ) ) { if( getcwd( curr_dir, sizeof( curr_dir ) ) == NULL ) { __set_errno( ENOENT ); return( NULL ); } len = strlen( curr_dir ); _WILL_FIT( len ); strcpy( q, curr_dir ); q += len; if( q[ -1 ] != '/' ) { _WILL_FIT( 1 ); *(q++) = '/'; } for( ;; ) { if( p[ 0 ] == '\0' ) break; if( p[ 0 ] != '.' ) { _WILL_FIT( 1 ); *(q++) = *(p++); continue; } ++p; if( _IS_SLASH( p[ 0 ] ) ) { /* ignore "./" in directory specs */ if( ! _IS_SLASH( q[ -1 ] ) ) { *q++ = '/'; } ++p; continue; } if( p[ 0 ] == '\0' ) break; if( p[ 0 ] == '.' && _IS_SLASH( p[ 1 ] ) ) { /* go up a directory for a "../" */ p += 2; if( ! _IS_SLASH( q[ -1 ] ) ) { return( NULL ); } q -= 2; for( ;; ) { if( q < buff ) { return( NULL ); } if( _IS_SLASH( *q ) ) break; --q; } ++q; *q = '\0'; continue; } _WILL_FIT( 1 ); *(q++) = '.'; } *q = '\0'; } else { len = strlen( p ); _WILL_FIT( len ); strcpy( q, p ); } return( buff ); #else const CHAR_TYPE *p; CHAR_TYPE *q; size_t len; int path_drive_idx; char curr_dir[ _MAX_PATH ]; p = path; q = buff; _WILL_FIT( 2 ); if( __F_NAME(isalpha,iswalpha)( p[ 0 ] ) && p[ 1 ] == STRING( ':' ) ) { path_drive_idx = ( __F_NAME(tolower,towlower)( p[ 0 ] ) - STRING( 'a' ) ) + 1; q[ 0 ] = p[ 0 ]; q[ 1 ] = p[ 1 ]; p += 2; } else { #if defined(__OS2__) ULONG drive_map; OS_UINT os2_drive; if( DosQCurDisk( &os2_drive, &drive_map ) ) { __set_errno( ENOENT ); return( NULL ); } path_drive_idx = os2_drive; #else path_drive_idx = TinyGetCurrDrive() + 1; #endif q[ 0 ] = STRING( 'A' ) + ( path_drive_idx - 1 ); q[ 1 ] = STRING( ':' ); } q += 2; if( ! _IS_SLASH( p[ 0 ] ) ) { #if defined(__OS2__) OS_UINT dir_len = sizeof( curr_dir ); if( DosQCurDir( path_drive_idx, curr_dir, &dir_len ) ) { __set_errno( ENOENT ); return( NULL ); } #else if( __getdcwd( curr_dir, path_drive_idx ) ) { __set_errno( ENOENT ); return( NULL ); } #endif len = strlen( curr_dir ); if( curr_dir[ 0 ] != '\\' ) { _WILL_FIT( 1 ); *(q++) = STRING( '\\' ); } _WILL_FIT( len ); #ifdef __WIDECHAR__ if( mbstowcs( q, curr_dir, len + 1 ) == (size_t)-1 ) { return( NULL ); } #else strcpy( q, curr_dir ); #endif q += len; if( q[ -1 ] != STRING( '\\' ) ) { _WILL_FIT( 1 ); *(q++) = STRING( '\\' ); } for( ;; ) { if( p[ 0 ] == NULLCHAR ) break; if( p[ 0 ] != STRING( '.' ) ) { _WILL_FIT( 1 ); *(q++) = *(p++); continue; } ++p; // at least '.' if( _IS_SLASH( p[ 0 ] ) ) { /* ignore "./" in directory specs */ if( ! _IS_SLASH( q[ -1 ] ) ) { *q++ = STRING( '\\' ); } ++p; continue; } if( p[ 0 ] == NULLCHAR ) break; if( p[ 0 ] == STRING( '.' ) ) { /* .. */ ++p; if( _IS_SLASH( p[ 0 ] ) ) { /* "../" */ ++p; } if( ! _IS_SLASH( q[ -1 ] ) ) { return( NULL ); } q -= 2; for( ;; ) { if( q < buff ) { return( NULL ); } if( _IS_SLASH( *q ) ) break; if( *q == STRING( ':' ) ) { ++q; *q = STRING( '\\' ); break; } --q; } ++q; *q = NULLCHAR; continue; } _WILL_FIT( 1 ); *(q++) = STRING( '.' ); } *q = NULLCHAR; } else { len = __F_NAME(strlen,wcslen)( p ); _WILL_FIT( len ); __F_NAME(strcpy,wcscpy)( q, p ); } /* force to all backslashes */ for( q = buff; *q != NULLCHAR; ++q ) { if( *q == STRING( '/' ) ) { *q = STRING( '\\' ); } } return( buff ); #endif }