예제 #1
0
파일: open.c 프로젝트: Miguel-J/eneboo-core
/*
 *	 - file attribute setting, based on fileMode?
 *	 - handle other flags? (eg FILE_FLAG_NO_BUFFERING/FILE_FLAG_WRITE_THROUGH)
 */
int
win32_open(const char *fileName, int fileFlags,...)
{
	int			fd;
	HANDLE		h;
	SECURITY_ATTRIBUTES sa;

	/* Check that we can handle the request */
	assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND |
						 (O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) |
						 _O_SHORT_LIVED | O_DSYNC |
		  (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);

	sa.nLength = sizeof(sa);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	if ((h = CreateFile(fileName,
	/* cannot use O_RDONLY, as it == 0 */
					  (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
					 ((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ),
	/* These flags allow concurrent rename/unlink */
					(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
						&sa,
						openFlagsToCreateFileFlags(fileFlags),
						FILE_ATTRIBUTE_NORMAL |
					 ((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) |
			   ((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) |
			  ((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) |
				((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0) |
						((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0),
						NULL)) == INVALID_HANDLE_VALUE)
	{
		switch (GetLastError())
		{
				/* EMFILE, ENFILE should not occur from CreateFile. */
			case ERROR_PATH_NOT_FOUND:
			case ERROR_FILE_NOT_FOUND:
				errno = ENOENT;
				break;
			case ERROR_FILE_EXISTS:
				errno = EEXIST;
				break;
			case ERROR_ACCESS_DENIED:
				errno = EACCES;
				break;
			default:
				errno = EINVAL;
		}
		return -1;
	}

	/* _open_osfhandle will, on error, set errno accordingly */
	if ((fd = _open_osfhandle((long) h, fileFlags & O_APPEND)) < 0 ||
		(fileFlags & (O_TEXT | O_BINARY) && (_setmode(fd, fileFlags & (O_TEXT | O_BINARY)) < 0)))
		CloseHandle(h);			/* will not affect errno */
	return fd;
}
예제 #2
0
/*
 *	 - file attribute setting, based on fileMode?
 */
int
pgwin32_open(const char *fileName, int fileFlags,...)
{
    int			fd;
    HANDLE		h = INVALID_HANDLE_VALUE;
    SECURITY_ATTRIBUTES sa;
    int			loops = 0;

    /* Check that we can handle the request */
    assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND |
                         (O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) |
                         _O_SHORT_LIVED | O_DSYNC | O_DIRECT |
                         (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);

    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    while ((h = CreateFile(fileName,
                           /* cannot use O_RDONLY, as it == 0 */
                           (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) :
                           ((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ),
                           /* These flags allow concurrent rename/unlink */
                           (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
                           &sa,
                           openFlagsToCreateFileFlags(fileFlags),
                           FILE_ATTRIBUTE_NORMAL |
                           ((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) |
                           ((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) |
                           ((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) |
                           ((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0) |
                           ((fileFlags & O_DIRECT) ? FILE_FLAG_NO_BUFFERING : 0) |
                           ((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0),
                           NULL)) == INVALID_HANDLE_VALUE)
    {
        /*
         * Sharing violation or locking error can indicate antivirus, backup
         * or similar software that's locking the file. Try again for 30 seconds
         * before giving up.
         */
        DWORD err = GetLastError();
        if (err == ERROR_SHARING_VIOLATION ||
                err == ERROR_LOCK_VIOLATION)
        {
            pg_usleep(100000);
            loops++;

#ifndef FRONTEND
            if (loops == 50)
                ereport(LOG,
                        (errmsg("could not open file \"%s\": %s", fileName,
                                (err == ERROR_SHARING_VIOLATION)?_("sharing violation"):_("lock violation")),
                         errdetail("Continuing to retry for 30 seconds."),
                         errhint("You might have antivirus, backup, or similar software interfering with the database system.")));
#endif

            if (loops < 300)
                continue;
        }

        _dosmaperr(err);
        return -1;
    }

    /* _open_osfhandle will, on error, set errno accordingly */
    if ((fd = _open_osfhandle((long) h, fileFlags & O_APPEND)) < 0)
        CloseHandle(h);			/* will not affect errno */
    else if (fileFlags & (O_TEXT | O_BINARY) &&
             _setmode(fd, fileFlags & (O_TEXT | O_BINARY)) < 0)
    {
        _close(fd);
        return -1;
    }

    return fd;
}