-
-
Save niw/8bc3c5dae610619e82f71a009c4d3197 to your computer and use it in GitHub Desktop.
Demonstrate how iCloud Drive is surprisingly unreliable.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <time.h> | |
#include <unistd.h> | |
/* | |
This super simple C code demonstrates how iCloud Drive is unreliable. | |
Obviously, this code is creating a temporary file first, then creating a backup then rename it to original one. | |
This is actually used in [OBS Studio](https://obsproject.com/) settings file writing. | |
Build this command with `clang`, | |
``` | |
clang a.c | |
``` | |
then run `a.out` in the iCloud Drive directory (`~/Library/Mobile Documents/com~apple~CloudDocs`). | |
You will see the following strange iCloud Drive behavior. | |
After 1st execution: | |
``` | |
test.txt | |
``` | |
OK, expected. | |
After 2nd execution: | |
``` | |
test.txt | |
test.txt.bak | |
``` | |
OK, expected. | |
After 3rd execution: | |
``` | |
test.txt | |
test.txt.txt | |
``` | |
Huh, where is `test.txt.bak` and what is `test.txt.txt` ?! | |
After 4th execution: | |
``` | |
test.txt | |
test.txt.bak | |
test.txt.txt | |
``` | |
Okay, keep going... | |
After 5th execution: | |
``` | |
test.txt | |
test.txt 2.txt | |
test.txt.txt | |
``` | |
Come on! what is `test.txt 2.txt` ?! | |
iCloud Drive seems like confused if `rename(3)` is executed in a sequence, | |
which is a totally valid operation. | |
*/ | |
int main() { | |
const char *file = "test.txt"; | |
const char *tmp = "test.txt.tmp"; | |
const char *bak = "test.txt.bak"; | |
FILE * const f = fopen(tmp, "w"); | |
if (f == NULL) { | |
return -1; | |
} | |
fprintf(f, "%ld\n", time(NULL)); | |
fclose(f); | |
if (access(file, F_OK) == 0) { | |
if (rename(file, bak) != 0) { | |
fprintf(stderr, "Failed to rename %s to %s.\n", file, bak); | |
return -1; | |
} | |
} | |
if (rename(tmp, file) != 0) { | |
fprintf(stderr, "Failed to rename %s to %s.\n", tmp, file); | |
return -1; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment