c语⾔调⽤dos命令
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;
}
分析⼀下原理估计就能看懂了:
当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接受命令之后做的事了。
再解释下fork的原理:当⼀个进程A调⽤fork时,系统内核创建⼀个新的进程B,并将A的内存映像复制到B的进程空间中,因为A和B是⼀样的,那么他们怎么知道⾃⼰是⽗进程还是⼦进程呢,看fork的返回值就知道,上⾯也说了fork在⼦进程中返回0,在⽗进程中返回⼦进程的pid。
windows中的情况也类似,就是execl换了个⼜臭⼜长的名字,参数名也换的看了让⼈发晕的,我在MSDN中到了原型,给⼤家看看:代码如下:
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpVerb,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
⽤法见下:
ShellExecute(NULL, "open", "c:\\a.reg", NULL, NULL, SW_SHOWNORMAL);
你也许会奇怪 ShellExecute中有个⽤来传递⽗进程环境变量的参数 lpDirectory,linux中的execl却没有,这是因为execl是编译器的函数(在⼀定程度上隐藏具体系统实现),在linux中它会接着产⽣⼀个linux系统的调⽤ execve, 原型见下:
int execve(const char * file,const char **argv,const char **envp);
看到这⾥就会明⽩为什么system()会接受⽗进程的环境变量,但是⽤system改变环境变量后,syste
m⼀返回主函数还是没变。原因从system的实现可以看到,它是通过产⽣新进程实现的,从我的分析中可以看到⽗进程和⼦进程间没有进程通信,⼦进程⾃然改变不了⽗进程的环境变量。
使⽤了system函数就能执⾏dos指令。
代码如下:
#include <stdio.h>
#include <stdlib.h>
xiaoyu()
{
char *a;
int n=0;
FILE *f;
f=fopen("file.bat","w+");/*新建⼀个批处理*/
if(f==NULL)
exit(1);
a="echo"; /*DOS命令*/
for(n=65;n<=90;n++)/*⼤写A-Z*/
fprintf(f,"%s %c\n",a,n);/*利⽤ASCII码输出A-Z,写出批处理*/
fclose(f);
shell代码system("file.bat");/*运⾏批处理*/
}
main()
{
char *string;
xiaoyu();
string="echo C语⾔的system函数\n";/*输出中⽂*/
system(string);
system("pause");/*程序暂停*/
}
C中可以使⽤DOS命令,以后编程通过调⽤DOS命令很多操作就简单多了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论