[Vm-dev] is it possible access OS socket handler from Socket instance

Eliot Miranda eliot.miranda at gmail.com
Tue Aug 8 18:34:16 UTC 2017

Hi Denis,

On Tue, Aug 8, 2017 at 2:11 AM, Denis Kudriashov <dionisiydk at gmail.com>

> Hi.
> I play a bit of idea to make binding to libssh2 library.
> And the main problem is function
> int libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t
> socket)
> where socket parameter is raw OS socket handle as I understand.
> So question: is it possible to access this handle from image side from
> Socket instance?

Yes, but non-trivially.

> There is socketHandle instance variable which is bytearray. What is it?

It is an instance of this struct:

typedef struct
  int   sessionID;
  int   socketType;  /* 0 = TCP, 1 = UDP */
  void  *privateSocketPtr;
}  SQSocket, *SocketPtr;

The two most common definitions are:
typedef struct privateSocketStruct
  int s;            /* Unix socket */
  int connSema;         /* connection io notification semaphore */
  int readSema;         /* read io notification semaphore */
  int writeSema;        /* write io notification semaphore */
  int sockState;        /* connection + data state */
  int sockError;        /* errno after socket error */
  union sockaddr_any peer;  /* default send/recv address for UDP */
  socklen_t peerSize;       /* dynamic sizeof(peer) */
  union sockaddr_any sender;    /* sender address for last UDP receive */
  socklen_t senderSize;     /* dynamic sizeof(sender) */
  int multiListen;      /* whether to listen for multiple connections */
  int acceptedSock;     /* a connection that has been accepted */
} privateSocketStruct;

typedef struct privateSocketStruct {
  struct privateSocketStruct *next;

  int sockType;
  int sockState;
  int sockError;

  int readSema;
  int writeSema;
  int connSema;

  union sockaddr_any peer;  /* socket address in connect() or send/rcv
address for UDP */
  socklen_t peerSize;       /* dynamic sizeof(peer) */

  HANDLE mutex;             /* The mutex used for synchronized access to
this socket */
  acceptedSocketStruct *accepted; /* Accepted connections on a socket */

  DWORD  readWatcherOp;      /* read operation to watch */
  HANDLE hReadWatcherEvent;  /* event for waking up read watcher */
  HANDLE hReadThread;

  DWORD  writeWatcherOp;     /* write operation to watch */
  HANDLE hWriteWatcherEvent; /* event for waking up write watcher */
  HANDLE hWriteThread;

  volatile DWORD closePending; /* Cleanup counter */

  int readSelect;
  int writeSelect;
} privateSocketStruct;

So you *could* create an Alien on the 4 bytes at 9 in the handle on
32-bits, or the 8 bytes at 9 on 64-bits, and then decode the resulting
pointer to a privateSocketStruct.  On linux & mac os it is the 4 bytes at
1.  On Win32 it's the 4 bytes at 5, and on Win64 it's the 4 bytes at 9.

But I would instead add a new primitive to the socket plugin, something
like primitiveSocketGetNativeHandle, and use that :-)

To do this:
a) modify VMMaker.oscog's SocketPlugin to add the primitive
b) in platforms/Cross/plugins/SocketPlugin./SocketPlugin.h add something
    sqInt sqSocketNativeHandle(SocketPtr s, int type);
where type is, say, 0 for the normal file descriptor and other values for
future use (one platform has both data and control sockets in its
c) implement sqSocketNativeHandle appropriately in
platforms/win32/plugins/SocketPlugin/sqWin32NewNet.c et al. There are 5 in
all; Mac OS Carbon, RiscOS & Plan9 are the other three.)

Best regards,
> Denis

best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20170808/b7b15316/attachment.html>

More information about the Vm-dev mailing list