word_t file_open(struct object_heap* oh, struct ByteArray * name, word_t flags) { byte_t nameString[SLATE_FILE_NAME_LENGTH]; word_t nameLength; #ifdef WIN32 DWORD rwMode = 0; DWORD openMode = 0; #else char mode[8]; word_t modeIndex = 0; #endif word_t file; nameLength = extractCString(name, nameString, sizeof(nameString)); if (nameLength <= 0) return SLATE_ERROR_RETURN; file = file_allocate(oh); if (file < 0) return SLATE_ERROR_RETURN; /* (CLEAR \/ CREATE) /\ !WRITE */ if ((flags & SF_CLEAR || flags & SF_CREATE) && (! (flags & SF_WRITE))) error("ANSI does not support clearing or creating files that are not opened for writing"); /* WRITE /\ !READ */ if (flags & SF_WRITE && (! (flags & SF_READ))) error("ANSI does not support opening files for writing only"); if (flags & SF_WRITE) { if (flags & SF_CLEAR) { #ifdef WIN32 rwMode |= GENERIC_WRITE; #else mode[modeIndex++] = 'w'; #endif if (flags & SF_READ) #ifdef WIN32 rwMode |= GENERIC_READ; #else mode[modeIndex++] = '+'; #endif } else { #ifdef WIN32 rwMode |= GENERIC_READ; #else mode[modeIndex++] = 'r'; mode[modeIndex++] = '+'; #endif } } else if (flags & SF_READ) #ifdef WIN32 rwMode |= GENERIC_READ; #else mode[modeIndex++] = 'r'; #endif else {
FILE* fopen(const char* filename, const char* mode) { bool result = false; bool mode_r = false; bool mode_w = false; bool mode_a = false; bool mode_r_plus = false; bool mode_w_plus = false; bool mode_a_plus = false; bool mode_t = false; bool mode_b = false; int num_rwa; int flags = 0; int pmode = 0; int fd = -1; _FILE* file = NULL; if (filename == NULL || mode == NULL) return NULL; file = file_allocate(); if (file == NULL) return NULL; while (*mode != 0) { switch (*mode) { case 'r': if (*(mode+1) == '+') { mode_r_plus = true; mode++; } else mode_r = true; break; case 'w': if (*(mode+1) == '+') { mode_w_plus = true; mode++; } else mode_w = true; break; case 'a': if (*(mode+1) == '+') { mode_a_plus = true; mode++; } else mode_a = true; break; case 't': mode_t = true; break; case 'b': mode_b = true; break; } mode++; } num_rwa = 0; if (mode_r) num_rwa++; if (mode_w) num_rwa++; if (mode_a) num_rwa++; if (mode_r_plus) num_rwa++; if (mode_w_plus) num_rwa++; if (mode_a_plus) num_rwa++; if (num_rwa != 1) goto cleanup; if (mode_t && mode_b) goto cleanup; // r = O_RDONLY // w = O_CREAT|O_TRUNC | O_WRONLY // a = O_CREAT | O_WRONLY | O_APPEND // r+ = O_RDWR // w+ = O_CREAT|O_TRUNC | O_RDWR // a+ = O_CREAT | O_RDWR | O_APPEND if (mode_w || mode_a || mode_w_plus || mode_a_plus) { flags |= O_CREAT; pmode = S_IREAD | S_IWRITE; } if (mode_w || mode_w_plus) flags |= O_TRUNC; if (mode_r) flags |= O_RDONLY; else if (mode_w || mode_a) flags |= O_WRONLY; else flags |= O_RDWR; if (mode_a || mode_a_plus) flags |= O_APPEND; if (mode_t) flags |= O_TEXT; if (mode_b) flags |= O_BINARY; fd = open(filename, flags, pmode); if (fd == -1) goto cleanup; file->fd = fd; file->bufferedChar = -1; file->error = FALSE; result = true; cleanup: if (result == false) { if (file != NULL) { file_release(file); file = NULL; // returned below } if (fd != -1) close(fd); } return (FILE*)file; }