Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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 "config.h"
20
#include "file.h"
21
#include "internal.h"
22
#include "log.h"
23
#include "mem.h"
24
#include 
25
#include 
26
#if HAVE_UNISTD_H
27
#include 
28
#endif
29
#if HAVE_MMAP
30
#include 
31
#endif
32
 
33
typedef struct {
34
    const AVClass *class;
35
    int   log_offset;
36
    void *log_ctx;
37
} FileLogContext;
38
 
39
static const AVClass file_log_ctx_class = {
40
    "FILE", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT,
41
    offsetof(FileLogContext, log_offset), offsetof(FileLogContext, log_ctx)
42
};
43
 
44
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size,
45
                int log_offset, void *log_ctx)
46
{
47
    FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
48
    int err, fd = avpriv_open(filename, O_RDONLY);
49
    struct stat st;
50
    av_unused void *ptr;
51
    off_t off_size;
52
    char errbuf[128];
53
    *bufptr = NULL;
54
 
55
    if (fd < 0) {
56
        err = AVERROR(errno);
57
        av_strerror(err, errbuf, sizeof(errbuf));
58
        av_log(&file_log_ctx, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, errbuf);
59
        return err;
60
    }
61
 
62
    if (fstat(fd, &st) < 0) {
63
        err = AVERROR(errno);
64
        av_strerror(err, errbuf, sizeof(errbuf));
65
        av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in fstat(): %s\n", errbuf);
66
        close(fd);
67
        return err;
68
    }
69
 
70
    off_size = st.st_size;
71
    if (off_size > SIZE_MAX) {
72
        av_log(&file_log_ctx, AV_LOG_ERROR,
73
               "File size for file '%s' is too big\n", filename);
74
        close(fd);
75
        return AVERROR(EINVAL);
76
    }
77
    *size = off_size;
78
 
79
#if HAVE_MMAP
80
    ptr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
81
    if (ptr == MAP_FAILED) {
82
        err = AVERROR(errno);
83
        av_strerror(err, errbuf, sizeof(errbuf));
84
        av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in mmap(): %s\n", errbuf);
85
        close(fd);
86
        return err;
87
    }
88
    *bufptr = ptr;
89
#elif HAVE_MAPVIEWOFFILE
90
    {
91
        HANDLE mh, fh = (HANDLE)_get_osfhandle(fd);
92
 
93
        mh = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL);
94
        if (!mh) {
95
            av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in CreateFileMapping()\n");
96
            close(fd);
97
            return -1;
98
        }
99
 
100
        ptr = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, *size);
101
        CloseHandle(mh);
102
        if (!ptr) {
103
            av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in MapViewOfFile()\n");
104
            close(fd);
105
            return -1;
106
        }
107
 
108
        *bufptr = ptr;
109
    }
110
#else
111
    *bufptr = av_malloc(*size);
112
    if (!*bufptr) {
113
        av_log(&file_log_ctx, AV_LOG_ERROR, "Memory allocation error occurred\n");
114
        close(fd);
115
        return AVERROR(ENOMEM);
116
    }
117
    read(fd, *bufptr, *size);
118
#endif
119
 
120
    close(fd);
121
    return 0;
122
}
123
 
124
void av_file_unmap(uint8_t *bufptr, size_t size)
125
{
126
#if HAVE_MMAP
127
    munmap(bufptr, size);
128
#elif HAVE_MAPVIEWOFFILE
129
    UnmapViewOfFile(bufptr);
130
#else
131
    av_free(bufptr);
132
#endif
133
}
134
 
135
int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) {
136
    FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
137
    int fd=-1;
138
#if !HAVE_MKSTEMP
139
    void *ptr= tempnam(NULL, prefix);
140
    if(!ptr)
141
        ptr= tempnam(".", prefix);
142
    *filename = av_strdup(ptr);
143
#undef free
144
    free(ptr);
145
#else
146
    size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
147
    *filename = av_malloc(len);
148
#endif
149
    /* -----common section-----*/
150
    if (*filename == NULL) {
151
        av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
152
        return AVERROR(ENOMEM);
153
    }
154
#if !HAVE_MKSTEMP
155
#   ifndef O_BINARY
156
#       define O_BINARY 0
157
#   endif
158
#   ifndef O_EXCL
159
#       define O_EXCL 0
160
#   endif
161
    fd = open(*filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
162
#else
163
    snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
164
    fd = mkstemp(*filename);
165
#ifdef _WIN32
166
    if (fd < 0) {
167
        snprintf(*filename, len, "./%sXXXXXX", prefix);
168
        fd = mkstemp(*filename);
169
    }
170
#endif
171
#endif
172
    /* -----common section-----*/
173
    if (fd < 0) {
174
        int err = AVERROR(errno);
175
        av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
176
        av_freep(filename);
177
        return err;
178
    }
179
    return fd; /* success */
180
}
181
 
182
#ifdef TEST
183
 
184
#undef printf
185
 
186
int main(void)
187
{
188
    uint8_t *buf;
189
    size_t size;
190
    if (av_file_map("file.c", &buf, &size, 0, NULL) < 0)
191
        return 1;
192
 
193
    buf[0] = 's';
194
    printf("%s", buf);
195
    av_file_unmap(buf, size);
196
    return 0;
197
}
198
#endif
199