forkpty的用法,ssh的超时设置

Himulaxinta2 2007-08-30 04:24:16
小弟我有段代码是远程执行一个命令或者一个程序,并且将执行的结果返回回来。
用的主要方法是forkpty创建一个子进程,用ssh执行并把执行的结果以FILE*文件返回给外部读取,写到用户界面上。
现在的问题是如果在执行远程程序的过程中把网络断开,那么主进程怎么也无法退出了。
这里碰到两个问题,一是为什么ssh需要很久(大约30分钟)才能检测到网络已断开;二是为啥外部读取并显示结果到界面的函数doExecute怎么也无法得到“连接超时,无法连接”等信息,就一直死在那边了!!
希望各位前辈高人指点一二,不甚感激!

下面是部分代码:
//execute a cmd by ssh method.
FILE* RemoteFacade::sshopen( UXcmd cmdopt, char *rcommand )
{
int fd, count;
pid_t pid;
char buffer[MAXLINE] = {0};
char target[MAXLINE];
char option[3];
char tmpchar[2];
char remotecmd[MAXLINE];
FILE *sshcmd;

// Build the command options

// Use the -t switch to force a pseudo-tty terminal. This
// is necessary for the Broadcom package to work correctly.
strcpy(option, "-t");

strcpy(target, cmdopt.username);
strcat(target, "@");
strcat(target, cmdopt.hostname);

strcpy(remotecmd, "echo __Start__; ");
strcat(remotecmd, rcommand);
strcat(remotecmd, "; echo ReturnCode=$?");
strcat(remotecmd, "; echo __End__");

#ifdef DEBUG
uxdebug("target:\"%s\" ; cmd:\"%s\" \n", target, rcommand);
#endif

pid = forkpty(&fd, 0, 0, 0);

if (pid == 0) {
execlp("ssh", "ssh", option, target, remotecmd, (void *)NULL);
exit(1);
} else if (pid == -1) {
return (FILE *)NULL;
} else {
sshcmd=fdopen(fd, "a+");
strcpy(buffer,"\0");
// Read 1 char at a time and build up a string
count=0;
if (sshcmd == 0) {
uxerror("Could not open ssh connection.");
return (FILE *)NULL;
}
while((fgets(tmpchar, 2, sshcmd) != NULL ) && (count++ < MAXLINE)){
strcat(buffer, tmpchar);
if ((int *)strstr(buffer,"ssword:") != NULL) {
fprintf(sshcmd, cmdopt.passwd);
fprintf(sshcmd, "\n");
fflush(sshcmd);
// reset search string
strcpy(buffer,"\0");
}
if ((int *)strstr(buffer,"connecting (yes/no)?") != NULL) {
fprintf (sshcmd,"yes\n");
fflush (sshcmd);
// reset search string
strcpy(buffer,"\0");
}
if ((int *)strstr(buffer,"Enter passphrase") != NULL) {
fprintf(sshcmd, cmdopt.passwd);
fprintf(sshcmd, "\n");
fflush(sshcmd);
// reset search string
strcpy(buffer,"\0");
}
if ((int *)strstr(buffer,"No route to host") != NULL) {
uxerror(buffer);
fclose(sshcmd);
return (FILE *)NULL;
}
if ((int *)strstr(buffer,"Permission denied") != NULL) {
uxerror(buffer);
fclose(sshcmd);
return (FILE *)NULL;
}
if ((int *)strstr(buffer,"Connection refused") != NULL) {
uxerror(buffer);
fclose(sshcmd);
return (FILE *)NULL;
}
if ((int *)strstr(buffer,"Host key verification failed") != NULL) {
uxerror(buffer);
fclose(sshcmd);
return (FILE *)NULL;
}
if ((int *)strstr(buffer,"Name or service not known") != NULL) {
uxerror(buffer);
fclose(sshcmd);
return (FILE *)NULL;
}
if ((int *)strstr(buffer,"__Start__") != NULL) {
return (FILE *)sshcmd;
}
}
}
return (FILE *)NULL;
}

//do the execute, and show the running result to user interface.
ERUXError RemoteFacade::doExecute(RemoteOutput *pOutput, const string cmdline,int &returnCode)
{
int ret= -1;
char ch_cmdLine[MAXLINE] = {0};
char buff[MAXLINE] = {0};
char* pRet;
strcpy(ch_cmdLine, cmdline.c_str());
uxdebug("b4 do execute, cmdline is: %s\n", cmdline.c_str());
FILE* sshfp= sshopen(m_cmdopts, ch_cmdLine);
if(sshfp == NULL)
return ERROR_REMOTE_CONNECT;

while(fgets(buff, MAXLINE, sshfp) != NULL){
if( (pRet = strstr(buff, "ReturnCode=")) != NULL ){
pRet += sizeof("ReturnCode=")-1;
if(*(pRet)>= '0' && *(pRet)<= '9'){
returnCode = atoi(pRet);
}
else{
uxerror("some err happened in get the return code back.\nThe cmd is :%s\n",cmdline.c_str());
}
}
else if ((int *)strstr(buff,"No route to host") != NULL) {
uxerror(buff);
fclose(sshfp);
return ERROR_REMOTE_CONNECT;
}
else if ((int *)strstr(buff,"Permission denied") != NULL) {
uxerror(buff);
fclose(sshfp);
return ERROR_REMOTE_ARGUMENT;
}
else if ((int *)strstr(buff,"Connection refused") != NULL) {
uxerror(buff);
fclose(sshfp);
return ERROR_REMOTE_CONNECT;
}
else if ((int *)strstr(buff,"Host key verification failed") != NULL) {
uxerror(buff);
fclose(sshfp);
return ERROR_REMOTE_CONNECT;
}
else if ((int *)strstr(buff,"Name or service not known") != NULL) {
uxerror(buff);
fclose(sshfp);
return ERROR_REMOTE_CONNECT;
}
else if ((int *)strstr(buff, "__End__") != NULL) {
break;
}
else{
if(pOutput!=NULL){
pOutput->printOut(buff); //Output the running result by the RemoteOutput.
}
else{
printf(buff);
}
}
}
fclose(sshfp);
return REMOTE_SUCCESS;
}
...全文
1112 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Himulaxinta2 2007-09-05
  • 打赏
  • 举报
回复
我以为csdn没人气,要么就是我没写清楚,都没人回答呢
谢谢兄弟们,有人顶就好啊;-)
lxs_lover520 2007-09-05
  • 打赏
  • 举报
回复
回答不出来。。。。顶下吧
Himulaxinta2 2007-09-03
  • 打赏
  • 举报
回复
怎么没有人回答我啊,奇怪了
Himulaxinta2 2007-08-30
  • 打赏
  • 举报
回复
我曾看过ssh的超时设置:
ssh -o ConnectTimeout=time
这个和要求应该不符的,不可能知道程序在远端需要执行多少时间
上面的需求是在网络断开的情况下,ssh能在需求时间内检测到并且返回错误信息。

23,115

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧