这一篇博客讲解进程和系统调用相关的知识

有这样一个场景,我需要输入一串文字,然后把我输入的文字加上一个本地的时间戳 保存在一个文件中,可以初步理解为一个备忘录也行

 #include <stdio.h>
#include <stdlib.h>
#include <time.h> /**
* 获取一个当前时间
*/
char *now() {
time_t t;
time(&t);
return asctime(localtime(&t));
} int main(int argc, const char * argv[]) { char comment[];
char cmd[]; fgets(comment, , stdin);
// sprintf 把内容写进一个变量中
sprintf(cmd, "echo '%s %s' >> reports.log",comment,now());
// 调用系统的方法来执行这段命令
system(cmd);
return ;
}

程序运行的结果是生成了一个文件

但有时候systemt() 函数也会是不安全的

sprintf(cmd, "echo ''&& ls / && echo' %s' >> reports.log",now());

修改上边的代码,然后会得到这样的结果

列出了根目录下的内容,因此可以使用命令删除文件或启动病毒

那么现在有一个场景,我们有exec来获取本机的网络配置,在Linux 和 Mac 上 你可以用一个叫/sbin/ifconfig的程序 在window上你用ipconfig

看代码

 #include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h> int main(int argc, const char * argv[]) { if (execl("/sbin/ifconfig", "/sbin/ifconfig",NULL) == -) { if (execlp("ipconfig", "ipconfig",NULL) == -) { fprintf(stderr, "Can not run ipconfig : %s",strerror(errno));
}
}
return ;
}

下边的代码也是很有意思的,可以充分说明exec函数的作用是停止当前进程 跳到另一个进程的

我们先创建一个叫做coffee.c 的文件,代码如下

 #include <stdio.h>
#include <stdlib.h> int main(int argc, char* argv[]) { char *w = getenv("EXTRA");
if (!w) {
w = getenv("FOOD");
}
if (!w) {
w = argv[argc - ];
} char *c = getenv("EXTRA");
if (!c) {
c = argv[argc - ];
} printf("%s with %s \n", c, w);
return ;
}

该程序的作用是先检测是否有环境变量EXTRA 没有就检测FOOD 如果还没有就给w赋值为最后一个参数值

先检测环境变量EXTRA 如果没有就给c赋值为最后一个参数

下边的代码可以检测我们上边这段代码是不是能够正确运行,首先我们新建一个coffeeTest.c的文件

 #include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h> int main(int argc, char* argv[]) { char *my_env[] = {"FOOD=Hanbaobao", NULL};
if (execle("./coffee", "./coffee", "abv", NULL, my_env) == -) {
fprintf(stderr, "Can not run process: %s",strerror(errno));
return ;
}
return ;
}
 gcc coffee.c -o coffee
gcc coffeeTest.c -o coffeeTest
./coffeeTest

得到的结果是

abv with Hanbaobao 

假如我们吧coffeeTest.c中的代码改成这样呢

  if (execl("./coffee", "./coffee", "abv", NULL) == -) {
fprintf(stderr, "Can not run process: %s",strerror(errno));
return ;
}

不出意外结果就是

abv with abv 

好了,我们已经了解exec函数的使用方法了,其实exec函数算是程序中的最后一行代码了,只要调用它之后,程序立即停止运行,原理就是停止当前进程开启另外一个进程

那么如果我们还想要后边的代码继续执行呢

先看个例子

 #include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h> int main(int argc, char* argv[]) { char *my_env[] = {"FOOD=Hanbaobao", NULL}; for (int i = ; i < ; i++) { pid_t pid = fork(); if (pid == -) {
fprintf(stderr, "Can not fork process: %s",strerror(errno));
return ;
} if (!pid) { if (execle("./coffee", "./coffee", "abv", NULL, my_env) == -) {
fprintf(stderr, "Can not run process: %s",strerror(errno));
return ;
}
} }
return ;
}

如果不加fork() 上边的程序只会打印一次结果,当循环中第一次调用exec的时候,后边的代码就不会再调用了

fork 是什么,看下边的解释

c 进程和系统调用的更多相关文章

  1. (转)Linux内核之进程和系统调用

    Linux内核之进程和系统调用 什么是系统调用 在Linux的世界里,我们经常会遇到系统调用这一术语,所谓系统调用,就是内核提供的.功能十分强大的一系列的函数.这些系统调用是在内核中实现的,再通过一定 ...

  2. linux strace-跟踪进程的系统调用或是信号产生情况,lstrace-跟踪己丑年调用库函数情况,进程跟踪调试命令

    本工具可以用来做大多数排除,比如mount一个NFS,很慢,找不出原因,我们可以使用strace命令来跟中mount这个经常所有的调用过程. strace 命令是一种强大的工具,它能够显示所有由用户空 ...

  3. [strace]跟踪进程的系统调用

    转自:https://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316692.html 简介 strace常用来跟踪进程执行时的系统调用和所接收的信号 ...

  4. 9.11 strace:跟踪进程的系统调用 、ltrace:跟踪进程调用库函数

    strace 是Linux环境下的一款程序调试工具,用于检查一个应用程序所使用的系统调用以及它所接收的系统信息.strace会追踪程序运行时的整个生命周期,输出每一个系统调用的名字.参数.返回值和执行 ...

  5. Linux进程管理及while循环

    目录 进程的相关概念 进程查看及管理工具的使用 Linux系统作业控制 调整进程优先级 网络客户端工具 bash之while循环 20.1.进程类型 守护进程 daemon,在系统引导过程中启动的进程 ...

  6. c 进程间的通信

    在上篇讲解了如何创建和调用进程 c 进程和系统调用 这篇文章就专门讲讲进程通信的问题 先来看一段下边的代码,这段代码的作用是根据关键字调用一个Python程序来检索RSS源,然后打开那个URL #in ...

  7. Linux进程学习

    进程与进程管理: 清屏:system("clear"); //#include <signal.h> 进程环境与进程属性: 什么是进程:简单的说,进程就是程序的一次执行 ...

  8. strace追踪未开始或者来不及捕获pid的进程(译)

    我的个人博客网站最近被攻击了,被用来发送一些垃圾邮件.但是我不知道这个进程是怎么来的,用top查看发现一个不知道干什么的perl脚本,决定给用strace查看一下. strace可以追踪一个进程的系统 ...

  9. Linux下取代top的进程管理工具 htop

    一.htop 简介 This is htop, an interactive process viewer for Linux. It is a text-mode application (for ...

随机推荐

  1. redux-amrc:用更少的代码发起异步 action

    很多人说 Redux 代码多,开发效率低.其实 Redux 是可以灵活使用以及拓展的,经过充分定制的 Redux 其实写不了几行代码.今天先介绍一个很好用的 Redux 拓展-- redux-amrc ...

  2. ArcGIS 10.0紧凑型切片读写方法

    首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...

  3. 【java】Naming.bind和Registry.bind区别

    Naming类和Registry类均在java.rmi包 Naming类通过解析URI绑定远程对象,将URI拆分成主机.端口和远程对象名称,使用的仍是Registry类. public static ...

  4. mac下安装及配置tomcat

    mac下的软件不像windows下的程序那样写注册表,对于tomcat的安装来说,在mac下是名符其实的绿色软件,具体操作如下: 1.到 apache官方主页 下载完整 tar.gz文件包.(没有专门 ...

  5. CSS样式重置(转)

    body,h1,h2,h3,h4,h5,h6,dl,dt,dd,ul,ol,li,th,td,p,blockquote,pre,form,fieldset,legend,input,button,te ...

  6. 前端MVC学习总结(一)——MVC概要与angular概要、模板与数据绑定

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.AngularJS是框架而jQuery则是库. 1.2. ...

  7. WPF 普通属性变化通知

    问题描述:使用ObservableCollection<OrderItem> source 给Datagrid.ItemsSource赋值,在后台更新source集合后,前台Datagri ...

  8. javascript有用小功能总结(未完待续)

    1)javascript让页面标题滚动效果 代码如下: <title>您好,欢迎访问我的博客</title> <script type="text/javasc ...

  9. arcgis api for js入门开发系列七图层控制(含源代码)

    上一篇实现了demo的地图分屏对比模块,本篇新增图层控制模块,截图如下(源代码见文章底部): 图层控制模块实现的思路如下: 1.在地图配置文件map.config.js里面配置图层目录树节点信息,作为 ...

  10. Android 中的mvvm

    我们来了解一下MVVM模式与Databinding ,MVVM是一种模式,Databinding 是一种框架.DataBinding是一个实现数据和UI绑定的框架.而ViewModel和View可以通 ...