• 应用程序 system 函数


    1、使用实例

    system("ps"); //执行shell命令ps
    2、使用注意事项
    system相当于创建了一个子进程,在子进程中调用程序。所以system执行的程序会继承主进程之前打开的文件、网络端口等资源。
    在system前执行以下操作  可消除上述继承。
    fcntl(fd, F_SETFD, FD_CLOEXEC); //fd为不能继承的文件或者端口句柄
    1)这里设置为FD_CLOEXEC表示当程序执行exec函数时本fd将被系统自动关闭,表示不传递给exec创建的新进程,;
    2)如果设置为fcntl(fd, F_SETFD, 0);那么本fd将保持打开状态复制到exec创建的新进程中
     
    3、system 函数原型
    #include 
    #include 
    #include 
    #include 
    int system(const char * cmdstring)
    {
        pid_t pid;
        int status;
        if(cmdstring == NULL){
              
             return (1);
        }
        if((pid = fork())<0){
                status = -1;
        }
        else if(pid == 0){
            execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
            -exit(127); //子进程正常执行则不会执行此语句
            }
        else{
                while(waitpid(pid, &status, 0) < 0){
                    if(errno != EINTER){
                        status = -1;
                        break;
                    }
                }
            }
            return status;
    }
    1、当system接受的命令为NULL时直接返回,否则fork出一个子进程,因为fork在两个进程:父进程和子进程中都返回,这里要检查返回的pid,fork在子进程中返回0,在父进程中返回子进程的pid,父进程使用waitpid等待子进程结束,子进程则是调用execl来启动一个程序代替自己,execl("/bin/sh", "sh", "-c", cmdstring,(char*)0)是调用shell,这个shell的路径是/bin/sh,后面的字符串都是参数,然后子进程就变成了一个shell进程,这个shell的参数是cmdstring,就是system接受的参数。在windows中的shell是command,想必大家很熟悉shell接受命令之后做的事了。
    2、看到这里你就会明白为什么system()会接受父进程的环境变量,但是用system改变环境变量后,system一返回主函数还是没变,原因从system的实现可以看到,它是通过产生新进程实现的,从我的分析中可以看到父进程和子进程间没有进程通信,子进程自然改变不了父进程的环境变量。
    3、execl与system的一个区别是:使用execl时最好在之前先调用fork,在子进程中执行execl,否则execl会返回。而system则不用,因为从它的实现源码来看,实际上已经调用了fork。
  • 相关阅读:
    vue-awesome-swiper-T 轮播图
    transition-T 手机端滑动验证
    VUE-T
    跨域配置-Access-Control-Allow-Origin
    HTML中CSS引入图片并铺满背景
    mysql_affected_rows()、mysql_fetch_row、mysql_fetch_assoc
    tp框架的四种路由方式
    sql注入
    禁用cookie,怎么获得session
    git解决冲突的方法
  • 原文地址:https://www.cnblogs.com/FarmPick/p/9145045.html
Copyright © 2020-2023  润新知