Senden file-Deskriptor von Linux-Buchse

Ich versuche zu senden, einige Datei-Deskriptor von linux-socket, aber es funktioniert nicht. Was mache ich falsch? Wie soll man zum Debuggen so etwas? Ich habe versucht, perror() ist es überall möglich ist, aber Sie behauptet, dass alles ok ist. Hier ist, was ich geschrieben habe:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <fcntl.h>

void wyslij(int socket, int fd)  //send fd by socket
{
    struct msghdr msg = {0};

    char buf[CMSG_SPACE(sizeof fd)];

    msg.msg_control = buf;
    msg.msg_controllen = sizeof buf;

    struct cmsghdr * cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof fd);

    *((int *) CMSG_DATA(cmsg)) = fd;

    msg.msg_controllen = cmsg->cmsg_len;  //why does example from man need it? isn't it redundant?

    sendmsg(socket, &msg, 0);
}


int odbierz(int socket)  //receive fd from socket
{
    struct msghdr msg = {0};
    recvmsg(socket, &msg, 0);

    struct cmsghdr * cmsg = CMSG_FIRSTHDR(&msg);

    unsigned char * data = CMSG_DATA(cmsg);

    int fd = *((int*) data);  //here program stops, probably with segfault

    return fd;
}


int main()
{
    int sv[2];
    socketpair(AF_UNIX, SOCK_DGRAM, 0, sv);

    int pid = fork();
    if (pid > 0)  //in parent
    {
        close(sv[1]);
        int sock = sv[0];

        int fd = open("./z7.c", O_RDONLY);

        wyslij(sock, fd);

        close(fd);
    }
    else  //in child
    {
        close(sv[0]);
        int sock = sv[1];

        sleep(0.5);
        int fd = odbierz(sock);
    }

}
Ich meinte CMSG_DATA ich weiß nicht, was Sie sind, aber ich denke, dass ich das problem gefunden.
Warum schicken Sie die Wert der Dateideskriptor über einen socket? Was die Empfänger damit machen soll? Wenn der Empfänger nicht im gleichen Prozess wie der Absender, wird der file-Deskriptor wird bedeutungslos sein, um den Empfänger, wie ein Datei-Deskriptor ist Prozess-spezifisch. In jedem Fall, auf der Empfängerseite, bei der Verwendung von recvmsg() müssen Sie eine Schleife durch das empfangen der Nachrichten-Header auf der Suche für die SOL_SOCKET/SCM_RIGHTS header. Jetzt sind Sie unter der Annahme, dass jede Nachricht beginnt mit SCM_RIGHTS, und das ist wahrscheinlich nicht immer der Fall sein.
Nur um zu überprüfen, Sie sind sich bewusst, dass es möglich ist, zu senden (nutzbare) Datei-Deskriptoren, die zwischen Prozessen mit SCM_RIGHTS und AF_UNIX sockets?
Ich ziehe meinen Kommentar über das senden der Wert eines file-descriptor-über Prozessgrenzen hinweg unwirksam. Aber mein Kommentar zu benötigen, um richtig zu Scannen, erhielt recvmsg() Header für SCM_RIGHTS immer noch gilt.
FWIW, Es ist nicht Linux-spezifisch sind (viele, aber ich glaube, nicht alle Unix-Geschmacksrichtungen, die es unterstützen). Aber ich Stimme zu, dass das Scannen der recvmsg() Header ist die beste Praxis 🙂

InformationsquelleAutor Dekakaruk | 2015-01-17

Schreibe einen Kommentar