免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: sx_boss
打印 上一主题 下一主题

[函数] 请教system函数 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-06-14 14:32 |只看该作者
mark.

论坛徽章:
0
12 [报告]
发表于 2007-06-14 14:40 |只看该作者
再次帖出我心爱的函数



  1. /*功能说明:这个函数用来调用外部程序(任何程序都可以,包括各种脚本),并且将外部程序的标准输出结果保存到一块内存中(内存可写),函数返回
  2. 这块内存的指针,调用者可以直接printf这个指针,!!!!!!!!!!!!!!!!最后一定要记得free!!!!!!!!!!!!

  3. 两种使用方法:lazy("ls -al /root"),lazy("ls",{"ls", "-al", "/root", (char *)0})

  4. 思路简述:用了两个进程一个管道,子进程调用system或者exec执行shell,并且把输出重定向到管道,父进程则从管道将数据读出,根据读出数据的数量自动扩展缓冲区大小

  5. 两个地方值得回味:1,关闭文件描述符,一些不用的文件描述符要关闭,很多时候都出现了管道阻塞,这个时候去proc里看看到底是哪些多余的描述符没有关闭,关掉它们那就好了
  6.                         2,如何打开被关闭的标准输出,有两种办法(a,用dup复制,以后再用dup2拷贝回来,本程序就是用这个办法.b,调用ttyname(1)查看当前打开的是哪个终端,然后再用open打开就行了)

  7. 命名来历:用这个函数之前问问自己,我写的还是C语言程序吗?
  8. */

  9. char *lazy(char *pCmd, char **env) {
  10.         char *pResult, *p;
  11.         int fd[2], fd_stdout;
  12.         int count=0;
  13.         int a1 = 0, a2 = 0;     //a1缓冲区总大小,a2缓冲区使用了多少
  14.         int maxlen = 4096;      //为什么使用4096?因为这刚好是管道的大小,可以参考~/code/ipc/pipe/question.c里的Q4

  15.         fd_stdout = dup(1);     //备份stdout,关闭之后想要再使用标准输出要靠这个备份的
  16.         pipe(fd);
  17.         close(1);
  18.         dup2(fd[1],1);
  19.         if (fork() == 0) {
  20.                 close(fd[1]);
  21.                 close(fd[0]);
  22.                 close(fd_stdout);
  23.                 if (env == NULL)        //exec和system都可以,不同的调用方法用不同的实现吧,呵呵
  24.                         system(pCmd);   //调用方法:lazy("ls -al /root")
  25.                 else
  26.                         execvp(pCmd, env);      //调用方法:lazy("ls",{"ls", "-al", "/root", (char *)0})

  27.                 exit(1);
  28.         }
  29.         close(fd[1]);
  30.         close(1);
  31.         fflush(stdout);
  32.         dup2(fd_stdout, 1);     //打开stdout

  33.         pResult = malloc(maxlen + 1);
  34.         a1 += maxlen + 1;
  35.         p = pResult;
  36.         while ((count = read(fd[0], pResult, maxlen)) > 0) {    //如果在read过程中超过了缓冲区边缘会返回-1,调试了很久才发现这个问题
  37.                 a2 += count;
  38.                 if (a1 - a2 <= maxlen) {
  39.                         p = realloc(p, a1 + maxlen);    //为什么要用个临时变量p来帮忙呢?:)这是一个小发现呵呵,看<Linux函数库参考手册>P33的笔记
  40.                         pResult = p + a2;
  41.                         a1 += maxlen;
  42.                         continue;
  43.                 }
  44.                 pResult += count;
  45.         }
  46.         *pResult = 0;   //打上字符串结束符
  47.         close(fd[0]);
  48.         wait(&count);

  49.         return p;
  50. }

  51. int main(void) {
  52.         char *result;
  53.         char *cmd = "ls";
  54.         char *cmd2 = "ls /dev";
  55.         char *env[] = {"ls", "-al", "/dev", (char *)0};

  56.         //result = lazy(cmd, env);
  57.         result = lazy(cmd2, NULL);

  58.         printf("%s", result);
  59.         free(result);
  60.         return 0;
  61. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP