LIST* pwd(void) { if (!pwd_result) { int buffer_size = PATH_MAX; char * result_buffer = 0; do { char * buffer = BJAM_MALLOC_RAW(buffer_size); result_buffer = getcwd(buffer,buffer_size); if (result_buffer) { #ifdef NT OBJECT * result = object_new(result_buffer); pwd_result = short_path_to_long_path(result); object_free( result ); #else pwd_result = object_new(result_buffer); #endif } buffer_size *= 2; BJAM_FREE_RAW(buffer); } while (!pwd_result && errno == ERANGE); if (!pwd_result) { perror("can not get current directory"); return L0; } } return list_new(L0, object_copy( pwd_result ) ); }
void file_dirscan( char * dir, scanback func, void * closure ) { PROFILE_ENTER( FILE_DIRSCAN ); file_info_t * d = 0; dir = short_path_to_long_path( dir ); /* First enter directory itself */ d = file_query( dir ); if ( !d || !d->is_dir ) { PROFILE_EXIT( FILE_DIRSCAN ); return; } if ( !d->files ) { PATHNAME f; string filespec[ 1 ]; string filename[ 1 ]; long handle; int ret; struct _finddata_t finfo[ 1 ]; LIST * files = L0; int d_length = strlen( d->name ); memset( (char *)&f, '\0', sizeof( f ) ); f.f_dir.ptr = d->name; f.f_dir.len = d_length; /* Now enter contents of directory */ /* Prepare file search specification for the findfirst() API. */ if ( d_length == 0 ) string_copy( filespec, ".\\*" ); else { /* * We can not simply assume the given folder name will never include * its trailing path separator or otherwise we would not support the * Windows root folder specified without its drive letter, i.e. '\'. */ char trailingChar = d->name[ d_length - 1 ] ; string_copy( filespec, d->name ); if ( ( trailingChar != '\\' ) && ( trailingChar != '/' ) ) string_append( filespec, "\\" ); string_append( filespec, "*" ); } if ( DEBUG_BINDSCAN ) printf( "scan directory %s\n", dir ); #if defined(__BORLANDC__) && __BORLANDC__ < 0x550 if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) ) { string_free( filespec ); PROFILE_EXIT( FILE_DIRSCAN ); return; } string_new ( filename ); while ( !ret ) { file_info_t * ff = 0; f.f_base.ptr = finfo->ff_name; f.f_base.len = strlen( finfo->ff_name ); string_truncate( filename, 0 ); path_build( &f, filename ); files = list_new( files, newstr(filename->value) ); ff = file_info( filename->value ); ff->is_file = finfo->ff_attrib & FA_DIREC ? 0 : 1; ff->is_dir = finfo->ff_attrib & FA_DIREC ? 1 : 0; ff->size = finfo->ff_fsize; ff->time = (finfo->ff_ftime << 16) | finfo->ff_ftime; ret = findnext( finfo ); } # else handle = _findfirst( filespec->value, finfo ); if ( ret = ( handle < 0L ) ) { string_free( filespec ); PROFILE_EXIT( FILE_DIRSCAN ); return; } string_new( filename ); while ( !ret ) { file_info_t * ff = 0; f.f_base.ptr = finfo->name; f.f_base.len = strlen( finfo->name ); string_truncate( filename, 0 ); path_build( &f, filename, 0 ); files = list_new( files, newstr( filename->value ) ); ff = file_info( filename->value ); ff->is_file = finfo->attrib & _A_SUBDIR ? 0 : 1; ff->is_dir = finfo->attrib & _A_SUBDIR ? 1 : 0; ff->size = finfo->size; ff->time = finfo->time_write; ret = _findnext( handle, finfo ); } _findclose( handle ); # endif string_free( filename ); string_free( filespec ); d->files = files; } /* Special case \ or d:\ : enter it */ { unsigned long len = strlen(d->name); if ( len == 1 && d->name[0] == '\\' ) (*func)( closure, d->name, 1 /* stat()'ed */, d->time ); else if ( len == 3 && d->name[1] == ':' ) { (*func)( closure, d->name, 1 /* stat()'ed */, d->time ); /* We've just entered 3-letter drive name spelling (with trailing slash), into the hash table. Now enter two-letter variant, without trailing slash, so that if we try to check whether "c:" exists, we hit it. Jam core has workarounds for that. Given: x = c:\whatever\foo ; p = $(x:D) ; p2 = $(p:D) ; There will be no trailing slash in $(p), but there will be one in $(p2). But, that seems rather fragile. */ d->name[2] = 0; (*func)( closure, d->name, 1 /* stat()'ed */, d->time ); } } /* Now enter contents of directory */ if ( d->files ) { LIST * files = d->files; while ( files ) { file_info_t * ff = file_info( files->string ); (*func)( closure, ff->name, 1 /* stat()'ed */, ff->time ); files = list_next( files ); } } PROFILE_EXIT( FILE_DIRSCAN ); }