view modules/socket.tp @ 145:7db37f040a6f

Basic socket support
author Mike Pavone <pavone@retrodev.com>
date Fri, 09 Aug 2013 04:15:53 -0700
parents 9bce890a7ff2
children 4c96a393103e
line wrap: on
line source

#{
	includeSystemHeader: "sys/types.h"
	includeSystemHeader: "sys/socket.h"
	includeSystemHeader: "netdb.h"

	llMessage: AF_INET withVars: {
		intret <- obj_int32 ptr
	} andCode: {
		intret <- make_object: (addr_of: obj_int32_meta) NULL 0
		intret num!: AF_INET
		intret
	}
	llMessage: AF_UNIX withVars: {
		intret <- obj_int32 ptr
	} andCode: {
		intret <- make_object: (addr_of: obj_int32_meta) NULL 0
		intret num!: AF_UNIX
		intret
	}
	llMessage: STREAM withVars: {
		intret <- obj_int32 ptr
	} andCode: {
		intret <- make_object: (addr_of: obj_int32_meta) NULL 0
		intret num!: SOCK_STREAM
		intret
	}
	llMessage: DGRAM withVars: {
		intret <- obj_int32 ptr
	} andCode: {
		intret <- make_object: (addr_of: obj_int32_meta) NULL 0
		intret num!: SOCK_DGRAM
		intret
	}
	llMessage: socket withVars: {
		fd <- obj_int32 ptr
		domain <- obj_int32 ptr
		type <- obj_int32 ptr
		protocol <- obj_int32 ptr
	} andCode: :domain type protocol {
		fd <- make_object: (addr_of: obj_int32_meta) NULL 0
		fd num!: (socket: (domain num) (type num) (protocol num))
		fd
	}

	new <- :domain type protocol {
		sfd <- socket: domain type protocol
		#{
			fd <- {sfd}
			llMessage: close withVars: {
				sfd <- obj_int32 ptr
			} andCode: {
				sfd <- mcall: fd 1 self
				close: (sfd num)
				self
			}
			llMessage: send:withFlags withVars: {
				odata <- object ptr
				flags <- obj_int32 ptr
				sdata <- string ptr
				sfd <- obj_int32 ptr
				res <- obj_int32 ptr
			} andCode: :odata :flags {
				sdata <- mcall: string 1 odata
				sfd <- mcall: fd 1 self
				res <- make_object: (addr_of: obj_int32_meta) NULL 0
				res num!: (send: (sfd num) (sdata data) (sdata bytes) (flags num))
				res
			}
			send <- :data {
				send: data withFlags: 0
			}
		}
	}

	llMessage: _connectTo:onPort withVars: {
		host <- string ptr
		port <- string ptr
		hints <- struct: addrinfo
		info <- (struct: addrinfo) ptr
		domain <- obj_int32 ptr
		type <- obj_int32 ptr
		protocol <- obj_int32 ptr
		sock <- object ptr
		sfd <- obj_int32 ptr
	} andCode: :host :port {
		memset: (addr_of: hints) 0 (sizeof: hints)
		hints ai_family!: AF_UNSPEC
		hints ai_socktype!: SOCK_STREAM
		getaddrinfo: (host data) (port data) (addr_of: hints) (addr_of: info)

		domain <- make_object: (addr_of: obj_int32_meta) NULL 0
		domain num!: (info ai_family)
		type <- make_object: (addr_of: obj_int32_meta) NULL 0
		type num!: (info ai_socktype)
		protocol <- make_object: (addr_of: obj_int32_meta) NULL 0
		protocol num!: (info ai_protocol)

		sock <- mcall: new 4 self domain type protocol
		sfd <- mcall: fd 1 sock

		connect: (sfd num) (info ai_addr) (info ai_addrlen)

		freeaddrinfo: info
		sock
	}

	connectTo:onPort <- :host :port {
		_connectTo: host onPort: (string: port)
	}
	listenOn <- :port {
	}
	listenAt:onPort <- :host :port {
	}
}