Issue
The following is my code for a method that copies a file from a path to a file to a directory provided as the destination. The copy works perfectly fine, however my chmod call assigns the wrong permissions to the copied file in the destination. If the permission in the source is 644, the copied file has a permission of 170 or 120.
I have been attempting to debug this for hours and it's driving me slightly crazy so any help is greatly appreciated.
void copy_file(char* src, char* dest) {
char a;
//extract file name through a duplicate ptr
char* fname = strdup(src);
char* dname = basename(fname);
//open read and write streams
FILE* read;
FILE* write;
read = fopen(src, "r");
chdir(dest);
write = fopen(dname, "w");
//error checking
if (read == NULL) //|| (write == NULL))
{
perror("Read Error: ");
exit(0);
}
else if (write == NULL)
{
perror("Write Error: ");
exit(0);
}
//write from src to dest char by char
while (1){
a = fgetc(read);
if (a == EOF)
{
break;
}
fputc(a, write);
}
//close files
fclose(read);
fclose(write);
// this is where I attempt to assign source file permissions
//and it goes horribly wrong
struct stat src_st;
if(stat(src, &src_st)){
perror("stat: ");
}
chmod(dname, src_st.st_mode);
printf("%o\n", src_st.st_mode & 0777);
}
Solution
You fopen(src, "r")
, then you chdir(dest)
. This means that when you later call stat(src, &src_st)
, there is no reason to think that stat
will access the same file as fopen
did, or indeed that stat
will access any file at all.
If stat
fails, you proceed to call chmod
anyway, so you pass whatever random junk was in src_st.st_mode
to chmod
.
You should use fstat(fileno(read), &src_st)
before calling fclose(src)
, instead of calling stat(src, &src_st)
.
Answered By - rob mayoff Answer Checked By - Marilyn (WPSolving Volunteer)