[gambit-list] Get OS file descriptor of TCP socket port Re: Location

Mikael mikael.trash at gmail.com
Sun Jan 17 07:10:47 EST 2010


Taylor,

The code attached at the bottom does what you want, without need for linking
to os_io.c . In case Gambit would change it might need update.

Mikael

2010/1/17 Taylor Venable <taylor at metasyntax.net>

> Hi, I've been hacking a lot the last couple days to try to figure out
> how to get the file descriptor for a socket created with open-tcp-client
> on Linux.  I've finally got it figured out, and to do it I obtain the
> rdevice for the port via the condition variable and in C cast it to a
> ___device_tcp_client_struct to extract the 's' field (the file descrip-
> tor).  There's only one problem: whereas ___device_stream_struct is
> defined in os_io.h and I can conveniently include it from my C code, the
> definition of ___device_tcp_client_struct is in os_io.c and I had to
> copy it out and paste it into my code.  Is there something about that
> definition that makes its location in the C source (rather than the
> header) necessary?  I'd prefer to just #include something, but if the
> only way is to copy/paste those lines then I'll just continue to do
> that.  Thanks for any advice.
>
> --
> Taylor Venable
> http://metasyntax.net/
>
> _______________________________________________
> Gambit-list mailing list
> Gambit-list at iro.umontreal.ca
> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
>


 -


(c-declare "
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include </usr/local/Gambit-C/current/lib/os_io.h> // I'm well aware this is
not the default installation directory for this file.
                                                   // Though let's use it
for convention. Requires os.h and os_time.h .
")


; How to get file descriptor of TCP socket port:
; ##make-device-port on _io.scm 1202 puts its rdevice and wdevice parameters
; as condition-variable-name of ##vector-ref 44 and 45 of the port.
; ##make-device-port is invoked by ##make-device-port-from-single-device of
row 1560,
; which is in turn invoked by ##make-tcp-client-port 5767, which is in turn
invoked
; by ##open-tcp-client on row 5816. Please note that rdevice and wdevice are
the
; same variable. It is generated by ##os-device-tcp-client-open invoked on
; row 5807, that's declared in _kernel.scm row 3966, which calls
___os_device_tcp_client_open
; that's declared in os_io.c row 7272. So the return value contains this.
; The return value is generated by ___NONNULLPOINTER_to_SCMOBJ (defined in
c_intf.c 4617) that convers an arbitrary pointer
; to a SCMOBJ. In this case it's the ___device_tcp_client structure dev.
;
; The socket (i.e. the file descriptor) is generated by a call to the OS
function socket
; on row 3407 in the function create_tcp_socket. The result is written to
the SOCKET_TYPE
; pointer argument that's the first parameter of the function. The function
is called by
; ___device_tcp_client_setup_from_sockaddr declared on row 3559. After
generation it passes
; the socket into ___device_tcp_client_setup_from_socket declared on row
3472, as third parameter.
; As first parameter, the function takes the ___device_tcp_client. It copies
the socket into the ->s
; property of the structure.
;
; ___device_tcp_client is declared on row 2960 in os_io.c . The structure is
designed like that first
; in it, there's a ___device_stream, then the socket comes. ___device_stream
is defined in os_io.h row 414.
; SOCKET_TYPE is declared in os_io.c and is defined to int on USE_POSIX
systems, and to SOCKET on USE_WIN32
; systems.
;
; Thus, to get the socket file descriptor of an open TCP socket port, take
the int sizeof(___device_stream)
; bytes into (condition-variable-name (##vector-ref port 44)) .
;
; ** In case this function stops working with a new version of Gambit,
; ** First check if the ___device_tcp_client structure has been changed,
that is, if the first property is not
; ** a ___device_stream and the second the socket anymore.
; ** Second, check if the name parameter of vector-index no. 44 of TCP
connection ports aren't
; ** (see macro-device-port-rdevice-condvar's definition)
; ** foreign-objects in general, and ___device_tcp_client values in
particular, anymore. Use (##vector->list port).

(define (tcp-socket-port->fd port)
  (let* ((___device_tcp_client (condition-variable-name
(util#device-port-rdevice-condvar port)))
         (ptr (foreign-address ___device_tcp_client)))
    ((c-lambda (unsigned-long) int #<<C
       int ptrv = ___arg1;
       // fprintf(stderr,"In C now, the pointer value is %i.
sizeof(___device_stream) is %i.\n\n",ptrv,sizeof(___device_stream));
       // ___device_stream* v = ___CAST(___device_stream*,(int*) ptrv);
       // fprintf(stderr,"v is %i.\n",(int) v);
       ptrv += sizeof(___device_stream);
       int* ptr = (int*) ptrv;
       // fprintf(stderr,"In C now, after having added to the pointer, it's
%i (%i). The value found at its location is %i.\n\n",(int) ptr,ptrv,*ptr);
       ___result = *ptr;
C
               ) ptr)))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20100117/19ca283d/attachment.htm>


More information about the Gambit-list mailing list