cvsuser     05/02/14 02:57:23

  Modified:    .        MANIFEST
               include/parrot io.h
               io       io.c io_passdown.c io_private.h io_unix.c
                        io_win32.c
               lib/Parrot Distribution.pm
               ops      io.ops ops.num
  Added:       examples/io httpd.imc
  Log:
  [perl #34117] [PATCH] fix make html
  
  make html failes currently, because the src/test_main.c file was moved
  to examples/c/text_main.c.
  
  ChangeLog:
     - update search path to find the file test_main.c.
     - warn if a file is not found
  
  [perl #34120] [PATCH] win32 bind, listen, accept
  
  This patch extends the io NET_DEVEL with the 'server' functions bind,
  listen and accept. I only tested it on win32, so no idea what happens on
  unix. I'm not sure wether i did it right with the ops numbering, but it
  worked for me (See the next patch).
  
  Changelog:
    - implement bind, listen, accept on win32
    - some casting cleanup
  
  [perl #34121] [NEW] imc http server
  
  Now it's getting funny. I have written a tiny webserver in imc, that can
  serve the parrot html documentation. That's also a pretty good test for
  the NET_DEVEL and file readings functions. I tested it on win32, so no
  idea what happens on unix.
  The attached file should be placed in examples/io (no idea how to create
  a /dev/null patch on win32!).
  
  This patch depends of course on #34120.
  
  [perl #34126] [PATCH] fix unix bind, listen, accept
  
  With this patch the tiny webserver from # 34121 runs also on linux
  (tested on debian testing).
  
  depends on #34120
  
  Changelog:
    - fix bind, listen, accept on unix
    - remove some debug output
  
  All
  Courtesy of Markus Amslser <[EMAIL PROTECTED]>
  
  Revision  Changes    Path
  1.832     +1 -0      parrot/MANIFEST
  
  Index: MANIFEST
  ===================================================================
  RCS file: /cvs/public/parrot/MANIFEST,v
  retrieving revision 1.831
  retrieving revision 1.832
  diff -u -r1.831 -r1.832
  --- MANIFEST  2 Feb 2005 12:23:22 -0000       1.831
  +++ MANIFEST  14 Feb 2005 10:57:18 -0000      1.832
  @@ -545,6 +545,7 @@
   examples/compilers/japhc.c                        [main]doc
   examples/io/echo_client.imc                       [main]doc
   examples/io/http.imc                              [main]doc
  +examples/io/httpd.imc                             [main]doc
   examples/io/net_smtp.pasm                         [main]doc
   examples/io/pioctl.pasm                           [main]doc
   examples/io/pipe2.imc                             [main]doc
  
  
  
  1.1                  parrot/examples/io/httpd.imc
  
  Index: httpd.imc
  ===================================================================
  =head1 NAME
  
  examples/io/httpd.imc - HTTP server
  
  =head1 SYNOPSIS
  
      % ./parrot examples/io/httpd.imc
  
  =head1 DESCRIPTION
  
  A very tiny HTTP-Server. Currently only understands GET method.
  It's a nice way of testing pretty all io funtions.
  
  By default it binds to localhost:1234, and serves the HTML Documentation
  in ./docs/html. Make sure you have built them with
  
      % make html
  
  After that you can browse the documenation with
  
      http://localhost:1234/html/index.html
  
  Currently the URL isn't decoded, so the docs get served only partially
  
  Be sure to set C<PARROT_NET_DEVEL> to 1 in F<io/io_private.h> and
  rebuild Parrot or the network layer won't exist.
  
  TODO
      make it work on W32/IE
  
  
  =cut
  
  .sub _main
      .local pmc sock
      .local pmc work
      .local pmc fp
      .local string address
      .local string buf
      .local string req
      .local string rep
      .local string temp
      .local int ret
      .local int len
      .local int pos
        .local int occ1
        .local int occ2
        .local string meth
        .local string url
        .local string doc_root
        .local string file_con
  
        .local string tst
        .local string tst2
  
        doc_root = "docs"
  
      socket sock, 2, 1, 0
      unless sock goto ERR
  
      # Pack a sockaddr_in structure with IP and port
      sockaddr address, 1234, "localhost"
      print "Binding to port 1234\n"
      bind ret, sock, address
  
  
  NEXT:
      listen ret, sock, 5
  
        accept work, sock
  
        req = ""
  MORE:
      recv ret, work, buf
      if ret <= 0 goto SERVE_REQ
      concat req, buf
        index pos, req, "\r\n\r\n"
        if pos >= 0 goto SERVE_REQ
        index pos, req, "\n\n"
        if pos >= 0 goto SERVE_REQ
        index pos, req, "\r\r"
        if pos >= 0 goto SERVE_REQ
        goto MORE
  
  SERVE_REQ:
  #    print "Request:\n"
  #    print req
  # split is not implemented, so parse it the old way
  # GET the method and file
        index occ1, req, " "
        add occ1, occ1, 1
        index occ2, req, " ", occ1
        sub len, occ1, 1
        substr meth, req, 0, len
        sub len, occ2, occ1
        substr url, req, occ1, len
  
        if meth == "GET" goto SERVE_GET
  
        print "unknown method:'"
        print meth
        print "'\n"
        goto NEXT
  
  
  SERVE_GET:
      # decode the url
        url = urldecode (url)
        # open the file in url
        if url !="/" goto GET2
        url = "/index.html"
        GET2:
        concat url, doc_root, url
        open fp, url, "<"
        unless fp goto SERVE_404
  
        read file_con, fp, 65535
        rep = "HTTP/1.x 200 OK\n"
        concat rep, "Server: Parrot-httpd/0.1\n"
  #     concat rep, "Content-type: text/html\n"
        concat rep, "Content-Length: "
        length len, file_con
        temp = to_string (len)
        concat rep, temp
        concat rep, "\n\n"
        concat rep, file_con
  
        send ret, work, rep
  
        print "served file '"
        print url
        print "'\n"
        goto NEXT
  
  SERVE_404:
        rep = "HTTP1/1 404 Not Found\nContent-Length: 3\n\n404\n"
        print "File not found: '"
        print url
        print "'\n"
        send ret, work, rep
        goto NEXT
  ERR:
      print "Socket error\n"
      end
  END:
      close sock
      end
  .end
  
  
  .sub to_string
        .param int n
        .local string ret
        .local string char
        .local int rest
        ret = ""
  NEXT_CHAR:
        mod rest, n, 10
        sub n, n, rest
        div n, n, 10
        add rest, 48, rest
        chr char, rest
        concat ret, char, ret
        if n>0 goto     NEXT_CHAR
  
      .pcc_begin_return
      .return ret
      .pcc_end_return
  .end
  
  
  
  
  .sub urldecode
        .param string in
        .local string out
        .local string char_in
        .local string char_out
        .local int c_out
        .local int pos_in
        .local int len
        .local string hex
  
        length len, in
        pos_in = 0
        out = ""
  START:
        if pos_in >= len goto END
        substr char_in, in, pos_in, 1
        char_out = char_in
        if char_in != "%" goto INC_IN
        # OK this was a escape character, next two are hexadecimal
        add pos_in, 1, pos_in
        substr hex, in, pos_in, 2
        c_out = hex_to_int (hex)
        chr char_out, c_out
        add pos_in, 1, pos_in
  
  INC_IN:
        concat out, char_out
        add pos_in, 1, pos_in
        goto START
  END:
    .pcc_begin_return
    .return out
    .pcc_end_return
  .end
  
  
  .sub hex_to_int
        .param string in
        .local string char
        .local int ret
        .local int pos
        .local int factor
        .local int temp
        .local int len
  
        ret = 0
        factor = 1
        length len, in
        sub pos, len, 1
  
  NEXT_CHAR:
        substr char, in, pos, 1
  
        if char=="0" goto CHAR0
        if char=="1" goto CHAR1
        if char=="2" goto CHAR2
        if char=="3" goto CHAR3
        if char=="4" goto CHAR4
        if char=="5" goto CHAR5
        if char=="6" goto CHAR6
        if char=="7" goto CHAR7
        if char=="8" goto CHAR8
        if char=="9" goto CHAR9
        if char=="A" goto CHARA
        if char=="B" goto CHARB
        if char=="C" goto CHARC
        if char=="D" goto CHARD
        if char=="E" goto CHARE
        if char=="F" goto CHARF
  
  CHAR0:
        temp = 0
        goto CHAREND
  CHAR1:
        temp = 1
        goto CHAREND
  CHAR2:
        temp = 2
        goto CHAREND
  CHAR3:
        temp = 3
        goto CHAREND
  CHAR4:
        temp = 4
        goto CHAREND
  CHAR5:
        temp = 5
        goto CHAREND
  CHAR6:
        temp = 6
        goto CHAREND
  CHAR7:
        temp = 7
        goto CHAREND
  CHAR8:
        temp = 8
        goto CHAREND
  CHAR9:
        temp = 9
        goto CHAREND
  CHARA:
        temp = 10
        goto CHAREND
  CHARB:
        temp = 11
        goto CHAREND
  CHARC:
        temp = 12
        goto CHAREND
  CHARD:
        temp = 13
        goto CHAREND
  CHARE:
        temp = 14
        goto CHAREND
  CHARF:
        temp = 15
        goto CHAREND
  
  CHAREND:
        mul temp, factor, temp
        add ret, temp, ret
        mul factor, factor, 16
        sub pos, pos, 1
        if pos>=0 goto  NEXT_CHAR
  
    .pcc_begin_return
    .return ret
    .pcc_end_return
  .end
  
  
  
  1.62      +4 -1      parrot/include/parrot/io.h
  
  Index: io.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/io.h,v
  retrieving revision 1.61
  retrieving revision 1.62
  diff -u -r1.61 -r1.62
  --- io.h      1 Feb 2005 09:43:18 -0000       1.61
  +++ io.h      14 Feb 2005 10:57:20 -0000      1.62
  @@ -1,7 +1,7 @@
   /* io.h
    *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: io.h,v 1.61 2005/02/01 09:43:18 leo Exp $
  + *     $Id: io.h,v 1.62 2005/02/14 10:57:20 leo Exp $
    *  Overview:
    *      Parrot IO subsystem
    *  Data Structure and Algorithms:
  @@ -184,6 +184,9 @@
   extern INTVAL PIO_recv(theINTERP, PMC *pmc, STRING **buf);
   extern INTVAL PIO_send(theINTERP, PMC *pmc, STRING *buf);
   extern INTVAL PIO_connect(theINTERP, PMC *pmc, STRING *address);
  +extern INTVAL PIO_bind(theINTERP, PMC *pmc, STRING *address);
  +extern INTVAL PIO_listen(theINTERP, PMC *pmc, INTVAL backlog);
  +extern PMC *PIO_accept(theINTERP, PMC *pmc);
   
   
   extern INTVAL PIO_putps(theINTERP, PMC *io, STRING *s);
  
  
  
  1.109     +68 -1     parrot/io/io.c
  
  Index: io.c
  ===================================================================
  RCS file: /cvs/public/parrot/io/io.c,v
  retrieving revision 1.108
  retrieving revision 1.109
  diff -u -r1.108 -r1.109
  --- io.c      27 Jan 2005 14:11:37 -0000      1.108
  +++ io.c      14 Feb 2005 10:57:21 -0000      1.109
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: io.c,v 1.108 2005/01/27 14:11:37 leo Exp $
  +$Id: io.c,v 1.109 2005/02/14 10:57:21 leo Exp $
   
   =head1 NAME
   
  @@ -1391,6 +1391,73 @@
   /*
   
   =item C<INTVAL
  +PIO_bind(theINTERP, PMC *pmc, STRING *address)>
  +
  +Binds C<*pmc>'s socket to the local address and port specified by 
C<*address>.
  +
  +=cut
  +
  +*/
  +
  +INTVAL
  +PIO_bind(theINTERP, PMC *pmc, STRING *address)
  +{
  +    ParrotIOLayer *l = PMC_struct_val(pmc);
  +    ParrotIO *io = PMC_data(pmc);
  +    if(!io)
  +        return -1;
  +
  +    return PIO_bind_down(interpreter, l, io, address);
  +}
  +
  +/*
  +
  +=item C<INTVAL
  +PIO_listen(theINTERP, PMC *pmc, INTVAL backlog)>
  +
  +Listen for new connections on socket C<*pmc>.
  +
  +=cut
  +
  +*/
  +
  +INTVAL
  +PIO_listen(theINTERP, PMC *pmc, INTVAL backlog)
  +{
  +    ParrotIOLayer *l = PMC_struct_val(pmc);
  +    ParrotIO *io = PMC_data(pmc);
  +    if(!io)
  +        return -1;
  +
  +    return PIO_listen_down(interpreter, l, io, backlog);
  +}
  +
  +/*
  +
  +=item C<INTVAL
  +PIO_accept(theINTERP, PMC *pmc)>
  +
  +Accept a new connection and return a newly created C<ParrotIO> socket.
  +=cut
  +
  +*/
  +
  +PMC *
  +PIO_accept(theINTERP, PMC *pmc)
  +{
  +    ParrotIO *io2;
  +    ParrotIOLayer *l = PMC_struct_val(pmc);
  +    ParrotIO *io = PMC_data(pmc);
  +    if(!io)
  +        return NULL;
  +
  +    io2 = PIO_accept_down(interpreter, l, io);
  +    return new_io_pmc(interpreter, io2);
  +}
  +
  +/*
  +
  +=item C<INTVAL
   PIO_isatty(theINTERP, PMC *pmc)>
   
   Returns a boolean value indicating whether C<*pmc> is a console/tty.
  
  
  
  1.10      +83 -1     parrot/io/io_passdown.c
  
  Index: io_passdown.c
  ===================================================================
  RCS file: /cvs/public/parrot/io/io_passdown.c,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- io_passdown.c     1 Oct 2004 08:46:50 -0000       1.9
  +++ io_passdown.c     14 Feb 2005 10:57:21 -0000      1.10
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: io_passdown.c,v 1.9 2004/10/01 08:46:50 leo Exp $
  +$Id: io_passdown.c,v 1.10 2005/02/14 10:57:21 leo Exp $
   
   =head1 NAME
   
  @@ -568,6 +568,88 @@
   
   /*
   
  +=item C<INTVAL
  +PIO_bind_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, STRING 
*address)>
  +
  +Looks for the implementation of C<Bind> and calls it if found,
  +returning its return value.
  +
  +Returns C<-1> if no implementation is found.
  +
  +
  +=cut
  +
  +*/
  +
  +INTVAL
  +PIO_bind_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, STRING *address)
  +{
  +    while (layer) {
  +        if (layer->api->Bind) {
  +            return layer->api->Bind(interpreter, layer, io, address);
  +        }
  +        layer = PIO_DOWNLAYER(layer);
  +    }
  +    return -1;
  +}
  +
  +/*
  +
  +=item C<INTVAL
  +PIO_listen_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, INTVAL 
backlog)>
  +
  +Looks for the implementation of C<listen> and calls it if found,
  +returning its return value.
  +
  +Returns C<-1> if no implementation is found.
  +
  +
  +=cut
  +
  +*/
  +
  +INTVAL
  +PIO_listen_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, INTVAL 
backlog)
  +{
  +    while (layer) {
  +        if (layer->api->Listen) {
  +            return layer->api->Listen(interpreter, layer, io, backlog);
  +        }
  +        layer = PIO_DOWNLAYER(layer);
  +    }
  +    return -1;
  +}
  +
  +/*
  +
  +=item C<ParrotIO *
  +PIO_accept_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, STRING 
*address)Y
  +
  +
  +Looks for the implementation of C<Accept> and calls it if found,
  +returning its return value.
  +
  +Returns C<-1> if no implementation is found.
  +
  +
  +=cut
  +
  +*/
  +
  +ParrotIO *
  +PIO_accept_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io)
  +{
  +    while (layer) {
  +        if (layer->api->Accept) {
  +            return layer->api->Accept(interpreter, layer, io);
  +        }
  +        layer = PIO_DOWNLAYER(layer);
  +    }
  +    return -1;
  +}
  +
  +/*
  +
   =back
   
   =head1 SEE ALSO
  
  
  
  1.19      +7 -1      parrot/io/io_private.h
  
  Index: io_private.h
  ===================================================================
  RCS file: /cvs/public/parrot/io/io_private.h,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- io_private.h      4 Oct 2004 11:39:51 -0000       1.18
  +++ io_private.h      14 Feb 2005 10:57:21 -0000      1.19
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: io_private.h,v 1.18 2004/10/04 11:39:51 leo Exp $
  +$Id: io_private.h,v 1.19 2005/02/14 10:57:21 leo Exp $
   
   =head1 NAME
   
  @@ -170,6 +170,9 @@
   INTVAL    PIO_recv_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, 
STRING **buf);
   INTVAL    PIO_send_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, 
STRING *buf);
   INTVAL    PIO_connect_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, 
STRING *address);
  +INTVAL    PIO_bind_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, 
STRING *address);
  +INTVAL    PIO_listen_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, 
INTVAL backlog);
  +ParrotIO *PIO_accept_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io);
   
   /*
    * By default, any layer not implementing an interface (ie. leaving
  @@ -227,6 +230,9 @@
                               STRING *);
       INTVAL          (*Send)(theINTERP, ParrotIOLayer *, ParrotIO *, STRING 
*);
       INTVAL          (*Recv)(theINTERP, ParrotIOLayer *, ParrotIO *, STRING 
**);
  +    INTVAL          (*Bind)(theINTERP, ParrotIOLayer *, ParrotIO *, STRING 
*);
  +    INTVAL          (*Listen)(theINTERP, ParrotIOLayer *, ParrotIO *, 
INTVAL);
  +    ParrotIO *      (*Accept)(theINTERP, ParrotIOLayer *, ParrotIO *);
   };
   
   /* these are defined rather than using NULL because strictly-speaking, ANSI C
  
  
  
  1.58      +9 -5      parrot/io/io_unix.c
  
  Index: io_unix.c
  ===================================================================
  RCS file: /cvs/public/parrot/io/io_unix.c,v
  retrieving revision 1.57
  retrieving revision 1.58
  diff -u -r1.57 -r1.58
  --- io_unix.c 1 Feb 2005 09:43:20 -0000       1.57
  +++ io_unix.c 14 Feb 2005 10:57:21 -0000      1.58
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: io_unix.c,v 1.57 2005/02/01 09:43:20 leo Exp $
  +$Id: io_unix.c,v 1.58 2005/02/14 10:57:21 leo Exp $
   
   =head1 NAME
   
  @@ -661,7 +661,6 @@
   
       sa.sin_port = htons(port);
   
  -    fprintf(stderr, "sockaddr_in: port %d\n", port);
       return string_make(interpreter, &sa, sizeof(struct sockaddr),
               "iso-8859-1", 0);
   }
  @@ -692,7 +691,6 @@
           io = PIO_new(interpreter, PIO_F_SOCKET, 0, PIO_F_READ|PIO_F_WRITE);
           io->fd = sock;
           io->remote.sin_family = fam;
  -        fprintf(stderr, "socket: fd = %d\n", sock);
           return io;
       }
       perror("socket:");
  @@ -1163,13 +1161,19 @@
       PIO_unix_socket,
       PIO_unix_connect,
       PIO_unix_send,
  -    PIO_unix_recv
  +    PIO_unix_recv,
  +    PIO_unix_bind,
  +    PIO_unix_listen,
  +    PIO_unix_accept
   #else
       0, /* no poll */
       0, /* no socket */
       0, /* no connect */
       0, /* no send */
  -    0 /* no recv */
  +    0, /* no recv */
  +    0, /* no bind */
  +    0, /* no listen */
  +    0  /* no accept */
   #endif
   };
   
  
  
  
  1.50      +112 -9    parrot/io/io_win32.c
  
  Index: io_win32.c
  ===================================================================
  RCS file: /cvs/public/parrot/io/io_win32.c,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- io_win32.c        1 Feb 2005 09:43:20 -0000       1.49
  +++ io_win32.c        14 Feb 2005 10:57:21 -0000      1.50
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: io_win32.c,v 1.49 2005/02/01 09:43:20 leo Exp $
  +$Id: io_win32.c,v 1.50 2005/02/14 10:57:21 leo Exp $
   
   =head1 NAME
   
  @@ -576,7 +576,7 @@
       ParrotIO * io;
       if((sock = socket(fam, type, proto)) >= 0) {
           io = PIO_new(interpreter, PIO_F_SOCKET, 0, PIO_F_READ|PIO_F_WRITE);
  -        io->fd = (void *) sock;
  +        io->fd = (PIOHANDLE) sock;
           io->remote.sin_family = fam;
           return io;
       }
  @@ -606,7 +606,7 @@
       }
   
   /*    PIO_eprintf(interpreter, "connect: fd = %d port = %d\n", io->fd, 
ntohs(io->remote.sin_port));*/
  -    if((connect((int)io->fd, (struct sockaddr*)&io->remote,
  +    if((connect((SOCKET)io->fd, (struct sockaddr*)&io->remote,
                      sizeof(struct sockaddr))) != 0) {
           PIO_eprintf(interpreter, "PIO_win32_connect: errno = %d\n", 
WSAGetLastError());
           return -1;
  @@ -637,7 +637,7 @@
       /*
        * Ignore encoding issues for now.
        */
  -    if((error = send((int)io->fd, (char *)PObj_bufstart(s) + byteswrote,
  +    if((error = send((SOCKET)io->fd, (char *)PObj_bufstart(s) + byteswrote,
                               PObj_buflen(s), 0)) >= 0) {
           byteswrote += error;
           if(byteswrote >= bytes) {
  @@ -656,7 +656,7 @@
   #else
               case EAGAIN:       goto AGAIN;
   #endif
  -            case EPIPE:        close((int)io->fd);
  +            case EPIPE:        close((SOCKET)io->fd);
                                  return -1;
               default:           return -1;
           }
  @@ -683,13 +683,13 @@
       char buf[2048+1];
   
   AGAIN:
  -             error = recv((int)io->fd, buf, 2048, 0);
  +     error = recv((SOCKET)io->fd, buf, 2048, 0);
                err = WSAGetLastError();
       if(error > 0) {
           if(error > 0)
               bytesread += error;
           else {
  -            close((int)io->fd);
  +            close((SOCKET)io->fd);
           }
           *s = string_make(interpreter, buf, bytesread, "iso-8859-1", 0);
           if(!*s) {
  @@ -703,12 +703,12 @@
           switch(err) {
               case WSAEINTR:        goto AGAIN;
               case WSAEWOULDBLOCK:  goto AGAIN;
  -            case WSAECONNRESET:   close((int)io->fd);
  +            case WSAECONNRESET:   close((SOCKET)io->fd);
   #if PIO_TRACE
               PIO_eprintf(interpreter, "recv: Connection reset by peer\n");
   #endif
                                  return -1;
  -            default:           close((int)io->fd);
  +            default:           close((SOCKET)io->fd);
   #if PIO_TRACE
                        PIO_eprintf(interpreter, "recv: errno = %d\n", err);
   #endif
  @@ -717,7 +717,104 @@
       }
   }
   
  +/*
  +
  +=item C<static INTVAL
  +PIO_win32_bind(theINTERP, ParrotIOLayer *layer, ParrotIO *io, STRING *l)>
  +
  +Binds C<*io>'s socket to the local address and port specified by C<*l>.
  +
  +=cut
  +
  +*/
  +
  +static INTVAL
  +PIO_win32_bind(theINTERP, ParrotIOLayer *layer, ParrotIO *io, STRING *l)
  +{
  +    struct sockaddr_in sa;
  +    if(!l) return -1;
  +
  +    memcpy(&sa, PObj_bufstart(l), sizeof(struct sockaddr));
  +    io->local.sin_addr.s_addr = sa.sin_addr.s_addr;
  +    io->local.sin_port = sa.sin_port;
  +    io->local.sin_family = AF_INET;
  +
  +    if((bind((SOCKET)io->fd, (struct sockaddr *)&io->local, sizeof(struct 
sockaddr))) == -1)
  +    {
  +        PIO_eprintf(interpreter, "PIO_win32_bind: errno = %d\n", 
WSAGetLastError());
  +        return -1;
  +    }
  +
  +    return 0;
  +}
  +
  +/*
  +
  +=item C<static INTVAL
  +PIO_win32_listen(theINTERP, ParrotIOLayer *layer, ParrotIO *io, INTVAL sec)>
  +
  +Listen for new connections. This is only applicable to C<STREAM> or
  +C<SEQ> sockets.
  +
  +=cut
  +
  +*/
   
  +static INTVAL
  +PIO_win32_listen(theINTERP, ParrotIOLayer *layer, ParrotIO *io, INTVAL 
backlog)
  +{
  +    if((listen((SOCKET)io->fd, backlog)) == -1) {
  +        fprintf(stderr, "listen: errno= ret=%d fd = %d port = %d\n",
  +             errno, io->fd, ntohs(io->local.sin_port));
  +        return -1;
  +    }
  +    return 0;
  +}
  +
  +/*
  +
  +=item C<static ParrotIO *
  +PIO_win32_accept(theINTERP, ParrotIOLayer *layer, ParrotIO *io)>
  +
  +Accept a new connection and return a newly created C<ParrotIO> socket.
  +
  +=cut
  +
  +*/
  +
  +static ParrotIO *
  +PIO_win32_accept(theINTERP, ParrotIOLayer *layer, ParrotIO *io)
  +{
  +    int newsock;
  +    int newsize;
  +    int err_code;
  +    ParrotIO *newio;
  +    newio = PIO_new(interpreter, PIO_F_SOCKET, 0, PIO_F_READ|PIO_F_WRITE);
  +    newsize = sizeof (struct sockaddr);
  +
  +    newsock = accept((SOCKET)io->fd, (struct sockaddr *)&(newio->remote), 
&newsize);
  +    err_code = WSAGetLastError();
  +
  +    if(err_code != 0)
  +    {
  +        fprintf(stderr, "accept: errno=%d", err_code);
  +        /* Didn't get far enough, free the io */
  +        mem_sys_free(newio);
  +        return NULL;
  +    }
  +
  +    newio->fd = (PIOHANDLE) newsock;
  +
  +    /* XXX FIXME: Need to do a getsockname and getpeername here to
  +     * fill in the sockaddr_in structs for local and peer
  +     */
  +
  +    /* Optionally do a gethostyaddr() to resolve remote IP address.
  +     * This should be based on an option set in the master socket
  +     */
  +
  +    return newio;
  +}
   
   #endif
   
  @@ -756,12 +853,18 @@
       PIO_win32_connect,
       PIO_win32_send,
       PIO_win32_recv,
  +    PIO_win32_bind,
  +    PIO_win32_listen,
  +    PIO_win32_accept
   #else
       0, /* no poll */
       0, /* no socket */
       0, /* no connect */
       0, /* no send */
       0, /* no recv */
  +    0, /* no bind */
  +    0, /* no listen */
  +    0, /* no accept */
   #endif
   };
   
  
  
  
  1.4       +4 -2      parrot/lib/Parrot/Distribution.pm
  
  Index: Distribution.pm
  ===================================================================
  RCS file: /cvs/public/parrot/lib/Parrot/Distribution.pm,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Distribution.pm   27 Mar 2004 22:22:36 -0000      1.3
  +++ Distribution.pm   14 Feb 2005 10:57:22 -0000      1.4
  @@ -1,5 +1,5 @@
   # Copyright: 2004 The Perl Foundation.  All Rights Reserved.
  -# $Id: Distribution.pm,v 1.3 2004/03/27 22:22:36 mikescott Exp $
  +# $Id: Distribution.pm,v 1.4 2005/02/14 10:57:22 leo Exp $
   
   =head1 NAME
   
  @@ -91,7 +91,8 @@
                $self->directory_with_name('encodings'),
                $self->directory_with_name('io'),
                $self->directory_with_name('pf'),
  -             $self->directory_with_name('types'),;
  +             $self->directory_with_name('types'),
  +             
$self->directory_with_name('examples')->directory_with_name('c'),;
   }
   
   =item C<c_source_file_with_name($name)>
  @@ -113,6 +114,7 @@
                        if $dir->file_exists_with_name($name);
        }
        
  +     print 'WARNING: ' . __FILE__ . ':' . __LINE__ . ' File not found:' . 
$name ."\n";
        return undef;
   }
   
  
  
  
  1.54      +21 -0     parrot/ops/io.ops
  
  Index: io.ops
  ===================================================================
  RCS file: /cvs/public/parrot/ops/io.ops,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -r1.53 -r1.54
  --- io.ops    1 Feb 2005 10:23:18 -0000       1.53
  +++ io.ops    14 Feb 2005 10:57:23 -0000      1.54
  @@ -521,6 +521,12 @@
   
   =item B<poll>(out INT, in PMC, in INT, in INT, in INT)
   
  +=item B<bind>(out INT, in PMC, in STR)
  +
  +=item B<listen>(out INT, in PMC, in INT)
  +
  +=item B<accept>(out PMC, in PMC)
  +
   =cut
   
   op socket(out PMC, in INT, in INT, in INT) :base_network {
  @@ -556,6 +562,21 @@
       goto NEXT();
   }
   
  +op bind(out INT, in PMC, in STR) :base_network {
  +    $1 = (INTVAL)PIO_bind(interpreter, $2, $3);
  +    goto NEXT();
  +}
  +
  +op listen(out INT, in PMC, in INT) :base_network {
  +    $1 = (INTVAL)PIO_listen(interpreter, $2, $3);
  +    goto NEXT();
  +}
  +
  +op accept(out PMC, in PMC) :base_network {
  +    $1 = PIO_accept(interpreter, $2);
  +    goto NEXT();
  +}
  +
   ########################################
   
   =back
  
  
  
  1.56      +5 -0      parrot/ops/ops.num
  
  Index: ops.num
  ===================================================================
  RCS file: /cvs/public/parrot/ops/ops.num,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- ops.num   17 Jan 2005 14:56:45 -0000      1.55
  +++ ops.num   14 Feb 2005 10:57:23 -0000      1.56
  @@ -1367,3 +1367,8 @@
   pop_pad_p                      1337
   interpinfo_s_i                 1338
   interpinfo_s_ic                1339
  +bind_i_p_s                     1340
  +bind_i_p_sc                    1341
  +listen_i_p_i                   1342
  +listen_i_p_ic                  1343
  +accept_p_p                     1344
  
  
  

Reply via email to