-1

I have a problem copying a file from a directory to another in C. Specifically, my code works well with textual files but doesn't with executable ones. The number of bytes written is correct and so are the file rights, but the result type of the copy is not recognized as executable by the file system (I'm working on a xubuntu Virtual Machine) and has "Unknown" type. Therefore, if I echo the results of md5sum from command line on bash, they are different.

In the following code, "checkErrno" is a function defined by me that calls perror. "currDir" is the current directory and "DIRNAME" is the directory I want to move to. All the libraries are correctly included, I just copied and pasted the chunk of code that matters.

struct stat fileSt;
if(stat(fileName,&fileSt) != 0) checkErrno("Stats file");
char currDir[PATH_MAX];
FILE* file;
if(getcwd(currDir,PATH_MAX) == NULL) checkErrno("Currdir");
if(chdir(DIRNAME) != 0) checkErrno("Chdir");
if((file = fopen(fileName,"w")) == NULL) checkErrno("Create file");
if(chmod(fileName, fileSt.st_mode & 07777)) perror("chmod");
if(fwrite(fileMsg.data.buf,1,fileSize,file) < fileSize) checkErrno("fwrite");
fflush(file);
if(fclose(file) != 0) checkErrno("fclose");
if(chdir(currDir) != 0) checkErrno("chdir");

Thanks in advance!

EDIT: The mistake was in the function I used to read the file. Once I found out I easily solved it.

Gixuna
  • 86
  • 8
  • 3
    Try to give a short, _complete_ program. The code you have shown here is missing a lot of things, such as how you read the file. – Thomas Padron-McCarthy Dec 15 '17 at 17:42
  • 2
    Yeah lots of code missing...Perhaps your buffer is 'read' incorrectly? Show us your read code please – Grantly Dec 15 '17 at 17:43
  • 2
    How do you know what code "matters" if you don't know what the problem is? – Chris Turner Dec 15 '17 at 17:50
  • The file is passed by a client on a buffer. I tested repeatedly the read and write functions and it works well with textual files. It just doesn't work with executable files. – Gixuna Dec 15 '17 at 17:52

2 Answers2

1

I don't know if this is your problem, but remember to open both files in binary mode: "wb" instead of just "w", and "rb" instead of just "r".

Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75
  • Thats what I thought too.... But is 'b' really necessary (trying to search for it now, haven't found clear answer...Although I tend to agree with you)..Can you post a link perhaps? – Grantly Dec 15 '17 at 17:39
  • 2
    @Grantly: On Unix, 'b' is usually not needed. – Thomas Padron-McCarthy Dec 15 '17 at 17:40
  • 3
    `b` is only necessary on Windows (more accurately, non-POSIX systems), and even there, only to avoid formatted translation, which you shouldn't be getting with raw reads and writes via `fread` and `fwrite`. It makes a *huge* difference on Windows with things like `fscanf`, etc. I don't see that here. – WhozCraig Dec 15 '17 at 17:41
  • 1
    @Grantly yes it is 100% necessary - "b" says that the file should not be interpreted as text - for example on windows opening in "r" will render "\n" as "\r\n" automatically - whereas the "rb" mode will leave all bytes unchanged - which is what you want when copying files. So for portibility always use "b". – Ankush Dec 15 '17 at 17:41
  • Aha, now I know why I was confused - when I write cross platform code...sometimes b is required, sometimes not. But yes - Windows needs the 'b' – Grantly Dec 15 '17 at 17:42
  • (Yeah I always use B anyway, even with text files....I never trust line ending markers...) – Grantly Dec 15 '17 at 17:45
  • Yes I do wafffle on I know....But OP could be worried about portability...could be running Virtual machines etc... How do you know he/she is using xubuntu? Is that like X on linux? – Grantly Dec 15 '17 at 17:52
1

Your chmod would clear all bits rather than set any

if(chmod(fileName, fileSt.st_mode & 07777))

You need to make sure the copy is marked at least executable, maybe readable as well,(I'm not sure if a user has to have read permission to execute something but it would make sense.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • Read permission is not needed to execute - as long as the execute flag is set anyone can execute the binary, even if they don't have read permission (true on Unix/POSIX not sure about other systems likes windows) – Ankush Dec 15 '17 at 18:41