上記のプロセスが継続的に実行され、適切な順序で開始されることを確認するデーモンからプロセスを開始します。
ある時点で、プロセスを開始したいexecv()
ので、引数用の文字列の配列を次のように準備します。
std::vector<std::string> args;
args.push_back("--debug");
args.push_back("--connect");
args.push_back("10.0.0.5:4040");
...
ほとんどの場合、そのような引数は 10 個ほどあります。
ここで、execv()
裸のポインターの配列にのみアクセスします。したがって、次のようにして、そのようなポインターの配列を作成します。
std::vector<char *> args_p; // sorry, my code actually uses std::vector<char const *> args_p -- so constness is fine here
for(auto a : args)
{
args_p.push_back(a.c_str());
}
args_p.push_back(nullptr); // list needs to be null terminated
次にexecv()
、最後の配列で呼び出すことができます。
execv(
args_p[0],
const_cast<char * const *>(&args_p[0])
);
これは、g++ 4.8.4 を使用した Ubuntu 14.04 で完全に機能していましたが、どういうわけか、c_str()
g++ 5.3.1 でコンパイルされた同じコードを実行しようとすると、ポインターが無効になります。
execv()
私の理解では、ベアポインタの配列を作成する最初のループと呼び出しの間で文字列を変更していないため、これはそうではありません。
リファレンスには次のように書かれています。
c_str() から取得したポインターは、次の方法で無効にすることができます。
- 文字列への非 const 参照を標準ライブラリ関数に渡す、または
- operator[]、at()、front()、back()、begin()、rbegin()、end()、rend() を除く、文字列に対する非 const メンバー関数の呼び出し。
PS私はすでに修正を行っていstdup()
ますc_str()
。可能であれば、文字列の余分なコピーを1つ避けたいと思っていました...