global_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
common_init_finish(g_ceph_context);
+ // input
bufferlist indata;
-
if (!in_file.empty()) {
if (get_indata(in_file.c_str(), indata)) {
derr << "failed to get data from '" << in_file << "'" << dendl;
}
}
+ // output
+ int out_fd;
+ if (out_file.empty()) {
+ out_fd = ::open("/dev/null", O_WRONLY);
+ out_file = "/dev/null";
+ } else if (out_file == "-") {
+ out_fd = dup(0);
+ } else {
+ out_fd = TEMP_FAILURE_RETRY(::open(out_file.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644));
+ if (out_fd < 0) {
+ int ret = errno;
+ derr << " failed to create file '" << out_file << "': "
+ << cpp_strerror(ret) << dendl;
+ return 1;
+ }
+ }
+
CephToolCtx *ctx = ceph_tool_common_init(mode, concise);
if (!ctx) {
derr << "ceph_tool_common_init failed." << dendl;
if (args.empty()) {
if (ceph_tool_do_cli(ctx))
ret = 1;
- }
- else {
+ } else {
while (!args.empty()) {
vector<string> cmd;
for (vector<const char*>::iterator n = args.begin();
cmd.push_back(np);
}
- if (ceph_tool_cli_input(ctx, cmd,
- out_file.empty() ? NULL : out_file.c_str(), indata))
+ bufferlist obl;
+ if (ceph_tool_do_command(ctx, cmd, indata, obl))
ret = 1;
+ int err = obl.write_fd(out_fd);
+ if (err) {
+ derr << " failed to write " << obl.length() << " bytes to " << out_file << ": "
+ << cpp_strerror(err) << dendl;
+ goto out;
+ }
+ derr << " wrote " << obl.length() << " byte payload to " << out_file << dendl;
}
}
if (ceph_tool_messenger_shutdown())
}
}
+ out:
+ ::close(out_fd);
if (ceph_tool_common_shutdown(ctx))
ret = 1;
return ret;
return 0;
}
-int ceph_tool_cli_input(CephToolCtx *ctx, std::vector<std::string> &cmd,
- const char *outfile, bufferlist &indata)
+int ceph_tool_do_command(CephToolCtx *ctx, std::vector<std::string>& cmd,
+ bufferlist& indata, bufferlist& outdata)
{
string rs;
- bufferlist odata;
- int ret = do_command(ctx, cmd, indata, rs, odata);
- if (ret)
- return ret;
-
- int len = odata.length();
- if (!len) {
- // no output
- return 0;
- }
-
- if (!outfile) {
- // error: no output specified
- derr << " got " << len << " byte payload, discarding "
- << "(specify -o <outfile)" << dendl;
- return 1;
- }
- if (strcmp(outfile, "-") == 0) {
- // write to stdout
- fwrite(odata.c_str(), len, 1, stdout);
- return 0;
- }
-
- // Write to a file. Don't truncate the file.
- int fd = TEMP_FAILURE_RETRY(::open(outfile, O_WRONLY|O_CREAT, 0644));
- if (fd < 0) {
- int err = errno;
- derr << " failed to create file '" << outfile << "': "
- << cpp_strerror(err) << dendl;
- return 1;
- }
- ret = odata.write_fd(fd);
- if (ret) {
- derr << " error writing file: " << cpp_strerror(ret) << dendl;
- close(fd);
- return 1;
- }
- derr << " wrote " << len << " byte payload to " << outfile << dendl;
- if (close(fd)) {
- int err = errno;
- derr << " error while closing file '" << outfile << "': "
- << cpp_strerror(err) << dendl;
- return 1;
- }
- return 0;
+ return do_command(ctx, cmd, indata, rs, outdata);
}
CephToolCtx* ceph_tool_common_init(ceph_tool_mode_t mode, bool concise)
int run_command(CephToolCtx *data, const char *line);
void send_observe_requests(CephToolCtx *ctx);
CephToolCtx* ceph_tool_common_init(ceph_tool_mode_t mode, bool concise);
-int ceph_tool_cli_input(CephToolCtx *ctx, std::vector<std::string> &cmd,
- const char *outfile, bufferlist &indata);
+int ceph_tool_do_command(CephToolCtx *ctx, std::vector<std::string>& cmd,
+ bufferlist& indata, bufferlist& outdata);
int ceph_tool_messenger_shutdown();
int ceph_tool_common_shutdown(CephToolCtx *ctx);