Пример #1
0
int get_fd_from_cache(FDcache fd_cache, const char path[], off_t* pst_size) {
	struct pathfd_t* p;
	int fd;
	struct stat stat_buf;
	if (fd_cache == NULL) return -1;
	if (strlen(path) >= FD_CACHE_MAX_PATH_LEN - 1) return -1;
	for (p = fd_cache->a; p != fd_cache->aend; ++p) {
		if (!strcmp(p->path, path)) {
			*pst_size = p->st_size;
			return p->fd;
		}
	} 
	if ((fd = add_fd_to_cache(fd_cache, path, pst_size)) == -1) {
		if ((fd = open(fd_cache->dir_prefix_buf, O_RDONLY|O_NONBLOCK)) == -1)
			return -1;
    	if (fstat(fd, &stat_buf) == -1) {
        	logfl(fd_cache->logger, "fstat error: %s", strerror(errno));
        	return -1;
    	}
		*pst_size = stat_buf.st_size;
		return fd;
	} else {
		return fd;
	}
}
Пример #2
0
/***********************************************************************
 *           server_get_unix_fd
 *
 * The returned unix_fd should be closed iff needs_close is non-zero.
 */
int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
                        int *needs_close, enum server_fd_type *type, unsigned int *options )
{
    sigset_t sigset;
    obj_handle_t fd_handle;
    int ret = 0, fd;
    unsigned int access = 0;

    *unix_fd = -1;
    *needs_close = 0;
    wanted_access &= FILE_READ_DATA | FILE_WRITE_DATA;

    server_enter_uninterrupted_section( &fd_cache_section, &sigset );

    fd = get_cached_fd( handle, type, &access, options );
    if (fd != -1) goto done;

    SERVER_START_REQ( get_handle_fd )
    {
        req->handle = wine_server_obj_handle( handle );
        if (!(ret = wine_server_call( req )))
        {
            if (type) *type = reply->type;
            if (options) *options = reply->options;
            access = reply->access;
            if ((fd = receive_fd( &fd_handle )) != -1)
            {
                assert( wine_server_ptr_handle(fd_handle) == handle );
                *needs_close = (reply->removable ||
                                !add_fd_to_cache( handle, fd, reply->type,
                                                  reply->access, reply->options ));
            }
            else ret = STATUS_TOO_MANY_OPENED_FILES;
        }
    }
    SERVER_END_REQ;

done:
    server_leave_uninterrupted_section( &fd_cache_section, &sigset );
    if (!ret && ((access & wanted_access) != wanted_access))
    {
        ret = STATUS_ACCESS_DENIED;
        if (*needs_close) close( fd );
    }
    if (!ret) *unix_fd = fd;
    return ret;
}