On Sat, Apr 09, 2011 at 02:47:35AM +0200, Stefano Sabatini wrote:
> From b563c12cb285f1e6eb8dc19d1a18323cd9280ea1 Mon Sep 17 00:00:00 2001
> From: Stefano Sabatini <stefano.sabatini-l...@poste.it>
> Date: Fri, 8 Apr 2011 18:32:25 +0200
> Subject: [PATCH] avio: add avio_check()
> 
> 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.
> ---
>  libavformat/avio.c |   19 +++++++++++++++++++
>  libavformat/avio.h |   15 +++++++++++++++
>  2 files changed, 34 insertions(+), 0 deletions(-)
> 
> diff --git a/libavformat/avio.c b/libavformat/avio.c
> index 7b066e3..cc57529 100644
> --- a/libavformat/avio.c
> +++ b/libavformat/avio.c
> @@ -362,6 +362,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)

When is ret > 0? A quick glance at ffurl_connect suggests that it
returns 0 on success or an AVERROR < 0 on error.

> +            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 03b6f6f..051c06e 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -127,6 +127,20 @@ attribute_deprecated void 
> url_set_interrupt_cb(URLInterruptCB *interrupt_cb);
>  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 intrinsecally unsafe, in the sense that the

nit: intrins_i_cally

> + * 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);
> +
> +/**
>   * The callback is called in blocking functions to test regulary if
>   * asynchronous interruption is needed. AVERROR_EXIT is returned
>   * in this case by the interrupted function. 'NULL' means no interrupt
> @@ -157,6 +171,7 @@ typedef struct URLProtocol {
>      int priv_data_size;
>      const AVClass *priv_data_class;
>      int flags;
> +    int (*url_check)(URLContext *h, int mask);
>  } URLProtocol;
>  
>  #if FF_API_REGISTER_PROTOCOL
> -- 
> 1.7.2.3
> 

> From 3337ee5fd1ca5772c293f76e7c15267077c8001f Mon Sep 17 00:00:00 2001
> From: Stefano Sabatini <stefano.sabatini-l...@poste.it>
> Date: Sat, 9 Apr 2011 01:32:37 +0200
> Subject: [PATCH] prefer avio_check() over url_exist()
> 
> The problem with url_exist() is that it tries to open a resource in
> RDONLY mode. If the file is a FIFO and there is already a reading
> client, the open() call will hang.
> 
> By using avio_check() with access mode of 0, the second reading
> process will check if the file exists without attempting to open it,
> thus avoiding the lock.
> 
> Fix issue #1663.
> ---
>  ffmpeg.c           |    2 +-
>  ffserver.c         |    4 ++--
>  libavformat/img2.c |    6 +++---
>  3 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/ffmpeg.c b/ffmpeg.c
> index 40e5e67..9153a5b 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -3870,7 +3870,7 @@ static void opt_output_file(const char *filename)
>              (strchr(filename, ':') == NULL ||
>               filename[1] == ':' ||
>               av_strstart(filename, "file:", NULL))) {
> -            if (url_exist(filename)) {
> +            if (avio_check(filename, 0) != AVERROR(ENOENT)) {
>                  if (!using_stdin) {
>                      fprintf(stderr,"File '%s' already exists. Overwrite ? 
> [y/N] ", filename);
>                      fflush(stderr);
> diff --git a/ffserver.c b/ffserver.c
> index 6e42979..5f165dd 100644
> --- a/ffserver.c
> +++ b/ffserver.c
> @@ -3684,7 +3684,7 @@ static void build_feed_streams(void)
>      for(feed = first_feed; feed != NULL; feed = feed->next_feed) {
>          int fd;
>  
> -        if (url_exist(feed->feed_filename)) {
> +        if (url_check(feed->feed_filename, URL_RDONLY)) {

Ehm...

Otherwise the patches looks good. I can confirm that it really solves
1663.

-- 
Anton Khirnov

Attachment: signature.asc
Description: Digital signature

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to