In the code below, could you please tell me why when fl_name
is about 207 characters in length (212 including the extension, and 227 including the relative path), the stat()
function fails and returns errno
of 2 and strerror( errno )
that the file doesn't exist?
The printf
right after the memcpy
in the while
loop, prints the correct path, file, and extension as retrieved from struct dirent
ep
but then says the very same file doesn't exist.
The loop works for all file names of length 207 or less.
I'm using minGW-W64. I tried using the _stat()
function also and the results were the same.
Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
int main ( void )
{
DIR *dp;
struct dirent *ep;
struct stat info;
int rc, q, l, i = 0, v = 0;
const char *path = NULL;
char *fl_name,
*p = NULL;
const char *sec_path = "../../databases/";
unsigned int len_sec_path = strlen( sec_path );
fl_name = malloc( len_sec_path + 261 );
// Want p to be at the point in fl_name to write the actual file and directory names in order to get the stats.
// memcpy returns the pointer to the destination; so, just add the length of path to that to get to the end.
p = memcpy( fl_name, sec_path, len_sec_path + 1 ) + len_sec_path;
if ( ( dp = opendir( fl_name ) ) == NULL )
{
printf( "Failed to open the directory of: %s", fl_name );
return 1;
}
while ( ep = readdir( dp ) )
{
memcpy( p, ep->d_name, ( l = strlen( ep->d_name ) ) > 259 ? 260 : l + 1 );
printf( "%d, %s\n", strlen( fl_name ), fl_name );
if ( ( rc = stat( fl_name, &info ) ) != 0 )
{
printf( "%s\n", fl_name );
printf( "rc = %d, errno : %d, strerror : %s\n", rc, errno, strerror( errno ) );
continue;
}
}
return 0;
}
Modifying the code to change the directory to sec_path
before attempting to get the file information solved this issue, at least such that the largest file name Windows will accept will not error.
int main ( void )
{
DIR *dp;
struct dirent *ep;
struct stat info;
int rc, q, l, i = 0, v = 0;
const char *path = NULL;
char *fl_name,
*p = NULL,
name;
const char *sec_path = "../../databases/";
unsigned int len_sec_path = strlen( sec_path );
fl_name = malloc( len_sec_path + 261 );
// Want p to be at the point in fl_name to write the actual file and directory names in order to get the stats.
// memcpy returns the pointer to the destination; so, just add the length of path to that to get to the end.
p = memcpy( fl_name, sec_path, len_sec_path + 1 ) + len_sec_path;
char *buffer;
if ( (buffer = _getcwd( NULL, 0 )) == NULL )
{
printf( "Failed to get current working directory." );
return 1;
}
printf( "buffer is %s\n", buffer );
if ( ( dp = opendir( fl_name ) ) == NULL )
{
printf( "Failed to open the directory of: %s", fl_name );
return 1;
}
if ( _chdir( sec_path ) )
{
printf( "Couldn't change directory." );
return 1;
}
while ( ep = readdir( dp ) )
{
memcpy( p, ep->d_name, ( l = strlen( ep->d_name ) ) > 259 ? 260 : l + 1 );
printf( "%d, %s\n", strlen( fl_name ), fl_name );
if ( ( rc = stat( p, &info ) ) != 0 )
{
printf( "%s\n", fl_name );
printf( "rc = %d, errno : %d, strerror : %s\n", rc, errno, strerror( errno ) );
continue;
}
}
if ( _chdir( buffer ) )
{
printf( "Couldn't change directory." );
return 1;
}
printf( "buffer is %s\n", buffer );
free( buffer );
return 0;
}