int FS()

in utils/fs/fs.c [105:196]


int FS(swopen) (const wchar_t* filename, int oflag, int shflag, int pmode)
{
  /* Construct access mode.  */
  DWORD dwDesiredAccess = 0;
  if (HAS_FLAG (oflag, _O_RDONLY))
    dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES;
  if (HAS_FLAG (oflag, _O_RDWR))
    dwDesiredAccess |= GENERIC_WRITE | GENERIC_READ | FILE_READ_DATA |
                       FILE_WRITE_DATA | FILE_READ_ATTRIBUTES |
                       FILE_WRITE_ATTRIBUTES;
  if (HAS_FLAG (oflag,  _O_WRONLY))
    dwDesiredAccess|= GENERIC_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES;

  /* Construct shared mode.  */
  DWORD dwShareMode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
  if (HAS_FLAG (shflag, _SH_DENYRW))
    dwShareMode &= ~(FILE_SHARE_READ | FILE_SHARE_WRITE);
  if (HAS_FLAG (shflag, _SH_DENYWR))
    dwShareMode &= ~FILE_SHARE_WRITE;
  if (HAS_FLAG (shflag, _SH_DENYRD))
    dwShareMode &= ~FILE_SHARE_READ;
  if (HAS_FLAG (pmode, _S_IWRITE))
    dwShareMode |= FILE_SHARE_READ | FILE_SHARE_WRITE;
  if (HAS_FLAG (pmode, _S_IREAD))
    dwShareMode |= FILE_SHARE_READ;

  /* Override access mode with pmode if creating file.  */
  if (HAS_FLAG (oflag, _O_CREAT))
    {
      if (HAS_FLAG (pmode, _S_IWRITE))
        dwDesiredAccess |= FILE_GENERIC_WRITE;
      if (HAS_FLAG (pmode, _S_IREAD))
        dwDesiredAccess |= FILE_GENERIC_READ;
    }

  /* Create file disposition.  */
  DWORD dwCreationDisposition = OPEN_EXISTING;
  if (HAS_FLAG (oflag, _O_CREAT))
    dwCreationDisposition = OPEN_ALWAYS;
  if (HAS_FLAG (oflag, (_O_CREAT | _O_EXCL)))
    dwCreationDisposition = CREATE_NEW;
  if (HAS_FLAG (oflag, _O_TRUNC) && !HAS_FLAG (oflag, _O_CREAT))
    dwCreationDisposition = TRUNCATE_EXISTING;

  /* Set file access attributes.  */
  DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
  if (HAS_FLAG (oflag, _O_RDONLY))
    dwFlagsAndAttributes |= 0; /* No special attribute.  */
  if (HAS_FLAG (oflag, (_O_CREAT | _O_TEMPORARY)))
    dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
  if (HAS_FLAG (oflag, (_O_CREAT | _O_SHORT_LIVED)))
    dwFlagsAndAttributes |= FILE_ATTRIBUTE_TEMPORARY;
  if (HAS_FLAG (oflag, _O_RANDOM))
    dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
  if (HAS_FLAG (oflag, _O_SEQUENTIAL))
    dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
  /* Flag is only valid on it's own.  */
  if (dwFlagsAndAttributes != FILE_ATTRIBUTE_NORMAL)
    dwFlagsAndAttributes &= ~FILE_ATTRIBUTE_NORMAL;

  /* Set security attributes.  */
  SECURITY_ATTRIBUTES securityAttributes;
  ZeroMemory (&securityAttributes, sizeof(SECURITY_ATTRIBUTES));
  securityAttributes.bInheritHandle       = !(oflag & _O_NOINHERIT);
  securityAttributes.lpSecurityDescriptor = NULL;
  securityAttributes.nLength              = sizeof(SECURITY_ATTRIBUTES);

  wchar_t* _filename = __hs_create_device_name (filename);
  if (!_filename)
    return -1;

  HANDLE hResult
    = CreateFileW (_filename, dwDesiredAccess, dwShareMode, &securityAttributes,
                   dwCreationDisposition, dwFlagsAndAttributes, NULL);
  free (_filename);
  if (INVALID_HANDLE_VALUE == hResult)
    return -1;

  /* Now we have a Windows handle, we have to convert it to an FD and apply
     the remaining flags.  */
  const int flag_mask = _O_APPEND | _O_RDONLY | _O_TEXT | _O_WTEXT;
  int fd = _open_osfhandle ((intptr_t)hResult, oflag & flag_mask);
  if (-1 == fd)
    return -1;

  /* Finally we can change the mode to the requested one.  */
  const int mode_mask = _O_TEXT | _O_BINARY | _O_U16TEXT | _O_U8TEXT | _O_WTEXT;
  if ((oflag & mode_mask) && (-1 == _setmode (fd, oflag & mode_mask)))
    return -1;

  return fd;
}