Linux-Development-Sys Digest #836, Volume #7      Tue, 9 May 00 05:13:16 EDT

Contents:
  sendmsg / recmsg / sockets / cmsg (Karl Keusgen)
  memory mapping ("alphonse.SIBLER")
  sendmsg / recmsg / sockets / cmsg (Karl Keusgen)

----------------------------------------------------------------------------

Date: Tue, 09 May 2000 11:01:31 +0000
From: Karl Keusgen <[EMAIL PROTECTED]>
Reply-To: [EMAIL PROTECTED]
Crossposted-To: comp.os.linux.development.apps,comp.os.linux.networking
Subject: sendmsg / recmsg / sockets / cmsg

This is a multi-part message in MIME format.
==============4919AEB52B5AD29CE487A522
Content-Type: multipart/alternative;
 boundary="------------AAACB9B526E8428788BDC815"


==============AAACB9B526E8428788BDC815
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

I'm on a multi-process application.
To communicate between the processes I use a pair of connected sockets,
created with socketpair(..);
There is no problem to pass filedeskriptors between the processes using
sendmsg and recmsg.
But just as long you do not change the type of the massage from
SOL_RIGHTS to any other type, just because you don't want to transmit
filedeskriptors all the time.
Now you have changed the type of the message to 0, for instance, because
you intended to transmit just a few chars, but then you want to transmit
a filedeskriptor again; you turn the type of the message to SOL_RIGHTS,
sendmsg is working without an error, but nothing is received.

I tried everything, setsockopt()... etc.

My Question is: Has anybody an Idea, how to use a pair of connected
sockets, sometimes you transmit a filedeskriptor, sometimes not. the
reading side of the "pipe" does not know what kind of message is coming.

At the moment I got the problem solved this way, that I do always
transmit a FileDescriptor, if it is just a dummy it is closed
immediately on the reading side. But I don't like this, sendmsg  does
not have to make a dup on everything, looking like a filedeskriptor.

I add a code of that, what I've talked about.  It is a running programm.

--
Karl Keusgen

IRKAS Systemhaus GmbH
- Softwareentwicklung -
Siemensstra�e 6
53121 Bonn

Phone   +49 228 / 962 187 19
Fax     +49 228 / 962 187 10

mailto:[EMAIL PROTECTED]
http://www.irkas.de



==============AAACB9B526E8428788BDC815
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
I'm on a multi-process application.
<br>To communicate between the processes I use a pair of connected sockets,
created with socketpair(..);
<br>There is no problem to pass filedeskriptors between the processes using
sendmsg and recmsg.
<br>But just as long you do not change the type of the massage from&nbsp;
SOL_RIGHTS to any other type, just because you don't want to transmit filedeskriptors
all the time.
<br>Now you have changed the type of the message to 0, for instance, because
you intended to transmit just a few chars, but then you want to transmit
a filedeskriptor again; you turn the type of the message to SOL_RIGHTS,
sendmsg is working without an error, but nothing is received.
<p>I tried everything, setsockopt()... etc.
<p>My Question is: Has anybody an Idea, how to use a pair of connected
sockets, sometimes you transmit a filedeskriptor, sometimes not. the reading
side of the "pipe" does not know what kind of message is coming.
<p>At the moment I got the problem solved this way, that I do always transmit
a FileDescriptor, if it is just a dummy it is closed immediately on the
reading side. But I don't like this, sendmsg&nbsp; does not have to make
a dup on everything, looking like a filedeskriptor.
<p>I add a code of that, what I've talked about.&nbsp; It is a running
programm.
<pre>--&nbsp;
Karl Keusgen

IRKAS Systemhaus GmbH
- Softwareentwicklung -
Siemensstra&szlig;e 6
53121 Bonn

Phone&nbsp;&nbsp; +49 228 / 962 187 19
Fax&nbsp;&nbsp;&nbsp;&nbsp; +49 228 / 962 187 10

<A HREF="mailto:[EMAIL PROTECTED]">mailto:[EMAIL PROTECTED]</A>
<A HREF="http://www.irkas.de">http://www.irkas.de</A></pre>
&nbsp;</html>

==============AAACB9B526E8428788BDC815==

==============4919AEB52B5AD29CE487A522
Content-Type: text/plain; charset=us-ascii;
 name="cmsg.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="cmsg.c"

/* ------------------------------------------------------------------------- */
/* Global Variables                                                          */
/* ------------------------------------------------------------------------- */

int    DummySocket = 0;

/* ------------------------------------------------------------------------- */
/* Defines                                                                   */
/* ------------------------------------------------------------------------- */

/* Maximum length of a message sended at once by using sendmsg */
#define MAX_MESSAGE_SIZE 1024

/* create a valid filedescriptor, because lateron sendmsg is used, which */
/* makes a dup, so that there is needed this filedeskriptor     */

/* ------------------------------------------------------------------------- */
/* Function     :   pipe_prepare_sendmsg                                     */
/*                                                                           */
/* Purpose      :   Ceates a valid filedescriptor, because lateron sendmsg   */
/*                  is used which makes a dup on a file-deskriptor.          */
/*                  To prevent any kind of problems with this dup when       */
/*                  you do not give a valid filedeskriptor to sendmsg,       */
/*                  sendmsg shall use the filedeskriptor, created by this    */
/*                  function.                                                */
/*                                                                           */
/* Parameter    :   none                                                     */
/*                                                                           */
/* Returnvalue  :   none                                                     */
/* ------------------------------------------------------------------------- */

void pipe_prepare_sendmsg()
{
    FUNCTION_HEADER_LEVEL_5 ("pipe_prepare_sendmsg")
    FUNCTION_HEADER_END()

    if ((DummySocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
    {
        log_message (LOG_LEVEL_FATAL,"prepare_sendmsg", "Cannot creat a socket - 
terminating process");
        return;
    }

}

/* ------------------------------------------------------------------------- */
/* Function     :   pipe_unpare_sendmsg                                      */
/*                                                                           */
/* Purpose      :   Closes the filedescriptor created by prepare_sendmsg     */
/*                                                                           */
/* Parameter    :   none                                                     */
/*                                                                           */
/* Returnvalue  :   none                                                     */
/* ------------------------------------------------------------------------- */

void pipe_unprepare_sendmsg()
{
    FUNCTION_HEADER_LEVEL_5 ("pipe_prepare_sendmsg")
    FUNCTION_HEADER_END()

    if (DummySocket) 
        close (DummySocket);

    return;
}


/* ------------------------------------------------------------------------- */
/* Function     :   pipe_send_message                                        */
/*                                                                           */
/* Purpose      :   Sends the given message to the connected partner by      */
/*                  writing the message in binary form onto the pipe         */
/*                  The maximum size is the number of bytes given in         */
/*                  MAX_MESSAGE_SIZE. If ther is more to transfer, the       */
/*                  message is cut to pieces and the procedure of sending    */
/*                  is repeated as often an neccesary                        */
/*                                                                           */
/* Parameter    :   hPipe           The pipe to be used to send              */
/*                  pMsg            The message to be sent                   */
/*                  bRecSD          Boolean indicating wether there is       */
/*                                  to send a Socket-Descriptor or not       */
/*                                                                           */
/* Returnvalue  :   Success indicator                                        */
/* ------------------------------------------------------------------------- */

BOOL pipe_send_message (PIPE hPipe, PMESSAGE pMsg)
{

   FUNCTION_HEADER_LEVEL_5 ("pipe_send_message")

   int         SocketDescriptor = DummySocket;   /* Socket-Descriptor        */

   struct      iovec vector;           /* some data to pass w/ the fd        */
   struct      msghdr msg;             /* the complete message               */
   struct      cmsghdr * cmsg;         /* the control message, which will    */
                                       /* include the SocketDescriptor       */

   int         TotalLength      = 0;   /* Length of the vector data          */
   int         SendedBytes      = 0;   /* Number of bytes that are sended at once */
   int         TotalSendedBytes = 0;   /* Number of bytes that are sended at all  */
   char        buff[MAXPIPE_SIZE + MESSAGEHDRSIZE] = "";

   FUNCTION_HEADER_END ()


    if (! DummySocket)
    {
        pipe_prepare_sendmsg();
        SocketDescriptor = DummySocket;
    }

    if (! hPipe [1])
    {
        /* Ignore error */
        return FALSE;
    }

    /* Store sende into message */
    pMsg->dwSenderId = process_get_ident ();
    
    /* Put together the first part of the message. */
    msg.msg_name    = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov     = &vector;
    msg.msg_iovlen  = 1;


    /* Check if there is a legal socket-descriptor to transfer or not */
    if ( pMsg->cmd == CMD_ACCEPT_TCP)
    {
        /* grep the number of the connectet socket from the data-line */
        memcpy (&SocketDescriptor, pMsg->pData, sizeof (INT));
    }

    /* Now for the control message. Allocate room for the socket-descriptor. */
    cmsg             = alloca(sizeof(struct cmsghdr) + sizeof (int));
    cmsg->cmsg_len   = sizeof(struct cmsghdr)        + sizeof (int);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type  = SCM_RIGHTS;

    /* copy the socket-descriptor onto the end of the control message */
    memcpy(cmsg->__cmsg_data, &SocketDescriptor, sizeof(int));

    msg.msg_control    = cmsg;
    msg.msg_controllen = cmsg->cmsg_len;


    /* get the total number of bytes to be sended including the messagehdr-size */
    TotalLength = pMsg->len + MESSAGEHDRSIZE;

    /* put the whole data to send into buff */
    memcpy(buff, pMsg, MESSAGEHDRSIZE);
    memcpy(buff + MESSAGEHDRSIZE, pMsg->pData, pMsg->len);

    do
    {
        /* set the llength of the vector-data */
        if ((TotalLength - TotalSendedBytes ) >= MAX_MESSAGE_SIZE )
        {
            vector.iov_len = MAX_MESSAGE_SIZE;
        }
        else
        {
            vector.iov_len = (TotalLength - TotalSendedBytes );
        }

        vector.iov_base = buff + TotalSendedBytes;

        /* send the whole thing to the other process and get back the how many */
        /* bytes were sended this time                                         */

        TotalSendedBytes += SendedBytes = sendmsg(hPipe[1], &msg, 0);


        if (SendedBytes  < 0)
        {
            log_last_os_error (LOG_LEVEL_FATAL, function_name, "sendmsg", 
OS_SOCKET_IO, NULL);
        }

        if ( SendedBytes != vector.iov_len)
        {
           log_message (LOG_LEVEL_ERROR, function_name, "Unable to send every bit of 
the complete data");

           if (pMsg->cmd == CMD_ACCEPT_TCP && SocketDescriptor) 
close(SocketDescriptor);
           return FALSE;
        }
    }
    while (TotalSendedBytes < TotalLength );

    /* If this function has been called from the controller- or listening-process */
    /* and a socket-descriptor has been passed by this function to the            */
    /* comunication- or controller-process, the socket-descriptor is no longer    */
    /* needed in the calling process and can be closed now.                       */
    if (pMsg->cmd == CMD_ACCEPT_TCP && SocketDescriptor) close(SocketDescriptor);

    log_message (LOG_LEVEL_DEBUG_5, function_name, "Inner Programm Communication, 
sended  %d Bytes ", TotalSendedBytes);

    return TRUE;
}


/* ------------------------------------------------------------------------- */
/* Function     :   pipe_recv_message                                        */
/*                                                                           */
/* Purpose      :   Checks the given pipe for data coming in. If any it      */
/*                  reads all of the data into the given message structure   */
/*                  If no message is to be read it makes the message IDLE    */
/*                                                                           */
/* Parameter    :   hPipe           The pipe to be used to send              */
/*                  pMsg            The message structure to be filled with  */
/*                                  the incoming message - if any            */
/*                                                                           */
/* Returnvalue  :   Success indicator                                        */
/* ------------------------------------------------------------------------- */

BOOL pipe_recv_message (PIPE hPipe, PMESSAGE pMsg)
{
    FUNCTION_HEADER_LEVEL_5 ("pipe_recv_message")

    int             SocketError             = 0;
                                            
    struct iovec    vector;                             /* file name from the child */
    struct msghdr   msg;                                    /* full message */
    struct cmsghdr* cmsg;                           /* control message with the socket 
descriptor */
                                            
    int             ReceivedBytes           = 0;    /* number of bytes that are 
receivet at once */
    int             TotalReceivedBytes      = 0;    /* number of bytes that are 
received at all */
    int             TotalLength             = 0;    /* total length of the vector-data 
*/
    int             posWrite                = 0;    /* write-position of a char array 
*/
    char            buff[MAX_MESSAGE_SIZE]  = "";


    int             fd                      = 0;    /* illegal fildescriptors */


    FUNCTION_HEADER_END ()

    /* Reset length */
    pMsg->len = 0;

    /* Check pipe */
    if (! hPipe [0])
    {
        /* Error - we should die */
        log_message (LOG_LEVEL_ERROR, function_name, "Pipe handle is zero");

        return FALSE;
    }

    /* Check if anything is inside */
    if ((SocketError = tcp_ip_peek_socket (hPipe[0], TRUE)) != 1)
    {
        /* pipe is ok, but nothing to read */
        pMsg->cmd = CMD_IDLE;

        return TRUE;
    }
    else if (SocketError == -1)
    {
        log_message (LOG_LEVEL_ERROR, function_name, "Pipe - Error occured while 
testing the readibility ");

        return FALSE;
    }

    /* the pipe is now checked, so that we can start to receive some nice things */

    /* set up the iovec for the data to receive */
    vector.iov_base = buff;
    vector.iov_len  = MAX_MESSAGE_SIZE;

    /* the message we're expecting to receive */
    msg.msg_name    = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov     = &vector;
    msg.msg_iovlen  = 1;

    /* allocate some space for the control-message-structure and */
    /* the socket-descriptor                                     */
    cmsg                = alloca(sizeof(struct cmsghdr) + sizeof(int));
    cmsg->cmsg_len      = sizeof(struct cmsghdr) + sizeof(int);
    msg.msg_control     = cmsg;
    msg.msg_controllen  = cmsg->cmsg_len;

    do
    {
        /* the receiving of data */
        TotalReceivedBytes += ReceivedBytes = recvmsg(hPipe[0], &msg, 0);

        if (posWrite)
        {
              memcpy(pMsg->pData + posWrite, vector.iov_base, ReceivedBytes);
              posWrite += ReceivedBytes;

              /* close illegal filedescriptors */
              memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
              if(fd) close(fd);
        }
        else if (ReceivedBytes >= MESSAGEHDRSIZE)
        {
            memcpy(pMsg, vector.iov_base, MESSAGEHDRSIZE);
            memcpy(pMsg->pData, vector.iov_base + MESSAGEHDRSIZE, ReceivedBytes - 
MESSAGEHDRSIZE);


            /* Check if there is to transfer a Socket-Descriptor!?          */
            /* If so, than grab it from the control structure and put       */
            /* the pure number onto the beginning of the pMsg->pData stream */
            if (pMsg->cmd == CMD_ACCEPT_TCP)
            {
                /* put the SocketDescriptor at the beginning of the data-stream */
                memcpy(pMsg->pData, CMSG_DATA(cmsg), sizeof(int));

            }
            else if (pMsg->cmd != CMD_ACCEPT_TCP)
            {
                /* close illegalyreceived filedescriptors */
                memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
                if(fd) close(fd);
            }

            posWrite += (ReceivedBytes - MESSAGEHDRSIZE);
            TotalLength = pMsg->len + MESSAGEHDRSIZE;
        }
        else
        {          
            /* log error */
            log_message (LOG_LEVEL_ERROR, function_name, "Did not receive a complete 
MessageHeader");
            return FALSE;
        }

        memset (buff, 0, MAX_MESSAGE_SIZE);
    } 
    while (TotalReceivedBytes < TotalLength) ;

    log_message (LOG_LEVEL_DEBUG_5, function_name, "Inner Programm Communication, 
received  %d Bytes ", TotalReceivedBytes);

    return TRUE;
}


==============4919AEB52B5AD29CE487A522==


------------------------------

From: "alphonse.SIBLER" <[EMAIL PROTECTED]>
Subject: memory mapping
Date: Tue, 9 May 2000 10:51:10 +0200

How can I share a memory buffer between un user-level process and a driver.
Can anyone give a skeleton of an example
 mmap (user and kernel level)
 nopage, ...

Where can I find a explanation of the complete memory mapping mechanism. ?

Thank you
Alphonse SIBLER
[EMAIL PROTECTED]




------------------------------

Date: Tue, 09 May 2000 11:07:07 +0000
From: Karl Keusgen <[EMAIL PROTECTED]>
Reply-To: [EMAIL PROTECTED]
Crossposted-To: comp.os.linux.networking
Subject: sendmsg / recmsg / sockets / cmsg

This is a multi-part message in MIME format.
==============1B6B3044467AAB292C55DFF6
Content-Type: multipart/alternative;
 boundary="------------0E17020802A4A6539B950F3C"


==============0E17020802A4A6539B950F3C
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

I'm on a multi-process application.
To communicate between the processes I use a pair of connected sockets,
created
with socketpair(..);
There is no problem to pass filedeskriptors between the processes using
sendmsg and
recmsg.
But just as long you do not change the type of the massage from
SOL_RIGHTS to any
other type, just because you don't want to transmit filedeskriptors all
the time.
Now you have changed the type of the message to 0, for instance, because
you
intended to transmit just a few chars, but then you want to transmit a
filedeskriptor
again; you turn the type of the message to SOL_RIGHTS, sendmsg is
working without
an error, but nothing is received.

I tried everything, setsockopt()... etc.

My Question is: Has anybody an Idea, how to use a pair of connected
sockets,
sometimes you transmit a filedeskriptor, sometimes not. the reading side
of the "pipe"
does not know what kind of message is coming.

At the moment I got the problem solved this way, that I do always
transmit a
FileDescriptor, if it is just a dummy it is closed immediately on the
reading side. But I
don't like this, sendmsg  does not have to make a dup on everything,
looking like a
filedeskriptor.

I add a code of that, what I've talked about.  It is a running programm.

____________________________
i.A. Karl Keusgen

IRKAS Systemhaus GmbH
- Softwareentwicklung -
Siemensstra�e 6
53121 Bonn

Phone   +49 228 / 962 187 19
Fax     +49 228 / 962 187 10

mailto:[EMAIL PROTECTED]
http://www.irkas.de



==============0E17020802A4A6539B950F3C
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
I'm on a multi-process application.
<br>To communicate between the processes I use a pair of connected sockets,
created
<br>with socketpair(..);
<br>There is no problem to pass filedeskriptors between the processes using
sendmsg and
<br>recmsg.
<br>But just as long you do not change the type of the massage from&nbsp;
SOL_RIGHTS to any
<br>other type, just because you don't want to transmit filedeskriptors
all the time.
<br>Now you have changed the type of the message to 0, for instance, because
you
<br>intended to transmit just a few chars, but then you want to transmit
a filedeskriptor
<br>again; you turn the type of the message to SOL_RIGHTS, sendmsg is working
without
<br>an error, but nothing is received.
<p>I tried everything, setsockopt()... etc.
<p>My Question is: Has anybody an Idea, how to use a pair of connected
sockets,
<br>sometimes you transmit a filedeskriptor, sometimes not. the reading
side of the "pipe"
<br>does not know what kind of message is coming.
<p>At the moment I got the problem solved this way, that I do always transmit
a
<br>FileDescriptor, if it is just a dummy it is closed immediately on the
reading side. But I
<br>don't like this, sendmsg&nbsp; does not have to make a dup on everything,
looking like a
<br>filedeskriptor.
<p>I add a code of that, what I've talked about.&nbsp; It is a running
programm.
<pre>____________________________
i.A. Karl Keusgen

IRKAS Systemhaus GmbH
- Softwareentwicklung -
Siemensstra&szlig;e 6
53121 Bonn

Phone&nbsp;&nbsp; +49 228 / 962 187 19
Fax&nbsp;&nbsp;&nbsp;&nbsp; +49 228 / 962 187 10

<A HREF="mailto:[EMAIL PROTECTED]">mailto:[EMAIL PROTECTED]</A>
<A HREF="http://www.irkas.de">http://www.irkas.de</A></pre>
&nbsp;</html>

==============0E17020802A4A6539B950F3C==

==============1B6B3044467AAB292C55DFF6
Content-Type: text/plain; charset=us-ascii;
 name="cmsg.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="cmsg.c"

/* passfd.c -- sample program which passes a file descriptor */ 
 
/* We behave like a simple /bin/cat, which only handles one  
   argument (a file name). We create Unix domain sockets through 
   socketpair(), and then fork(). The child opens the file whose  
   name is passed on the command line, passes the file descriptor  
   and file name back to the parent, and then exits. The parent waits  
   for the file descriptor from the child, then copies data from that  
   file descriptor to stdout until no data is left. The parent then  
   exits. */ 
 
#include <alloca.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <sys/uio.h> 
#include <sys/un.h> 
#include <sys/wait.h> 
#include <unistd.h> 
 
#include "sockutil.h"           /* simple utility functions */ 
 
/* The child process. This sends the file descriptor. */ 
int childProcess(char * filename, int sock) { 
    int fd; 
    struct iovec vector;        /* some data to pass w/ the fd */ 
    struct msghdr msg;          /* the complete message */ 
    struct cmsghdr * cmsg;      /* the control message, which will */ 
                                /* include the fd */ 
 
    /* Open the file whose descriptor will be passed. */ 
    if ((fd = open(filename, O_RDONLY)) < 0) { 
        perror("open"); 
        return 1; 
    } 
 
    /* Send the file name down the socket, including the trailing 
       '\0' */ 
    vector.iov_base = filename; 
    vector.iov_len = strlen(filename) + 1; 
 
    /* Put together the first part of the message. Include the 
       file name iovec */ 
    msg.msg_name = NULL; 
    msg.msg_namelen = 0; 
    msg.msg_iov = &vector; 
    msg.msg_iovlen = 1; 
 
    /* Now for the control message. We have to allocate room for 
       the file descriptor. */ 
    cmsg = alloca(sizeof(struct cmsghdr) + sizeof(fd)); 
    cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(fd); 
    cmsg->cmsg_level = SOL_SOCKET; 
    cmsg->cmsg_type = SCM_RIGHTS; 
   
    /* copy the file descriptor onto the end of the control  
       message */ 
    memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd)); 
 
    msg.msg_control = cmsg; 
    msg.msg_controllen = cmsg->cmsg_len; 
 
    if (sendmsg(sock, &msg, 0) != vector.iov_len) 
        die("sendmsg"); 
 
    return 0; 
} 
 
/* The parent process. This receives the file descriptor. */ 
int parentProcess(int sock) { 
    char buf[80];               /* space to read file name into */ 
    struct iovec vector;        /* file name from the child */ 
    struct msghdr msg;          /* full message */ 
    struct cmsghdr * cmsg;      /* control message with the fd */ 
    int fd; 
 
    /* set up the iovec for the file name */ 
    vector.iov_base = buf; 
    vector.iov_len = 80; 
 
    /* the message we're expecting to receive */ 
 
    msg.msg_name = NULL; 
    msg.msg_namelen = 0; 
    msg.msg_iov = &vector; 
    msg.msg_iovlen = 1; 
 
    /* dynamically allocate so we can leave room for the file 
       descriptor */ 
    cmsg = alloca(sizeof(struct cmsghdr) + sizeof(fd)); 
    cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(fd); 
    msg.msg_control = cmsg; 
    msg.msg_controllen = cmsg->cmsg_len; 
 
    if (!recvmsg(sock, &msg, 0))  
        return 1; 
 
    printf("got file descriptor for '%s'\n",  
           (char *) vector.iov_base); 
 
    /* grab the file descriptor from the control structure */ 
    memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd)); 
    
    copyData(fd, 1); 
 
    return 0; 
} 
 
int main(int argc, char ** argv) { 
    int socks[2]; 
    int status; 
 
    if (argc != 2) { 
        fprintf(stderr, "only a single argument is supported\n"); 
        return 1; 
    } 
 
    /* Create the sockets. The first is for the parent and the 
       second is for the child (though we could reverse that 
       if we liked. */ 
    if (socketpair(PF_UNIX, SOCK_STREAM, 0, socks))  
        die("socketpair"); 
 
    if (!fork()) { 
        /* child */ 
        close(socks[0]); 
        return childProcess(argv[1], socks[1]); 
    } 
 
    /* parent */ 
    close(socks[1]); 
    parentProcess(socks[0]); 
 
    /* reap the child */ 
    wait(&status); 
 
    if (WEXITSTATUS(status)) 
        fprintf(stderr, "child failed\n"); 
 
    return 0; 
} 
/********************************************************************************************************************************/

/* sockutil.h */

void die(char * message); 
void copyData(int from, int to); 
#ifndef CMSG_DATA 
#define CMSG_DATA(cmsg) ((cmsg)->cmsg_data) 
#endif 

/********************************************************************************************************************************/

/* sockutil.c - simple utility functions */ 
 
#include <stdio.h> 
#include <unistd.h> 
 
#include "sockutil.h" 
 
/* issue an error message via perror() and terminate the program */ 
void die(char * message) { 
    perror(message); 
    exit(1); 
} 
 
/* Copies data from file descriptor 'from' to file descriptor 'to' 
   until nothing is left to be copied. Exits if an error occurs.   */ 
void copyData(int from, int to) { 
    char buf[1024]; 
    int amount; 
     
    while ((amount = read(from, buf, sizeof(buf))) > 0) { 
        if (write(to, buf, amount) != amount) { 
            die("write"); 
            return; 
        } 
    } 
    if (amount < 0) 
        die("read"); 
} 

==============1B6B3044467AAB292C55DFF6==


------------------------------


** FOR YOUR REFERENCE **

The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:

    Internet: [EMAIL PROTECTED]

You can send mail to the entire list (and comp.os.linux.development.system) via:

    Internet: [EMAIL PROTECTED]

Linux may be obtained via one of these FTP sites:
    ftp.funet.fi                                pub/Linux
    tsx-11.mit.edu                              pub/linux
    sunsite.unc.edu                             pub/Linux

End of Linux-Development-System Digest
******************************

Reply via email to