0

I am trying to transfer files over a TCP connection, and I noticed that binary/executable files on Mac don't have file extensions. This doesn't seem to be a problem when reading from an existing binary file, but when trying to write to a new one, it creates a blank file with no extensions-nothing. How can I fix this? Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    char* filename = "helloworld";
    FILE* file = fopen(filename, "rb");
    FILE* writefile = fopen("test", "wb");
    fseek(file, 0, SEEK_END);
    unsigned int size = ftell(file);
    printf("Size of %s is: %d bytes\n", filename, size);
    fseek(file, 0, SEEK_SET);
    char* line = (char *) malloc(size+1);
    fread(line, size, 1, file);
    fwrite(line, size, 1, writefile);
    free(line);
    fclose(writefile);
    fclose(file);
    return 0;
}

helloworld is the existing executable I'm reading from (which is working) and I'm trying to write to a new executable which would be called test

Serket
  • 3,785
  • 3
  • 14
  • 45

2 Answers2

0

Your code looks fine (ignoring lack of error checking). You'll need to add x (executable) permission when the copy is done.

From the terminal, you can type chmod +x test.

From within the program:

#include <sys/types.h>
#include <sys/stat.h>

...

    fclose(writefile);
    fclose(file);
    chmod("test", S_IRWXU);
    return 0;
}
rtx13
  • 2,580
  • 1
  • 6
  • 22
  • 1
    If it’s blank, adding the executable bit isn’t going to make it not blank. – Ry- Apr 30 '20 at 07:07
  • thanks, is there a way I can do this through the c program? – Serket Apr 30 '20 at 07:07
  • @Ry- what do you mean? it worked – Serket Apr 30 '20 at 07:09
  • 1
    @Serket: You ran `chmod +x` on your blank file and content appeared inside it? How did you originally determine that it was blank? – Ry- Apr 30 '20 at 07:10
  • @Ry- the file executed just fine. It wouldn't let me run it prior to adding the x – Serket Apr 30 '20 at 07:12
  • 1
    @Serket so the file is not blank?? – Jabberwocky Apr 30 '20 at 07:12
  • @Jabberwocky no. it just wasn't an executable. it didn't have a file extension and therefore wouldn't run – Serket Apr 30 '20 at 07:13
  • 1
    @Serket: A lack of a file extension isn’t what makes it unable to run, and being unable to run doesn’t make it blank. Your question should probably be reworded a lot if it’s going to help people with the same problem in the future. Glad you got an answer, though. – Ry- Apr 30 '20 at 07:16
  • @Ry given the title, macos, mention of lack of filename extensions for executables, I read between the lines... – rtx13 Apr 30 '20 at 07:20
0

This is an example of the XY problem. You say it's about writing the file and naming it yet your real problem was that you cannot execute the output file. The latter is the real problem. You could have avoided considering the X by using diff to compare the two files. That would have encouraged you to consider the meta Y possibilities (i.e., permissions).

If your code executes stat on the input file, then it can execute meta functions like chmod and utime for the output file given values from the stat struct.

For example, if your code included this:

struct stat stat_filename; /* filename is an unsuitable name for such a variable */
if (stat(filename, &stat_filename)) {
    perror("cannot stat input file");
    exit(1);
}

Then after you finish writing the output file, you could do this:

if (chmod("test", stat_filename.st_mode)) { /* need variable to hold output filename */
    perror("cannot chmod output file");
    exit(1);
}

If you do it this way, then the output file will be closer to a "mirror" copy of the input file.

Jeff Holt
  • 2,940
  • 3
  • 22
  • 29