2 of 2 fixed off-by-one error (credit to @WilliamMorris)

I think that a more idiomatic C interface would be

ssize_t file_get_content(const char *file_name, char *content[]);

Returning the number of bytes actually read would be analogous to read(2) and printf(3). On error, the return value could be -1, and the reason would be in errno. For consistency, I would have file_save_content() return the number of bytes written, or -1 on error.

It would be convenient if you allocated an extra byte and appended a \0 terminator to the result. Then the caller has the option to treat the buffer as a null-terminated string, if it believes the file to contain text. It would still be able to treat it as binary data (possibly containing NUL bytes) based on the return value.

When getting the contents of an empty file, I would expect it to produce an "empty" buffer, not a NULL pointer.

There is a possibility of a race condition: the file could be truncated between the stat() and the fread(). You could actually handle that case a bit more gracefully.

int file_get_content(const char *file_name, char *buf[]) {
    struct stat file_stat;
    if (0 != stat(file_name, &file_stat)) {
        return -1;
    }

    if (NULL == (*buf = 1 + malloc(file_stat.st_size))) {
        return -1;
    }

    FILE *file;
    if (NULL == (file = fopen(file_name, "rb"))) {
        free(*buf);
        return -1;
    }

    ssize_t bytes_read = fread(*buf, 1, file_stat.st_size, file);
    (*buf)[bytes_read] = '\0';
    fclose(file);
    return bytes_read;
}

In file_save_content(), avoid tmpnam(), which allows a race condition between the time you call tmpnam() and fopen(). Also, rename() would fail unless the temporary file and the destination are on the same filesystem. As an alternative, I would recommend mkstemp() with the destination filename plus a ".XXXXXX" suffix, followed by fdopen().

As a nitpick, I'd prefer unlink() over remove(), since the former refuses to remove directories.

In the error handlers of file_save_content(), save and restore errno, because it would be more useful for the caller to see the original reason for the failure rather than a problem with the subsequent cleanup.