停止system()函数中使用的一些命令

时间:2012-10-10 19:01:50

标签: c ip-address ping

我的system()功能存在问题。

我需要实现一个简单的bash,我的项目的一个模块是允许用户输入一些bash命令来执行它。

高于我实际做的事情:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// similar to gets
int reads(char* str)
{
#ifndef WIN32
    fflush(stdout);
    strcpy(str,GetServiceLine());
#else
    gets(str);
#endif

    return 1;
}

int main(void) {
    char str[100];

        while(strcmp(str, "exit")) {
            printf("\nNote: type \"exit\" to return menu\n");
            printf("MyBash$ ");
            reads(str);

            system(str);
        }

    return 0;
}

我的问题在于ping等命令。

当我在我的电脑上运行此代码并尝试执行合法ping的{​​{1}}命令时,它可以正常工作,我可以使用IP停止ping进程,但当我以同样的方式在我的目标上运行它时,我无法使用CTRL+C,我的进程始终保持CTRL+C电话。

有人可以帮助我吗?

注意:我阅读this post有关如何使用CTRL + C来破坏系统功能的信息。我尝试了这个建议,但没有用。

感谢。

3 个答案:

答案 0 :(得分:1)

既然你还没有尝试过,我会把它作为建议扔在这里。您始终可以install a signal handler来捕捉您感兴趣的信号。

这是一个使用(主要)代码的快速示例,演示了如何完成:

#include <signal.h>
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h>   

void intHandler(int dummy) 
{
    exit(1);   // Do whatever you want here to handle it...
}

int main(void) 
{
    char str[100];
    signal(SIGINT, intHandler);   
    signal(SIGKILL, intHandler);
    while(strcmp(str, "exit")) {
       printf("\nNote: type \"exit\" to return menu\n");
       printf("MyBash$ ");
       gets(str);
       system(str);
    }      
    return 0; 
} 

我可以使用它来捕获ctrl + C,但我不确定它是否是您正在寻找的。

答案 1 :(得分:1)

在上述评论之后,我只想解释为什么你无法以优雅的方式控制它(虽然在评论中建议了一些黑客攻击)。

如果你分叉了一个子进程,然后在子进程上调用了exec来执行传递给exec作为参数的二进制文件,那么

系统命令将会完全正常运行。

system()函数应忽略SIGINT和SIGQUIT信号,并在等待命令终止时阻止SIGCHLD信号。如果这可能导致应用程序错过可能导致它被杀死的信号,那么应用程序应检查system()的返回值并采取适当的任何操作。

请记住,这是特定于操作系统的行为,并且没有这样的标准。

system() function call in Linux

内部ping实用程序将在icmp上运行并等待,直到从另一个节点收到响应。

您可能会按照另一个答案中的建议编写一个信号处理程序并调用killpid()但它会被阻塞,直到对system()的调用返回为止。这在功能的规格中说明。所以你可以终止,但只能在通话结束后才能终止。 :)

答案 2 :(得分:0)

下面用于修复我的问题的代码。我不知道是否是更好的解决方案,但在这种情况下解决了我的问题。

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// similar to gets
int reads(char* str)
{
#ifndef WIN32
    fflush(stdout);
    strcpy(str,GetServiceLine());
#else
    gets(str);
#endif

    return 1;
}

void getCommandName(char input[], char output[])
{
    int count=0;

    while (input[count] != NULL && input[count] != ' ' && input[count] != '\0') {
        output[count] = input[count];
        count++;
    }
}

int killLastCommand(int pid)
{
    char commandKill[30];

    memset(commandKill, 0, 30);

    sprintf(commandKill, "kill -9 %d", pid);
    return(!system(commandKill));
}

int main(void) {
    FILE *fp; //Will be used with popen()
    char str[100];
    char lastCommandName[50];
    char pidofCommand[50];
    char strLastPIDCommand[10];
    int lastPIDCommand=0;

    memset (str, 0, 100);

        while(strcmp(str, "exit")) {
        if (lastPIDCommand == 0) {
            memset (lastCommandName, 0, 50); //Clean lastCommandName array
            memset (pidofCommand, 0, 50); //Clean pidofCommand array
            memset (strLastPIDCommand, 0, 10); //Clean strLastPIDCommand array

            printf("\n\nNote: type \"exit\" to return menu\n");
            printf("MyBash$ ");
                reads(str);

            if (strcmp(str, "exit")) {
                    sprintf(str, "%s &", str);
            }

            getCommandName(str, lastCommandName);

            system(str);
            sleep(1); //Sleep to guarantee than command will end

            sprintf(pidofCommand, "pidof %s", lastCommandName); 

            //Saving PID
            fp = popen(pidofCommand, "r");

            if (fp) {
                fgets(strLastPIDCommand, 10, fp);
                lastPIDCommand = atoi(strLastPIDCommand);
            } else {
                //Handle error
            }
            pclose(fp);

printf("commandName = %s\r\n", lastCommandName);
printf("pid = %d\r\n", lastPIDCommand);
        } else {
            printf("\n\nYou have a command running, press 'kill' to stop it before to type another command\n");
            printf("EITVBash$ \n\n");
            reads(str);

//          if (str[0] == 0x03) { //CTRL+C hexa code
            if (!strcmp(str, "kill")) {
                if (killLastCommand(lastPIDCommand)) {
                    lastPIDCommand = 0;
                }
            }
        }
    }

    return 0;
}

我的实施可能不干净,但我对c没有太多经验。

谢谢大家。