2017-03-25 09:21:39 +00:00
|
|
|
/**
|
|
|
|
* The MIT License (MIT)
|
|
|
|
*
|
2019-01-01 13:37:28 +00:00
|
|
|
* Copyright (c) 2013-2019 Winlin
|
2017-03-25 09:21:39 +00:00
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
|
|
* the Software without restriction, including without limitation the rights to
|
|
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
|
|
* subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
|
|
* copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
2014-07-04 23:33:18 +00:00
|
|
|
|
|
|
|
#include <srs_kernel_file.hpp>
|
|
|
|
|
2015-11-11 02:37:50 +00:00
|
|
|
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
|
2014-11-19 08:16:04 +00:00
|
|
|
#ifndef _WIN32
|
2014-07-04 23:33:18 +00:00
|
|
|
#include <unistd.h>
|
2015-08-18 06:08:54 +00:00
|
|
|
#include <sys/uio.h>
|
2014-11-19 08:16:04 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
2014-07-04 23:33:18 +00:00
|
|
|
#include <sstream>
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
#include <srs_kernel_log.hpp>
|
|
|
|
#include <srs_kernel_error.hpp>
|
|
|
|
|
2019-05-13 00:48:53 +00:00
|
|
|
// For utest to mock it.
|
|
|
|
_srs_open_t _srs_open_fn = ::open;
|
|
|
|
_srs_write_t _srs_write_fn = ::write;
|
2019-05-14 00:13:27 +00:00
|
|
|
_srs_read_t _srs_read_fn = ::read;
|
2019-05-13 00:48:53 +00:00
|
|
|
_srs_lseek_t _srs_lseek_fn = ::lseek;
|
2019-05-14 00:24:43 +00:00
|
|
|
_srs_close_t _srs_close_fn = ::close;
|
2019-05-13 00:48:53 +00:00
|
|
|
|
2014-07-04 23:33:18 +00:00
|
|
|
SrsFileWriter::SrsFileWriter()
|
|
|
|
{
|
2014-07-05 15:29:45 +00:00
|
|
|
fd = -1;
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsFileWriter::~SrsFileWriter()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t SrsFileWriter::open(string p)
|
2014-07-04 23:33:18 +00:00
|
|
|
{
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t err = srs_success;
|
2014-07-04 23:33:18 +00:00
|
|
|
|
|
|
|
if (fd > 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_ALREADY_OPENED, "file %s already opened", p.c_str());
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int flags = O_CREAT|O_WRONLY|O_TRUNC;
|
|
|
|
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2019-05-13 00:48:53 +00:00
|
|
|
if ((fd = _srs_open_fn(p.c_str(), flags, mode)) < 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
2015-07-28 09:56:50 +00:00
|
|
|
path = p;
|
2014-07-04 23:33:18 +00:00
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
return err;
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t SrsFileWriter::open_append(string p)
|
2015-02-19 11:50:10 +00:00
|
|
|
{
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-02-19 11:50:10 +00:00
|
|
|
|
|
|
|
if (fd > 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_ALREADY_OPENED, "file %s already opened", path.c_str());
|
2015-02-19 11:50:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int flags = O_APPEND|O_WRONLY;
|
|
|
|
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2019-05-13 00:49:38 +00:00
|
|
|
if ((fd = _srs_open_fn(p.c_str(), flags, mode)) < 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
|
2015-02-19 11:50:10 +00:00
|
|
|
}
|
|
|
|
|
2015-07-28 09:56:50 +00:00
|
|
|
path = p;
|
2015-02-19 11:50:10 +00:00
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
return err;
|
2015-02-19 11:50:10 +00:00
|
|
|
}
|
|
|
|
|
2014-07-04 23:33:18 +00:00
|
|
|
void SrsFileWriter::close()
|
|
|
|
{
|
|
|
|
if (fd < 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-14 00:24:43 +00:00
|
|
|
if (_srs_close_fn(fd) < 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_warn("close file %s failed", path.c_str());
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
fd = -1;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SrsFileWriter::is_open()
|
|
|
|
{
|
|
|
|
return fd > 0;
|
|
|
|
}
|
|
|
|
|
2017-02-03 14:49:19 +00:00
|
|
|
void SrsFileWriter::seek2(int64_t offset)
|
2015-02-21 11:14:05 +00:00
|
|
|
{
|
2019-05-13 00:48:53 +00:00
|
|
|
off_t r0 = _srs_lseek_fn(fd, (off_t)offset, SEEK_SET);
|
2017-06-13 08:10:46 +00:00
|
|
|
srs_assert(r0 != -1);
|
2015-02-21 11:14:05 +00:00
|
|
|
}
|
|
|
|
|
2014-07-04 23:33:18 +00:00
|
|
|
int64_t SrsFileWriter::tellg()
|
|
|
|
{
|
2019-05-13 00:48:53 +00:00
|
|
|
return (int64_t)_srs_lseek_fn(fd, 0, SEEK_CUR);
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
|
2014-07-04 23:33:18 +00:00
|
|
|
{
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t err = srs_success;
|
2014-07-04 23:33:18 +00:00
|
|
|
|
|
|
|
ssize_t nwrite;
|
|
|
|
// TODO: FIXME: use st_write.
|
2019-12-23 10:12:45 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
if ((nwrite = ::_write(fd, buf, (unsigned int)count)) < 0) {
|
|
|
|
#else
|
2019-05-13 00:48:53 +00:00
|
|
|
if ((nwrite = _srs_write_fn(fd, buf, count)) < 0) {
|
2019-12-23 10:12:45 +00:00
|
|
|
#endif
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_WRITE, "write to file %s failed", path.c_str());
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pnwrite != NULL) {
|
|
|
|
*pnwrite = nwrite;
|
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
return err;
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t SrsFileWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite)
|
2015-05-24 14:43:02 +00:00
|
|
|
{
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-05-24 14:43:02 +00:00
|
|
|
|
|
|
|
ssize_t nwrite = 0;
|
|
|
|
for (int i = 0; i < iovcnt; i++) {
|
2017-01-30 11:35:04 +00:00
|
|
|
const iovec* piov = iov + i;
|
2015-05-24 14:43:02 +00:00
|
|
|
ssize_t this_nwrite = 0;
|
2017-12-31 04:11:48 +00:00
|
|
|
if ((err = write(piov->iov_base, piov->iov_len, &this_nwrite)) != srs_success) {
|
|
|
|
return srs_error_wrap(err, "write file");
|
2015-05-24 14:43:02 +00:00
|
|
|
}
|
|
|
|
nwrite += this_nwrite;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pnwrite) {
|
|
|
|
*pnwrite = nwrite;
|
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
return err;
|
2015-05-24 14:43:02 +00:00
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t SrsFileWriter::lseek(off_t offset, int whence, off_t* seeked)
|
2017-02-03 14:49:19 +00:00
|
|
|
{
|
2019-05-13 00:48:53 +00:00
|
|
|
off_t sk = _srs_lseek_fn(fd, offset, whence);
|
2017-02-03 14:49:19 +00:00
|
|
|
if (sk < 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_SEEK, "seek file");
|
2017-02-03 14:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (seeked) {
|
|
|
|
*seeked = sk;
|
|
|
|
}
|
2017-12-31 04:11:48 +00:00
|
|
|
|
|
|
|
return srs_success;
|
2017-02-03 14:49:19 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 11:32:41 +00:00
|
|
|
ISrsFileReaderFactory::ISrsFileReaderFactory()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ISrsFileReaderFactory::~ISrsFileReaderFactory()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SrsFileReader* ISrsFileReaderFactory::create_file_reader()
|
|
|
|
{
|
|
|
|
return new SrsFileReader();
|
|
|
|
}
|
|
|
|
|
2014-07-04 23:33:18 +00:00
|
|
|
SrsFileReader::SrsFileReader()
|
|
|
|
{
|
|
|
|
fd = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
SrsFileReader::~SrsFileReader()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t SrsFileReader::open(string p)
|
2014-07-04 23:33:18 +00:00
|
|
|
{
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t err = srs_success;
|
2014-07-04 23:33:18 +00:00
|
|
|
|
|
|
|
if (fd > 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_ALREADY_OPENED, "file %s already opened", path.c_str());
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2019-05-14 00:13:27 +00:00
|
|
|
if ((fd = _srs_open_fn(p.c_str(), O_RDONLY)) < 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_OPENE, "open file %s failed", p.c_str());
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
2015-07-28 09:56:50 +00:00
|
|
|
path = p;
|
2014-07-04 23:33:18 +00:00
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
return err;
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SrsFileReader::close()
|
|
|
|
{
|
|
|
|
int ret = ERROR_SUCCESS;
|
|
|
|
|
|
|
|
if (fd < 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-14 00:24:43 +00:00
|
|
|
if (_srs_close_fn(fd) < 0) {
|
2019-05-14 00:13:27 +00:00
|
|
|
srs_warn("close file %s failed. ret=%d", path.c_str(), ret);
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
fd = -1;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SrsFileReader::is_open()
|
|
|
|
{
|
|
|
|
return fd > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t SrsFileReader::tellg()
|
|
|
|
{
|
2019-05-14 00:13:27 +00:00
|
|
|
return (int64_t)_srs_lseek_fn(fd, 0, SEEK_CUR);
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SrsFileReader::skip(int64_t size)
|
|
|
|
{
|
2019-05-14 00:13:27 +00:00
|
|
|
off_t r0 = _srs_lseek_fn(fd, (off_t)size, SEEK_CUR);
|
2017-06-13 08:10:46 +00:00
|
|
|
srs_assert(r0 != -1);
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
2017-02-03 14:49:19 +00:00
|
|
|
int64_t SrsFileReader::seek2(int64_t offset)
|
2014-07-04 23:33:18 +00:00
|
|
|
{
|
2019-05-14 00:13:27 +00:00
|
|
|
return (int64_t)_srs_lseek_fn(fd, (off_t)offset, SEEK_SET);
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int64_t SrsFileReader::filesize()
|
|
|
|
{
|
|
|
|
int64_t cur = tellg();
|
2019-05-14 00:13:27 +00:00
|
|
|
int64_t size = (int64_t)_srs_lseek_fn(fd, 0, SEEK_END);
|
2017-06-13 08:10:46 +00:00
|
|
|
|
2019-05-14 00:13:27 +00:00
|
|
|
off_t r0 = _srs_lseek_fn(fd, (off_t)cur, SEEK_SET);
|
2017-06-13 08:10:46 +00:00
|
|
|
srs_assert(r0 != -1);
|
|
|
|
|
2014-07-04 23:33:18 +00:00
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t SrsFileReader::read(void* buf, size_t count, ssize_t* pnread)
|
2014-07-04 23:33:18 +00:00
|
|
|
{
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t err = srs_success;
|
2014-07-04 23:33:18 +00:00
|
|
|
|
|
|
|
ssize_t nread;
|
|
|
|
// TODO: FIXME: use st_read.
|
2019-12-23 10:12:45 +00:00
|
|
|
#ifdef _WIN32
|
2019-12-23 13:09:00 +00:00
|
|
|
if ((nread = _read(fd, buf, (unsigned int)count)) < 0) {
|
2019-12-23 10:12:45 +00:00
|
|
|
#else
|
2019-05-14 00:13:27 +00:00
|
|
|
if ((nread = _srs_read_fn(fd, buf, count)) < 0) {
|
2019-12-23 10:12:45 +00:00
|
|
|
#endif
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_READ, "read from file %s failed", path.c_str());
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (nread == 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_EOF, "file EOF");
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pnread != NULL) {
|
|
|
|
*pnread = nread;
|
|
|
|
}
|
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
return err;
|
2014-07-04 23:33:18 +00:00
|
|
|
}
|
2014-08-02 14:18:39 +00:00
|
|
|
|
2017-12-31 04:11:48 +00:00
|
|
|
srs_error_t SrsFileReader::lseek(off_t offset, int whence, off_t* seeked)
|
2017-02-03 14:49:19 +00:00
|
|
|
{
|
2019-05-14 00:13:27 +00:00
|
|
|
off_t sk = _srs_lseek_fn(fd, offset, whence);
|
2017-02-03 14:49:19 +00:00
|
|
|
if (sk < 0) {
|
2017-12-31 04:11:48 +00:00
|
|
|
return srs_error_new(ERROR_SYSTEM_FILE_SEEK, "seek %v failed", (int)sk);
|
2017-02-03 14:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (seeked) {
|
|
|
|
*seeked = sk;
|
|
|
|
}
|
2017-12-31 04:11:48 +00:00
|
|
|
|
|
|
|
return srs_success;
|
2017-02-03 14:49:19 +00:00
|
|
|
}
|
|
|
|
|