Compare commits

...

5 Commits

7 changed files with 101 additions and 30 deletions

1
.gitignore vendored
View File

@ -13,3 +13,4 @@ src/*.Lib
.vamosrc .vamosrc
activate activate
test/ test/
patches/

Binary file not shown.

83
API.md
View File

@ -3,7 +3,9 @@
Most functions will return -2 if the bsdsocket.library is Most functions will return -2 if the bsdsocket.library is
not open. not open.
### Setup ---
## Setup
#### ADDR=Socket Library Open #### ADDR=Socket Library Open
@ -16,11 +18,15 @@ Try to open bsdsocket.library version 4.
* If needed, you'll be able to directly access library functions * If needed, you'll be able to directly access library functions
using this address. using this address.
---
#### Socket Library Close #### Socket Library Close
Close bsdsocket.library. This is safe to call if the library Close bsdsocket.library. This is safe to call if the library
is not open is not open
---
#### RESULT=Socket Set Nonblocking(Socket, IsNonblocking BOOL) #### RESULT=Socket Set Nonblocking(Socket, IsNonblocking BOOL)
Make a socket blocking (False, default), or nonblocking (True). Make a socket blocking (False, default), or nonblocking (True).
@ -29,6 +35,8 @@ Make a socket blocking (False, default), or nonblocking (True).
* Result of IoctlSocket call. * Result of IoctlSocket call.
---
#### RESULT=Socket Reuse Addr(Socket) #### RESULT=Socket Reuse Addr(Socket)
Make a listening socket reuse the address it's trying to bind to. Make a listening socket reuse the address it's trying to bind to.
@ -38,9 +46,9 @@ You probably want to call this right before Socket Listen.
* Result of setsockopt call. * Result of setsockopt call.
---
## Connections
### Connections
#### SOCKET=Socket Create Inet Socket #### SOCKET=Socket Create Inet Socket
@ -51,6 +59,8 @@ Create a new Internet socket for reading or writing.
* Socket number on success * Socket number on success
* -1 on failure * -1 on failure
---
#### RESULT=Socket Connect(Socket to IPAddress$, Port) #### RESULT=Socket Connect(Socket to IPAddress$, Port)
Attempt to connect to a remote host. Currently doesn't Attempt to connect to a remote host. Currently doesn't
@ -65,6 +75,8 @@ support DNS lookups.
to see if the connection succeeded to see if the connection succeeded
* -11 port out of range * -11 port out of range
---
#### RESULT=Socket Reuse Addr(Socket) #### RESULT=Socket Reuse Addr(Socket)
Set a server socket to reuse an interface and port that had Set a server socket to reuse an interface and port that had
@ -77,6 +89,8 @@ setsockopt() for you.
The result of calling setsockopt() while setting your socket The result of calling setsockopt() while setting your socket
to reuse addresses. to reuse addresses.
---
#### RESULT=Socket Bind(Socket to IPAddress, Port) #### RESULT=Socket Bind(Socket to IPAddress, Port)
Attempt to bind a socket to a network interface. Use Attempt to bind a socket to a network interface. Use
@ -89,6 +103,8 @@ interfaces.
* -1 on other error * -1 on other error
* -11 port out of range * -11 port out of range
---
#### RESULT=Socket Listen(Socket) #### RESULT=Socket Listen(Socket)
Start listening for connections. Start listening for connections.
@ -98,6 +114,8 @@ Start listening for connections.
* 0 on success * 0 on success
* -1 on failure * -1 on failure
---
#### NEW_SOCKET=Socket Accept(Socket) #### NEW_SOCKET=Socket Accept(Socket)
Get the socket that connected to this one. Wait for a connect Get the socket that connected to this one. Wait for a connect
@ -115,11 +133,13 @@ socket non-blocking and use Fdsets and Select!
* The remote socket number on success * The remote socket number on success
* -1 on failure * -1 on failure
#### RESULT=Socket Async Wait Reading(Socket, Wait_ms) ---
#### RESULT=Socket Wait Async Reading(Socket, Wait_ms)
Wait the given number of milliseconds for the nonblocking socket to be ready for reading. Wait the given number of milliseconds for the nonblocking socket to be ready for reading.
Use this when you're waiting for a client to connect to you, or if you're waiting for Use on a listen socket to await new connections, or on a connected socket to await
a remote socket to send you data. incoming data packets.
##### Returns ##### Returns
@ -127,7 +147,9 @@ a remote socket to send you data.
* -1 on error. Use `Socket Errno` for more detail. * -1 on error. Use `Socket Errno` for more detail.
* 1 on success. * 1 on success.
#### RESULT=Socket Async Wait Writing(Socket, Wait_ms) ---
#### RESULT=Socket Wait Async Writing(Socket, Wait_ms)
Wait the given number of milliseconds for the nonblocking socket to be ready for writing. Wait the given number of milliseconds for the nonblocking socket to be ready for writing.
Use this when you're connecting to a remote server and want to know if the connection Use this when you're connecting to a remote server and want to know if the connection
@ -143,6 +165,8 @@ has been completed.
checks will return 1. checks will return 1.
* 1 on success. * 1 on success.
---
#### RESULT=Socket Set Timeout(Socket, Wait_ms) #### RESULT=Socket Set Timeout(Socket, Wait_ms)
Set a socket to timeout after Wait_ms milliseconds if reading or writing doesn't complete. Set a socket to timeout after Wait_ms milliseconds if reading or writing doesn't complete.
@ -152,6 +176,8 @@ Set a socket to timeout after Wait_ms milliseconds if reading or writing doesn't
* 0 on success * 0 on success
* -1 on error * -1 on error
---
#### RESULT=Socket Close Socket(Socket) #### RESULT=Socket Close Socket(Socket)
Close a socket. Close a socket.
@ -161,9 +187,9 @@ Close a socket.
* 0 on success * 0 on success
* -1 on error * -1 on error
---
## Data Transfers
### Data Transfers
#### SENT=Socket Send$(Socket, String$) #### SENT=Socket Send$(Socket, String$)
@ -194,6 +220,8 @@ End Proc
* Number of characters sent * Number of characters sent
* -1 on other error * -1 on other error
---
#### SENT=Socket Send(Socket, Data Pointer, Length) #### SENT=Socket Send(Socket, Data Pointer, Length)
Send a block of data to a connected socket. Send a block of data to a connected socket.
@ -203,6 +231,8 @@ Send a block of data to a connected socket.
* Number of characters sent * Number of characters sent
* -1 on other error * -1 on other error
---
#### DATA$=Socket Recv$(Socket, MaxLength) #### DATA$=Socket Recv$(Socket, MaxLength)
Retrieve at most MaxLength bytes from Socket, and put them into a string. Retrieve at most MaxLength bytes from Socket, and put them into a string.
@ -212,7 +242,9 @@ If Len(DATA$) < MaxLength, you've read the last bit of data from the socket.
* String of data, which is blank if there is no more data. * String of data, which is blank if there is no more data.
### LENGTH=Socket Recv(Socket to Dataptr, MaxLength) ---
#### LENGTH=Socket Recv(Socket to Dataptr, MaxLength)
Retrieve at most MaxLength bytes from Socket, and put them into the memory Retrieve at most MaxLength bytes from Socket, and put them into the memory
address at Dataptr. address at Dataptr.
@ -222,9 +254,9 @@ address at Dataptr.
* Count of bytes read * Count of bytes read
* -1 on error * -1 on error
---
## Informational
### Informational
#### HOST=Socket Get Host(Socket) #### HOST=Socket Get Host(Socket)
@ -234,6 +266,8 @@ Get the IPv4 (Long) host value the given socket is using.
* Host as a long value * Host as a long value
---
#### PORT=Socket Get Port(Socket) #### PORT=Socket Get Port(Socket)
Get the 16-bit port (Word) value the given socket is using. Get the 16-bit port (Word) value the given socket is using.
@ -242,6 +276,8 @@ Get the 16-bit port (Word) value the given socket is using.
* Port as a word value * Port as a word value
---
#### RESULT$=Socket Inet Ntoa$(Host) #### RESULT$=Socket Inet Ntoa$(Host)
Turn a long Host address into a string. Turn a long Host address into a string.
@ -250,6 +286,8 @@ Turn a long Host address into a string.
* IP address as string * IP address as string
---
#### RESULT=Socket Errno #### RESULT=Socket Errno
Get the error from the last command. Note that this is Get the error from the last command. Note that this is
@ -260,6 +298,8 @@ not cleared on a successful command!
Error number from last call. Look in <sys/error.h> for more Error number from last call. Look in <sys/error.h> for more
details. details.
---
#### RESULT=Socket Herrno #### RESULT=Socket Herrno
Get the error from the last DNS resolver command. Get the error from the last DNS resolver command.
@ -268,6 +308,8 @@ Get the error from the last DNS resolver command.
Resolver error number (`h_errno`) from last call. Resolver error number (`h_errno`) from last call.
---
#### RESULT$=Dns Get Address By Name$(Domain Name$) #### RESULT$=Dns Get Address By Name$(Domain Name$)
Look up the first IP address associated with this hostname. Look up the first IP address associated with this hostname.
@ -282,6 +324,8 @@ out. There's no way to set this timeout, or cancel or override it via AMOS.
String with IP address, or blank string on error. String with IP address, or blank string on error.
---
#### RESULT=Socket Status(Socket) #### RESULT=Socket Status(Socket)
Returns basic connection information about a socket. Returns basic connection information about a socket.
@ -305,9 +349,9 @@ Status of socket:
* 6 = Connecting * 6 = Connecting
* 7 = Connected * 7 = Connected
---
## Low Level
### Low Level
#### RESULT=Socket Setsockopt Int(Socket, Option, Value) #### RESULT=Socket Setsockopt Int(Socket, Option, Value)
@ -319,6 +363,8 @@ Socket Reuse Addr().
* Result of setsockopt call * Result of setsockopt call
---
#### RESULT=Socket Getsockopt Int(Socket, Option) #### RESULT=Socket Getsockopt Int(Socket, Option)
Get a socket option. You probably want SO_ERROR, Get a socket option. You probably want SO_ERROR,
@ -329,6 +375,8 @@ attempt a connection with a non-blocking socket.
* Result of getsockopt call * Result of getsockopt call
---
#### ADDR=Socket Fdset Zero(fd_set) #### ADDR=Socket Fdset Zero(fd_set)
Clear out the specified fd_set. Clear out the specified fd_set.
@ -338,6 +386,8 @@ Clear out the specified fd_set.
* Address to that particular fd_set * Address to that particular fd_set
* -1 if fd_set out of range. You get 16 of them. * -1 if fd_set out of range. You get 16 of them.
---
#### ADDR=Socket Fdset Set(fd_set, Socket to Value BOOL) #### ADDR=Socket Fdset Set(fd_set, Socket to Value BOOL)
Set or clear a socket bit in an fd_set. Set or clear a socket bit in an fd_set.
@ -347,6 +397,8 @@ Set or clear a socket bit in an fd_set.
* Address to that particular fd_set * Address to that particular fd_set
* -1 if fd_set is out of range or socket is out of range. * -1 if fd_set is out of range or socket is out of range.
---
#### RESULT=Socket Fdset Is Set(fd_set, Socket) #### RESULT=Socket Fdset Is Set(fd_set, Socket)
See if the particular socket remained after a Socket Select call. See if the particular socket remained after a Socket Select call.
@ -355,6 +407,8 @@ See if the particular socket remained after a Socket Select call.
* True or False if the socket is set or not * True or False if the socket is set or not
---
#### RESULT=Socket Select(Max Socket, Read fd_set, Write fd_set, Error fd_set, TimeoutMS) #### RESULT=Socket Select(Max Socket, Read fd_set, Write fd_set, Error fd_set, TimeoutMS)
Wait for the specified number of milliseconds. If any of the sockets Wait for the specified number of milliseconds. If any of the sockets
@ -366,4 +420,3 @@ how many sockets were left.
* 0 on timeout * 0 on timeout
* -1 on error * -1 on error
* # of interesting sockets on success

View File

@ -207,6 +207,12 @@ to contact me.
* `Dns Get Address By Name$` * `Dns Get Address By Name$`
* `Socket Recv$` * `Socket Recv$`
### 1.1.3 (2024-04-17)
* Fix bug in fdset macro where using D3 for a parameter could cause corruption
* Copy a null-terminated copy of IP address for SocketIPAddressPortToSockaddr
* Retructure API docs for easier reading
# Development # Development
### Environment ### Environment

View File

@ -7,7 +7,7 @@
; extension number 18 ; extension number 18
ExtNb equ 18-1 ExtNb equ 18-1
Version MACRO Version MACRO
dc.b "1.1.2-20240318" dc.b "1.1.3-20240417"
ENDM ENDM
VerNumber equ $1 VerNumber equ $1
@ -366,14 +366,18 @@ _ToSockaddr_PortOK:
MOVE.L sockaddr_ram-MB(A3),A0 MOVE.L sockaddr_ram-MB(A3),A0
ADD.L D3,A0 ; A0 contains our offset in ram ADD.L D3,A0 ; A0 contains our offset in ram
MOVE.B #len_sockaddr_in,sockaddr_in_sin_len(A0) MOVEM.L A1-A3/D3,-(SP)
MOVE.B #AF_INET,sockaddr_in_sin_family(A0)
MOVE.W D2,sockaddr_in_sin_port(A0)
MOVEM.L A0-A3/D3,-(SP) MOVE.L D1,A1 ; ip string address
MOVE.W (A1)+,D3 ; string length
MOVE.L D1,A0 ; ip address ; temporarily store a null-terminated copy of the ip string in A0
ADDQ #2,A0 ; string data starts 2 bytes in MOVE.L A0,A2
SUBQ #1,D3 ; DBRA loop runs D3 + 1 times
_ToSockaddr_CopyIPString:
MOVE.B (A1)+,(A2)+
DBRA D3,_ToSockaddr_CopyIPString
MOVE.B #0,(A2) ; end of string
; if the string contains "INADDR_ANY", we use that value instead ; if the string contains "INADDR_ANY", we use that value instead
MOVE.L A0,A1 MOVE.L A0,A1
@ -397,8 +401,15 @@ _ToSockaddr_ParseIPAddress:
CALLLIB inet_addr CALLLIB inet_addr
_ToSockaddr_DoneParsing: _ToSockaddr_DoneParsing:
MOVEM.L (SP)+,A0-A3/D3 MOVEM.L (SP)+,A1-A3/D3
MOVE.L D0,sockaddr_in_sin_addr(A0)
; create struct sockaddr_in
MOVE.W #AF_INET,sockaddr_in_sin_family(A0)
MOVE.W D2,sockaddr_in_sin_port(A0)
LEA sockaddr_in_sin_addr(A0),A3
MOVE.L D0,(A3)+
CLR.L (A3)+
CLR.L (A3)+
MOVE.L A0,D0 MOVE.L A0,D0
MOVEM.L (SP)+,A0/A3/D3 MOVEM.L (SP)+,A0/A3/D3

View File

@ -16,8 +16,7 @@ SO_REUSEADDR EQU $4
MAX_SOCKETS EQU 64 MAX_SOCKETS EQU 64
len_sockaddr_in EQU 16 len_sockaddr_in EQU 16
sockaddr_in_sin_len EQU 0 sockaddr_in_sin_family EQU 0
sockaddr_in_sin_family EQU 1
sockaddr_in_sin_port EQU 2 sockaddr_in_sin_port EQU 2
sockaddr_in_sin_addr EQU 4 sockaddr_in_sin_addr EQU 4

View File

@ -30,18 +30,19 @@ LeaFdset MACRO
; LeaFdsetForBit fd_set reg,target address,target bit in address ; LeaFdsetForBit fd_set reg,target address,target bit in address
LeaFdsetForBit MACRO LeaFdsetForBit MACRO
LeaFdset \1,\2 ; get fdset base address in \2 LeaFdset \1,\2 ; get fdset base address in \2
MOVE.L D3,-(SP) MOVEM.L D3-D4,-(SP)
MOVE.L \3,D3 ; Put target bit into D3 MOVE.L \3,D3 ; Put target bit into D3
ROR.L #5,D3 ; lop off the first 5 bits ROR.L #5,D3 ; lop off the first 5 bits
AND.L #$7,D3 ; only keep the top three AND.L #$7,D3 ; only keep the top three
ROL.L #2,D3 ; multiply by 4 ROL.L #2,D3 ; multiply by 4
ADD.L D3,\2 ; add that value to the fdset address ADD.L D3,\2 ; add that value to the fdset address
AND.L #$1F,\3 ; only keep 0-31 in \3 MOVE.L \3,D4
AND.L #$1F,D4 ; only keep 0-31 in \3
MOVEQ #1,D3 MOVEQ #1,D3
ROL.L \3,D3 ; shift that bit left as many as target ROL.L D4,D3 ; shift that bit left as many as target
MOVE.L D3,\3 ; put that in the target MOVE.L D3,\3 ; put that in the target
MOVE.L (SP)+,D3 MOVEM.L (SP)+,D3-D4
ENDM ENDM