[FFmpeg-devel] [libav-devel] [PATCH 2/6] avio: add avio_check()
Stefano Sabatini
stefano.sabatini-lala at poste.it
Tue Apr 12 19:34:59 CEST 2011
On date Tuesday 2011-04-12 10:23:54 +0200, Anton Khirnov wrote:
> From: Stefano Sabatini <stefano.sabatini-lala at poste.it>
>
> The new function is more flexible than url_exist(), as it allows to
> specify which access flags to check, and does not require an explicit
> open of the checked resource.
>
> Signed-off-by: Anton Khirnov <anton at khirnov.net>
> ---
> libavformat/avio.c | 19 +++++++++++++++++++
> libavformat/avio.h | 15 +++++++++++++++
> libavformat/url.h | 1 +
> 3 files changed, 35 insertions(+), 0 deletions(-)
>
> diff --git a/libavformat/avio.c b/libavformat/avio.c
> index ad1f1b4..18b2ee6 100644
> --- a/libavformat/avio.c
> +++ b/libavformat/avio.c
> @@ -374,6 +374,25 @@ int url_exist(const char *filename)
> return 1;
> }
>
> +int avio_check(const char *url, int flags)
> +{
> + URLContext *h;
> + int ret = ffurl_alloc(&h, url, flags);
> + if (ret)
> + return ret;
> +
> + if (h->prot->url_check) {
> + ret = h->prot->url_check(h, flags);
> + } else {
> + ret = ffurl_connect(h);
> + if (ret >= 0)
> + ret = flags;
> + }
> +
> + ffurl_close(h);
> + return ret;
> +}
> +
> int64_t ffurl_size(URLContext *h)
> {
> int64_t pos, size;
> diff --git a/libavformat/avio.h b/libavformat/avio.h
> index b980d49..285c9c7 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -134,6 +134,7 @@ typedef struct URLProtocol {
> int priv_data_size;
> const AVClass *priv_data_class;
> int flags;
> + int (*url_check)(URLContext *h, int mask);
> } URLProtocol;
>
> typedef struct URLPollEntry {
> @@ -347,6 +348,20 @@ attribute_deprecated int url_close_buf(AVIOContext *s);
> int url_exist(const char *url);
>
> /**
> + * Return AVIO_* access flags corresponding to the access permissions
> + * of the resource in url, or a negative value corresponding to an
> + * AVERROR code in case of failure. The returned access flags are
> + * masked by the value in flags.
> + *
> + * @note This function is intrinsically unsafe, in the sense that the
> + * checked resource may change its existence or permission status from
> + * one call to another. Thus you should not trust the returned value,
> + * unless you are sure that no other processes are accessing the
> + * checked resource.
> + */
> +int avio_check(const char *url, int flags);
Please don't apply this since there is a problem with it.
#define AVIO_RDONLY 0 /**< read-only */
#define AVIO_WRONLY 1 /**< write-only */
#define AVIO_RDWR 2 /**< read-write */
Indeed AVIO_* are not flags but modes, and it doesn't much sense
OR-ing them, so for example
AVIO_RDONLY|AVIO_WRONLY == AVIO_WRONLY.
and with this patch we have:
avio_check(url, 0) == 0 -> check for existence
equivalent to
avio_check(url, AVIO_RDONLY) == AVIO_RDONLY -> check for exclusive readability
which doesn't look right (while the fact that we don't open the
resource still avoids the lock, and thus fixes roundup issue 1663).
A possible solution discussed with Anton would be to make AVIO_*
constansts proper flags.
For example we could replace the AVIO_RDONLY and AVIO_WRONLY constants
like this:
#define AVIO_FLAG_RD 1
#define AVIO_FLAG_WR 2
or simply redefine them at the next major bump, but before that the
logic of this avio_check() is broken.
Another possibility:
make avio_check() accept and return flags obtained by shifting 1 by
AVIO_* mode value, for example:
// check for existence
avio_check(url, 0) == 0
// check for exclusive readability
avio_check(url, (1<<AVIO_RDONLY)) > 0
// check for readability
avio_check(url, (1<<AVIO_RDONLY)|(1<<AVIO_RDWR)) > 0
but not very nice from the usability POV.
I'm greatly sorry for not having noticed this problem before.
More information about the ffmpeg-devel
mailing list