//------------------------------------------------------------------------------
//! @file XrdCpNonStreaming.cc
//! @author Elvin Sindrilaru - CERN
//------------------------------------------------------------------------------
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2021 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#include "XrdCl/XrdClFile.hh"
#include
#include
#include
#include
#include
//------------------------------------------------------------------------------
//! This executable simulates a client that writes a file in non-streaming mode.
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
if (argc < 3) {
std::cerr << "Usage: " << argv[0] << " \n"
<< " - local input file used as source of data\n"
<< " - XRootD URL where file is written\n"
<< std::endl;
exit(EINVAL);
}
std::string fn_path = argv[1];
std::string surl = argv[2];
XrdCl::URL url(surl);
if (!url.IsValid()) {
std::cerr << "error: given XRootD URL is not valid" << std::endl;
exit(EINVAL);
}
struct stat info;
if (stat(fn_path.c_str(), &info)) {
std::cerr << "error: failed to stat input file" << std::endl;
exit(EINVAL);
}
// Allocate buffer used for transfer
uint32_t block_size = 1024 * 1024;
std::unique_ptr buffer {new char[block_size + 3]};
// Open file and start writing
XrdCl::File file;
XrdCl::XRootDStatus status =
file.Open(surl, XrdCl::OpenFlags::Delete | XrdCl::OpenFlags::Write,
XrdCl::Access::UR | XrdCl::Access::UW);
if (!status.IsOK()) {
std::cerr << "error: unable to open file for writing, errno="
<< status.errNo << std::endl;
exit(status.errNo);
}
size_t sz;
int64_t offset = 0ull;
int fd = open(fn_path.c_str(), O_RDONLY);
if (fd == -1) {
std::cerr << "error: failed to open input file " << fn_path << std::endl;
exit(EIO);
}
// Write all the odd blocks
offset = block_size;
while (offset < info.st_size) {
sz = pread(fd, buffer.get(), block_size, offset);
if (!sz) {
break;
}
std::cout << "offset = " << offset << " length = " << sz << std::endl;
status = file.Write(offset, sz, buffer.get());
if (!status.IsOK()) {
std::cerr << "error: failed write offset=" << offset << ", lenght="
<< block_size << std::endl;
exit(status.errNo);
}
offset += (2 * sz);
}
offset = 0;
// Write all the even blocks
while (offset < info.st_size) {
sz = pread(fd, buffer.get(), block_size + 3, offset);
if (!sz) {
break;
}
std::cout << "offset = " << offset << " length = " << sz << std::endl;
status = file.Write(offset, sz, buffer.get());
if (!status.IsOK()) {
std::cerr << "error: failed write offset=" << offset << ", lenght="
<< block_size << std::endl;
exit(status.errNo);
}
offset += (2 * block_size);
}
if (!file.Close().IsOK()) {
std::cerr << "error: failed to close file" << std::endl;
exit(EIO);
}
}