当前位置: 首页 > news >正文

php心水主论坛网站制作网页设计wordpress logo修改

php心水主论坛网站制作网页设计,wordpress logo修改,wordpress notes,外贸找客户有什么网站目录 进程程序替换[1~5]1.程序替换的接口#xff08;加载器#xff09;2.什么是程序替换#xff1f;3.进程替换的原理4.引入多进程5.系列程序替换接口的详细解析#xff08;重点#xff01;#xff09; 自定义编写一个极简版shell[6~8]6.完成命令行提示符7.获取输入的命令… 目录 进程程序替换[1~5]1.程序替换的接口加载器2.什么是程序替换3.进程替换的原理4.引入多进程5.系列程序替换接口的详细解析重点 自定义编写一个极简版shell[6~8]6.完成命令行提示符7.获取输入的命令行字符串8.完整的代码与测试效果9.补充——内建命令 进程程序替换[1~5] 创建子进程的目的是 1.让子进程执行父进程的一部分代码 2.让子进程执行一个全新的程序代码——进程的程序替换。 1.程序替换的接口加载器 程序替换的接口有 environ是环境变量表的指针在环境变量讲过 头文件 #include unistd.h 函数 int execl(const char *path, const char *arg, …); int execlp(const char *file, const char *arg, …); int execle(const char *path, const char *arg, …,char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]); 返回值 调用成功没有返回值 调用出错返回-1比如替换不存在的程序就会失败 所以execl系列函数只有出错的返回值而没有成功的返回值 即只要有返回值就失败了。 关于execl系列函数的使用 因为这些程序替换函数如果替换成功后面我们自己的程序就会被替换不再执行会执行替换的程序。 所以我们一般不用对这些函数的返回值做判断在使用完这些函数后直接使用exit(1)退出就可以了因为替换成功了不会执行退出函数替换失败了就会执行exit(1)异常退出 补充 参数中的“…”表示的是可变参数列表可变参数列表的作用是可以给函数传递任意个数个参数。 比如这个函数前面两个指明的参数时必须传的但是后面的参数可以不传也可以任意个数去传。其实与平时调用printf一样逗号后面的参数需要多少个就传多少个 2.什么是程序替换 ——用一段简单的代码来解释 //测试代码 #include stdio.h #include stdlib.h #include unistd.hint main() {printf(begin...\n);printf(我是一个进程了,我的PID:%d\n, getpid());execl(/bin/ls, ls, -a, -l, NULL);printf(end...\n); }结果 可以观察到上面执行的是自己写的程序后面执行的是ls命令。 ls是一个磁盘中的可执行程序也就是一个文件当我们自己的进程运行时在内存中有自己的pcb和代码数据刚开始执行的时候执行的使我们自己的代码和数据当执行execl时就将磁盘中的ls可执行程序替换到当前进程的代码和数据中main函数中老的代码和数据全都被替换了所以后面执行的就不是我们自己的代码和数据了执行的是替换后的ls的代码和数据所以后面我们自己程序中的end…也没有打印出来。 3.进程替换的原理 在程序替换的时候进程的数据和代码直接被新的程序所替换如下图所示并且直接换物理内存左边的映射不变。 并且在进程替换的时候并没有创建新的子进程只是将当前的进程进行了替换让CPU去调度当前进程就可以运行了进程的内核pcb和虚拟地址空间都没有发生变化。 4.引入多进程 1.程序替换是整体替换不能局部替换。 意思就是当前进程调用了程序替换接口则当前进程全部的代码和数据都会被替换成新的。 2.程序替换只会影响调用的进程因为进程具有独立性。 虽然父子进程通过页表指向同样的代码和数据但是当子进程发生进程替换的时候会发生写时拷贝将父子进程进行区分就不会影响父进程了。代码区和数据区全都发生写时拷贝 例如下面的代码只替换子进程的程序 #include stdio.h #include stdlib.h #include unistd.h #includesys/types.h #include sys/wait.hint main() {pid_t id fork();if(id 0){printf(我是子进程:%d\n, getpid());execl(/bin/ls, ls, -a, -l, NULL);//1.这里注释的是下面会替换失败的情况这种情况父进程获取退出码为1//execl(/bin/lssssss, ls, -a, -l, NULL);//2.这里注释的是下面会替换成功但是替换的程序内部出错的情况这种情况父进程获取退出码为2//execl(/bin/ls, ls, -abcdefg, -l, NULL);exit(1);}sleep(5);int status 0;printf(我是父进程:%d\n, getpid());waitpid(id, status, 0);printf(child exit code:%d\n, WEXITSTATUS(status));return 0; }运行结果 成功父子进程正常运行子进程执行替换程序 失败父子进程正常运行子进程执行原有代码 解析 如果程序替换成功则父进程waitpid获取到替换进程的退出码“0” 如果程序替换失败则父进程waitpid获取到原来进程的退出码“1” 如果程序替换成功但是替换成功的程序选项错误这时的错误退出码也是由替换后的程序返回的就比如前面代码中的成功但是退出码是2的情况。 5.系列程序替换接口的详细解析重点 这些所有接口都符合前面所讲的性质只是用法略有差异。 头文件 #include unistd.h 函数 int execl(const char *path, const char *arg, …); int execlp(const char *file, const char *arg, …); int execle(const char *path, const char *arg, …,char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]); int execl(const char *path, const char *arg, …) ——“l”表示list以列表方式一个个传参。 path——想要执行程序的路径比如ls就传/bin/ls arg——执行该程序的方式在命令行怎么执行就怎么传参比如ls -a -l就传ls, -a, -l参数最后必须以NULL结尾 例execl(/bin/ls, ls, -a, -l, NULL); int execv(const char *path, char *const argv[]) ——“v”表示vector以数组方式一次性传参。 path——想要执行程序的路径比如ls就传/bin/ls argv[]——传参以指针数组方式传在命令行怎么执行数组中就怎么写比如可以定义一个指针数组char *myargv[] {ls, -a, -l, NULL};传入的数组最后以NULL结尾 例 char *myargv[] {ls, -l, -a, NULL}; execv(/bin/ls, myargv);int execlp(const char *file, const char *arg, …) ——“p”表示环境变量PATH会自动在PATH中查找。 file——想要执行的程序不用带路径比如ls就传ls arg——与execl的arg传入参数方式完全一样。比如ls -a -l就传ls, -a, -l 例execlp(ls, ls, -a, -l, NULL); 4.int execvp(const char *file, char *const argv[]) ——“v”与“p”的意思和上面的一样。 file——想要执行的程序不用带路径比如ls就传ls argv[]——传参以指针数组方式传。与execv一样 例execvp(ls, myargv); int execle(const char *path, const char *arg, …,char *const envp[]) ——父进程给子进程手动传环境变量。 path——想要执行程序的路径。 arg——执行该程序的方式一个一个传入。 envp[]——自定义环境变量以NULL结尾比如char *const myenv[] {MYENVYouCanSeeMe, NULL}; 解析可以通过这些接口调用自己写好的其他可执行程序。这些程序可以不是C程序其他语言都可以调用 例如目录如下如所示我们要通过myproc调用otherproc并在otherproc中获取myproc传给它的环境变量MYENV。 //myproc.c #include stdio.h #include stdlib.h #include unistd.h #include sys/types.h #include sys/wait.hint main() {pid_t id fork();if(id 0){printf(我是子进程:%d\n, getpid());char *const myenv[] {MYENVYouCanSeeMe, NULL};//自定义环境变量execle(./Otherproc/otherproc, otherproc, NULL, myenv);//传入自定义环境变量exit(1);}sleep(5);int status 0;printf(我是父进程:%d\n, getpid());waitpid(id, status, 0);printf(child exit code:%d\n, WEXITSTATUS(status));return 0; }//otherproc.cc #include iostream #include unistd.h #include stdlib.h #include sys/types.h using namespace std;int main() {for(int i 0; i 5; i){cout 这是子进程, PID : getpid() MYENV : (getenv(MYENV)NULL? NULL : getenv(MYENV)) PATH : (getenv(PATH)NULL? NULL : getenv(PATH)) endl;sleep(1);}return 0; }运行结果可以看到子进程获取了父进程传入的自定义环境变量。 注意自定义环境变量envp是覆盖式传入之前的老的会被覆盖 如果我们想把父进程的环境变量原封不动的传给子进程那么就用environ之前讲过的获取环境变量的方法之一传入即可。 用法在父进程创建extern char **environ;后直接传入。 比如 #include stdio.h #include stdlib.h #include unistd.h #include sys/types.h #include sys/wait.hint main() {extern char **environ;//获取父进程环境变量下面通过execle传入pid_t id fork();if(id 0){printf(我是子进程:%d\n, getpid());execle(./Otherproc/otherproc, otherproc, NULL, environ);exit(1);}sleep(5);int status 0;printf(我是父进程:%d\n, getpid());waitpid(id, status, 0);printf(child exit code:%d\n, WEXITSTATUS(status));return 0; }运行结果发现子进程获取了父进程的默认环境变量PATH。 如果我们想保留原来父进程的环境变量并且在此基础上增加自定义环境变量呢 ——int putenv(char *string);那个进程调用这个函数就在当前的进程中新增一个环境变量。 头文件#include stdlib.h。 #include stdio.h #include stdlib.h #include unistd.h #include sys/types.h #include sys/wait.hint main() {extern char **environ;pid_t id fork();if(id 0){printf(我是子进程:%d\n, getpid());putenv(MYENVYouCanSeeMe);execle(./Otherproc/otherproc, otherproc, NULL, environ);exit(1);}sleep(5);int status 0;printf(我是父进程:%d\n, getpid());waitpid(id, status, 0);printf(child exit code:%d\n, WEXITSTATUS(status));return 0; }我们的子进程otherproc默认继承的是父进程proc的环境变量那么父进程的环境变量从哪里来 ——bash所以我们也可以不用putenv来追加环境变量直接在命令行输入export MYENVYouCanSeeMe来给bash添加一个环境变量这样默认传入environ的时候子进程也会接收到MYENV这个环境变量了。 int execve(const char *path, char *const argv[], char *const envp[]); 发现这个接口在man手册中被单独放出来了和前面的有什么区别 ——接口用法的规则和前面的几个一模一样类推即可不再详细解析。 那么区别是这个是真正提供的的系统调用接口上面的所有都是对这个的封装 自定义编写一个极简版shell[6~8] bash就是一个进程 6.完成命令行提示符 bash会接收我们输入的命令行字符串并且不会退出一直在为我们打印命令行提示符。 一个命令行提示符包括 [用户名 主机名 当前路径的名称]$ 每个字段都可以通过对应的系统调用获取但是现在对我来说意义不大这里直接打印就不使用了。 //实现命令行提示符 int main() {while(1){printf([YGHMyMachina CurrentPath]#);//命令行的输入是在当前行输入不能用\nfflush(stdout);//不用\n不会行刷新出来所以要用fflush刷新缓冲区sleep(100);//测试观察这句之后不要} }7.获取输入的命令行字符串 使用接口fget——从特定的标准输入stream当中获取命令行输入。 接口函数char *fgets(char *s, int size, FILE *stream); 头文件stdio.h 手册查询 1.首先我们自己定一个一个命令行commandstr然后通过fgets获取输入的命令行字符串 #include stdio.h #include string.h #include unistd.h #include assert.h#define MAX 1024int main() {char commandstr[MAX] {0};while(1){printf([YGHMyMachina CurrentPath]# );//命令行的输入是在当前行输入不能用\nfflush(stdout);//不用\n不会行刷新出来所以要用fflush刷新缓冲区char *s fgets(commandstr, sizeof(commandstr), stdin);//输入的时候最后缓冲区会输入一个\nassert(s);//断言在debug方式的时候存在release方式会被裁掉(void)s;//这句的用处是让断言在release方式下也不会失效因为assert被去掉了s没有被使用会报警这里用一下就不会报警了commandstr[strlen(commandstr) - 1] \0;//去掉我们缓冲区中输入的\nprintf(%s\n, commandstr);//测试观察一下这句之后不要} }2.然后我们也不能自己来执行命令行输入要执行的程序因为如果进程替换了我们作为命令行自己就会被替换掉了这样是不合理的所以肯定需要子进程来处理。 即父进程把命令给子进程然后父进程等待结果就行了。 同时我们的自定义缓冲区中输入的是一整个连续的字符串需要切割成单个的命令传入比如“ls -a -l” 要切割成 “ls”, “-a”, “-l”。 ——可以自己切割也可以使用字符串分割函数char* strtok(char* str, const char* sep); 进行字符串的切割 #include stdio.h #include string.h #include unistd.h #include stdlib.h #include assert.h #include sys/types.h #include sys/wait.h#define MAX 1024 #define ARGC 64 #define SEP //分隔符空格//字符串切割函数 int split(char* commandstr, char* argv[]) {assert(commandstr);assert(argv);argv[0] strtok(commandstr, SEP);//函数切割后返回第一个地址if(argv[0] NULL){return 1;}int i 1;while(argv[i] strtok(NULL, SEP));//这一句等价于下面的一段代码//while(1)//{// argv[i] strtok(NULL, SEP);//NULL表示还是继续切割commandstr// if(argv[i] NULL)// {// break;// }// i;//}return 0; }int main() {while(1){char commandstr[MAX] {0};//放在循环内部每次输入后重新创建缓冲区判断char* argv[ARGC] {NULL};//存放切割后的字符串printf([YGHMyMachina CurrentPath]# );//命令行的输入是在当前行输入不能用\nfflush(stdout);//不用\n不会行刷新出来所以要用fflush刷新缓冲区char *s fgets(commandstr, sizeof(commandstr), stdin);//输入的时候最后缓冲区会输入一个\nassert(s);//断言在debug方式的时候存在release方式会被裁掉(void)s;//这句的用处是让断言在release方式下也不会失效因为assert被去掉了s没有被使用会报警这里用一下就不会报警了commandstr[strlen(commandstr) - 1] \0;//去掉我们缓冲区中输入的\nint n split(commandstr, argv);//字符串切割if(n ! 0)//判断字符串是否切割成功{continue;}pid_t id fork();assert(id 0);(void)id;if(id 0){//子进程exit(0);}//父进程int status 0;//退出码waitpid(id, status, 0);//阻塞等待子进程} }完成切割后进行进程的替换要使用execvp因为输入的命令没有地址要在环境变量中直接寻找需要“p”而且输入的命令行字符串时切割开放在一个数组中的所以需要“v”。 #include stdio.h #include string.h #include unistd.h #include stdlib.h #include assert.h #include sys/types.h #include sys/wait.h#define MAX 1024 #define ARGC 64 #define SEP //分隔符空格//字符串切割函数 int split(char* commandstr, char* argv[]) {assert(commandstr);assert(argv);argv[0] strtok(commandstr, SEP);//函数切割后返回第一个地址if(argv[0] NULL){return 1;}int i 1;while(argv[i] strtok(NULL, SEP));//这一句等价于下面的一段代码//while(1)//{// argv[i] strtok(NULL, SEP);//NULL表示还是继续切割commandstr// if(argv[i] NULL)// {// break;// }// i;//}return 0; }//用来输出切割后的字符串的函数 void debugPrintf(char* argv[]) {for(int i 0; argv[i]; i){printf(%d: %s\n, i, argv[i]);} }int main() {while(1){char commandstr[MAX] {0};//放在循环内部每次输入后重新创建缓冲区判断char* argv[ARGC] {NULL};//存放切割后的字符串printf([YGHMyMachina CurrentPath]# );//命令行的输入是在当前行输入不能用\nfflush(stdout);//不用\n不会行刷新出来所以要用fflush刷新缓冲区char *s fgets(commandstr, sizeof(commandstr), stdin);//输入的时候最后缓冲区会输入一个\nassert(s);//断言在debug方式的时候存在release方式会被裁掉(void)s;//这句的用处是让断言在release方式下也不会失效因为assert被去掉了s没有被使用会报警这里用一下就不会报警了commandstr[strlen(commandstr) - 1] \0;//去掉我们缓冲区中输入的\nint n split(commandstr, argv);//字符串切割if(n ! 0)//判断字符串是否切割成功{continue;}//debugPrintf(argv);//测试输出切割后的字符串pid_t id fork();assert(id 0);(void)id;if(id 0){//子进程execvp(argv[0], argv);exit(1);//替换失败直接退出}//父进程int status 0;//退出码waitpid(id, status, 0);//阻塞等待子进程} }8.完整的代码与测试效果 以上就实现了一个最基础的极简版的shell命令行以下是删除不必要的完整代码 #include stdio.h #include string.h #include unistd.h #include stdlib.h #include assert.h #include sys/types.h #include sys/wait.h#define MAX 1024 #define ARGC 64 #define SEP //分隔符空格//字符串切割函数 int split(char* commandstr, char* argv[]) {assert(commandstr);assert(argv);argv[0] strtok(commandstr, SEP);//函数切割后返回第一个地址if(argv[0] NULL){return 1;}int i 1;while(argv[i] strtok(NULL, SEP));//这一句等价于下面的一段代码return 0; }int main() {while(1){char commandstr[MAX] {0};//放在循环内部每次输入后重新创建缓冲区判断char* argv[ARGC] {NULL};//存放切割后的字符串printf([YGHMyMachina CurrentPath]# );//命令行的输入是在当前行输入不能用\nfflush(stdout);//不用\n不会行刷新出来所以要用fflush刷新缓冲区char *s fgets(commandstr, sizeof(commandstr), stdin);//输入的时候最后缓冲区会输入一个\nassert(s);//断言在debug方式的时候存在release方式会被裁掉(void)s;//这句的用处是让断言在release方式下也不会失效因为assert被去掉了s没有被使用会报警这里用一下就不会报警了commandstr[strlen(commandstr) - 1] \0;//去掉我们缓冲区中输入的\nint n split(commandstr, argv);//字符串切割if(n ! 0)//判断字符串是否切割成功{continue;}pid_t id fork();assert(id 0);(void)id;if(id 0){//子进程execvp(argv[0], argv);exit(1);//替换失败直接退出}//父进程int status 0;//退出码waitpid(id, status, 0);//阻塞等待子进程} }测试效果 9.补充——内建命令 对于我们前面自己完成的shell因为是在子进程中执行的所以只能完成ls这样的命令cd命令就无法移动到指定目录因为需要由父进程bash来运行才能做到移动像cd这样的命令我们称之为内建命令要特殊处理。 以cd为例要调用chdir修改工作路径来直接让bash修改路径即可 头文件 #include unistd.h 函数 int chdir(const char *path); 参数 要改变的路径绝对/相对 返回值 成功返回0失败返回-1 所以加上这样一段代码就可以让bash来执行cd命令了 //cd是内建命令让bash来执行 if(strcmp(argv[0], cd) 0) {if(argv[1] ! NULL){chdir(argv[1]);}continue;//直接通过chdir让bash修改就不用往后传给子进程了 }还有像export导入环境变量也是内建命令也可以用同样的方式来实现 直接使用putenv由bash来执行将环境变量导入。 注意 用户自己定义的环境变量在bash中要用户自己来维护不能用一个经常被覆盖的缓冲区来保存环境变量。因为环境变量导入后是直接指向缓冲区中保存的字符串的如果经常被刷新的话就找不到了 //因为维护了缓冲区所以贴完整的代码 #include stdio.h #include string.h #include unistd.h #include stdlib.h #include assert.h #include sys/types.h #include sys/wait.h#define MAX 1024 #define ARGC 64 #define SEP //分隔符空格//字符串切割函数 int split(char* commandstr, char* argv[]) {assert(commandstr);assert(argv);argv[0] strtok(commandstr, SEP);//函数切割后返回第一个地址if(argv[0] NULL){return 1;}int i 1;while(argv[i] strtok(NULL, SEP));//这一句等价于下面的一段代码return 0; }//用来输出切割后的字符串的函数 void debugPrintf(char* argv[]) {for(int i 0; argv[i]; i){printf(%d: %s\n, i, argv[i]);} }int main() {char myenv[32][256] {0};//自定义维护的环境变量缓冲区int env_index 0;while(1){char commandstr[MAX] {0};//放在循环内部每次输入后重新创建缓冲区判断char* argv[ARGC] {NULL};//存放切割后的字符串printf([YGHMyMachina CurrentPath]# );//命令行的输入是在当前行输入不能用\nfflush(stdout);//不用\n不会行刷新出来所以要用fflush刷新缓冲区char *s fgets(commandstr, sizeof(commandstr), stdin);//输入的时候最后缓冲区会输入一个\nassert(s);//断言在debug方式的时候存在release方式会被裁掉(void)s;//这句的用处是让断言在release方式下也不会失效因为assert被去掉了s没有被使用会报警这里用一下就不会报警了commandstr[strlen(commandstr) - 1] \0;//去掉我们缓冲区中输入的\nint n split(commandstr, argv);//字符串切割if(n ! 0)//判断字符串是否切割成功{continue;}//cd是内建命令让bash来执行if(strcmp(argv[0], cd) 0){if(argv[1] ! NULL){chdir(argv[1]);}continue;}else if(strcmp(argv[0], export) 0)//export是内建命令让bash执行{if(argv[1] ! NULL){strcpy(myenv[env_index], argv[1]);//拷贝到自定义的环境变量缓冲区putenv(myenv[env_index]);//导入因为commandstr会被覆盖}continue;}//配置ls命令的配色方案if(strcmp(argv[0], ls) 0){int pos 0;while(argv[pos]){pos;}argv[pos] (char*)--colorauto;argv[pos] NULL;}//debugPrintf(argv);//输出切割后的字符串pid_t id fork();assert(id 0);(void)id;if(id 0){//子进程execvp(argv[0], argv);exit(1);//替换失败直接退出}//父进程int status 0;//退出码waitpid(id, status, 0);//阻塞等待子进程} } 而此时获取的env还是子进程的环境变量我们要查的是bash的环境变量所也要对env命令做特殊处理echo命令同理也需要处理。 #include stdio.h #include string.h #include unistd.h #include stdlib.h #include assert.h #include sys/types.h #include sys/wait.h#define MAX 1024 #define ARGC 64 #define SEP //分隔符空格//字符串切割函数 int split(char* commandstr, char* argv[]) {assert(commandstr);assert(argv);argv[0] strtok(commandstr, SEP);//函数切割后返回第一个地址if(argv[0] NULL){return 1;}int i 1;while(argv[i] strtok(NULL, SEP));//这一句等价于下面的一段代码return 0; }//用来输出切割后的字符串的函数 void debugPrintf(char* argv[]) {for(int i 0; argv[i]; i){printf(%d: %s\n, i, argv[i]);} }void showEnv() {extern char** environ;for(int i 0; environ[i]; i){printf(%d:%s\n, i, environ[i]);} } int main() {char myenv[32][256] {0};//自定义维护的环境变量缓冲区int env_index 0;while(1){int last_exit 0;//保存最后获取的退出码char commandstr[MAX] {0};//放在循环内部每次输入后重新创建缓冲区判断char* argv[ARGC] {NULL};//存放切割后的字符串printf([YGHMyMachina CurrentPath]# );//命令行的输入是在当前行输入不能用\nfflush(stdout);//不用\n不会行刷新出来所以要用fflush刷新缓冲区char *s fgets(commandstr, sizeof(commandstr), stdin);//输入的时候最后缓冲区会输入一个\nassert(s);//断言在debug方式的时候存在release方式会被裁掉(void)s;//这句的用处是让断言在release方式下也不会失效因为assert被去掉了s没有被使用会报警这里用一下就不会报警了commandstr[strlen(commandstr) - 1] \0;//去掉我们缓冲区中输入的\nint n split(commandstr, argv);//字符串切割if(n ! 0)//判断字符串是否切割成功{continue;}//cd是内建命令让bash来执行if(strcmp(argv[0], cd) 0){if(argv[1] ! NULL){chdir(argv[1]);}continue;}else if(strcmp(argv[0], export) 0)//export是内建命令让bash执行{if(argv[1] ! NULL){strcpy(myenv[env_index], argv[1]);//拷贝到自定义的环境变量缓冲区putenv(myenv[env_index]);//导入因为commandstr会被覆盖}continue;}else if(strcmp(argv[0], env) 0)//env如果交给子进程打印的是子进程的特殊处理打印bash的{showEnv();continue;}else if(strcmp(argv[0], echo) 0){const char* target_env NULL;if(*argv[1] $){if(*argv[1]1 ?){printf(%d\n, last_exit);continue;}else{target_env getenv(argv[1]1);}if(target_env ! NULL){printf(%s%s\n, argv[1] 1, target_env);}}}//配置ls命令的配色方案if(strcmp(argv[0], ls) 0){int pos 0;while(argv[pos]){pos;}argv[pos] (char*)--colorauto;argv[pos] NULL;}//debugPrintf(argv);//输出切割后的字符串pid_t id fork();assert(id 0);(void)id;if(id 0){//子进程execvp(argv[0], argv);exit(1);//替换失败直接退出}//父进程int status 0;//退出码pid_t ret waitpid(id, status, 0);//阻塞等待子进程if(ret 0)//获取退出码{last_exit WEXITSTATUS(status);}} }
http://www.w-s-a.com/news/19804/

相关文章:

  • 企业网站规划方案网站是做排行榜
  • 万维网网站个人申请网站
  • 我想做网站怎么做昆山网站建设 全是乱码
  • 单位做网站怎么做圣诞树html网页代码
  • 网页开发与网站开发企业网站托管服务常用指南
  • 一站式服务图片临沂做进销存网站
  • 鸣蝉智能建站标准物质网站建设模板
  • 电商网站建设技术员的工作职责商业网站制作价格
  • 网站html模板免费下载公司的网站建设费用入什么科目
  • 高中生做网站网页网页制作教程零基础学会
  • 做金融网站有哪些要求WordPress站内搜索代码
  • 济南网站怎么做seowordpress注册发邮件
  • 珠海网站设计平台东莞市手机网站建设平台
  • 网站开发文档合同怎么在wordpress导航条下方加入文字广告链接
  • 网站建设需怎么做有网站怎么做企业邮箱
  • 网站制作流程视频教程小程序多少钱一年
  • 暗网是什么网站花都网站建设哪家好
  • 贵州网站开发流程晋江论坛手机版
  • 网站建设丿金手指谷哥14阿里巴巴官网电脑版
  • 网站开发招聘信息匿名ip访问网站受限
  • 网站转app工具网站规划建设与管理维护大作业
  • flash是怎么做网站的.net购物网站开发
  • 烟台网站建设求职简历品质商城网站建设
  • 做百度外链哪些网站权重高点做网站具备的条件
  • 怎么样用ppt做网站红番茄 网站点评
  • 建设银行河北分行招聘网站哪里能找到网站
  • 兰州营销型网站网站建设收费标准
  • 网站首页动图怎么做自己做网站很难
  • 自建网站如何盈利推广引流最快的方法
  • 网页设计网站结构图怎么弄网站用户 分析