文章目录

  • linux_C_fork函数的使用
    • references
    • code
      • 主程序
      • 调试宏头文件
      • 编译程序
      • execve example
      • execl example
      • warning: missing sentinel in function call [-Wformat=]

linux_C_fork函数的使用

references

  • Process Identification pid_t data type in C language
  • getpid(2) - Linux manual page (man7.org)

code

主程序

使用到的函数的解释如下


#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include "prints.h"
/* NAMEfork - create a child processSYNOPSIS#include <sys/types.h>#include <unistd.h>pid_t fork(void);RETURN VALUEOn success, the PID of the child process is returned in the parent(即,fork()成功时,子进程的pid被返回给父进程), and 0 is returned in the child.(而被fork出来的进程去检查进程中的相应变量时会是0)On failure, -1 is returned in the parent, no child process is created, and  errno is set appropriately.*/
/*
SLEEP(3)                                                                       Linux Programmer's Manual                                                                      SLEEP(3)NAMEsleep - sleep for a specified number of secondsSYNOPSIS#include <unistd.h>unsigned int sleep(unsigned int seconds);DESCRIPTIONsleep() causes the calling thread to sleep either until the number of real-time seconds specified in seconds have elapsed or until a signal arrives which is not ignored.RETURN VALUEZero if the requested time has elapsed, or the number of seconds left to sleep, if the call was interrupted by a signal handler.*/int main()
{pid_t fpid; // fpid表示fork函数返回的值fpid = fork();dprint(fpid);int time_sec=30;// 判断fork()是否成创建子进程if (fpid < 0)printf("error in fork!");/* 如果成功创建子进程,则父子进程将执行相同的代码为了区分父子进程的后续执行,在下方进一步对进程id做判断其中,我们使用了getpid(),用来获取当前进程的ID *//* 如果运行这段代码是子进程,那么就会进入到判断会是true(因为,fork返回给子进程中fpid变量的值是0),从而执行else if{}块中的操作而如果是父进程(fork()的调用者进程执行以下代码时,fpid不会是0,会跳到else块中执行*/else if (fpid == 0){printf("child process: id is %d\n", getpid());dprint(fpid);int i = time_sec;while (i--){sleep(1);dprint(i);printf("child process is running____");}}else{printf("parent process, my process id is %d\n", getpid());dprint(fpid);int j = time_sec;while (j--){sleep(1);dprint(j);printf("parent process is running!!!!");}}return 0;
}

调试宏头文件

// 数值调试宏
#ifndef CXXU
#define CXXU 1#define dprint(expr) printf(#expr " = %d\n", expr)
#define gprint(expr) printf(#expr " = %g\n", expr)
#define fprint(expr) printf(#expr " = %f\n", expr)
#define sprint(expr) printf(#expr " = %s\n", expr)
#define sprintln(expr) printf(expr "\n")#endif

编译程序

  • gcc testFork.c -o testFork

execve example

/* execve.c */#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "prints.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>/* execve */
/*NAMEexecve - execute programSYNOPSIS#include <unistd.h>int execve(const char *pathname, char *const argv[],char *const envp[]);DESCRIPTIONexecve()  executes  the program referred to by pathname.  This causes the programthat is currently being run by the calling process to be replaced with a new pro‐gram,  with  newly  initialized  stack, heap, and (initialized and uninitialized)data segments.pathname must be either a binary executable, or a script starting with a line of the form:#!interpreter [optional-arg]For details of the latter case, see "Interpreter scripts" below.argv  is  an array of pointers to strings passed to the new program as its command-line arguments.  By conven‐tion, the first of these strings (i.e., argv[0]) should contain the filename associated with  the  file  beingexecuted.  The argv array must be terminated by a NULL pointer.  (Thus, in the new program, argv[argc] will beNULL.)envp is an array of pointers to strings, conventionally of the form key=value, which are passed as  the  envi‐ronment of the new program.  The envp array must be terminated by a NULL pointer.The argument vector and environment can be accessed by the new program's main function, when it is defined as:int main(int argc, char *argv[], char *envp[])Note, however, that the use of a third argument to the main function is not specified in POSIX.1; according toPOSIX.1, the environment should be accessed via the external variable environ(7).*//* exec()family */
/*The exec() family of functions replaces the current process image with a new process image.  The functions described in this manual page are layered on top of execve(2).  (See the manual page for execve(2) for further details about the replacement of the current process image.)The initial argument for these functions is the name of a file that is to be executed.The functions can be grouped based on the letters following the "exec" prefix.*/
/* execl() family */
// int execl(const char *pathname, const char *arg, ...
//           /* (char  *) NULL */);
// int execlp(const char *file, const char *arg, ...
//            /* (char  *) NULL */);
// int execle(const char *pathname, const char *arg, ...
//            /*, (char *) NULL, char *const envp[] */);
/*
l - execl(), execlp(), execle()The const char *arg and subsequent ellipses can be thought of as arg0, arg1, ..., argn.Together they describe a list of one or more pointers to null-terminated strings  that represent  the  argument list available to the executed program. The first argument, by convention, should point to the filename associated with the file being executed.The list of arguments must be terminated by a null pointer, and, since these are variadic(可变参数的) functions, this pointer must be cast (char *) NULL.By contrast with the 'l' functions, the 'v' functions (below) specify the command-line arguments of the executed program as a vector. */
/* execv() family */
/* int execv(const char *pathname, char *const argv[]);int execvp(const char *file, char *const argv[]);int execvpe(const char *file, char *const argv[],char *const envp[]); */
/* v - execv(), execvp(), execvpe()
The `char *const argv[]` argument is an array of pointers to `null - terminated strings` (char arrays) that represent `the argument list` available to the new program.
The first argument, by convention, should point to the filename associated with the file being executed.
The array of pointers must be terminated by a null pointer. */
/* RETURN VALUE (execve) */
/*On success, execve() does not return,on error -1 is returned, and errno is set appropriately. */
/* Note (execve()) */
/*  All that execve() does is arrange for  an  existing process (the calling process) to execute a new program.One sometimes sees execve() (and the related functions described in exec(3)) described  as  "executing  a  newprocess"  (or  similar).This is a highly misleading description: there is no new process;many attributes of the calling process remain unchanged (in particular, its PID).*/
/*//execve() does not return on success,and the text, initialized data, uninitialized data (bss),  and  stack  ofthe calling process are `overwritten `according to the contents of the newly loaded program.If the current program is being ptraced, a SIGTRAP signal is sent to it after a successful execve().If  the  set-user-ID bit is set on the program file referred to by pathname, then the effective user ID of thecalling process is changed to that of the owner of the program file.  Similarly, if the  set-group-ID  bit  isset on the program file, then the effective group ID of the calling process is set to the group of the programfile.*/
int main(int argc, char *argv[])
{/* 参数列表在启动者中指定 */char *newargv[] = {NULL, "hello", "world", NULL};// char *newargv[] = {"hello", "world", NULL};//wrong!// char *newargv[] = {argv[1],"hello", "world", NULL};//Ok,the most convinent pattern.// char **pn = newargv;// char **pn;// pn = {"",NULL};// pn = {"hello", "world", NULL};// char* newargv[]={"abc","def"}char *newenviron[] = {NULL};// if (argc != 2)// {//     fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);//     exit(EXIT_FAILURE);// }// newargv[0] = argv[1];// 调用其他程序,修改进程镜像(由这里的被调用程序的参数由前面定义的newargv指针数组来提供(null-terminated))// argv[1]:the second item in the command line (the programe name passed to execve to lanunch)/* as we known,the argv vector of command line program has features:argv[0] will be the consider as the very command line program name (itself),so,actually,the first argument of the cli program will be the argv[1],and so on,in this case,we just need place our actual arguments from the argv[1](the argv[0] could be assigned with NULL) */char *program = argv[1];program = argv[1];char *argv2[] = {program, "../","-li", NULL};char **newargvs = argv2;// pn = {NULL,"",NULL};//花括号不可以用来赋值,只可以用来初始化!// pn = argv2;sprint(program);sprint(argv[0]);sprint(argv[1]);// traversepp(pn, 2);execve(program, newargvs, newenviron);// execve(program, argv2, newenviron);/* Print a message describing the meaning of the value of errno.*/perror("execve"); /* execve() only returns on error */exit(EXIT_FAILURE);
}
/*
We can use the second program to exec the first as follows:
$ cc myecho.c -o myecho
$ cc execve.c -o execve
//运行时,需要完整的相对路径或者绝对路径(无法通过别名来启动程序,但是符号链接时可以的!)
$  *//* 测试 */
/*
./execve  /usr/local/bin/exa*/
/*
// ./execve myecho #//失败,不完整的路径参数
./execve ./myecho #//成功
argv[0]: ./myecho
argv[1]: hello
argv[2]: world*//*
└─[1] <git:(master 479de41✱) > gcc execve.c -o execve
┌─[cxxu@cxxuAli] - [~/cppCodes] - [2022-04-26 08:37:37]
└─[0] <git:(master 479de41✱✈) > ./execve ./myecho
argv[0]: ./myecho
argv[1]: hello
argv[2]: world*/

execl example

#include "prints.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "common_fun.c"
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
int main(int argc, char const *argv[])
{// 执行/bin目录下的ls, 第一参数为程序名ls, 第二个参数为"-al", 第三个参数为"/etc/passwd"// execl(//     "/usr/bin/head", "head", "-n", "5",//     "/etc/passwd",NULL);sprintln("start new program with execl");if (execl("/bin/ls", "ls", "-al","/home", (char *)NULL) < 0){sprintln("error!");}else{sprintln("success!");}return 0;
}

warning: missing sentinel in function call [-Wformat=]

// int execl(const char *pathname, const char *arg, ...
//           /* (char  *) NULL */);

// char *newp = {NULL};

warning: missing sentinel in function call [-Wformat=] "/home/", (char *)NULL, newp) < 0)

将环境参数删除即可

linux_C_fork函数/execv/execl的使用_数据类型pid_t/getpid/sleep /warning: missing sentinel in function call相关推荐

  1. Linux exec 系列函数:execl execv等

    Linux exec 系列函数:execl execv等 1. exec函数族 1.1 exec 重要说明!!! 1.2 使用exec函数族主要有两种情况: 2. exec函数族共有6种不同形式的函数 ...

  2. exec系列函数(execl、execlp、execle、execv、execvp)使用

    一.exec 替换进程映像 在进程的创建上 Unix 采用了一个独特的方法,它将进程创建与加载一个新进程映象二者分离.这样的好处是有更多的余地对两种操作进行管理. 当我们创建了一个进程之后,通常将子进 ...

  3. execlp使用例子_linux系统编程之进程(五):exec系列函数(execl,execlp,execle,execv,execvp)使用...

    本节目标: exec替换进程映像 exec关联函数组(execl.execlp.execle.execv.execvp) 一,exec替换进程映像 在进程的创建上Unix采用了一个独特的方法,它将进程 ...

  4. linux系统编程之进程(五):exec系列函数(execl,execlp,execle,execv,execvp)使用

    本节目标: exec替换进程映像 exec关联函数组(execl.execlp.execle.execv.execvp) 一,exec替换进程映像 在进程的创建上Unix采用了一个独特的方法,它将进程 ...

  5. exec系列函数(execl,execlp,execle,execv,execvp)使用

    一.exec替换进程映像 在进程的创建上Unix采用了一个独特的方法,它将进程创建与加载一个新进程映象分离.这样的好处是有更多的余地对两种操作进行管理. 当我们创建了一个进程之后,通常将子进程替换成新 ...

  6. pandas使用select_dtypes函数移除dataframe中指定数据类型的数据列(exclude columns based on the data type in dataframe)

    pandas使用select_dtypes函数移除dataframe中指定数据类型的数据列(exclude columns based on the data type in dataframe) 目 ...

  7. 返回值类型与函数类型不匹配_golang基础语法,定义函数类型 为已存在的数据类型起别名...

    简介 在 GO 语言中还有另外一种定义使用函数的方式,就是函数类型,所谓的函数类型就是将函数作为一种类型可以用来定义变量,这种用法类似于前面我们讲过的 int ,float64,string 等类型, ...

  8. Python的Numpy库的函数astype()在将大范围数据类型转换为小范围数据类型时并不是做饱和(saturate)操作(附实现饱和操作的方法)

    Python的Numpy库的函数astype()在将大范围数据类型转换为小范围数据类型时并不是做饱和(saturate)操作. 关于什么是饱和操作,可以参看博文:https://blog.csdn.n ...

  9. pandas使用fillna函数将dataframe中缺失值替换为空字符串(replace missing value with blank string in dataframe)

    pandas使用fillna函数将dataframe中缺失值替换为空字符串(replace missing value with blank string in dataframe) 目录 panda ...

最新文章

  1. 管理者的智慧:靠制度管人,不靠人管人
  2. Django Localization 之language file
  3. 16.6 创建测试数据
  4. 关于Entity Framework中的Attached报错相关解决方案的总结
  5. 模拟聊天室显示语句保持最新显示
  6. synchronized原理_synchronized 关键字底层原理
  7. 关于@Import注解的几个问题
  8. c语言作业答案 填空题,C语言练习题-填空题(带答案)
  9. centos8安装smplayer
  10. css加号图标_css样式画加号和减号(+和-)效果
  11. 武神主宰中的科幻理论体系设定
  12. 【数学建模竞赛指南】对大学生性价比超高的数学建模竞赛
  13. 线性代数 —— 线性组合与线性表出,线性相关与线性无关
  14. gpu服务器厂家_高人气的最近的GPU服务器
  15. Python数据攻略-Pandas进行Excel文件读写
  16. 关于最近研究的绕过某校园网认证登录-DNS隧道-dns2tcp
  17. java实现.费诺编码_香农费诺编码的matlab实现.doc
  18. escape()与unescape()
  19. 曲面触摸传感器设计的挑战
  20. 【图像去雾】颜色衰减先验图像去雾【含Matlab源码 2036期】

热门文章

  1. 我的世界服务器连接协议,go-mc: Minecraft(我的世界)各种协议的Go实现
  2. ABAP 生产订单的创建与修改函数
  3. 《死亡邮件》评怀疑这是QQ邮箱的推广电影
  4. git cherry-pick 的时候出现git cherry-pick xxx  fatal: bad object xxx
  5. acml会议级别_ACL-NLP顶级会议
  6. 稀疏数组——优化五子棋游戏的小技巧
  7. Ubuntu 16.04 64位 安装 modelsim
  8. 5不触发系统键盘_智能化子系统红外周界报警的基础知识介绍!
  9. 命令行导入mysql数据库
  10. java:熊怪吃核桃