mirror of
https://gitee.com/TarsCloud/TarsCpp.git
synced 2025-01-03 05:22:26 +08:00
support run in container
This commit is contained in:
parent
c8f541fcce
commit
26ce453b08
@ -717,6 +717,9 @@ void Application::main(const TC_Option &option)
|
||||
|
||||
string config = TC_File::load2str(ServerConfig::ConfigFile);
|
||||
|
||||
__out__.debug() << "config:" << ServerConfig::ConfigFile << endl;
|
||||
__out__.debug() << "config:" << config << endl;
|
||||
|
||||
main(config);
|
||||
}
|
||||
|
||||
|
@ -239,52 +239,52 @@ void QueryEpBase::setObjName(const string & sObjName)
|
||||
notifyEndpoints(_activeEndpoints,_inactiveEndpoints,true);
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> QueryEpBase::sepEndpoint(const string& sEndpoints)
|
||||
{
|
||||
vector<string> vEndpoints;
|
||||
bool flag = false;
|
||||
string::size_type startPos = 0;
|
||||
string::size_type sepPos = 0;
|
||||
for(string::size_type pos = 0; pos < sEndpoints.size(); pos++)
|
||||
{
|
||||
if(sEndpoints[pos] == ':' && !flag )
|
||||
{
|
||||
sepPos = pos;
|
||||
flag = true;
|
||||
}
|
||||
else if(flag)
|
||||
{
|
||||
if(sEndpoints[pos] == ' ')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(TC_Port::strncasecmp("tcp", (sEndpoints.c_str() + pos), 3) == 0
|
||||
|| TC_Port::strncasecmp("udp", (sEndpoints.c_str() + pos), 3) == 0
|
||||
|| TC_Port::strncasecmp("ssl", (sEndpoints.c_str() + pos), 3) == 0)
|
||||
{
|
||||
string ep = TC_Common::trim(string(sEndpoints.c_str() + startPos, sepPos - startPos));
|
||||
if(!ep.empty()) {
|
||||
vEndpoints.push_back(ep);
|
||||
}
|
||||
startPos = pos;
|
||||
}
|
||||
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
string ep = sEndpoints.substr(startPos);
|
||||
|
||||
if(!ep.empty()) {
|
||||
vEndpoints.push_back(ep);
|
||||
}
|
||||
|
||||
// vEndpoints.push_back(sEndpoints.substr(startPos));
|
||||
|
||||
return vEndpoints;
|
||||
}
|
||||
//
|
||||
//vector<string> QueryEpBase::sepEndpoint(const string& sEndpoints)
|
||||
//{
|
||||
// vector<string> vEndpoints;
|
||||
// bool flag = false;
|
||||
// string::size_type startPos = 0;
|
||||
// string::size_type sepPos = 0;
|
||||
// for(string::size_type pos = 0; pos < sEndpoints.size(); pos++)
|
||||
// {
|
||||
// if(sEndpoints[pos] == ':' && !flag )
|
||||
// {
|
||||
// sepPos = pos;
|
||||
// flag = true;
|
||||
// }
|
||||
// else if(flag)
|
||||
// {
|
||||
// if(sEndpoints[pos] == ' ')
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if(TC_Port::strncasecmp("tcp", (sEndpoints.c_str() + pos), 3) == 0
|
||||
// || TC_Port::strncasecmp("udp", (sEndpoints.c_str() + pos), 3) == 0
|
||||
// || TC_Port::strncasecmp("ssl", (sEndpoints.c_str() + pos), 3) == 0)
|
||||
// {
|
||||
// string ep = TC_Common::trim(string(sEndpoints.c_str() + startPos, sepPos - startPos));
|
||||
// if(!ep.empty()) {
|
||||
// vEndpoints.push_back(ep);
|
||||
// }
|
||||
// startPos = pos;
|
||||
// }
|
||||
//
|
||||
// flag = false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// string ep = sEndpoints.substr(startPos);
|
||||
//
|
||||
// if(!ep.empty()) {
|
||||
// vEndpoints.push_back(ep);
|
||||
// }
|
||||
//
|
||||
//// vEndpoints.push_back(sEndpoints.substr(startPos));
|
||||
//
|
||||
// return vEndpoints;
|
||||
//}
|
||||
|
||||
void QueryEpBase::setEndpoints(const string & sEndpoints, set<EndpointInfo> & setEndpoints)
|
||||
{
|
||||
@ -297,7 +297,7 @@ void QueryEpBase::setEndpoints(const string & sEndpoints, set<EndpointInfo> & se
|
||||
bool bFirstWeightType = true;
|
||||
unsigned int iWeightType = 0;
|
||||
|
||||
vector<string> vEndpoints = sepEndpoint(sEndpoints);
|
||||
vector<string> vEndpoints = TC_Endpoint::sepEndpoint(sEndpoints);
|
||||
|
||||
for (size_t i = 0; i < vEndpoints.size(); ++i)
|
||||
{
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 39c6f87733710a28eb5e57e42558c7e016d84eba
|
||||
Subproject commit 9d299a769d9f827670b726984e40ae9f52b3189c
|
@ -155,10 +155,10 @@ private:
|
||||
*/
|
||||
void setObjName(const string & sObjName);
|
||||
|
||||
/*
|
||||
* 解析endpoint
|
||||
*/
|
||||
vector<string> sepEndpoint(const string& sEndpoints);
|
||||
// /*
|
||||
// * 解析endpoint
|
||||
// */
|
||||
// vector<string> sepEndpoint(const string& sEndpoints);
|
||||
|
||||
/*
|
||||
* 从sEndpoints提取ip列表信息
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,14 @@
|
||||
/* A Bison parser, made by GNU Bison 2.7. */
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
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.
|
||||
the Free Software Foundation; either version 2, 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
|
||||
@ -15,7 +16,9 @@
|
||||
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 <http://www.gnu.org/licenses/>. */
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
@ -30,16 +33,6 @@
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_YY_TARS_TAB_HPP_INCLUDED
|
||||
# define YY_YY_TARS_TAB_HPP_INCLUDED
|
||||
/* Enabling traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 1
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
@ -79,29 +72,48 @@ extern int yydebug;
|
||||
BAD_CHAR = 288
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define TARS_VOID 258
|
||||
#define TARS_STRUCT 259
|
||||
#define TARS_BOOL 260
|
||||
#define TARS_BYTE 261
|
||||
#define TARS_SHORT 262
|
||||
#define TARS_INT 263
|
||||
#define TARS_DOUBLE 264
|
||||
#define TARS_FLOAT 265
|
||||
#define TARS_LONG 266
|
||||
#define TARS_STRING 267
|
||||
#define TARS_VECTOR 268
|
||||
#define TARS_MAP 269
|
||||
#define TARS_NAMESPACE 270
|
||||
#define TARS_INTERFACE 271
|
||||
#define TARS_IDENTIFIER 272
|
||||
#define TARS_OUT 273
|
||||
#define TARS_OP 274
|
||||
#define TARS_KEY 275
|
||||
#define TARS_ROUTE_KEY 276
|
||||
#define TARS_REQUIRE 277
|
||||
#define TARS_OPTIONAL 278
|
||||
#define TARS_CONST_INTEGER 279
|
||||
#define TARS_CONST_FLOAT 280
|
||||
#define TARS_FALSE 281
|
||||
#define TARS_TRUE 282
|
||||
#define TARS_STRING_LITERAL 283
|
||||
#define TARS_SCOPE_DELIMITER 284
|
||||
#define TARS_CONST 285
|
||||
#define TARS_ENUM 286
|
||||
#define TARS_UNSIGNED 287
|
||||
#define BAD_CHAR 288
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef int YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void *YYPARSE_PARAM);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#else /* ! YYPARSE_PARAM */
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#endif /* ! YYPARSE_PARAM */
|
||||
|
||||
#endif /* !YY_YY_TARS_TAB_HPP_INCLUDED */
|
||||
|
@ -1,6 +1,6 @@
|
||||
// **********************************************************************
|
||||
// This file was generated by a TARS parser!
|
||||
// TARS version 3.0.3.
|
||||
// TARS version 3.0.4.
|
||||
// **********************************************************************
|
||||
|
||||
#ifndef __HELLO_H_
|
||||
|
@ -111,7 +111,7 @@ TEST_F(UtilEpollServerTest, RunTcp)
|
||||
|
||||
TEST_F(UtilEpollServerTest, RunEnableManualListen)
|
||||
{
|
||||
int i = 0;
|
||||
// int i = 0;
|
||||
for(int i = 0; i <= TC_EpollServer::NET_THREAD_MERGE_HANDLES_CO; i++)
|
||||
{
|
||||
MyTcpServer server;
|
||||
|
35
unit-test/util/test_tc_port.cpp
Executable file
35
unit-test/util/test_tc_port.cpp
Executable file
@ -0,0 +1,35 @@
|
||||
#include "util/tc_port.h"
|
||||
#include "util/tc_common.h"
|
||||
#include <cmath>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace tars;
|
||||
|
||||
class UtilPortTest : public testing::Test
|
||||
{
|
||||
public:
|
||||
//添加日志
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
}
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
}
|
||||
virtual void SetUp() //TEST跑之前会执行SetUp
|
||||
{
|
||||
}
|
||||
virtual void TearDown() //TEST跑完之后会执行TearDown
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(UtilPortTest, testExec)
|
||||
{
|
||||
string err;
|
||||
string result = TC_Port::exec("ls '*.txt'", err);
|
||||
cout << result << endl;
|
||||
}
|
@ -369,6 +369,12 @@ public:
|
||||
*/
|
||||
void parse(const string &desc);
|
||||
|
||||
/*
|
||||
* 解析成多个endpoint(tcp -h xxx -p yyy:udp -h xxx -p yyy:ssl -h xxx -p xxx)
|
||||
* 支持ipv6地址
|
||||
*/
|
||||
static vector<string> sepEndpoint(const string& sEndpoints);
|
||||
|
||||
private:
|
||||
void init(const string& host, int port, int timeout, EType type, int grid, int qos, int weight, unsigned int weighttype, AUTH_TYPE authType);
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __TC_PORT_H
|
||||
|
||||
#include "util/tc_platform.h"
|
||||
#include "util/tc_ex.h"
|
||||
|
||||
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
|
||||
@ -36,6 +37,15 @@ using namespace std;
|
||||
namespace tars
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief 跨平台port异常类
|
||||
*/
|
||||
struct TC_Port_Exception : public TC_Exception
|
||||
{
|
||||
TC_Port_Exception(const string &buffer) : TC_Exception(buffer){};
|
||||
~TC_Port_Exception() throw() {};
|
||||
};
|
||||
|
||||
class TC_Port
|
||||
{
|
||||
public:
|
||||
@ -81,13 +91,46 @@ public:
|
||||
|
||||
static int64_t getpid();
|
||||
|
||||
/**
|
||||
* 获取环境变量
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
static std::string getEnv(const std::string &name);
|
||||
|
||||
/**
|
||||
* 设置环境变量
|
||||
* @param name
|
||||
* @param value
|
||||
*/
|
||||
static void setEnv(const std::string &name, const std::string &value);
|
||||
|
||||
/**
|
||||
* 运行一个脚本
|
||||
* @param cmd
|
||||
* @param err
|
||||
* @return 程序的标准输出
|
||||
*/
|
||||
static std::string exec(const char* cmd);
|
||||
|
||||
/**
|
||||
* 运行一个脚本(程序+命令行)
|
||||
* @param cmd
|
||||
* @param err
|
||||
* @return: 程序的标准输出
|
||||
*/
|
||||
static std::string exec(const char* cmd, std::string &err);
|
||||
|
||||
/**
|
||||
* fork子进程并运行程序
|
||||
* @param sExe: 可执行程序路径
|
||||
* @param sPwdPath: 程序运行的当前路径
|
||||
* @param sRollLogPath: 滚动日志路径(stdout会重定向到滚动日志), 为空则不重定向
|
||||
* @param vOptions: 参数
|
||||
* @return 子进程id: ==0: 子进程中, >0: 父进程中(子进程pid), 其他抛出异常 TC_Port_Exception
|
||||
*/
|
||||
static int64_t forkExec(const string& sExe, const string& sPwdPath, const string& sRollLogPath, const vector<string>& vOptions);
|
||||
|
||||
/**
|
||||
* 注册ctrl+c回调事件(SIGINT/CTRL_C_EVENT)
|
||||
* @param callback
|
||||
|
@ -250,7 +250,6 @@ public:
|
||||
*/
|
||||
void init(size_t num);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 停止所有线程, 会等待所有线程结束
|
||||
*/
|
||||
|
@ -256,6 +256,51 @@ void TC_Endpoint::parse(const string &str)
|
||||
// _authType = 1;
|
||||
}
|
||||
|
||||
vector<string> TC_Endpoint::sepEndpoint(const string& sEndpoints)
|
||||
{
|
||||
vector<string> vEndpoints;
|
||||
bool flag = false;
|
||||
string::size_type startPos = 0;
|
||||
string::size_type sepPos = 0;
|
||||
for(string::size_type pos = 0; pos < sEndpoints.size(); pos++)
|
||||
{
|
||||
if(sEndpoints[pos] == ':' && !flag )
|
||||
{
|
||||
sepPos = pos;
|
||||
flag = true;
|
||||
}
|
||||
else if(flag)
|
||||
{
|
||||
if(sEndpoints[pos] == ' ')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(TC_Port::strncasecmp("tcp", (sEndpoints.c_str() + pos), 3) == 0
|
||||
|| TC_Port::strncasecmp("udp", (sEndpoints.c_str() + pos), 3) == 0
|
||||
|| TC_Port::strncasecmp("ssl", (sEndpoints.c_str() + pos), 3) == 0)
|
||||
{
|
||||
string ep = TC_Common::trim(string(sEndpoints.c_str() + startPos, sepPos - startPos));
|
||||
if(!ep.empty()) {
|
||||
vEndpoints.push_back(ep);
|
||||
}
|
||||
startPos = pos;
|
||||
}
|
||||
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
string ep = sEndpoints.substr(startPos);
|
||||
|
||||
if(!ep.empty()) {
|
||||
vEndpoints.push_back(ep);
|
||||
}
|
||||
|
||||
return vEndpoints;
|
||||
}
|
||||
|
||||
|
||||
/*************************************TC_TCPClient**************************************/
|
||||
|
||||
TC_ClientSocket::TC_ClientSocket() : _port(0),_timeout(3000)
|
||||
|
@ -272,6 +272,155 @@ std::string TC_Port::exec(const char* cmd, std::string &err)
|
||||
return fileData;
|
||||
}
|
||||
|
||||
int64_t TC_Port::forkExec(const string& sExePath, const string& sPwdPath, const string& sRollLogPath, const vector<string>& vOptions)
|
||||
{
|
||||
vector<string> vEnvs;
|
||||
|
||||
if (sExePath.empty())
|
||||
{
|
||||
throw TC_Port_Exception("[TC_Port::forkExec] server exe: " + sExePath + " is empty.");
|
||||
}
|
||||
|
||||
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
|
||||
if (TC_File::isFileExistEx(sExePath) && !TC_File::canExecutable(sExePath))
|
||||
{
|
||||
TC_File::setExecutable(sExePath, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Current directory
|
||||
//
|
||||
const char *pwdCStr = sPwdPath.c_str();
|
||||
|
||||
#if TARGET_PLATFORM_WINDOWS
|
||||
vector<string> vArgs;
|
||||
|
||||
vArgs.insert(vArgs.end(), vOptions.begin(), vOptions.end());
|
||||
|
||||
string path;
|
||||
for (vector<string>::const_iterator p = vArgs.begin(); p != vArgs.end(); ++p)
|
||||
{
|
||||
path += " " + *p;
|
||||
}
|
||||
|
||||
string command = sExePath + " " + path;
|
||||
|
||||
TCHAR p[1024];
|
||||
strncpy_s(p, sizeof(p) / sizeof(TCHAR), command.c_str(), command.length());
|
||||
|
||||
STARTUPINFO si;
|
||||
memset(&si, 0, sizeof(si));
|
||||
PROCESS_INFORMATION pi;
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE; //TRUE表示显示创建的进程的窗口
|
||||
|
||||
if (!CreateProcessA(
|
||||
NULL, // 指向一个NULL结尾的、用来指定可执行模块的宽字节字符串
|
||||
p, // 命令行字符串
|
||||
NULL, // 指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。
|
||||
NULL, // 如果lpProcessAttributes参数为空(NULL),那么句柄不能被继承。<同上>
|
||||
false, // 指示新进程是否从调用进程处继承了句柄。
|
||||
CREATE_NEW_CONSOLE|CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, // 指定附加的、用来控制优先类和进程的创建的标
|
||||
NULL, // 指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境
|
||||
pwdCStr, // 指定子进程的工作路径
|
||||
&si, // 决定新进程的主窗体如何显示的STARTUPINFO结构体
|
||||
&pi // 接收新进程的识别信息的PROCESS_INFORMATION结构体
|
||||
))
|
||||
{
|
||||
string err = TC_Exception::parseError(TC_Exception::getSystemCode());
|
||||
|
||||
throw TC_Port_Exception("[TC_Port::forkExec] CreateProcessA exception:" + err);
|
||||
}
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
return pi.dwProcessId;
|
||||
|
||||
#else
|
||||
vector<string> vArgs;
|
||||
vArgs.push_back(sExePath);
|
||||
vArgs.insert(vArgs.end(), vOptions.begin(), vOptions.end());
|
||||
|
||||
int argc = static_cast<int>(vArgs.size());
|
||||
char **argv = static_cast<char **>(malloc((argc + 1) * sizeof(char *)));
|
||||
int i = 0;
|
||||
for (vector<string>::const_iterator p = vArgs.begin(); p != vArgs.end(); ++p, ++i)
|
||||
{
|
||||
assert(i < argc);
|
||||
argv[i] = strdup(p->c_str());
|
||||
}
|
||||
assert(i == argc);
|
||||
argv[argc] = 0;
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1)
|
||||
{
|
||||
throw TC_Port_Exception("[TC_Port::forkExec] fork exception");
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX));
|
||||
for (int fd = 3; fd < maxFd; ++fd)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
//server stdcout 日志在滚动日志显示
|
||||
if (!sRollLogPath.empty())
|
||||
{
|
||||
TC_File::makeDirRecursive(TC_File::extractFilePath(sRollLogPath));
|
||||
#if TARGET_PLATFORM_IOS
|
||||
if ((freopen(sRollLogPath.c_str(), "ab", stdout)) != NULL && (freopen(sRollLogPath.c_str(), "ab", stderr)) != NULL)
|
||||
#else
|
||||
if ((freopen64(sRollLogPath.c_str(), "ab", stdout)) != NULL && (freopen64(sRollLogPath.c_str(), "ab", stderr)) != NULL)
|
||||
#endif
|
||||
{
|
||||
cout << argv[0] << " redirect stdout and stderr to " << sRollLogPath << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
//重定向失败 直接退出
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << argv[0] << " cannot redirect stdout and stderr to log file sRollLogPath is empty" << endl;
|
||||
}
|
||||
|
||||
// for_each(vEnvs.begin(), vEnvs.end(), EnvVal());
|
||||
|
||||
if (strlen(pwdCStr) != 0)
|
||||
{
|
||||
if (chdir(pwdCStr) == -1)
|
||||
{
|
||||
cerr << argv[0] << " cannot change working directory to " << pwdCStr << "|errno=" << errno << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (execvp(argv[0], argv) == -1)
|
||||
{
|
||||
cerr << "cannot execute " << argv[0] << "|errno=" << strerror(errno) << endl;
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; argv[i]; i++)
|
||||
{
|
||||
free(argv[i]);
|
||||
}
|
||||
free(argv);
|
||||
}
|
||||
return pid;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
shared_ptr<TC_Port::SigInfo> TC_Port::_sigInfo = std::make_shared<TC_Port::SigInfo>();
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user