Compare commits
29 Commits
jb/rd-patc
...
main
Author | SHA1 | Date |
---|---|---|
John Bintz | d670a1691f | |
John Bintz | 0f4d54ad70 | |
John Bintz | 5c70c42570 | |
John Bintz | 6c216b31e8 | |
John Bintz | 8232bcf6ca | |
John Bintz | 1ee8e2c60c | |
John Bintz | 4b4ec33440 | |
John Bintz | 780a1820f3 | |
John Bintz | ab20c1b1ea | |
John Bintz | 4ba0993483 | |
John Bintz | cf1dff31b9 | |
John Bintz | 79e77287bb | |
John Bintz | f93a33ee0d | |
John Bintz | e041696136 | |
John Bintz | bd6d8a1295 | |
John Bintz | cbb822f895 | |
John Bintz | 6db285d328 | |
John Bintz | 534f04273b | |
John Bintz | 3452973001 | |
John Bintz | 2ba9fd6c82 | |
John Bintz | 12b859eaf3 | |
John Bintz | 8a4235270c | |
John Bintz | 882ee8cba2 | |
John Bintz | e4711f1783 | |
John Bintz | b25f08cdae | |
John Bintz | 771d40fab7 | |
John Bintz | 53c73d8888 | |
John Bintz | fdab7b432e | |
John Bintz | ade45f63b8 |
|
@ -4,12 +4,17 @@ dist/
|
|||
build/
|
||||
aminet/
|
||||
Disk.info
|
||||
private-test/
|
||||
stuff/
|
||||
patches/
|
||||
.vamosrc
|
||||
activate
|
||||
test/report.txt
|
||||
test/TestSuite.info
|
||||
src/report.txt
|
||||
src/BSDSocket_Labels.s
|
||||
src/BSDSocket_Size.s
|
||||
src/bsdsocket_lib.fd
|
||||
src/bsdsocket_lvo.i
|
||||
src/*.Lib
|
||||
.vamosrc
|
||||
activate
|
||||
test/
|
||||
libs/
|
||||
|
|
Binary file not shown.
117
API.md
117
API.md
|
@ -3,7 +3,9 @@
|
|||
Most functions will return -2 if the bsdsocket.library is
|
||||
not open.
|
||||
|
||||
### Setup
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
#### 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
|
||||
using this address.
|
||||
|
||||
---
|
||||
|
||||
#### Socket Library Close
|
||||
|
||||
Close bsdsocket.library. This is safe to call if the library
|
||||
is not open
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Set Nonblocking(Socket, IsNonblocking BOOL)
|
||||
|
||||
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=Socket Reuse Addr(Socket)
|
||||
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### Connections
|
||||
## Connections
|
||||
|
||||
#### SOCKET=Socket Create Inet Socket
|
||||
|
||||
|
@ -51,10 +59,23 @@ Create a new Internet socket for reading or writing.
|
|||
* Socket number on success
|
||||
* -1 on failure
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Connect(Socket to IPAddress$, Port)
|
||||
|
||||
Attempt to connect to a remote host. Currently doesn't
|
||||
support DNS lookups.
|
||||
Attempt to connect to a remote IP address.
|
||||
|
||||
##### Emulation vs. Physical/FPGA Amiga note
|
||||
|
||||
On emulated Amigas (FS-UAE) with emulated `bsdsocket.library`, a failure in
|
||||
`Socket Connect` due to giving the function a bad IP address allows you to reuse
|
||||
the socket. On real or FPGA-based Amiga running real TCP/IP stacks (MiamiDX,
|
||||
Roadshow), the socket will be made unusable and you'll need to
|
||||
`Socket Close Socket` and reopen the socket with whatever parameters necessary.
|
||||
Closing and opening `bsdsocket.library` has the same effect.
|
||||
|
||||
Always close and re-open a socket if you have any `Socket Connect` failure and
|
||||
any non-blocking polling loops time out!
|
||||
|
||||
##### Returns
|
||||
|
||||
|
@ -64,19 +85,24 @@ support DNS lookups.
|
|||
the socket with Socket Select and Socket Getsockopt Int
|
||||
to see if the connection succeeded
|
||||
* -11 port out of range
|
||||
* -13 IP address has zero length
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Reuse Addr(Socket)
|
||||
|
||||
Set a server socket to reuse an interface and port that had
|
||||
been used recently. You likely want this if you're building
|
||||
something that listens on a port for connections. This calls
|
||||
setsockopt() for you.
|
||||
`setsockopt()` for you.
|
||||
|
||||
##### Returns
|
||||
|
||||
The result of calling setsockopt() while setting your socket
|
||||
to reuse addresses.
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Bind(Socket to IPAddress, Port)
|
||||
|
||||
Attempt to bind a socket to a network interface. Use
|
||||
|
@ -89,6 +115,8 @@ interfaces.
|
|||
* -1 on other error
|
||||
* -11 port out of range
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Listen(Socket)
|
||||
|
||||
Start listening for connections.
|
||||
|
@ -98,6 +126,8 @@ Start listening for connections.
|
|||
* 0 on success
|
||||
* -1 on failure
|
||||
|
||||
---
|
||||
|
||||
#### NEW_SOCKET=Socket Accept(Socket)
|
||||
|
||||
Get the socket that connected to this one. Wait for a connect
|
||||
|
@ -115,11 +145,13 @@ socket non-blocking and use Fdsets and Select!
|
|||
* The remote socket number on success
|
||||
* -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.
|
||||
Use this when you're waiting for a client to connect to you, or if you're waiting for
|
||||
a remote socket to send you data.
|
||||
Use on a listen socket to await new connections, or on a connected socket to await
|
||||
incoming data packets.
|
||||
|
||||
##### Returns
|
||||
|
||||
|
@ -127,7 +159,9 @@ a remote socket to send you data.
|
|||
* -1 on error. Use `Socket Errno` for more detail.
|
||||
* 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.
|
||||
Use this when you're connecting to a remote server and want to know if the connection
|
||||
|
@ -143,6 +177,8 @@ has been completed.
|
|||
checks will return 1.
|
||||
* 1 on success.
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Set Timeout(Socket, Wait_ms)
|
||||
|
||||
Set a socket to timeout after Wait_ms milliseconds if reading or writing doesn't complete.
|
||||
|
@ -152,18 +188,21 @@ Set a socket to timeout after Wait_ms milliseconds if reading or writing doesn't
|
|||
* 0 on success
|
||||
* -1 on error
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Close Socket(Socket)
|
||||
|
||||
Close a socket.
|
||||
|
||||
|
||||
##### Returns
|
||||
|
||||
* 0 on success
|
||||
* -1 on error
|
||||
|
||||
---
|
||||
|
||||
|
||||
### Data Transfers
|
||||
## Data Transfers
|
||||
|
||||
#### SENT=Socket Send$(Socket, String$)
|
||||
|
||||
|
@ -194,6 +233,8 @@ End Proc
|
|||
* Number of characters sent
|
||||
* -1 on other error
|
||||
|
||||
---
|
||||
|
||||
#### SENT=Socket Send(Socket, Data Pointer, Length)
|
||||
|
||||
Send a block of data to a connected socket.
|
||||
|
@ -203,6 +244,8 @@ Send a block of data to a connected socket.
|
|||
* Number of characters sent
|
||||
* -1 on other error
|
||||
|
||||
---
|
||||
|
||||
#### DATA$=Socket Recv$(Socket, MaxLength)
|
||||
|
||||
Retrieve at most MaxLength bytes from Socket, and put them into a string.
|
||||
|
@ -212,7 +255,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.
|
||||
|
||||
### 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
|
||||
address at Dataptr.
|
||||
|
@ -222,9 +267,9 @@ address at Dataptr.
|
|||
* Count of bytes read
|
||||
* -1 on error
|
||||
|
||||
---
|
||||
|
||||
|
||||
### Informational
|
||||
## Informational
|
||||
|
||||
#### HOST=Socket Get Host(Socket)
|
||||
|
||||
|
@ -234,6 +279,8 @@ Get the IPv4 (Long) host value the given socket is using.
|
|||
|
||||
* Host as a long value
|
||||
|
||||
---
|
||||
|
||||
#### PORT=Socket Get Port(Socket)
|
||||
|
||||
Get the 16-bit port (Word) value the given socket is using.
|
||||
|
@ -242,6 +289,8 @@ Get the 16-bit port (Word) value the given socket is using.
|
|||
|
||||
* Port as a word value
|
||||
|
||||
---
|
||||
|
||||
#### RESULT$=Socket Inet Ntoa$(Host)
|
||||
|
||||
Turn a long Host address into a string.
|
||||
|
@ -250,6 +299,8 @@ Turn a long Host address into a string.
|
|||
|
||||
* IP address as string
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Errno
|
||||
|
||||
Get the error from the last command. Note that this is
|
||||
|
@ -260,6 +311,8 @@ not cleared on a successful command!
|
|||
Error number from last call. Look in <sys/error.h> for more
|
||||
details.
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Herrno
|
||||
|
||||
Get the error from the last DNS resolver command.
|
||||
|
@ -268,6 +321,8 @@ Get the error from the last DNS resolver command.
|
|||
|
||||
Resolver error number (`h_errno`) from last call.
|
||||
|
||||
---
|
||||
|
||||
#### RESULT$=Dns Get Address By Name$(Domain Name$)
|
||||
|
||||
Look up the first IP address associated with this hostname.
|
||||
|
@ -282,32 +337,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.
|
||||
|
||||
#### RESULT=Socket Status(Socket)
|
||||
|
||||
Returns basic connection information about a socket.
|
||||
|
||||
##### Warning
|
||||
|
||||
Since none of the socket processing of this extension happens in the
|
||||
background, you're likely better off using other means to detect
|
||||
socket status.
|
||||
|
||||
* Disconnected: Try a recv and get zero bytes back. Check Socket Errno.
|
||||
* Broken: Try a send. If it fails, check Socket Errno.
|
||||
* Ready: Use the Async Wait functions.
|
||||
|
||||
##### Returns
|
||||
|
||||
Status of socket:
|
||||
|
||||
* 0 = Closed
|
||||
* 2 = Listening
|
||||
* 6 = Connecting
|
||||
* 7 = Connected
|
||||
|
||||
|
||||
|
||||
### Low Level
|
||||
## Low Level
|
||||
|
||||
#### RESULT=Socket Setsockopt Int(Socket, Option, Value)
|
||||
|
||||
|
@ -319,6 +350,8 @@ Socket Reuse Addr().
|
|||
|
||||
* Result of setsockopt call
|
||||
|
||||
---
|
||||
|
||||
#### RESULT=Socket Getsockopt Int(Socket, Option)
|
||||
|
||||
Get a socket option. You probably want SO_ERROR,
|
||||
|
@ -329,6 +362,8 @@ attempt a connection with a non-blocking socket.
|
|||
|
||||
* Result of getsockopt call
|
||||
|
||||
---
|
||||
|
||||
#### ADDR=Socket Fdset Zero(fd_set)
|
||||
|
||||
Clear out the specified fd_set.
|
||||
|
@ -338,6 +373,8 @@ Clear out the specified fd_set.
|
|||
* Address to that particular fd_set
|
||||
* -1 if fd_set out of range. You get 16 of them.
|
||||
|
||||
---
|
||||
|
||||
#### ADDR=Socket Fdset Set(fd_set, Socket to Value BOOL)
|
||||
|
||||
Set or clear a socket bit in an fd_set.
|
||||
|
|
50
README.md
50
README.md
|
@ -130,6 +130,7 @@ Socket Library Close
|
|||
* [Hop to the Top: Bunny's Revenge](https://rabbit.robsmithdev.co.uk/)
|
||||
* The game uses this extension to send and receive high score information.
|
||||
I also did some of the art for the game!
|
||||
* [Gopherized](https://allanon71.itch.io/gopherized)
|
||||
|
||||
Doing something cool with the extension?
|
||||
[Contact me](https://theindustriousrabbit.com/about) and I'll add it to the list!
|
||||
|
@ -152,6 +153,16 @@ Doing something cool with the extension?
|
|||
timeouts using `Socket Async Wait Writing` to determine if the Internet
|
||||
is available.
|
||||
|
||||
## Slot 18 taken already?
|
||||
|
||||
I'm also building releases for slots 9, 11, and 17. They're available for
|
||||
separate download from each Release version 1.1.4 and on.
|
||||
|
||||
Note that you won't be able to load the test AMOS programs, or any other
|
||||
progaam using the Slot 18 version, because AMOS uses the extension's slot
|
||||
number in the saved tile. You'll have to export and import ASCII versions
|
||||
of programs.
|
||||
|
||||
## Versioning
|
||||
|
||||
This project uses semantic versioning.
|
||||
|
@ -168,10 +179,12 @@ throw a link to theindustriousrabbit.com somewhere! You can
|
|||
also find a donate link on
|
||||
[the About section on The Industrious Rabbit](https://theindustriousrabbit.com/about).
|
||||
|
||||
## Feedback? Bug reports?
|
||||
## Feedback? Bug reports? Patches?
|
||||
|
||||
Go to the [About section on The Industrious Rabbit](https://theindustriousrabbit.com/about)
|
||||
to contact me.
|
||||
First, run `test/TestSuite` to generate a `report.txt` file.
|
||||
|
||||
Then, go to the [About section on The Industrious Rabbit](https://theindustriousrabbit.com/about)
|
||||
to contact me, send the `report.txt` along with the details on your issue.
|
||||
|
||||
## Changelog
|
||||
|
||||
|
@ -207,7 +220,20 @@ to contact me.
|
|||
* `Dns Get Address By Name$`
|
||||
* `Socket Recv$`
|
||||
|
||||
# Development
|
||||
### 1.1.3
|
||||
|
||||
Internal release.
|
||||
|
||||
### 1.1.4 (2024-05-02)
|
||||
|
||||
* Fix bug in fdset macro where using D3 for a parameter could cause corruption.
|
||||
* Copy a null-terminated copy of IP address for `SocketIPAddressPortToSockaddr`.
|
||||
* Add test suite to exercise extension functionality.
|
||||
* Fix several crash bugs found due to the test suite.
|
||||
* Retructure API docs for easier reading.
|
||||
* Improve build and release tooling.
|
||||
|
||||
## Development
|
||||
|
||||
### Environment
|
||||
|
||||
|
@ -239,9 +265,25 @@ Run `bin/setup` to do most of the setups above.
|
|||
|
||||
### Debugging
|
||||
|
||||
#### Cross-platform
|
||||
|
||||
Modify data in the `DebugArea` and read it by `Peek`/`Deek`/`Leek`ing from
|
||||
the base address provided by `Socket Get Debug Area`.
|
||||
|
||||
#### WinUAE/FS-UAE
|
||||
|
||||
In the debugger, set a memory breakpoint at `$100` for two written bytes:
|
||||
|
||||
```
|
||||
w 0 100 2
|
||||
```
|
||||
|
||||
Then, in your code, clear those two bytes to stop execution at that point:
|
||||
|
||||
```asm
|
||||
CLR.W $100
|
||||
```
|
||||
|
||||
### Releasing
|
||||
|
||||
#### Ubuntu/Debian
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
for i in examples/*.amos; do
|
||||
for i in examples/*.amos test/*.amos; do
|
||||
echo "$i"
|
||||
~/Projects/amostools/listamos -e AMOSPro_BSDSocket.Lib "${i}" > "${i%.amos}.basic" 2>/dev/null
|
||||
~/Projects/amostools/listamos -e src/AMOSPro_BSDSocket.Lib "${i}" > "${i%.amos}.basic" 2>/dev/null
|
||||
done
|
||||
|
|
18
bin/release
18
bin/release
|
@ -24,6 +24,22 @@ source.lines.each do |line|
|
|||
end
|
||||
end
|
||||
|
||||
FileUtils.cp 'src/AMOSPro_BSDSocket.Lib', 'AMOSPro_BSDSocket.Lib'
|
||||
|
||||
strings = []
|
||||
Open3.popen2e('strings', 'AMOSPro_BSDSocket.Lib') do |stdin, stdout_and_stderr, wait_thr|
|
||||
stdin.close
|
||||
|
||||
stdout_and_stderr.each { |l| strings << l }
|
||||
|
||||
wait_thr.join
|
||||
end
|
||||
|
||||
unless strings.any? { |s| s[version] }
|
||||
puts "Extension build doesn't match source version! Did you rebuild it yet on the Amiga?"
|
||||
exit 1
|
||||
end
|
||||
|
||||
FileUtils.mkdir_p 'dist'
|
||||
|
||||
build_base = 'build'
|
||||
|
@ -35,8 +51,6 @@ FileUtils.rm_rf 'aminet'
|
|||
FileUtils.mkdir_p build_dir
|
||||
FileUtils.mkdir_p 'aminet'
|
||||
|
||||
FileUtils.mv 'src/AMOSPro_BSDSocket.Lib', 'AMOSPro_BSDSocket.Lib' if File.exist?('src/AMOSPro_BSDSocket.Lib')
|
||||
|
||||
hackerbun_target = File.expand_path("dist/AMOSPro_BSDSocket_#{version}.lha")
|
||||
|
||||
[
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
; get the effective address of something in extension memory
|
||||
Dlea MACRO
|
||||
MOVE.L ExtAdr+ExtNb*16(A5),\2
|
||||
ADD.W #\1-MB,\2
|
||||
ENDM
|
||||
|
||||
; load the base of extension memory into a register
|
||||
Dload MACRO
|
||||
MOVE.L ExtAdr+ExtNb*16(A5),\1
|
||||
ENDM
|
||||
|
||||
; wrap code that doesn't take arguments with these
|
||||
PreserveStackInstruction MACRO
|
||||
MOVEM.L A2-A6/D6-D7,-(SP)
|
||||
ENDM
|
||||
RestoreStackInstruction MACRO
|
||||
MOVEM.L (SP)+,A2-A6/D6-D7
|
||||
ENDM
|
||||
|
||||
; wrap code that takes arguments with these
|
||||
PreserveStackFunction MACRO
|
||||
MOVEM.L A2/A4-A6/D6-D7,-(SP)
|
||||
ENDM
|
||||
RestoreStackFunction MACRO
|
||||
MOVEM.L (SP)+,A2/A4-A6/D6-D7
|
||||
ENDM
|
||||
|
||||
; Push and pop the extension's data storage into A3
|
||||
WithDataStorageToA3 MACRO
|
||||
MOVE.L A3,-(SP)
|
||||
Dload A3
|
||||
ENDM
|
||||
EndDataStorage MACRO
|
||||
MOVE.L (SP)+,A3
|
||||
ENDM
|
||||
|
||||
EvenOutStringAddress MACRO
|
||||
MOVE.W \1,\2
|
||||
AND.W #$0001,\2
|
||||
ADD.W \2,\1
|
||||
ENDM
|
||||
|
408
src/BSDSocket.s
408
src/BSDSocket.s
|
@ -5,9 +5,10 @@
|
|||
; Writing this code the right way, 25 years later.
|
||||
|
||||
; extension number 18
|
||||
ExtNb equ 18-1
|
||||
; this now comes from GenAm command line option
|
||||
;ExtNb equ 18-1
|
||||
Version MACRO
|
||||
dc.b "1.1.2-20240318"
|
||||
dc.b "1.1.4-20240502"
|
||||
ENDM
|
||||
VerNumber equ $1
|
||||
|
||||
|
@ -22,23 +23,190 @@ VerNumber equ $1
|
|||
Include "+AMOS_Includes.s"
|
||||
Include "bsdsocket_lvo.i"
|
||||
|
||||
Include "LongDivide.s"
|
||||
Include "Constants.s"
|
||||
Include "fd_set.s"
|
||||
Include "AMOSMacros.s"
|
||||
; get the effective address of something in extension memory
|
||||
Dlea MACRO
|
||||
MOVE.L ExtAdr+ExtNb*16(A5),\2
|
||||
ADD.W #\1-MB,\2
|
||||
ENDM
|
||||
|
||||
; load the base of extension memory into a register
|
||||
Dload MACRO
|
||||
MOVE.L ExtAdr+ExtNb*16(A5),\1
|
||||
ENDM
|
||||
|
||||
; call an AmigaOS function via LVO(A6)
|
||||
CALLLIB MACRO
|
||||
JSR _LVO\1(A6)
|
||||
ENDM
|
||||
|
||||
; bsdsocket library stuff
|
||||
; ported from the various C include headers
|
||||
SOCK_STREAM EQU 1
|
||||
PF_INET EQU 2
|
||||
AF_INET EQU PF_INET
|
||||
IPPROTO_TCP EQU 6
|
||||
|
||||
; get the BSDSocket library ready for CALLLIB
|
||||
LoadBSDSocketBaseFromA3 MACRO
|
||||
INADDR_ANY EQU 0
|
||||
|
||||
FIONBIO EQU $8004667E
|
||||
FIONASYNC EQU $8004667D
|
||||
|
||||
SOL_SOCKET EQU $FFFF
|
||||
SO_REUSEADDR EQU $4
|
||||
|
||||
MAX_SOCKETS EQU 64
|
||||
|
||||
len_sockaddr_in EQU 16
|
||||
sockaddr_in_sin_family EQU 1
|
||||
sockaddr_in_sin_port EQU 2
|
||||
sockaddr_in_sin_addr EQU 4
|
||||
|
||||
; global errors
|
||||
Error_OtherError EQU -1
|
||||
Error_LibraryNotOpen EQU -2
|
||||
Error_PortOutOfRange EQU -11
|
||||
Error_FdsetOutOfRange EQU -11
|
||||
Error_UnableToBind EQU -12
|
||||
|
||||
; socket herrno and tag lists
|
||||
; built from:
|
||||
; * https://wiki.amigaos.net/amiga/autodocs/bsdsocket.doc.txt
|
||||
; * https://github.com/deplinenoise/amiga-sdk/blob/master/netinclude/amitcp/socketbasetags.h
|
||||
; * http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_2._guide/node012E.html
|
||||
|
||||
TAG_USER EQU (1<<31)
|
||||
SBTF_REF EQU $8000
|
||||
SBTB_CODE EQU 1
|
||||
SBTS_CODE EQU $3FFF
|
||||
SBTC_HERRNO EQU 6
|
||||
|
||||
HerrnoTag EQU (TAG_USER|SBTF_REF|((SBTC_HERRNO&SBTS_CODE)<<SBTB_CODE))
|
||||
|
||||
; wrap code that doesn't take arguments with these
|
||||
PreserveStackInstruction MACRO
|
||||
MOVEM.L A2-A6/D6-D7,-(SP)
|
||||
ENDM
|
||||
RestoreStackInstruction MACRO
|
||||
MOVEM.L (SP)+,A2-A6/D6-D7
|
||||
ENDM
|
||||
|
||||
; wrap code that takes arguments with these
|
||||
PreserveStackFunction MACRO
|
||||
MOVEM.L A2/A4-A6/D6-D7,-(SP)
|
||||
ENDM
|
||||
RestoreStackFunction MACRO
|
||||
MOVEM.L (SP)+,A2/A4-A6/D6-D7
|
||||
ENDM
|
||||
|
||||
LoadBSDSocketBase MACRO
|
||||
MOVE.L BSDSocketBase-MB(A3),A6
|
||||
ENDM
|
||||
|
||||
WithDataStorage MACRO
|
||||
MOVE.L A3,-(SP)
|
||||
Dload A3
|
||||
ENDM
|
||||
|
||||
EndDataStorage MACRO
|
||||
MOVE.L (SP)+,A3
|
||||
ENDM
|
||||
|
||||
; fdset macros
|
||||
EnsureValidFdset MACRO
|
||||
CMP.L #MaxFd_sets,\1
|
||||
BLT \2
|
||||
|
||||
MOVE.L #Error_FdsetOutOfRange,D3
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
ENDM
|
||||
|
||||
EnsureValidFdsetBit MACRO
|
||||
CMP.L #64,\1
|
||||
BGE _EnsureValidFdsetBit_Fail\@
|
||||
BRA \2
|
||||
_EnsureValidFdsetBit_Fail\@:
|
||||
MOVE.L \3,D3
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
ENDM
|
||||
|
||||
LeaFdset MACRO
|
||||
MOVE.L \1,-(SP)
|
||||
Dlea fd_sets,\2 ; base of all, these are longs
|
||||
ROL.L #3,\1 ; multiply by 8
|
||||
ADD.L \1,\2 ; add to base of all
|
||||
MOVE.L (SP)+,\1
|
||||
ENDM
|
||||
|
||||
; LeaFdsetForBit fd_set reg,target address,target bit in address
|
||||
LeaFdsetForBit MACRO
|
||||
LeaFdset \1,\2 ; get fdset base address in \2
|
||||
MOVEM.L D3-D4,-(SP)
|
||||
MOVE.L \3,D3 ; Put target bit into D3
|
||||
ROR.L #5,D3 ; lop off the first 5 bits
|
||||
AND.L #$7,D3 ; only keep the top three
|
||||
ROL.L #2,D3 ; multiply by 4
|
||||
ADD.L D3,\2 ; add that value to the fdset address
|
||||
|
||||
MOVE.L \3,D4
|
||||
AND.L #$1F,D4 ; only keep 0-31 in \3
|
||||
|
||||
MOVEQ #1,D3
|
||||
ROL.L D4,D3 ; shift that bit left as many as target
|
||||
MOVE.L D3,\3 ; put that in the target
|
||||
MOVEM.L (SP)+,D3-D4
|
||||
|
||||
ENDM
|
||||
|
||||
; d0 = value to be divided
|
||||
; d1 = divisor
|
||||
; returns:
|
||||
; d0 = divided value
|
||||
; d1 = remainder
|
||||
LongDivideD0ByD1 MACRO
|
||||
CMP.L D0,D1
|
||||
BMI _LongDivide_StartDivide\@
|
||||
|
||||
MOVE.L D0,D1
|
||||
MOVEQ #0,D0
|
||||
BRA _LongDivide_Skip\@
|
||||
|
||||
_LongDivide_StartDivide\@:
|
||||
|
||||
MOVEM.L D2-D4,-(SP)
|
||||
MOVEQ #0,D2 ; remainder
|
||||
MOVE.L #31,D3 ; bit tracking
|
||||
; d4 tracks the status register
|
||||
|
||||
_LongDivide_ContinueDivide\@:
|
||||
ASL.L #1,D0
|
||||
SCS D4 ; bit that got rolled out
|
||||
AND.L #1,D4
|
||||
ROL.L #1,D2
|
||||
ADD.L D4,D2 ; roll the value onto the remainder
|
||||
|
||||
MOVE.L D2,D4
|
||||
SUB.L D1,D4
|
||||
|
||||
BMI _LongDivide_NotDivisible\@
|
||||
ADDQ #1,D0
|
||||
MOVE.L D4,D2
|
||||
|
||||
_LongDivide_NotDivisible\@:
|
||||
DBRA D3,_LongDivide_ContinueDivide\@
|
||||
MOVE.L D2,D1
|
||||
MOVEM.L (SP)+,D2-D4
|
||||
|
||||
_LongDivide_Skip\@:
|
||||
ENDM
|
||||
|
||||
EvenOutStringAddress MACRO
|
||||
MOVE.W \1,\2
|
||||
AND.W #$0001,\2
|
||||
ADD.W \2,\1
|
||||
ENDM
|
||||
|
||||
; check if we've opened the bsd socket library
|
||||
; we do this a lot, this could probably become something
|
||||
; we jsr to...
|
||||
|
@ -290,16 +458,16 @@ End
|
|||
CALLLIB OpenLibrary
|
||||
|
||||
MOVE.L D0,BSDSocketBase-MB(A3)
|
||||
BEQ .Finish
|
||||
BEQ _SocketLibraryOpen_Finish
|
||||
|
||||
; reserve ram for sockaddr_ins
|
||||
MOVE.L #MAX_SOCKETS*len_sockaddr_in,D0
|
||||
Rjsr L_RamFast
|
||||
BEQ .Finish
|
||||
BEQ _SocketLibraryOpen_Finish
|
||||
|
||||
MOVE.L D0,sockaddr_ram-MB(A3)
|
||||
|
||||
.Finish:
|
||||
_SocketLibraryOpen_Finish:
|
||||
MOVE.L BSDSocketBase-MB(A3),D3
|
||||
|
||||
RestoreStackInstruction
|
||||
|
@ -345,7 +513,7 @@ End
|
|||
;
|
||||
; Turn an IP address and port into a sockaddr_in strucure
|
||||
;
|
||||
; d0 - 0 on success, -1 on failure
|
||||
; d0 - address of sockaddr_in on success, -1 on failure
|
||||
; - - - - - - - -
|
||||
Lib_Def SocketIPAddressPortToSockaddr
|
||||
|
||||
|
@ -366,14 +534,26 @@ _ToSockaddr_PortOK:
|
|||
MOVE.L sockaddr_ram-MB(A3),A0
|
||||
ADD.L D3,A0 ; A0 contains our offset in ram
|
||||
|
||||
MOVE.B #len_sockaddr_in,sockaddr_in_sin_len(A0)
|
||||
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
|
||||
ADDQ #2,A0 ; string data starts 2 bytes in
|
||||
BNE _ToSockaddr_StringHasLength
|
||||
MOVEM.L (SP)+,A0-A3/D3
|
||||
MOVEM.L (SP)+,A0/A3/D3
|
||||
|
||||
MOVE.L #-14,D0
|
||||
RTS
|
||||
|
||||
_ToSockaddr_StringHasLength:
|
||||
|
||||
; temporarily store a null-terminated copy of the ip string in A0
|
||||
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
|
||||
MOVE.L A0,A1
|
||||
|
@ -393,12 +573,20 @@ _ToSockaddr_KeepCheckingString_2:
|
|||
|
||||
_ToSockaddr_ParseIPAddress:
|
||||
Dload A3
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB inet_addr
|
||||
|
||||
_ToSockaddr_DoneParsing:
|
||||
MOVEM.L (SP)+,A0-A3/D3
|
||||
MOVE.L D0,sockaddr_in_sin_addr(A0)
|
||||
|
||||
; create struct sockaddr_in
|
||||
MOVE.B #len_sockaddr_in,(A0)
|
||||
MOVE.B #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
|
||||
MOVEM.L (SP)+,A0/A3/D3
|
||||
|
@ -429,7 +617,7 @@ _SocketCreateInetSocket_LibraryOpen:
|
|||
MOVE.L #SOCK_STREAM,D1
|
||||
MOVE.L #IPPROTO_TCP,D2
|
||||
Dload A3
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB socket
|
||||
|
||||
MOVE.L D0,D3
|
||||
|
@ -478,7 +666,6 @@ _SocketCreateInetSocket_Done:
|
|||
Ret_Int
|
||||
|
||||
_SocketConnect_LibraryOpen:
|
||||
|
||||
MOVE.L D0,-(SP) ; socket id onto stack
|
||||
|
||||
Rbsr L_SocketIPAddressPortToSockaddr
|
||||
|
@ -502,7 +689,7 @@ _SocketConnect_SockaddrIn:
|
|||
; socket id is in D0
|
||||
; sockaddr_in is in A0
|
||||
MOVE.L #len_sockaddr_in,D1 ; len
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB connect
|
||||
MOVEM.L (SP)+,A0/A3
|
||||
|
||||
|
@ -538,8 +725,8 @@ _SocketConnect_SockaddrIn:
|
|||
_SocketSendString_LibraryOpen:
|
||||
MOVEQ #0,D2 ; flags
|
||||
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB send
|
||||
EndDataStorage
|
||||
|
||||
|
@ -584,8 +771,8 @@ _SocketSendData_LibraryOpen:
|
|||
_SocketSendData_NotNegative:
|
||||
MOVEQ #0,D2 ; flags
|
||||
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB send
|
||||
EndDataStorage
|
||||
|
||||
|
@ -635,11 +822,11 @@ _SocketBind_SockaddrIn:
|
|||
MOVE.L D0,A0
|
||||
MOVE.L (SP)+,D0
|
||||
|
||||
WithDataStorageToA3
|
||||
WithDataStorage
|
||||
; socket id is in D0
|
||||
; sockaddr_in is in A0
|
||||
MOVE.L #len_sockaddr_in,D1 ; len
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB bind
|
||||
EndDataStorage
|
||||
|
||||
|
@ -658,22 +845,22 @@ _SocketBind_SockaddrIn:
|
|||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Lib_Par SocketErrno
|
||||
; - - - - - - - - - - - - -
|
||||
PreserveStackInstruction
|
||||
PreserveStackFunction
|
||||
|
||||
EnsureBSDSocketLibrary _SocketErrno_LibraryOpen
|
||||
|
||||
RestoreStackInstruction
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
|
||||
_SocketErrno_LibraryOpen:
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB Errno
|
||||
EndDataStorage
|
||||
|
||||
MOVE.L D0,D3
|
||||
|
||||
RestoreStackInstruction
|
||||
RestoreStackFunction
|
||||
RTS
|
||||
|
||||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -701,8 +888,8 @@ _SocketListen_LibraryOpen:
|
|||
MOVE.L D3,D2
|
||||
MOVEQ #5,D1
|
||||
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB listen
|
||||
EndDataStorage
|
||||
|
||||
|
@ -737,10 +924,10 @@ _SocketAccept_LibraryOpen:
|
|||
|
||||
MOVE.L D3,D2
|
||||
|
||||
WithDataStorageToA3
|
||||
WithDataStorage
|
||||
Dlea AcceptScratchArea,A0
|
||||
Dlea len_sockaddr_in_ptr,A1
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB accept
|
||||
EndDataStorage
|
||||
|
||||
|
@ -803,11 +990,11 @@ _SocketSetNonblocking_IsBlocking:
|
|||
|
||||
_SocketSetNonblocking_Ioctl:
|
||||
|
||||
WithDataStorageToA3
|
||||
WithDataStorage
|
||||
MOVE.L D1,IoctlSockOptScratch-MB(A3)
|
||||
Dlea IoctlSockOptScratch,A0
|
||||
MOVE.L #FIONBIO,D1
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB IoctlSocket
|
||||
|
||||
MOVE.L D0,D3
|
||||
|
@ -865,12 +1052,12 @@ _SocketGetsockoptInt_LibraryOpen:
|
|||
MOVE.L #SOL_SOCKET,D1 ; level
|
||||
|
||||
MOVE.L A3,-(SP)
|
||||
WithDataStorageToA3
|
||||
WithDataStorage
|
||||
Dlea IoctlSockOptScratch,A0 ; optval
|
||||
MOVE.L #4,getsockopt_len-MB(A3)
|
||||
Dlea getsockopt_len,A1
|
||||
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB getsockopt
|
||||
EndDataStorage
|
||||
MOVE.L (SP)+,A3
|
||||
|
@ -1144,6 +1331,12 @@ _SocketSelect_PerformSelect
|
|||
; - - - - - - - - - - - - -
|
||||
PreserveStackFunction
|
||||
|
||||
EnsureBSDSocketLibrary _SocketGetHost_LibraryOpen
|
||||
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
|
||||
_SocketGetHost_LibraryOpen:
|
||||
MULU #len_sockaddr_in,D3
|
||||
Dload A0
|
||||
MOVE.L sockaddr_ram-MB(A0),A0
|
||||
|
@ -1164,6 +1357,13 @@ _SocketSelect_PerformSelect
|
|||
; - - - - - - - - - - - - -
|
||||
PreserveStackFunction
|
||||
|
||||
EnsureBSDSocketLibrary _SocketGetPort_LibraryOpen
|
||||
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
|
||||
_SocketGetPort_LibraryOpen:
|
||||
|
||||
MULU #len_sockaddr_in,D3
|
||||
Dload A0
|
||||
MOVE.L sockaddr_ram-MB(A0),A0
|
||||
|
@ -1184,15 +1384,17 @@ _SocketSelect_PerformSelect
|
|||
Lib_Par SocketInetNtoA
|
||||
; - - - - - - - - - - - - -
|
||||
PreserveStackFunction
|
||||
EnsureBSDSocketLibrary _SocketInetNtoA_LibraryOpen
|
||||
EnsureBSDSocketLibrary _SocketInetNtoa_LibraryOpen
|
||||
|
||||
MOVE.L ChVide(A5),D3
|
||||
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
Ret_String
|
||||
|
||||
_SocketInetNtoA_LibraryOpen:
|
||||
_SocketInetNtoa_LibraryOpen:
|
||||
MOVE.L D3,D0
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB Inet_NtoA
|
||||
EndDataStorage
|
||||
|
||||
|
@ -1222,6 +1424,7 @@ _SocketInetNtoA_StringSizeLoop:
|
|||
|
||||
MOVE.W D4,(A0)+ ; length of string
|
||||
SUBQ #1,D4
|
||||
|
||||
_SocketInetNtoA_StringCopyLoop:
|
||||
MOVE.B (A2,D4),(A0,D4)
|
||||
DBRA D4,_SocketInetNtoA_StringCopyLoop
|
||||
|
@ -1272,12 +1475,14 @@ _SocketRecvString_NotNegative:
|
|||
|
||||
_SocketRecvString_NotTooLong:
|
||||
MOVE.L A3,-(SP) ; preserve A3
|
||||
|
||||
MOVE.L D0,-(SP) ; preserve D0
|
||||
; reserve memory for recv buffer
|
||||
Rjsr L_RamFast ; D0 now contains memory pointer
|
||||
BNE _SocketRecvString_BufferAllocated
|
||||
; reserve failed
|
||||
MOVE.L (SP)+,D0
|
||||
|
||||
MOVE.L (SP)+,A3
|
||||
|
||||
MOVE.L ChVide(A5),D3 ; empty string
|
||||
|
@ -1291,10 +1496,12 @@ _SocketRecvString_BufferAllocated:
|
|||
MOVEQ #0,D2 ; flags
|
||||
|
||||
MOVEM.L A0-A1/D1,-(SP)
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB recv ; D0 has received length or -1
|
||||
EndDataStorage
|
||||
|
||||
MOVEM.L (SP)+,A0-A1/D1
|
||||
|
||||
; did we receive data? if we didn't get a single byte, we're done
|
||||
|
@ -1305,6 +1512,7 @@ _SocketRecvString_BufferAllocated:
|
|||
MOVE.L D1,D0
|
||||
MOVE.L A0,A1
|
||||
Rjsr L_RamFree
|
||||
|
||||
MOVE.L (SP)+,A3
|
||||
|
||||
MOVE.L ChVide(A5),D3
|
||||
|
@ -1312,7 +1520,6 @@ _SocketRecvString_BufferAllocated:
|
|||
Ret_String
|
||||
|
||||
; TODO received data is wrong somewhere
|
||||
|
||||
_SocketRecvString_DataReceived:
|
||||
; D0 contains socket receive length
|
||||
|
||||
|
@ -1344,7 +1551,7 @@ _SocketRecvString_CopyData:
|
|||
MOVE.L A0,-(SP)
|
||||
MOVE.L A3,A1
|
||||
Rjsr L_RamFree
|
||||
MOVE.L (SP)+,D3
|
||||
MOVE.L (SP)+,D3 ; string return
|
||||
MOVE.L (SP)+,A3
|
||||
|
||||
RestoreStackFunction
|
||||
|
@ -1383,8 +1590,8 @@ _SocketRecvData_LibraryOpen:
|
|||
Ret_Int
|
||||
|
||||
_SocketRecvData_PositiveLength:
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB recv ; D0 has received length or -1
|
||||
EndDataStorage
|
||||
|
||||
|
@ -1393,6 +1600,8 @@ _SocketRecvData_PositiveLength:
|
|||
RestoreStackFunction
|
||||
Ret_Int
|
||||
|
||||
|
||||
|
||||
; actually close the library
|
||||
|
||||
Lib_Def DoSocketLibraryClose
|
||||
|
@ -1407,6 +1616,7 @@ _SocketRecvData_PositiveLength:
|
|||
CLR.L sockaddr_ram-MB(A3) ; prevent double free
|
||||
|
||||
_DoSocketLibraryClose_CloseLibrary:
|
||||
|
||||
MOVE.L BSDSocketBase-MB(A3),D0
|
||||
|
||||
BEQ _DoSocketLibraryClose_Skip
|
||||
|
@ -1463,7 +1673,7 @@ _SocketWaitAsyncWriting_LibraryOpen:
|
|||
Rbsr L_MicrosecondsToTimeval ; A3 contains timeval
|
||||
|
||||
Dload A4
|
||||
MOVE.L D0,-(SP)
|
||||
MOVEM.L D0,-(SP)
|
||||
; set up WaitSelect
|
||||
MOVEQ #0,D1
|
||||
LeaFdset D1,A1 ; write fdset
|
||||
|
@ -1485,7 +1695,7 @@ _SocketWaitAsyncWriting_LibraryOpen:
|
|||
TST.L D0
|
||||
BEQ _SocketWaitAsyncWriting_Timeout
|
||||
BMI _SocketWaitAsyncWriting_Error
|
||||
MOVE.L (SP)+,D0 ; D0 contains socket again
|
||||
MOVEM.L (SP)+,D0 ; D0 contains socket again
|
||||
|
||||
Dload A4
|
||||
; a socket became interesting, check the Fdset
|
||||
|
@ -1511,19 +1721,19 @@ _SocketWaitAsyncWriting_CheckSockopt:
|
|||
|
||||
MOVE.L A3,-(SP)
|
||||
|
||||
WithDataStorageToA3
|
||||
WithDataStorage
|
||||
Dlea IoctlSockOptScratch,A0 ; optval
|
||||
MOVE.L #4,getsockopt_len-MB(A3)
|
||||
Dlea getsockopt_len,A1
|
||||
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB getsockopt
|
||||
EndDataStorage
|
||||
|
||||
MOVE.L (SP)+,A3
|
||||
|
||||
TST.L D0
|
||||
BMI _SocketWaitAsyncWriting_Error
|
||||
BMI _SocketWaitAsyncWriting_Error2
|
||||
|
||||
Dlea IoctlSockOptScratch,A0
|
||||
MOVE.L (A0),D0
|
||||
|
@ -1545,6 +1755,7 @@ _SocketWaitAsyncWriting_Ready:
|
|||
|
||||
_SocketWaitAsyncWriting_Error:
|
||||
MOVE.L (SP)+,D1
|
||||
_SocketWaitAsyncWriting_Error2:
|
||||
MOVEM.L (SP)+,A3-A4
|
||||
|
||||
MOVE.L #-1,D3
|
||||
|
@ -1626,7 +1837,6 @@ _SocketWaitAsyncReading_LibraryOpen:
|
|||
BMI _SocketWaitAsyncReading_Done
|
||||
MOVE.L (SP)+,D0 ; D0 contains socket again
|
||||
|
||||
;Dload A4
|
||||
; a socket became interesting, check the Fdset
|
||||
MOVE.L D0,D3 ; socket in D3
|
||||
MOVEQ #0,D1 ; fdset in D1
|
||||
|
@ -1721,12 +1931,12 @@ _SocketReuseAddr_LibraryOpen:
|
|||
|
||||
MOVE.L #SOL_SOCKET,D1 ; Level
|
||||
|
||||
WithDataStorageToA3
|
||||
WithDataStorage
|
||||
Dlea IoctlSockOptScratch,A0 ; optval
|
||||
MOVE.L D3,A0
|
||||
MOVEQ #4,D3
|
||||
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB setsockopt
|
||||
EndDataStorage
|
||||
|
||||
|
@ -1737,44 +1947,46 @@ _SocketReuseAddr_LibraryOpen:
|
|||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
; =Dns Get Address By Name$(Name String)
|
||||
;
|
||||
; Get the status of a socket
|
||||
; Convert a host name to an IP address
|
||||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Lib_Par DnsGetHostAddressByName
|
||||
|
||||
PreserveStackFunction
|
||||
EnsureBSDSocketLibrary .LibraryOpen
|
||||
EnsureBSDSocketLibrary _DnsGetHostAddressByName_LibraryOpen
|
||||
|
||||
MOVE.L ChVide(A5),D3
|
||||
|
||||
RestoreStackFunction
|
||||
Ret_String
|
||||
|
||||
.LibraryOpen:
|
||||
_DnsGetHostAddressByName_LibraryOpen:
|
||||
; string so you need demande, hichaine, and chvide
|
||||
MOVE.L D3,A0 ; name
|
||||
MOVEQ #0,D0
|
||||
MOVE.W (A0)+,D0 ; d0 contains length
|
||||
MOVE.L D0,D1 ; d1 also has length
|
||||
MOVE.L D0,D2 ; d2 also has length
|
||||
Rjsr L_RamFast ; d0 contains address
|
||||
BNE .StringRamAllocated
|
||||
BNE _DnsGetHostAddressByName_StringRamAllocated
|
||||
|
||||
MOVE.L ChVide(A5),D3
|
||||
|
||||
RestoreStackFunction
|
||||
Ret_String
|
||||
|
||||
.StringRamAllocated:
|
||||
_DnsGetHostAddressByName_StringRamAllocated:
|
||||
MOVE.L D0,A1 ; a1 contains address
|
||||
SUBQ #1,D1 ; reduce by one for DBRA
|
||||
.KeepCopyingAMOSString
|
||||
|
||||
_DnsGetHostAddressByName_KeepCopyingAMOSString:
|
||||
MOVE.B (A0)+,(A1)+ ; byte copy
|
||||
DBRA D1,.KeepCopyingAMOSString ; keep copying
|
||||
DBRA D1,_DnsGetHostAddressByName_KeepCopyingAMOSString ; keep copying
|
||||
MOVE.B #0,(A1)+ ; null terminate string
|
||||
MOVE.L D0,A0 ; first param of gethostbyname
|
||||
|
||||
MOVEM.L A0/D2,-(SP)
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB gethostbyname
|
||||
EndDataStorage
|
||||
MOVEM.L (SP)+,A0/D2
|
||||
|
@ -1787,21 +1999,21 @@ _SocketReuseAddr_LibraryOpen:
|
|||
MOVE.L (SP)+,D0
|
||||
|
||||
TST.L D0
|
||||
BNE .GetIPAddress
|
||||
BNE _DnsGetHostAddressByName_GetIPAddress
|
||||
|
||||
RestoreStackFunction
|
||||
|
||||
MOVE.L ChVide(A5),D3
|
||||
Ret_String
|
||||
|
||||
.GetIPAddress:
|
||||
_DnsGetHostAddressByName_GetIPAddress:
|
||||
MOVE.L D0,A0
|
||||
MOVE.L 16(A0),A1 ; **h_addr_list
|
||||
MOVE.L (A1),A1 ; *h_addr_list
|
||||
MOVE.L (A1),D0 ; h_addr_list[0]
|
||||
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB Inet_NtoA
|
||||
EndDataStorage
|
||||
|
||||
|
@ -1809,27 +2021,32 @@ _SocketReuseAddr_LibraryOpen:
|
|||
MOVE.L A2,-(SP)
|
||||
MOVEQ #0,D3
|
||||
|
||||
.GetIPAddressLength:
|
||||
_DnsGetHostAddressByName_GetIPAddressLength:
|
||||
ADDQ #1,D3
|
||||
TST.B (A2)+
|
||||
BNE .GetIPAddressLength
|
||||
BNE _DnsGetHostAddressByName_GetIPAddressLength
|
||||
MOVE.L (SP)+,A2
|
||||
|
||||
SUBQ #1,D3
|
||||
MOVE.L D3,D4
|
||||
|
||||
AND.W #$FFFE,D3
|
||||
ADDQ #2,D3
|
||||
|
||||
Rjsr L_Demande ; string is in A0/A1
|
||||
LEA 2(A0,D3.W),A1
|
||||
MOVE.L A1,HiChaine(A5)
|
||||
MOVE.L A0,D3
|
||||
MOVE.L A0,A1
|
||||
|
||||
MOVE.W D4,(A1)+
|
||||
|
||||
MOVE.W D4,(A0)+
|
||||
SUBQ #1,D4
|
||||
|
||||
.KeepCopying:
|
||||
MOVE.B (A2,D4),(A0,D4)
|
||||
DBRA D4,.KeepCopying
|
||||
_DnsGetHostAddressByName_KeepCopying:
|
||||
MOVE.B (A2)+,(A1)+
|
||||
DBRA D4,_DnsGetHostAddressByName_KeepCopying
|
||||
|
||||
MOVE.L A0,D3
|
||||
|
||||
RestoreStackFunction
|
||||
|
||||
|
@ -1844,7 +2061,7 @@ _SocketReuseAddr_LibraryOpen:
|
|||
; - - - - - - - - - - - - -
|
||||
PreserveStackFunction
|
||||
|
||||
MOVE.L D3,D4 ; milliseconds
|
||||
MOVE.L D3,D4 ; milliseconts
|
||||
MOVE.L (A3)+,D0 ; socket id
|
||||
|
||||
EnsureBSDSocketLibrary _SocketSetTimeout_LibraryOpen
|
||||
|
@ -1866,7 +2083,7 @@ _SocketSetTimeout_LibraryOpen:
|
|||
MOVE.L (A0)+,(A1)+
|
||||
SUB.L #8,A1 ; go back
|
||||
|
||||
WithDataStorageToA3
|
||||
WithDataStorage
|
||||
; socket is d0
|
||||
MOVE.L #SOL_SOCKET,D1 ; Level
|
||||
MOVE.L #$1005,D2 ; SO_SNDTIMEO
|
||||
|
@ -1874,7 +2091,7 @@ _SocketSetTimeout_LibraryOpen:
|
|||
MOVEQ #8,D3
|
||||
|
||||
MOVEM.L D0/A0,-(SP)
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB setsockopt
|
||||
|
||||
TST.L D0
|
||||
|
@ -1885,7 +2102,7 @@ _SocketSetTimeout_LibraryOpen:
|
|||
MOVE.L #$1006,D2 ; SO_RCVTIMEO
|
||||
MOVEQ #8,D3
|
||||
|
||||
LoadBSDSocketBaseFromA3
|
||||
LoadBSDSocketBase
|
||||
CALLLIB setsockopt
|
||||
|
||||
EndDataStorage
|
||||
|
@ -1912,17 +2129,17 @@ _SocketSetTimeout_Fail:
|
|||
Lib_Par SocketCloseSocket
|
||||
; - - - - - - - - - - - - -
|
||||
PreserveStackFunction
|
||||
EnsureBSDSocketLibrary .LibraryOpen
|
||||
EnsureBSDSocketLibrary _SocketCloseSocket_LibraryOpen
|
||||
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
|
||||
.LibraryOpen:
|
||||
_SocketCloseSocket_LibraryOpen:
|
||||
|
||||
MOVE.L D3,D0
|
||||
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB CloseSocket
|
||||
EndDataStorage
|
||||
|
||||
|
@ -1939,7 +2156,12 @@ _SocketSetTimeout_Fail:
|
|||
Lib_Par SocketHerrno
|
||||
; - - - - - - - - - - - - -
|
||||
PreserveStackFunction
|
||||
EnsureBSDSocketLibrary _SocketHerrno_LibraryOpen
|
||||
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
|
||||
_SocketHerrno_LibraryOpen:
|
||||
; set up tag list memory and place for herrno to go
|
||||
Dlea AcceptScratchArea,A0
|
||||
MOVE.L A0,A2
|
||||
|
@ -1952,13 +2174,13 @@ _SocketSetTimeout_Fail:
|
|||
MOVE.L 0,(A0)+
|
||||
MOVE.L A2,A0
|
||||
|
||||
WithDataStorageToA3
|
||||
LoadBSDSocketBaseFromA3
|
||||
WithDataStorage
|
||||
LoadBSDSocketBase
|
||||
CALLLIB SocketBaseTagList
|
||||
EndDataStorage
|
||||
|
||||
TST.L D0
|
||||
BEQ .success
|
||||
BEQ _SocketHerrno_success
|
||||
|
||||
; failed
|
||||
MOVE.L #-1,D3
|
||||
|
@ -1966,7 +2188,7 @@ _SocketSetTimeout_Fail:
|
|||
RestoreStackFunction
|
||||
Ret_Int
|
||||
|
||||
.success
|
||||
_SocketHerrno_success:
|
||||
MOVE.L (A1),D3
|
||||
|
||||
RestoreStackFunction
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
; bsdsocket library stuff
|
||||
; ported from the various C include headers
|
||||
SOCK_STREAM EQU 1
|
||||
PF_INET EQU 2
|
||||
AF_INET EQU PF_INET
|
||||
IPPROTO_TCP EQU 6
|
||||
|
||||
INADDR_ANY EQU 0
|
||||
|
||||
FIONBIO EQU $8004667E
|
||||
FIONASYNC EQU $8004667D
|
||||
|
||||
SOL_SOCKET EQU $FFFF
|
||||
SO_REUSEADDR EQU $4
|
||||
|
||||
MAX_SOCKETS EQU 64
|
||||
|
||||
len_sockaddr_in EQU 16
|
||||
sockaddr_in_sin_len EQU 0
|
||||
sockaddr_in_sin_family EQU 1
|
||||
sockaddr_in_sin_port EQU 2
|
||||
sockaddr_in_sin_addr EQU 4
|
||||
|
||||
; global errors
|
||||
Error_OtherError EQU -1
|
||||
Error_LibraryNotOpen EQU -2
|
||||
Error_PortOutOfRange EQU -11
|
||||
Error_FdsetOutOfRange EQU -11
|
||||
Error_UnableToBind EQU -12
|
||||
|
||||
; socket herrno and tag lists
|
||||
; built from:
|
||||
; * https://wiki.amigaos.net/amiga/autodocs/bsdsocket.doc.txt
|
||||
; * https://github.com/deplinenoise/amiga-sdk/blob/master/netinclude/amitcp/socketbasetags.h
|
||||
; * http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_2._guide/node012E.html
|
||||
|
||||
TAG_USER EQU (1<<31)
|
||||
SBTF_REF EQU $8000
|
||||
SBTB_CODE EQU 1
|
||||
SBTS_CODE EQU $3FFF
|
||||
SBTC_HERRNO EQU 6
|
||||
|
||||
HerrnoTag EQU (TAG_USER|SBTF_REF|((SBTC_HERRNO&SBTS_CODE)<<SBTB_CODE))
|
|
@ -1,43 +0,0 @@
|
|||
; d0 = value to be divided
|
||||
; d1 = divisor
|
||||
; returns:
|
||||
; d0 = divided value
|
||||
; d1 = remainder
|
||||
LongDivideD0ByD1 MACRO
|
||||
CMP.L D0,D1
|
||||
BMI _LongDivide_StartDivide\@
|
||||
|
||||
MOVE.L D0,D1
|
||||
MOVEQ #0,D0
|
||||
BRA _LongDivide_Skip\@
|
||||
|
||||
_LongDivide_StartDivide\@:
|
||||
|
||||
MOVEM.L D2-D4,-(SP)
|
||||
MOVEQ #0,D2 ; remainder
|
||||
MOVE.L #31,D3 ; bit tracking
|
||||
; d4 tracks the status register
|
||||
|
||||
_LongDivide_ContinueDivide\@:
|
||||
ASL.L #1,D0
|
||||
SCS D4 ; bit that got rolled out
|
||||
AND.L #1,D4
|
||||
ROL.L #1,D2
|
||||
ADD.L D4,D2 ; roll the value onto the remainder
|
||||
|
||||
MOVE.L D2,D4
|
||||
SUB.L D1,D4
|
||||
|
||||
BMI _LongDivide_NotDivisible\@
|
||||
ADDQ #1,D0
|
||||
MOVE.L D4,D2
|
||||
|
||||
_LongDivide_NotDivisible\@:
|
||||
DBRA D3,_LongDivide_ContinueDivide\@
|
||||
MOVE.L D2,D1
|
||||
MOVEM.L (SP)+,D2-D4
|
||||
|
||||
_LongDivide_Skip\@:
|
||||
ENDM
|
||||
|
||||
|
|
@ -2,12 +2,19 @@ echo "***Assembling AMOSPro_BSDSocket.Lib"
|
|||
assign AMOSPro_System: SYS:Development/AMOS_Pro
|
||||
assign AMOSPro_Sources: amos-pro-bsdsocket-extension:stuff/AMOS-Professional-Official
|
||||
AMOSPro_Sources:c/Library_Digest BSDSocket.s
|
||||
AMOSPro_Sources:c/Genam FROM BSDSocket.s TO AMOSPro_BSDSocket.Lib
|
||||
AMOSPro_Sources:c/Genam FROM BSDSocket.s TO AMOSPro_BSDSocket.Lib -e ExtNb=18-1
|
||||
;delete >NIL: BSDSocket_Labels.s
|
||||
;delete >NIL: BSDSocket_Size.s
|
||||
FAILAT 21
|
||||
copy AMOSPro_System:APSystem/AMOSPro_BSDSocket.lib AMOSPro_System:APSystem/AMOSPro_BSDSocket.lib.bak
|
||||
FAILAT 10
|
||||
copy AMOSPro_BSDSocket.Lib AMOSPro_System:APSystem/
|
||||
;use an amos file here that includes the plugin to quickly build a test program
|
||||
;apcmp "aqua_test_plugin.amos" inclib
|
||||
apcmp "/test/TestSuite.amos" inclib
|
||||
|
||||
echo "Build for slot 9"
|
||||
AMOSPro_Sources:c/Genam FROM BSDSocket.s TO AMOSPro_BSDSocket_Slot9.Lib -e ExtNb=9-1
|
||||
echo "Build for slot 11"
|
||||
AMOSPro_Sources:c/Genam FROM BSDSocket.s TO AMOSPro_BSDSocket_Slot11.Lib -e ExtNb=11-1
|
||||
echo "Build for slot 17"
|
||||
AMOSPro_Sources:c/Genam FROM BSDSocket.s TO AMOSPro_BSDSocket_Slot17.Lib -e ExtNb=17-1
|
||||
|
||||
|
|
47
src/fd_set.s
47
src/fd_set.s
|
@ -1,47 +0,0 @@
|
|||
; fdset macros
|
||||
EnsureValidFdset MACRO
|
||||
CMP.L #MaxFd_sets,\1
|
||||
BLT \2
|
||||
|
||||
MOVE.L #Error_FdsetOutOfRange,D3
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
ENDM
|
||||
|
||||
EnsureValidFdsetBit MACRO
|
||||
CMP.L #64,\1
|
||||
BGE _EnsureValidFdsetBit_Fail\@
|
||||
BRA \2
|
||||
_EnsureValidFdsetBit_Fail\@:
|
||||
MOVE.L \3,D3
|
||||
RestoreStackFunction
|
||||
Ret_Int
|
||||
ENDM
|
||||
|
||||
; LeaFdset fd_set reg,target
|
||||
LeaFdset MACRO
|
||||
MOVE.L \1,-(SP)
|
||||
Dlea fd_sets,\2 ; base of all, these are longs
|
||||
ROL.L #3,\1 ; multiply by 8
|
||||
ADD.L \1,\2 ; add to base of all
|
||||
MOVE.L (SP)+,\1
|
||||
ENDM
|
||||
|
||||
; LeaFdsetForBit fd_set reg,target address,target bit in address
|
||||
LeaFdsetForBit MACRO
|
||||
LeaFdset \1,\2 ; get fdset base address in \2
|
||||
MOVE.L D3,-(SP)
|
||||
MOVE.L \3,D3 ; Put target bit into D3
|
||||
ROR.L #5,D3 ; lop off the first 5 bits
|
||||
AND.L #$7,D3 ; only keep the top three
|
||||
ROL.L #2,D3 ; multiply by 4
|
||||
ADD.L D3,\2 ; add that value to the fdset address
|
||||
|
||||
AND.L #$1F,\3 ; only keep 0-31 in \3
|
||||
|
||||
MOVEQ #1,D3
|
||||
ROL.L \3,D3 ; shift that bit left as many as target
|
||||
MOVE.L D3,\3 ; put that in the target
|
||||
MOVE.L (SP)+,D3
|
||||
|
||||
ENDM
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,354 @@
|
|||
' BSD Socket Extension Test Suite
|
||||
'
|
||||
' Exercise all known functionality of the extension and write
|
||||
' a report file detailing the result.
|
||||
|
||||
Screen Open 0,640,200,4,Hires
|
||||
|
||||
_FILE_HANDLE=1
|
||||
Dim _CONTEXT$(10)
|
||||
_CONTEXT_INDEX=0
|
||||
|
||||
Global _FILE_HANDLE,_CONTEXT$(),_CONTEXT_INDEX
|
||||
|
||||
Procedure _ADD_TO_REPORT[MESSAGE$]
|
||||
_CONTEXT_STRING$=""
|
||||
For I=0 To _CONTEXT_INDEX-1
|
||||
_CONTEXT_STRING$=_CONTEXT_STRING$+_CONTEXT$(I)
|
||||
If I<>(_CONTEXT_INDEX-1)
|
||||
_CONTEXT_STRING$=_CONTEXT_STRING$+"/"
|
||||
End If
|
||||
Next I
|
||||
_OUTPUT$="["+_CONTEXT_STRING$+"] "+MESSAGE$
|
||||
Print #_FILE_HANDLE,_OUTPUT$
|
||||
Print _OUTPUT$
|
||||
' ensure line is printed on screen to catch crashes
|
||||
Wait Vbl
|
||||
End Proc
|
||||
|
||||
Procedure _BEGIN_CONTEXT[NAME$]
|
||||
_CONTEXT$(_CONTEXT_INDEX)=NAME$
|
||||
_CONTEXT_INDEX=_CONTEXT_INDEX+1
|
||||
End Proc
|
||||
|
||||
Procedure _END_CONTEXT
|
||||
_CONTEXT_INDEX=_CONTEXT_INDEX-1
|
||||
End Proc
|
||||
|
||||
Open Out _FILE_HANDLE,"report.txt"
|
||||
|
||||
_BEGIN_CONTEXT["Socket Library Open"]
|
||||
_BEGIN_CONTEXT["Open Library"]
|
||||
|
||||
_LIBRARY_ADDRESS=Socket Library Open
|
||||
_ADD_TO_REPORT[Str$(_LIBRARY_ADDRESS)]
|
||||
|
||||
_END_CONTEXT
|
||||
|
||||
If _LIBRARY_ADDRESS=0
|
||||
_ADD_TO_REPORT["bsdsocket.library not available, ending tests"]
|
||||
_END_CONTEXT
|
||||
Goto _FINISH_SUITE
|
||||
End If
|
||||
|
||||
_BEGIN_CONTEXT["Double open"]
|
||||
_NEW_LIBRARY_ADDRESS=Socket Library Open
|
||||
_ADD_TO_REPORT[Str$(_NEW_LIBRARY_ADDRESS)]
|
||||
_END_CONTEXT
|
||||
|
||||
_END_CONTEXT
|
||||
|
||||
|
||||
_BEGIN_CONTEXT["Socket Create Inet Socket"]
|
||||
SOCKET=Socket Create Inet Socket
|
||||
_ADD_TO_REPORT[Str$(SOCKET)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Reuse Addr"]
|
||||
RESULT=Socket Reuse Addr(SOCKET)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Set Nonblocking"]
|
||||
_BEGIN_CONTEXT["False"]
|
||||
RESULT=Socket Set Nonblocking(SOCKET,False)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["True"]
|
||||
RESULT=Socket Set Nonblocking(SOCKET,True)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_ADD_TO_REPORT["Preserving this state for rest of tests"]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Dns Get Address By Name$"]
|
||||
|
||||
_BEGIN_CONTEXT["Bad domain name"]
|
||||
IP$=Dns Get Address By Name$("u8dsf93jsdfoiodsoi.sdfjdsoifueru.sadfasdsdasd")
|
||||
Print IP$
|
||||
_ADD_TO_REPORT[IP$]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["localhost"]
|
||||
IP$=Dns Get Address By Name$("localhost")
|
||||
_ADD_TO_REPORT[IP$]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["aminet.net"]
|
||||
IP$=Dns Get Address By Name$("aminet.net")
|
||||
Print IP$
|
||||
_ADD_TO_REPORT[IP$]
|
||||
_ADD_TO_REPORT["Using this IP address for connection tests"]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Returned string can be manipulated"]
|
||||
_ADD_TO_REPORT["Cat"+IP$+"Dog"]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Connect"]
|
||||
_BEGIN_CONTEXT["port too high"]
|
||||
RESULT=Socket Connect(SOCKET To IP$,999999)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["blank ip"]
|
||||
RESULT=Socket Connect(SOCKET To "",80)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["invalid ip -- requires reopening failed socket"]
|
||||
RESULT=Socket Connect(SOCKET To "999.999.999.999",80)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Close Socket"]
|
||||
RESULT=Socket Close Socket(SOCKET)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
' re-set up this socket after a failed connection
|
||||
SOCKET=Socket Create Inet Socket
|
||||
_=Socket Set Nonblocking(SOCKET,True)
|
||||
|
||||
_BEGIN_CONTEXT["aminet IP ("+IP$+") from above"]
|
||||
RESULT=Socket Connect(SOCKET To IP$,80)
|
||||
_ADD_TO_REPORT[Str$(RESULT)+" (ok to be -1, will Wait Async Writing next)"]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Wait Async Writing"]
|
||||
|
||||
_BEGIN_CONTEXT["With unconnected socket"]
|
||||
OTHER_SOCKET=Socket Create Inet Socket
|
||||
_=Socket Set Nonblocking(OTHER_SOCKET,True)
|
||||
|
||||
_BEGIN_CONTEXT["2 second timeout"]
|
||||
RESULT=Socket Wait Async Writing(OTHER_SOCKET,2000)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Zero timeout"]
|
||||
RESULT=Socket Wait Async Writing(OTHER_SOCKET,0)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Connected socket"]
|
||||
_BEGIN_CONTEXT["Two second timeout"]
|
||||
RESULT=Socket Wait Async Writing(SOCKET,2000)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Zero timeout"]
|
||||
RESULT=Socket Wait Async Writing(SOCKET,0)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Attempt to get actual connection"]
|
||||
For TRIES=0 To 10
|
||||
RESULT=Socket Wait Async Writing(SOCKET,500)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
If RESULT>0
|
||||
Exit
|
||||
End If
|
||||
Next TRIES
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Get Host"]
|
||||
_BEGIN_CONTEXT["socket id too high"]
|
||||
RESULT=Socket Get Host(999999)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["socket id is valid"]
|
||||
RESULT=Socket Get Host(SOCKET)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Get Port"]
|
||||
_BEGIN_CONTEXT["socket id too high"]
|
||||
RESULT=Socket Get Port(999999)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["socket id is valid"]
|
||||
RESULT=Socket Get Port(SOCKET)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Inet Ntoa$"]
|
||||
_BEGIN_CONTEXT["Use the socket host"]
|
||||
RESULT$=Socket Inet Ntoa$(Socket Get Host(SOCKET))
|
||||
_ADD_TO_REPORT[RESULT$]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["String can be manipulated"]
|
||||
_ADD_TO_REPORT["Cat"+RESULT$+"Dog"]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Send and Socket Send$"]
|
||||
HTTP_REQUEST_HEADERS$="GET / HTTP/1.0"+Chr$(10)+"Host: amiga"+Chr$(10)+Chr$(10)
|
||||
|
||||
_BEGIN_CONTEXT["Socket send$ first half"]
|
||||
FIRST_HALF$=Left$(HTTP_REQUEST_HEADERS$,10)
|
||||
RESULT=Socket Send$(SOCKET,FIRST_HALF$)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket send second half"]
|
||||
SECOND_HALF_START=Varptr(HTTP_REQUEST_HEADERS$)+10
|
||||
SECOND_HALF_LENGTH=Len(HTTP_REQUEST_HEADERS$)-10
|
||||
RESULT=Socket Send(SOCKET,SECOND_HALF_START,SECOND_HALF_LENGTH)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket wait Async Reading"]
|
||||
_BEGIN_CONTEXT["With unconnected socket"]
|
||||
_BEGIN_CONTEXT["2 second timeout"]
|
||||
RESULT=Socket Wait Async Reading(OTHER_SOCKET,2000)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
_BEGIN_CONTEXT["Zero timeout"]
|
||||
RESULT=Socket Wait Async Reading(OTHER_SOCKET,0)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["With aminet socket"]
|
||||
_BEGIN_CONTEXT["2 second timeout"]
|
||||
RESULT=Socket Wait Async Reading(SOCKET,2000)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Zero timeout"]
|
||||
RESULT=Socket Wait Async Reading(SOCKET,0)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_END_CONTEXT
|
||||
|
||||
'Goto _FINISH_SUITE
|
||||
|
||||
_BEGIN_CONTEXT["Socket Recv$ and Socket Recv"]
|
||||
_BEGIN_CONTEXT["Socket Recv$"]
|
||||
_BEGIN_CONTEXT["Read 20 characters"]
|
||||
RESULT$=Socket Recv$(SOCKET,20)
|
||||
_ADD_TO_REPORT[RESULT$]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["String can be manipulated"]
|
||||
_ADD_TO_REPORT["Cat"+RESULT$+"Dog"]
|
||||
_END_CONTEXT
|
||||
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Socket Read"]
|
||||
Reserve As Work 20,20
|
||||
|
||||
_BEGIN_CONTEXT["Read 20 bytes"]
|
||||
RESULT=Socket Recv(SOCKET To Start(20),20)
|
||||
_ADD_TO_REPORT[Str$(RESULT)]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Data was read"]
|
||||
BASE$="12345678901234567890"
|
||||
For I=0 To 19
|
||||
Mid$(BASE$,I+1,1)=Chr$(Peek(Start(20)+I))
|
||||
Next I
|
||||
_ADD_TO_REPORT[BASE$]
|
||||
_END_CONTEXT
|
||||
|
||||
Erase 20
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_FINISH_SUITE:
|
||||
|
||||
_BEGIN_CONTEXT["Socket Library Close"]
|
||||
_BEGIN_CONTEXT["Close"]
|
||||
Socket Library Close
|
||||
_ADD_TO_REPORT["Success"]
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Double close"]
|
||||
Socket Library Close
|
||||
_ADD_TO_REPORT["Success"]
|
||||
_END_CONTEXT
|
||||
_END_CONTEXT
|
||||
|
||||
_BEGIN_CONTEXT["Call functions with library closed"]
|
||||
_=Socket Set Nonblocking(0,True)
|
||||
_ADD_TO_REPORT["Socket Set Nonblocking"]
|
||||
_=Socket Reuse Addr(0)
|
||||
_ADD_TO_REPORT["Socket Reuse Addr"]
|
||||
_=Socket Create Inet Socket
|
||||
_ADD_TO_REPORT["Socket Create Inet Socket"]
|
||||
_=Socket Connect(0 To "",0)
|
||||
_ADD_TO_REPORT["Socket Connect"]
|
||||
_=Socket Bind(0 To "",0)
|
||||
_ADD_TO_REPORT["Socket Bind"]
|
||||
_=Socket Listen(0)
|
||||
_ADD_TO_REPORT["Socket Listen"]
|
||||
_=Socket Accept(0)
|
||||
_ADD_TO_REPORT["Socket Accept"]
|
||||
_=Socket Wait Async Reading(0,0)
|
||||
_ADD_TO_REPORT["Socket Wait Async Reading"]
|
||||
_=Socket Wait Async Writing(0,0)
|
||||
_ADD_TO_REPORT["Socket Wait Async Writing"]
|
||||
_=Socket Set Timeout(0,0)
|
||||
_ADD_TO_REPORT["Socket Set Timeout"]
|
||||
_=Socket Close Socket(0)
|
||||
_ADD_TO_REPORT["Socket Close Socket"]
|
||||
_=Socket Send$(0,"")
|
||||
_ADD_TO_REPORT["Socket Send$"]
|
||||
_=Socket Send(0,0,0)
|
||||
_ADD_TO_REPORT["Socket Send"]
|
||||
_$=Socket Recv$(0,0)
|
||||
_ADD_TO_REPORT["Socket Recv$"]
|
||||
_=Socket Recv(0 To 0,0)
|
||||
_ADD_TO_REPORT["Socket Recv"]
|
||||
_=Socket Get Host(0)
|
||||
_ADD_TO_REPORT["Socket Get Host"]
|
||||
_=Socket Get Port(0)
|
||||
_ADD_TO_REPORT["Socket Get Port"]
|
||||
_$=Socket Inet Ntoa$(0)
|
||||
_ADD_TO_REPORT["Socket Inet Ntoa$"]
|
||||
_=Socket Errno
|
||||
_ADD_TO_REPORT["Socket Errno"]
|
||||
_=Socket Herrno
|
||||
_ADD_TO_REPORT["Socket Herrno"]
|
||||
_$=Dns Get Address By Name$("")
|
||||
_ADD_TO_REPORT["Dns Get Address By Name$"]
|
||||
_END_CONTEXT
|
||||
|
||||
Close 1
|
Loading…
Reference in New Issue