【问题标题】:ioctl giving Invalid Argumentioctl 给出无效参数
【发布时间】:2012-07-06 12:28:43
【问题描述】:

我想在两个不同的程序之间发送一个打开的文件描述符。所以我使用ioctlnamed pipes 这样做。但是我得到了 ioctl 的无效参数。

#include <stropts.h>
#include "accesories.c"
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>

#define MSGSIZ 63
char *fifo = "fifo";

int send_err(int fd, int errcode, const char *msg)
{
    int     n;

    if ((n = strlen(msg)) > 0)
        if (write(fd, msg, n) != n)    /* send the error message */
            return(-1);

    if (errcode >= 0)
        errcode = -1;   /* must be negative */

    if (send_fd(fd, errcode) < 0)
        return(-1);

    return(0);
}

int send_fd(int fd, int fd_to_send)
{
    char    buf[2];     /* send_fd()/recv_fd() 2-byte protocol */

    buf[0] = 0;         /* null byte flag to recv_fd() */
    if (fd_to_send < 0) {
        buf[1] = -fd_to_send;   /* nonzero status means error */
        if (buf[1] == 0)
            buf[1] = 1; /* -256, etc. would screw up protocol */
    } else {
        buf[1] = 0;     /* zero status means OK */
    }
    //printf("From the write %d\n",buf[0]);
    if (write(fd, buf, 2) != 2)
        return(-1);

    if (fd_to_send >= 0)
        if (ioctl(fd, I_SENDFD, fd_to_send) < 0)
        {
            printf("Eroor ::: %s\n",strerror(errno));
            return(-1);
        }
    return(0);
}




int main(int argc, char const *argv[])
{
    int fd, j, nwrite;
    char msgbuf[MSGSIZ+1];
    int fd_to_send;


    if((fd_to_send = open("vi",O_RDONLY)) < 0)
        printf("vi open failed");

    if(argc < 2)
    {
        fprintf(stderr, "Usage: sendmessage msg ... \n");
        exit(1);
    }
    /* open fifo with O_NONBLOCK set */
    if((fd = open(fifo, O_WRONLY | O_NONBLOCK)) < 0)
        printf("fifo open failed");

    /* send messages */
    for (j = 1; j < argc; j++)
    {
        if(strlen(argv[j]) > MSGSIZ)
        {
            fprintf(stderr, "message too long %s\n", argv[j]);
            continue;
        }
        strcpy(msgbuf, argv[j]);
        if((nwrite = write(fd, msgbuf, 6)) == -1)
            printf("message write failed");
    }

    printf("From send_fd %d \n",send_fd(fd,fd_to_send));

    exit(0);

}

文件附件 .h 只包含一些常见的包含文件,没有别的。 首先,我发送一条简单的消息,然后调用send_fd,它首先发送一条 2 字节的消息,然后必须使用 ioctl 发送文件描述符。但事实并非如此。

【问题讨论】:

  • 你是如何创建文件描述符的? I_SENDFD 是一个 STREAMS 的东西,不适用于任何管道。它也是一个非常晦涩的 API。使用 sendmsg() 系统调用通过 Unix 域套接字发送文件描述符更为常见。您有什么理由要使用 I_SENDFD 吗?
  • 我正在打开文件 vi 以创建文件描述符。是否可以使用发送消息发送文件描述符?我的意思是打开的文件描述符不仅仅是整数。

标签: c linux ioctl


【解决方案1】:

看起来像linux doesn't support I_SENDFD。 cmets 表明 I_SENDFD 在文档中,但实际上不受支持,并导致您遇到错误消息。 wikipedia entry for STREAMS 声明 linux 内核不支持流。 wikipedia 条目确实指向了一些可用于添加流支持的第三方包,但 LiS 尚未移植到 2.6 内核,OpenSS7 在 4 年内没有任何积极的开发。

不过,linux 确实支持类似的东西。这个机制使用一个特殊的消息类型SCM_RIGHTS 来通过一个带有sendmsg 并从recvmsg 获得的UNIX 域套接字传递一个文件描述符。示例可以通过简单的网络搜索找到,完整示例似乎来自 The Linux Programming Interface 一书,源代码为sendingreceiving

【讨论】:

  • 我不想使用 UNIX 域套接字发送文件描述符/套接字描述符。有什么办法吗。
  • @knoxxs:我很同情,但这有点像说我不想用鸡蛋做煎蛋卷。除了将其发送到进程之外,您可以使用fork/exec 代替吗?
  • Linux 支持 I_SENDFD,或者至少文档支持它。但它很奇怪而且很少见。基于套接字的文件描述符传递是每个人实际使用和测试的机制。
  • @AndyRoss:我提供的链接解释说它是留下的不应该的代码。我对其他来源的搜索支持这一点。
  • 请对不赞成票发表评论,以便我知道需要改进的地方,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 2012-01-01
  • 1970-01-01
相关资源
最近更新 更多