~ubuntu-branches/ubuntu/precise/ceph/precise-proposed

« back to all changes in this revision

Viewing changes to src/common/run_cmd.cc

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2011-04-25 10:09:05 UTC
  • mfrom: (1.1.3 upstream) (0.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110425100905-exm7dfvi2v5ick02
Tags: 0.27-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 
2
// vim: ts=8 sw=2 smarttab
 
3
/*
 
4
 * Ceph - scalable distributed file system
 
5
 *
 
6
 * Copyright (C) 2011 New Dream Network
 
7
 *
 
8
 * This is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU Lesser General Public
 
10
 * License version 2.1, as published by the Free Software
 
11
 * Foundation.  See file COPYING.
 
12
 *
 
13
 */
 
14
 
 
15
#include "common/config.h"
 
16
#include "common/debug.h"
 
17
#include "common/errno.h"
 
18
 
 
19
#include <errno.h>
 
20
#include <stdarg.h>
 
21
#include <stdlib.h>
 
22
#include <sys/types.h>
 
23
#include <sys/wait.h>
 
24
#include <unistd.h>
 
25
#include <vector>
 
26
 
 
27
#define dout_prefix *_dout
 
28
 
 
29
int run_cmd(const char *cmd, ...)
 
30
{
 
31
  int ret;
 
32
  std::vector <const char *> arr;
 
33
  va_list ap;
 
34
  va_start(ap, cmd);
 
35
  const char *c = cmd;
 
36
  do {
 
37
    arr.push_back(c);
 
38
    c = va_arg(ap, const char*);
 
39
  } while (c != NULL);
 
40
  va_end(ap);
 
41
  arr.push_back(NULL);
 
42
 
 
43
  ret = fork();
 
44
  if (ret == -1) {
 
45
    int err = errno;
 
46
    derr << "run_cmd(" << cmd << "): unable to fork(): " << cpp_strerror(err)
 
47
         << dendl;
 
48
    return -1;
 
49
  }
 
50
  else if (ret == 0) {
 
51
    // execvp doesn't modify its arguments, so the const-cast here is safe.
 
52
    execvp(cmd, (char * const*)&arr[0]);
 
53
    _exit(127);
 
54
  }
 
55
  int status;
 
56
  while (waitpid(ret, &status, 0) == -1) {
 
57
    int err = errno;
 
58
    if (err == EINTR)
 
59
      continue;
 
60
    derr << "run_cmd(" << cmd << "): waitpid error: "
 
61
         << cpp_strerror(err) << dendl;
 
62
    return -1;
 
63
  }
 
64
  if (WIFEXITED(status)) {
 
65
    return WEXITSTATUS(status);
 
66
  }
 
67
  else if (WIFSIGNALED(status)) {
 
68
    derr << "run_cmd(" << cmd << "): terminated by signal" << dendl;
 
69
    return -1;
 
70
  }
 
71
  derr << "run_cmd(" << cmd << "): terminated by unknown mechanism" << dendl;
 
72
  return -1;
 
73
}