"Fossies" - the Fresh Open Source Software Archive

Member "NetPIPE-3.7.2/src/vmsplice.c" (19 Aug 2010, 9981 Bytes) of package /linux/privat/old/NetPIPE-3.7.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "vmsplice.c" see the Fossies "Dox" file reference documentation.

    1 /*****************************************************************************/
    2 /* "NetPIPE" -- Network Protocol Independent Performance Evaluator.          */
    3 /* Copyright 1997, 1998 Iowa State University Research Foundation, Inc.      */
    4 /*                                                                           */
    5 /* This program is free software; you can redistribute it and/or modify      */
    6 /* it under the terms of the GNU General Public License as published by      */
    7 /* the Free Software Foundation.  You should have received a copy of the     */
    8 /* GNU General Public License along with this program; if not, write to the  */
    9 /* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */
   10 /*                                                                           */
   11 /*     * vmsplice.c           ---- vmsplice                                  */
   12 /*****************************************************************************/
   13 #include    "netpipe.h"
   14 
   15 #define _GNU_SOURCE
   16 #include <fcntl.h>
   17 #include <sys/uio.h>
   18 #include <unistd.h>
   19 #include <sys/types.h>
   20 #include <sys/stat.h>
   21 #include <fcntl.h>
   22 #include <signal.h>
   23 
   24 static int pipe_to_child[2];
   25 static int pipe_to_parent[2];
   26 static int vmsplice_to_child[2];
   27 static int vmsplice_to_parent[2];
   28 static char *fcontrol_to_parent = NULL, *fcontrol_to_child = NULL;
   29 static char *fdata_to_parent = NULL, *fdata_to_child = NULL;
   30 
   31 /* Don't know if this is hard-coded in the kernel or not */
   32 const int MAX_VMSPLICE_SIZE = 65536;
   33 
   34 
   35 static void despair(const char *msg)
   36 {
   37     fprintf(stderr, "%s  Aborting in despair.\n", msg);
   38 
   39     CleanUp(NULL);
   40 
   41     exit(1);
   42 }   
   43 
   44 static void sig_handler(int sig)
   45 {
   46     CleanUp(NULL);
   47 }   
   48 
   49 static void pipe_send(int *fd, void *buf, size_t len)
   50 {
   51     int ret;
   52     char *start = (char*) buf;
   53 
   54     while (1) {
   55         ret = write(fd[1], start, len);
   56         if (0 == ret) {
   57             despair("Netpipe wrote 0 bytes down a pipe.");
   58         } else if (ret > 0) {
   59             len -= ret;
   60             start += ret;
   61             if (0 == len) {
   62                 return;
   63             }
   64         } else {
   65             despair("Netpipe got an error writing down a pipe.");
   66         }
   67     }
   68 }
   69 
   70 static void pipe_recv(int *fd, void *buf, size_t len)
   71 {
   72     int ret;
   73     char *start = (char*) buf;
   74 
   75     while (1) {
   76         ret = read(fd[0], start, len);
   77         if (0 == ret) {
   78             despair("Netpipe read 0 bytes down a pipe.");
   79             exit(1);
   80         } else if (ret > 0) {
   81             len -= ret;
   82             start += ret;
   83             if (0 == len) {
   84                 return;
   85             }
   86         } else {
   87             despair("Netpipe got an error reading from a pipe; that shouldn't happen.");
   88         }
   89     }
   90 }
   91 
   92 void Init(ArgStruct *p, int* pargc, char*** pargv)
   93 {
   94     /* Install a signal handler to remove all stale fifos if someone
   95        hits ctrl-c */
   96     signal(SIGHUP, sig_handler);
   97     signal(SIGINT, sig_handler);
   98 }
   99 
  100 void Setup(ArgStruct *p)
  101 {
  102     pid_t pid;
  103     const char *base = "NPknem.vmsplice";
  104     const char *child_suffix = "to-child";
  105     const char *parent_suffix = "to-parent";
  106     int need_fork = 0, am_parent = 0;
  107 
  108     /* If no filename was specified, then we're the parent until we
  109        fork */
  110     if (NULL == p->host) {
  111         am_parent = 1;
  112         need_fork = 1;
  113     } 
  114     /* If the file was specified, see if all 4 files exist.  If it does,
  115        then we're the parent.  Otherwise, we're the "child". */
  116     else {
  117         int ret;
  118         struct stat sbuf;
  119 
  120         base = p->host;
  121         need_fork = 0;
  122 
  123         asprintf(&fcontrol_to_parent, "%s.control-%s", base, parent_suffix);
  124         asprintf(&fcontrol_to_child, "%s.control-%s", base, child_suffix);
  125         asprintf(&fdata_to_parent, "%s.data-%s", base, parent_suffix);
  126         asprintf(&fdata_to_child, "%s.data-%s", base, child_suffix);
  127 
  128         if (0 == stat(fcontrol_to_parent, &sbuf) &&
  129             0 == stat(fcontrol_to_child, &sbuf) &&
  130             0 == stat(fdata_to_parent, &sbuf) &&
  131             0 == stat(fdata_to_child, &sbuf)) {
  132             am_parent = 0;
  133         } else {
  134             unlink(fcontrol_to_parent);
  135             unlink(fcontrol_to_child);
  136             unlink(fdata_to_parent);
  137             unlink(fdata_to_child);
  138             am_parent = 1;
  139         }
  140     }
  141 
  142     /* If we can fork, then it's easy to just create pipes between
  143        parent and child */
  144     if (need_fork) {
  145         if (pipe(pipe_to_child) < 0 ||
  146             pipe(pipe_to_parent) < 0 ||
  147             pipe(vmsplice_to_child) < 0 ||
  148             pipe(vmsplice_to_parent) < 0) {
  149             despair("Netpipe failed to create a pipe.");
  150         }
  151 
  152         /* Now fork the child and reset transmitter / receiver flags as
  153            appropriate */
  154         if (0 == fork()) {
  155             /* CHILD */
  156             p->rcv = 1;
  157             p->tr = 0;
  158             
  159             /* Close the relevant ends of pipes */
  160             close(pipe_to_child[1]);
  161             close(pipe_to_parent[0]);
  162             close(vmsplice_to_child[1]);
  163             close(vmsplice_to_parent[0]);
  164         } else {
  165             /* PARENT */
  166             p->rcv = 0;
  167             p->tr = 1;
  168             
  169             /* Close the relevant ends of pipes */
  170             close(pipe_to_child[0]);
  171             close(pipe_to_parent[1]);
  172             close(vmsplice_to_child[0]);
  173             close(vmsplice_to_parent[1]);
  174         }
  175     }
  176 
  177     /* Otherwise, we have unrelated processes.  So open up several
  178        named pipes. */
  179     else {
  180         if (am_parent) {
  181             /* Parent */
  182             p->rcv = 0;
  183             p->tr = 1;
  184 
  185             if (mkfifo(fcontrol_to_parent, 0600) < 0 ||
  186                 mkfifo(fcontrol_to_child, 0600) < 0 ||
  187                 mkfifo(fdata_to_parent, 0600) < 0 ||
  188                 mkfifo(fdata_to_child, 0600) < 0) {
  189                 /* This is where people typically hit ctrl-c, so don't
  190                    print an error in this case */
  191                 if (EINTR == errno) {
  192                     exit(0);
  193                 }
  194                 despair("Netpipe was unable to create a named pipe.");
  195             }
  196 
  197             if ((pipe_to_parent[0] = open(fcontrol_to_parent, O_RDONLY)) < 0 ||
  198                 (pipe_to_child[1] = open(fcontrol_to_child, O_WRONLY)) < 0 ||
  199                 (vmsplice_to_parent[0] = open(fdata_to_parent, O_RDONLY)) < 0 ||
  200                 (vmsplice_to_child[1] = open(fdata_to_child, O_WRONLY)) < 0) {
  201                 /* This is where people typically hit ctrl-c, so don't
  202                    print an error in this case */
  203                 if (ENOENT == errno || EINTR == errno) {
  204                     exit(0);
  205                 }
  206                 despair("Netpipe was unable to open parent ends of the named pipes.");
  207             }
  208         } else {
  209             /* Child */
  210             p->rcv = 1;
  211             p->tr = 0;
  212 
  213             if ((pipe_to_parent[1] = open(fcontrol_to_parent, O_WRONLY)) < 0 ||
  214                 (pipe_to_child[0] = open(fcontrol_to_child, O_RDONLY)) < 0 ||
  215                 (vmsplice_to_parent[1] = open(fdata_to_parent, O_WRONLY)) < 0 ||
  216                 (vmsplice_to_child[0] = open(fdata_to_child, O_RDONLY)) < 0) {
  217                 despair("Netpipe was unable to open child ends of the named pipes.");
  218             }
  219         }
  220     }
  221     printf("All pipes opened\n");
  222 
  223     return;
  224 }
  225 
  226 void Sync(ArgStruct *p)
  227 {
  228     int bogus;
  229 
  230     /* Parent */
  231     if (p->tr) {
  232         pipe_send(pipe_to_child, &bogus, sizeof(bogus));
  233         pipe_recv(pipe_to_parent, &bogus, sizeof(bogus));
  234     } 
  235 
  236     /* Child */
  237     else {
  238         pipe_recv(pipe_to_child, &bogus, sizeof(bogus));
  239         pipe_send(pipe_to_parent, &bogus, sizeof(bogus));
  240     }
  241 }
  242 
  243 void PrepareToReceive(ArgStruct *p)
  244 {
  245 }
  246 
  247 void SendData(ArgStruct *p)
  248 {
  249     long ret;
  250     int fd = p->tr ? vmsplice_to_child[1] : vmsplice_to_parent[1];
  251     int left = p->bufflen;
  252     struct iovec v = {
  253         .iov_base = p->s_ptr,
  254         .iov_len = p->bufflen
  255     };
  256 
  257     /* Can only vmsplice 64k at a time -- don't know if this is a
  258        hard-coded limit or not */
  259     while (left > 0) {
  260         v.iov_len = left > MAX_VMSPLICE_SIZE ? MAX_VMSPLICE_SIZE : left;
  261         if (vmsplice(fd, &v, 1, 0) != v.iov_len) {
  262             despair("Netpipe failed to vmsplice.");
  263         }
  264         left -= v.iov_len;
  265         v.iov_base += v.iov_len;
  266     }
  267 }
  268 
  269 void RecvData(ArgStruct *p)
  270 {
  271     int fd = p->tr ? vmsplice_to_parent[0] : vmsplice_to_child[0];
  272     int len, left = p->bufflen;
  273     char *dest = p->r_ptr;
  274 
  275     /* Can only vmsplice 64k at a time */
  276     while (left > 0) {
  277         len = left > MAX_VMSPLICE_SIZE ? MAX_VMSPLICE_SIZE : left;
  278         if (read(fd, dest, len) != len) {
  279             despair("Netpipe failed to read bytes from the vmsplice.");
  280         }
  281         left -= len;
  282         dest += len;
  283     }
  284 }
  285 
  286 void SendTime(ArgStruct *p, double *t)
  287 {
  288     /* Only child calls SendTime */
  289     pipe_send(pipe_to_parent, t, sizeof(*t));
  290 }
  291 
  292 void RecvTime(ArgStruct *p, double *t)
  293 {
  294     /* Only parent calls RecvTime */
  295     pipe_recv(pipe_to_parent, t, sizeof(*t));
  296 }
  297 
  298 void SendRepeat(ArgStruct *p, int rpt)
  299 {
  300     /* Only parent calls SendRepeat */
  301     pipe_send(pipe_to_child, &rpt, sizeof(rpt));
  302 }
  303 
  304 void RecvRepeat(ArgStruct *p, int *rpt)
  305 {
  306     /* Only child calls RecvRepeat */
  307     pipe_recv(pipe_to_child, rpt, sizeof(*rpt));
  308 }
  309 
  310 void CleanUp(ArgStruct *p)
  311 {
  312     close(pipe_to_parent[0]);
  313     close(pipe_to_parent[1]);
  314     close(pipe_to_child[0]);
  315     close(pipe_to_child[1]);
  316 
  317     close(vmsplice_to_parent[0]);
  318     close(vmsplice_to_parent[1]);
  319     close(vmsplice_to_child[0]);
  320     close(vmsplice_to_child[1]);
  321 
  322     /* Don't leave stale fifos around */
  323     if (NULL != fcontrol_to_parent) {
  324         unlink(fcontrol_to_parent);
  325     }
  326     if (NULL != fcontrol_to_child) {
  327         unlink(fcontrol_to_child);
  328     }
  329     if (NULL != fdata_to_parent) {
  330         unlink(fdata_to_parent);
  331     }
  332     if (NULL != fdata_to_child) {
  333         unlink(fdata_to_child);
  334     }
  335 }
  336 
  337 
  338 
  339 void Reset(ArgStruct *p)
  340 {
  341 }
  342 
  343 
  344 void AfterAlignmentInit(ArgStruct *p)
  345 {
  346 }