使用 poll 从管道读取

发布于 2024-09-28 12:21:14 字数 1061 浏览 2 评论 0原文

我试图使用轮询从管道读取数据,这里是代码:

#include <stdio.h>
#include <fcntl.h>
#include <poll.h>
#define MAX_BUFF_SIZE 128

int main(void){
    char buff[MAX_BUFF_SIZE];
    char *buf;
    int fd,ret,len;
    struct pollfd fdinfo[1];

    if((fd = open("/home/s/pipe", O_RDONLY)) == NULL) {
        printf("Error Opening File.\n");
        exit(1);
    }

    fdinfo[0].fd = fd;
    fdinfo[0].events = POLLIN|POLLPRI ;

    while(1){
        ret = poll(fdinfo,1,-1);
        if (ret < 0) printf("\n\r error");

        if ( ((fdinfo[0].revents&POLLIN) == POLLIN) || ((fdinfo[0].revents&POLLPRI) == POLLPRI) ){
            len = read(fdinfo[0].fd, buff, MAX_BUFF_SIZE);
            if (len > 0){
                buff[len] = 0;
                buf = (char *) malloc(len);
                memcpy(buf, buff, len);
                printf("\n read len %d\n %s",len, buf);
                free(buf);
             }
        }

    }
    return 0;
}

它似乎工作不正常 - 在每个正确的数据之后,我在输出中得到很多垃圾,但我不知道它来自哪里。所以我寻求帮助。

提前谢谢

im trying to read data from pipe using poll, here is code:

#include <stdio.h>
#include <fcntl.h>
#include <poll.h>
#define MAX_BUFF_SIZE 128

int main(void){
    char buff[MAX_BUFF_SIZE];
    char *buf;
    int fd,ret,len;
    struct pollfd fdinfo[1];

    if((fd = open("/home/s/pipe", O_RDONLY)) == NULL) {
        printf("Error Opening File.\n");
        exit(1);
    }

    fdinfo[0].fd = fd;
    fdinfo[0].events = POLLIN|POLLPRI ;

    while(1){
        ret = poll(fdinfo,1,-1);
        if (ret < 0) printf("\n\r error");

        if ( ((fdinfo[0].revents&POLLIN) == POLLIN) || ((fdinfo[0].revents&POLLPRI) == POLLPRI) ){
            len = read(fdinfo[0].fd, buff, MAX_BUFF_SIZE);
            if (len > 0){
                buff[len] = 0;
                buf = (char *) malloc(len);
                memcpy(buf, buff, len);
                printf("\n read len %d\n %s",len, buf);
                free(buf);
             }
        }

    }
    return 0;
}

It does not seems to work fine - after each properly data i got a lot of garbage in output, but i dont know where it comes frome. So im asking for help.

thx in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仅冇旳回忆 2024-10-05 12:21:14

如果至少有 MAX_BUFF_SIZE 字节可用,则 len 将设置为 MAX_BUFF_SIZE,并且 buff[len] 将写入超过 buff 末尾的内容。在那之后,所有的赌注都消失了。您可以通过将 MAX_BUFF_SIZE - 1 传递给 read() 来修复此问题。

然而,更令人担忧的是,您没有在 memcpy() 调用中复制 \0,因为字节数包括 >\0len + 1

当我们这样做时:

  • 不要从 malloc( )
  • 检查 malloc() 的返回值是否为 NULL
  • 如果 poll() 错误,您仍在检查 < code>revents 字段,该字段将不再适用于
  • 您的测试 if ( ((fdinfo[0].revents&POLLIN) == POLLIN) || ((fdinfo[0].revents& POLLPRI) == POLLPRI) ) 最好写成 if (fdinfo[0].revents & (POLLIN | POLLPRI)) 但无论如何都没有必要,因为你已经要求 poll() 只查找这两件事

If there is at least MAX_BUFF_SIZE bytes available, len will be set to MAX_BUFF_SIZE, and buff[len] will write past the end of buff. After that, all bets are off. You can fix this by passing MAX_BUFF_SIZE - 1 to read().

However, more worryingly, you're not copying the \0 in your memcpy() call, as the number of bytes including the \0 is len + 1.

While we're at it:

  • don't cast the return from malloc()
  • check the return from malloc() isn't NULL
  • if poll() errors, you're still checking the revents field, which won't be applicable any more
  • your test if ( ((fdinfo[0].revents&POLLIN) == POLLIN) || ((fdinfo[0].revents&POLLPRI) == POLLPRI) ) could better be written if (fdinfo[0].revents & (POLLIN | POLLPRI)) but shouldn't be necessary anyway, as you've asked poll() to look for these two things only
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文