Description: When attempting to open a non-existent file on an iOS device, I observed inconsistent return values between the open function from the standard libc library and the kernel syscall (syscall number 5). While the libc open function returns -1, as expected and documented, the kernel syscall open function unexpectedly returns 2. This discrepancy necessitates clarification and documentation to understand the underlying behavior and ensure predictable results when working with file I/O operations in iOS.
Code snippet for ASM code:
#if defined(__arm64__)
#define __asm_syscall(...) do { \
asm volatile ("svc 0x80" : "=r"(x0) : __VA_ARGS__ : "memory", "cc"); \
return x0; \
} while (0)
__attribute__((always_inline))
static inline long asm_open(const void* __path, int __flags, int __mode) {
register long x16 __asm__("x16") = 5; // 5: open
register long x0 __asm__("x0") = (long)__path;
register long x1 __asm__("x1") = (long)__flags;
register long x2 __asm__("x2") = (long)__mode;
__asm_syscall("r"(x16), "0"(x0), "r"(x1), "r"(x2));
}
#endif
This is how I call the function:
char file_path[1024];
int fd = 0;
// Set the file path
strcpy(file_path, getenv("HOME"));
strcat(file_path, "/Documents/non-existent.txt");
// Open file
fd = (int)asm_open(file_path, (O_RDWR | O_CREAT), 0666); // -> This returns 2 instead of -1 like stand open function from libc
LOGI("[INFO] : Open %d", fd); // [INFO] : Open 2