C Unix 管道示例

2023-12-31

尝试实现一个shell,主要是管道。我已经编写了这个测试用例,我希望将 ls 简单地通过管道传输到 wc ...它肯定不会按预期工作。它将 ls 打印到终端,然后打印内存耗尽。 我非常不知道如何解决这个问题并让它发挥作用。 find_path 在我的所有测试中都有效。

编辑-我必须在项目中使用 execv ,它是一个类的东西,但我已经用 execvp 尝试过以防万一,它做了完全相同的事情。另外,这只是一个例子,一个测试来看看为什么它不起作用,我为两个命令和 waitpid 调用 fork 两次,因为我没有其他事情可做。

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
int find_path(char* execname, char** dst)
{        
        char *path = getenv("PATH");
        path = strdup(path);
        char *pos;
        path = strtok_r(path, ":", &pos);
        char *originalpath  = path;
        do
        {
                char* test = (char*)calloc(strlen(path) + strlen(execname) + 2, sizeof(char));
                test = strcpy(test, path);
                int testlen = strlen(test);
                (*(test+testlen)) = '/';
                strcpy(test + testlen + 1,execname);
                struct stat buf;
                int result = stat(test, &buf);
                if (result == 0)
                {
                        *dst = test;
                        free (originalpath);
                        return 1;
                }
                else
                {
                        free(test);
                }

        } while ((path = strtok_r(NULL, ":", &pos)) != NULL);
        free(originalpath);
        return 0;
}

int main()
{
    char *cmd1 = "ls";
    char *cmd2 = "wc";
    int filedes[2];
    pipe(filedes);
    char** argv = (char**)calloc(1, sizeof(char*)); 
    argv[0] = (char*)malloc(sizeof(char*));
    argv[0] = NULL;

    pid_t pid = fork();
    if (pid == 0)
    {
        char *path;
                find_path(cmd1, &path);
        dup2(filedes[1],stdout);

        execv(path,argv); 
    }
    pid = fork();
    if (pid == 0)
    {
        dup2(filedes[0], stdin);
        char *path;
        find_path(cmd2, &path);
        execv(path, argv);

    }
    else
        waitpid(pid);

}

通常,当程序难以调试时,最好稍微简化它以消除错误源。这是您的程序,经过简化以删除find_path作为错误来源:

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

int main(void)
{
    int filedes[2];
    pipe(filedes);

    /* Run LS. */
    pid_t pid = fork();
    if (pid == 0) {
        /* Set stdout to the input side of the pipe, and run 'ls'. */
        dup2(filedes[1], 1);
        char *argv[] = {"ls", NULL};
        execv("/bin/ls", argv);
    } else {
        /* Close the input side of the pipe, to prevent it staying open. */
        close(filedes[1]);
    }

    /* Run WC. */
    pid = fork();
    if (pid == 0) {
        dup2(filedes[0], 0);
        char *argv[] = {"wc", NULL};
        execv("/usr/bin/wc", argv);
    }

    /* Wait for WC to finish. */
    waitpid(pid);
}

这应该如您所期望的那样。

在简化过程中,出现了一些错误:

  • argv[]未正确设置,特别是 argv[0] 被设置为 NULL;
  • 该程序没有关闭正在提供给的管道的输入侧ls. When ls完成后,管道没有被关闭(因为wc进程仍然打开),防止wc从始至终。
  • 该程序混淆了值stdout and stdin(其类型为FILE*) 与文件描述符编号0 and 1(由dup, pipe, etc.)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C Unix 管道示例 的相关文章

随机推荐

  • &'a T 是否意味着 T: 'a?

    从我自己的理解和实验来看 这似乎是正确的 但我还没有找到记录它的权威来源 Rust by Example 有一个bounds https doc rust lang org rust by example scope lifetime li
  • Google Play 中不允许使用 com.example 包名称

    我是 Android 应用程序开发新手 我正在创建简单的 Android 应用程序 导出 android 应用程序并将包名称指定为AndroidManifestfile包名为 com example zingyminds apk 现在我得到
  • 使用 FFT 进行高斯图像滤波

    对于图像分割 我使用 OpenCV 的高斯特征差异GaussianBlur 范围从 0 8 到 8 43 指数步长为 1 4 我的图像尺寸为 4096 x 2160 因此这需要相当长的时间 在一个核心上需要 8 秒 这在处理视频时相当长 您
  • 如何更改活动/选定选项卡的颜色?

    我希望当未选择选项卡时颜色为默认灰色 但作为我的颜色tabBarColor选择选项卡时的颜色 我找不到更改标签栏中标题颜色的方法 我怎样才能做到这一点 这是我的代码 Home screen TabNavigator Home screen
  • lub(T1,...Tn) 是什么意思?

    以下引用来自 JLS 14 20 http docs oracle com javase specs jls se8 html jls 14 html jls 14 20 异常参数的声明类型 将其类型表示为 与替代方案 D1 的结合D2 D
  • OpenCV 霍​​夫圆

    我使用 Xcode 和 c 我已经从以下位置复制了 HoughCircles 代码OpenCV 文档 http opencv willowgarage com documentation cpp feature detection html
  • 在 SageMath 中运行时使用 Dask 会抛出 ImportError

    最近 我一直在尝试使用 Dask 并行化一些 Sage 运行 OSX 11 2 3 的 MacBook Pro 上的 Sage 9 4 代码 我遇到的问题是 虽然我可以在 Sage 中运行 Dask 但每当我包含任何非 纯 python 代
  • 我们可以将事件侦听器添加到“Vega-Lite”规范吗?

    我是 Vega 和 Vega Lite 的新手 我正在使用 Vega Lite 创建一个简单的条形图 但我无法添加任何事件侦听器 例如 徘徊 我想将鼠标悬停在一个栏上并更改该栏的颜色 如果您正在使用Vega嵌入 https github c
  • 如何收到图库应用程序可见的每个新图像的通知?

    背景 当用户下载新图像或使用相机捕获图像时 图库应用程序将更新以显示新图像 我需要在创建每个新图像后立即收到通知 无论它是如何创建的 相机 浏览器 就像图库应用程序所示 问题 事实证明 有一个 mediaScanner Android 组件
  • Curl:传输已关闭,剩余未完成的读取数据

    我遇到了大卷曲调用的问题 I get nread 传输已关闭 剩余未完成的读取数据 并且内容已部分交付 GET stats stats breakdown track track campaign search criteria 2 per
  • 无法生成用于构建和调试的资产。 OmniSharp 服务器未运行

    在 Visual Studio VS Code 上 使用 C 进行编码 我正在尝试生成要构建和调试的资产 但收到以下错误消息 无法生成用于构建和调试的资产 OmniSharp 服务器未运行 我在跑 NET版本3 1 301 视窗8 1 Vi
  • 从小表中删除重复行

    我在 PostgreSQL 8 3 8 数据库中有一个表 该表没有键 约束 并且有多行具有完全相同的值 我想删除所有重复项并仅保留每行的 1 个副本 特别有一列 名为 key 可用于识别重复项 即每个不同的 key 应该只存在一个条目 我怎
  • 需要在ggplot2中绘制条形图(以百分位方式)

    嗨 我有一个这样的数据集 ALL Critical Error Warning Review 2016 1412 475 4 125 154 45 49 2 58 116 86 12 1 17 我想使用 ggplot2 绘制堆叠条形图 其中
  • 混合构造函数并在 Javascript 代理对象上应用陷阱

    我有一个类 我想对其应用代理 观察方法调用和构造函数调用 计算器 js class Calc constructor add a b return a b minus a b return a b module exports Calc i
  • 仅查看 Mercurial 中的目录?

    如何仅从 Mercurial 存储库中查看子目录 看来我只能查看整个存储库 你不能 请参阅此处的讨论 https www mercurial scm org wiki PartialClone https www mercurial scm
  • SparkSQL CSV 的引用不明确

    我正在尝试在 SparkSQL 2 10 中读取一堆 CSV 文件 其自定义架构部分是 Double 部分是 String 如下所示 Build the schema val schemaStringS col1 col2 val sche
  • MatPlotLib 修改自定义线性分段颜色图

    关于已接受的答复这个问题 https stackoverflow com questions 38882233 geopandas matplotlib plot custom colors 38885389 38885389 如果我想使用
  • Java 期货管道

    我正在努力优化我的Future的管理技术 假设我们有这种典型的处理场景 我运行一个查询以从数据库中获取一些记录 SELECT FROM mytable WHERE mycondition 该查询返回很多我需要处理的行 例如 while re
  • 清除 TList 或 TObjectList

    我对使用什么来存储列表中的对象有点困惑 到目前为止我已经使用过TList并释放循环中的每个项目 然后我发现TObjectList自动执行此操作Free 然后我从文档中看到了这个TList Clear Call Clear清空 Items 数
  • C Unix 管道示例

    尝试实现一个shell 主要是管道 我已经编写了这个测试用例 我希望将 ls 简单地通过管道传输到 wc 它肯定不会按预期工作 它将 ls 打印到终端 然后打印内存耗尽 我非常不知道如何解决这个问题并让它发挥作用 find path 在我的