/**************************************************************************/ /* */ /* OCaml */ /* */ /* Xavier Leroy and Pascal Cuoq, projet Cristal, INRIA Rocquencourt */ /* */ /* Copyright 1996 Institut National de Recherche en Informatique et */ /* en Automatique. */ /* */ /* All rights reserved. This file is distributed under the terms of */ /* the GNU Lesser General Public License version 2.1, with the */ /* special exception on linking described in the file LICENSE. */ /* */ /**************************************************************************/ #define CAML_INTERNALS #include #include #include #include #include "unixsupport.h" #include static int open_access_flags[15] = { GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static int open_create_flags[15] = { 0, 0, 0, 0, 0, O_CREAT, O_TRUNC, O_EXCL, 0, 0, 0, 0, 0, 0, 0 }; static int open_share_flags[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FILE_SHARE_DELETE, 0, 0 }; enum { CLOEXEC = 1, KEEPEXEC = 2 }; static int open_cloexec_flags[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CLOEXEC, KEEPEXEC }; CAMLprim value caml_unix_open(value path, value flags, value perm) { int fileaccess, createflags, fileattrib, filecreate, sharemode, cloexec; SECURITY_ATTRIBUTES attr; HANDLE h; wchar_t * wpath; caml_unix_check_path(path, "open"); fileaccess = caml_convert_flag_list(flags, open_access_flags); sharemode = FILE_SHARE_READ | FILE_SHARE_WRITE | caml_convert_flag_list(flags, open_share_flags); createflags = caml_convert_flag_list(flags, open_create_flags); if ((createflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) filecreate = CREATE_NEW; else if ((createflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) filecreate = CREATE_ALWAYS; else if (createflags & O_TRUNC) filecreate = TRUNCATE_EXISTING; else if (createflags & O_CREAT) filecreate = OPEN_ALWAYS; else filecreate = OPEN_EXISTING; if ((createflags & O_CREAT) && (Int_val(perm) & 0200) == 0) fileattrib = FILE_ATTRIBUTE_READONLY; else fileattrib = FILE_ATTRIBUTE_NORMAL; cloexec = caml_convert_flag_list(flags, open_cloexec_flags); attr.nLength = sizeof(attr); attr.lpSecurityDescriptor = NULL; attr.bInheritHandle = cloexec & CLOEXEC ? FALSE : cloexec & KEEPEXEC ? TRUE : !caml_unix_cloexec_default; wpath = caml_stat_strdup_to_utf16(String_val(path)); h = CreateFile(wpath, fileaccess, sharemode, &attr, filecreate, fileattrib, NULL); caml_stat_free(wpath); if (h == INVALID_HANDLE_VALUE) { caml_win32_maperr(GetLastError()); caml_uerror("open", path); } return caml_win32_alloc_handle(h); }