linux下c/c++调用外部程序
system函数// system_exe.cc#include <cassert>#include <spdlog/common.h>#include <spdlog/spdlog.h>#include <string>#include <unistd.h>int main(int argc, char *argv[]) {assert
·
system函数
// system_exe.cc
#include <cassert>
#include <spdlog/common.h>
#include <spdlog/spdlog.h>
#include <string>
#include <unistd.h>
int main(int argc, char *argv[]) {
assert(argc >= 2);
spdlog::set_level(spdlog::level::debug);
std::string buff;
for (int i = 1; i < argc; ++i) {
spdlog::debug("append arg [{0}]", argv[i]);
buff.append(argv[i]);
buff.append(" ");
}
spdlog::info("system({0})", buff);
auto ret = system(buff.c_str());
spdlog::info("return {0}", ret);
return ret;
}
g++ -o system_exe -lspdlog system_exe.cc
exec系列函数
execv
函数声明
extern int execv(const char* __path,char *const* __argv[]);
__path: 是要执行程序的绝对路径。
__argv: 传入的参数数组,以nullptr结尾。
直接使用
// exe_agent_fst.cc
#include <cassert>
#include <cstring>
#include <mcheck.h>
#include <spdlog/common.h>
#include <spdlog/spdlog.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
setenv("MALLOC_TRACE", "output.log", 1); // 重定向malloc_trace的标准输出到output.log
mtrace();
spdlog::set_level(spdlog::level::debug);
assert(argc >= 2);
char **args_ = (char **)malloc(sizeof(char *) * argc);
for (int i = 2, j = 0; i < argc; ++i, ++j) {
args_[j] = argv[i];
}
args_[argc - 1] = nullptr;
spdlog::info("execv {0} ...", argv[1]);
auto result = execv(argv[1], args_);
// 程序不能执行的话返回-1,如果程序成功执行进程将交给argv[1],后面的程序不会执行
spdlog::info("execv result: {0}", result);
free(args_);
spdlog::debug("delete[] args_");
return result;
}
g++ -g -o exe_agent_fst -lspdlog exe_agent_fst.cc
./exe_agent_fst /usr/bin/ls . # 程序能成功执行
mtrace ./exe_agent_fst output.log # 显示exe_agent_fst.cc:14 发生了内存泄漏
利用fork
// exe_agent_snd.cc
#include <cassert>
#include <cstring>
#include <spdlog/common.h>
#include <spdlog/spdlog.h>
#include <unistd.h>
#include <wait.h>
const int kMaxArgc = 2048;
int main(int argc, char *argv[]) {
assert(2 <= argc && argc <= kMaxArgc);
spdlog::set_level(spdlog::level::debug);
auto pid = fork();
if (pid < 0) {
spdlog::error("error happend:{0}", strerror(errno));
exit(-1);
} else if (pid > 0) {
int status_;
auto _pid = waitpid(pid, &status_, 0);
spdlog::info("pid[{0}] return[{1}] status[{2}]", pid, _pid, status_);
} else {
char *args_[kMaxArgc];
for (int i = 0, j = 2; j < argc; ++j, ++i) {
args_[i] = argv[j];
}
args_[argc - 2] = nullptr;
auto ret = execv(argv[1], args_);
spdlog::error("{0}! process {1} error!", ret, argv[1]);
}
return 0;
}
# makefile
cc=g++
exe_agent:exe_agent_snd.cc
$(cc) -o $@ -lspdlog $<
make
./exe_agent /usr/bin/false
./exe_agent /usr/bin/true
./exe_agent /usr/bin/ls .
利用pipe进行进程间通信
#include <cstdio>
#include <spdlog/common.h>
#include <spdlog/spdlog.h>
#include <string>
#include <sys/wait.h>
#include <unistd.h>
static const int kMaxArgc = 1024;
int main(int argc, char *argv[]) {
assert(2 <= argc && argc < kMaxArgc);
spdlog::set_level(spdlog::level::debug);
int mypipe[2];
pipe(mypipe); // 构建一个pipe,mypipe[1]用于write,mypipe[0]用于读
auto pid = fork();
if (pid < 0) {
spdlog::error("fork error:{0}", strerror(errno));
return -1;
} else if (pid > 0) {
close(mypipe[1]);
auto fd = fdopen(mypipe[0], "r");
std::string msg_;
while (!feof(fd)) {
msg_.push_back(std::fgetc(fd));
}
msg_.pop_back();
spdlog::info("pid[{0}] output:{1}", pid, msg_);
int status_;
waitpid(pid, &status_, 0);
spdlog::info("pid[{0}] return[{1}]", pid, status_);
} else {
char *args_[kMaxArgc];
for (int i = 0, j = 2; j < argc; ++i, ++j) {
args_[i] = argv[j];
}
args_[argc - 2] = nullptr;
dup2(mypipe[1], STDOUT_FILENO);
close(mypipe[0]);
auto ret = execv(argv[1], args_);
spdlog::error("execv({0},...) error {1}:{2}", argv[1], ret,
strerror(errno));
return ret;
}
return 0;
}
附
- mtrace 安装
sudo yum install glibc-utils.x86_64 # readhat ...
or
sudo apt-get install glibc-utils # debian ...
更多推荐
已为社区贡献2条内容
所有评论(0)