Statistics
| Branch: | Revision:

ffmpeg / libavutil / file.c @ f02cbc45

History | View | Annotate | Download (3.23 KB)

1
/*
2
 * This file is part of FFmpeg.
3
 *
4
 * FFmpeg is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * FFmpeg is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with FFmpeg; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18

    
19
#include "file.h"
20
#include <fcntl.h>
21
#include <sys/stat.h>
22
#include <unistd.h>
23
#if HAVE_MMAP
24
#include <sys/mman.h>
25
#endif
26

    
27
typedef struct {
28
    const AVClass *class;
29
    int   log_offset;
30
    void *log_ctx;
31
} FileLogContext;
32

    
33
static const AVClass file_log_ctx_class = {
34
    "FILE", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT,
35
    offsetof(FileLogContext, log_offset), offsetof(FileLogContext, log_ctx)
36
};
37

    
38
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size,
39
                int log_offset, void *log_ctx)
40
{
41
    FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
42
    int err, fd = open(filename, O_RDONLY);
43
    struct stat st;
44
    av_unused void *ptr;
45
    off_t off_size;
46
    char errbuf[128];
47
    size_t max_size = HAVE_MMAP ? SIZE_MAX : FF_INTERNAL_MEM_TYPE_MAX_VALUE;
48
    *bufptr = NULL;
49

    
50
    if (fd < 0) {
51
        err = AVERROR(errno);
52
        av_strerror(err, errbuf, sizeof(errbuf));
53
        av_log(&file_log_ctx, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, errbuf);
54
        return err;
55
    }
56

    
57
    if (fstat(fd, &st) < 0) {
58
        err = AVERROR(errno);
59
        av_strerror(err, errbuf, sizeof(errbuf));
60
        av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in fstat(): %s\n", errbuf);
61
        close(fd);
62
        return err;
63
    }
64

    
65
    off_size = st.st_size;
66
    if (off_size > max_size) {
67
        av_log(&file_log_ctx, AV_LOG_ERROR,
68
               "File size for file '%s' is too big\n", filename);
69
        close(fd);
70
        return AVERROR(EINVAL);
71
    }
72
    *size = off_size;
73

    
74
#if HAVE_MMAP
75
    ptr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
76
    if ((int)(ptr) == -1) {
77
        err = AVERROR(errno);
78
        av_strerror(err, errbuf, sizeof(errbuf));
79
        av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in mmap(): %s\n", errbuf);
80
        close(fd);
81
        return err;
82
    }
83
    *bufptr = ptr;
84
#else
85
    *bufptr = av_malloc(*size);
86
    if (!*bufptr) {
87
        av_log(&file_log_ctx, AV_LOG_ERROR, "Memory allocation error occurred\n");
88
        close(fd);
89
        return AVERROR(ENOMEM);
90
    }
91
    read(fd, *bufptr, *size);
92
#endif
93

    
94
    close(fd);
95
    return 0;
96
}
97

    
98
void av_file_unmap(uint8_t *bufptr, size_t size)
99
{
100
#if HAVE_MMAP
101
    munmap(bufptr, size);
102
#else
103
    av_free(bufptr);
104
#endif
105
}
106

    
107
#ifdef TEST
108

    
109
#undef printf
110

    
111
int main(void)
112
{
113
    uint8_t *buf;
114
    size_t size;
115
    if (av_file_map("file.c", &buf, &size, 0, NULL) < 0)
116
        return 1;
117

    
118
    buf[0] = 's';
119
    printf("%s", buf);
120
    av_file_unmap(buf, size);
121
    return 0;
122
}
123
#endif