static struct input_stream *
input_file_open(const char *filename, GError **error_r)
{
	int fd, ret;
	struct stat st;
	struct file_input_stream *fis;

	if (!g_path_is_absolute(filename))
		return false;

	fd = open_cloexec(filename, O_RDONLY, 0);
	if (fd < 0) {
		if (errno != ENOENT && errno != ENOTDIR)
			g_set_error(error_r, file_quark(), errno,
				    "Failed to open \"%s\": %s",
				    filename, g_strerror(errno));
		return false;
	}

	ret = fstat(fd, &st);
	if (ret < 0) {
		g_set_error(error_r, file_quark(), errno,
			    "Failed to stat \"%s\": %s",
			    filename, g_strerror(errno));
		close(fd);
		return false;
	}

	if (!S_ISREG(st.st_mode)) {
		g_set_error(error_r, file_quark(), 0,
			    "Not a regular file: %s", filename);
		close(fd);
		return false;
	}

#ifdef POSIX_FADV_SEQUENTIAL
	posix_fadvise(fd, (off_t)0, st.st_size, POSIX_FADV_SEQUENTIAL);
#endif

	fis = g_new(struct file_input_stream, 1);
	input_stream_init(&fis->base, &input_plugin_file, filename);

	fis->base.size = st.st_size;
	fis->base.seekable = true;
	fis->base.ready = true;

	fis->fd = fd;

	return &fis->base;
}
static bool
input_file_seek(struct input_stream *is, goffset offset, int whence,
		GError **error_r)
{
	struct file_input_stream *fis = (struct file_input_stream *)is;

	offset = (goffset)lseek(fis->fd, (off_t)offset, whence);
	if (offset < 0) {
		g_set_error(error_r, file_quark(), errno,
			    "Failed to seek: %s", g_strerror(errno));
		return false;
	}

	is->offset = offset;
	return true;
}
static size_t
input_file_read(struct input_stream *is, void *ptr, size_t size,
		GError **error_r)
{
	struct file_input_stream *fis = (struct file_input_stream *)is;
	ssize_t nbytes;

	nbytes = read(fis->fd, ptr, size);
	if (nbytes < 0) {
		g_set_error(error_r, file_quark(), errno,
			    "Failed to read: %s", g_strerror(errno));
		return 0;
	}

	is->offset += nbytes;
	return (size_t)nbytes;
}
static struct input_stream *
input_file_open(const char *filename,
		GMutex *mutex, GCond *cond,
		GError **error_r)
{
	int fd, ret;
	struct stat st;
	struct file_input_stream *fis;

	if (!g_path_is_absolute(filename))
		return NULL;

	fd = open_cloexec(filename, O_RDONLY|O_BINARY, 0);
        if (fd < 0)  {
		// the filename doesn't exist	
		// try and open uri as if it were a track inside a container
		char* pathname = NULL;
		unsigned tnum;

		pathname = g_strdup(filename);
		remove_suffix(pathname,'/');

		tnum = cue_vtrack_tnum(filename);
		if ( tnum == 0 )
			tnum=1; // use filename from first track of cue file if no track found 
			
                if( g_str_has_suffix(pathname,".cue"))
                    pathname=cue_locate_audio_container_file(pathname,tnum) ;

		fd = open_cloexec(pathname, O_RDONLY|O_BINARY, 0);
		g_free(pathname);

		if (fd < 0) {
			if (errno != ENOENT && errno != ENOTDIR)
				g_set_error(error_r, file_quark(), errno,
						"Failed to open \"%s\": %s",
						filename, g_strerror(errno));
			return NULL;
		}
	}

	ret = fstat(fd, &st);
	if (ret < 0) {
		g_set_error(error_r, file_quark(), errno,
			    "Failed to stat \"%s\": %s",
			    filename, g_strerror(errno));
		close(fd);
		return NULL;
	}

	if (!S_ISREG(st.st_mode)) {
		g_set_error(error_r, file_quark(), 0,
			    "Not a regular file: %s", filename);
		close(fd);
		return NULL;
	}

#ifdef POSIX_FADV_SEQUENTIAL
	posix_fadvise(fd, (off_t)0, st.st_size, POSIX_FADV_SEQUENTIAL);
#endif

	fis = g_new(struct file_input_stream, 1);
	input_stream_init(&fis->base, &input_plugin_file, filename,
			  mutex, cond);

	fis->base.size = st.st_size;
	fis->base.seekable = true;
	fis->base.ready = true;

	fis->fd = fd;

	return &fis->base;
}