C语言实现unix系统调用system

system系统函数的功能是在c语言调用运行bash脚本的,只要是在bash可以运行的脚本,放在system函数中都可以运行.

其中命令行下的脚本是运行在当前bash环境下的.而对于脚本(.sh文件)或者system调用,是需要重新启动一个进程bash.我电脑ubuntu14.04默认启动的是/bin/sh,链接到的是dash,这个轻量级的bash.到底是bash还是dash,可以通过下面的命令查看.

这里写图片描述

dash和bash

dash和bash都是遵循posix标准的系统应用,dash相比于bash有更快的运行速度.关于详细介绍可以参看下面几篇介绍.
大概介绍:https://www.cyberciti.biz/faq/debian-ubuntu-linux-binbash-vs-bindash-vs-binshshell/
详细介绍:https://wiki.ubuntu.com/DashAsBinSh
性能对比:https://wiki.debian.org/DebianEeePC/Dash

基于性能的考虑,/bin/sh是调用dash,所以在运行($sh *.sh)命令的时候,是调用dash,作为其运行环境.而对于system函数也是调用/bin/sh.也就是在dash的环境下运行命令.

system(cmdstring)

system函数

概述

system函数通过/bin/sh-c执行命令行命令,在执行过程中,system函数会阻塞SIGCHLD信号(等待子进程返回,否则返回值会出现错误),会忽略SIGINT和SIGQUIT信号.

system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed.During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.

简单实现

system函数主要就是通过在子进程中执行/bin/sh -c cmdstring实现,主要涉及的是三个函数,fork,execl和waitpid
1.fork();创建一个子进程,如果创建失败,返回值为-1;
2.execl(“/bin/sh”,”sh”,”-c”,cmdstring,(char*)0);执行失败返回127.
3.如果三个函数都执行成功,那么函数的返回值为0;

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
int main(int argc,char*argv[]){

    int status =  mysystem("ls -l");
    printf("status = %d\n",status);
    return 0;
}
int mysystem(const char *cmdstring){


    int status;
    int pid = fork();

    if(pid==-1){
        return -1;
    }

    if(pid==0){

       //system("ps");
       int e_status;
       if((e_status = execl("/bin/sh","sh","-c",cmdstring,(char*)0))<0){
           printf("hello world %d\n",e_status);
           exit(127);
       }

       //Even though execl excute successly,this can not be excuted.
       //printf("hello world %d",e_status);
    }

    printf("the pid of child %d\n",pid);

    waitpid(pid,&status,0);
    return status;
}

system函数默认是忽略SIGINT(ctrl+c),SIGQUIT(ctrl+)信号的,上述的实现并没有涉及忽略这两个信号.因为不怎么熟悉如何忽略信号,之后再来补上,贴一篇比较完整的博客:http://blog.csdn.net/dlutbrucezhang/article/details/8914772

可以通过下面的代码测试这两个信号是被忽略的.

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc,char *argv[]){
    while(1){
        system("ps");
    }
    return 0;
}

发现,陷入死循环,ctrl+c和ctrl+\都无法停止.说明两个信号都被忽略了.ctrl+z挂起,可以正常停止.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验二 UNIX磁盘空间管理算法 (一) 实验目的 掌握UNIX外存空间管理中的分组链接算法。 (二) 实验内容 编写C语言程序,模拟UNIX磁盘空间管理中使用的分组链接法。 1.定义一个记录磁盘块号的堆栈S&mdash;free[10],以及记录栈中现有磁盘块数的变量S&mdash;nfree。 2.定义一个由40个元素构成的结构数组block[40]用作磁盘块存放。 struct size { int blocl[10]; } struct blocd { struct size a[10]; //用于在空闲磁盘块号链中存放磁盘块号 }block[40]; 3. 假设系统中文件的最大容量为100个磁盘块,且最多只有5个文件,定义一个由5个元素构成的结构数组file[5]用于记录各个文件占用的磁盘块,。 struct File { int fileblocd[100]; //用于记录分别分配给文件的磁盘块号 }file[5]; 4. 编写函数init( )完成空闲磁盘块号堆栈、空闲磁盘块号队列及记录文件占用磁盘块状态的file结构数组。 5. 编写函数alloc(fileno,blockd),完成磁盘块的分配操作。其中的参数fileno为文件序号,用于指定需要分配的文件。 6. 编写函数free(fileno),完成文件占用磁盘块的释放操作。其中的参数fileno为文件序号,用于指定需要释放磁盘块的文件。 7. 编写main( )函数完成下列操作: 调用init( )函数完成初始设置。 从终端输入命令,控制磁盘块的分配与回收操作。 (三) 实验要求 1. 在程序运行的结果中应包含磁盘块的分配与回收操作。 2. 可根据输入的文件名、文件大小进行模拟磁盘分配,并在每次分配与回收后显示分配与回收是否成功,以及分配、回收的磁盘块号。 3. 在程序执行过程中,至少应包含分配不成功一次的信息。 4. 可以查看当前磁盘块的使用情况:哪些块空闲,哪些块被哪些文件占用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值