|
#include <stdio.h> |
|
#include <string.h> |
|
#include <stdlib.h> |
|
#include <sys/errno.h> |
|
#include <sys/stat.h> |
|
#include <sys/types.h> |
|
|
|
int main() { |
|
char *name = "the_file_c.txt"; |
|
FILE *wf = fopen(name, "w"); |
|
if (wf == NULL) { |
|
printf("\033[31mFailed to open file: %s: %s\033[00m", name, strerror(errno)); |
|
exit(1); |
|
} |
|
|
|
int n = fprintf(wf, "abcdef"); |
|
if (n != 6) { |
|
fclose(wf); |
|
printf("\033[31mShort write: got %d want 6\033[00m", n); |
|
exit(1); |
|
} |
|
|
|
// Flush the stream |
|
fflush(wf); |
|
|
|
// Change the permission to be ONLY "-r--r--r--" |
|
if ((n = chmod(name, 0444)) != 0) { |
|
fclose(wf); |
|
printf("\033[31mFailed to chmod the file: %s\033[00m", strerror(n)); |
|
exit(1); |
|
} |
|
|
|
// Write more content to the file. |
|
fprintf(wf, "ghijkl"); |
|
fflush(wf); |
|
|
|
// Revert the permission change. |
|
if ((n = chmod(name, 0755)) != 0) { |
|
fclose(wf); |
|
printf("\033[31mFailed to revert permissions, got: %s\033[00m", strerror(n)); |
|
exit(1); |
|
} |
|
fclose(wf); |
|
|
|
struct stat *st; |
|
st = (struct stat*)malloc(sizeof(*st)); |
|
if (stat(name, st) != 0) { |
|
free(st); |
|
printf("\033[31mFailed to stat the file: %s\033[00m", strerror(errno)); |
|
exit(1); |
|
} |
|
|
|
size_t file_size = st->st_size; |
|
free(st); |
|
|
|
char *got = (char *)malloc(file_size); |
|
if (got == NULL) { |
|
printf("\033[31mMalloc failed: %s\033[00m", strerror(errno)); |
|
exit(1); |
|
} |
|
|
|
// Reopen it for purely reading. |
|
FILE *rf = fopen(name, "r"); |
|
|
|
if (fread(got, sizeof(*got), st->st_size, rf) < 0) { |
|
free(got); |
|
fclose(rf); |
|
printf("\033[31mFailed to read file: %s\033[00m", strerror(errno)); |
|
exit(1); |
|
} |
|
|
|
fclose(rf); |
|
|
|
const char *ideal_want = "abcdef"; |
|
if (strcmp(got, ideal_want) != 0) { |
|
printf("\033[31mUnfortunately mismatched content\nGot: %s\nWant: %s\n\033[00m", |
|
got, ideal_want); |
|
free(got); |
|
exit(1); |
|
} |
|
|
|
free(got); |
|
|
|
return 0; |
|
} |