From 48041fee19b39ded95dc50d774c09035d0782dd8 Mon Sep 17 00:00:00 2001 From: norayr Date: Thu, 19 Mar 2015 19:33:34 +0400 Subject: [PATCH] forking server example with oberon; -- noch. --- src/test/server/Makefile | 11 ++++ src/test/server/s.Mod | 102 +++++++++++++++++++++++++++++++ src/test/server/sockets.Mod | 119 ++++++++++++++++++++++++++++++++++++ src/test/server/types.Mod | 32 ++++++++++ 4 files changed, 264 insertions(+) create mode 100644 src/test/server/Makefile create mode 100644 src/test/server/s.Mod create mode 100644 src/test/server/sockets.Mod create mode 100644 src/test/server/types.Mod diff --git a/src/test/server/Makefile b/src/test/server/Makefile new file mode 100644 index 00000000..93eb2b6e --- /dev/null +++ b/src/test/server/Makefile @@ -0,0 +1,11 @@ + +VOC = /opt/voc/bin/voc + +all: + $(VOC) -s types.Mod sockets.Mod s.Mod -m + +clean: + rm *.h + rm *.c + rm *.o + rm *.sym diff --git a/src/test/server/s.Mod b/src/test/server/s.Mod new file mode 100644 index 00000000..ae49093d --- /dev/null +++ b/src/test/server/s.Mod @@ -0,0 +1,102 @@ +MODULE s; + +IMPORT sockets, types, Out := Console, Unix, S := SYSTEM; + +TYPE Int32 = types.Int32; + Int16 = types.Int16; + String = types.String; + +PROCEDURE DoSmth(sock : Int32); +VAR str, aff : String; + n, s : LONGINT; +BEGIN + s := SIZE(String); + aff := "Affirmative, Dave"; + n := Unix.Read(sock, S.ADR(str), s); + + IF n < 0 THEN + Out.String("error reading from socket"); Out.Ln; + END; + Out.String("message is "); Out.String(str); Out.Ln; + s := 17; + n := Unix.Write(sock, S.ADR(aff), s); + IF n < 2 THEN + Out.String("error writing to socket"); Out.Ln + END; + +END DoSmth; + + +PROCEDURE serve; +VAR sockfd, newsockfd, portno, clilen, pid: sockets.Int32; + ServAddr, CliAddr: sockets.SockAddrIn; + Null : Int32; + Port, maxQueue, res : Int32; + afinet, port: Int16; +BEGIN + Port := 2055; + maxQueue := 5; + Null := 0; + sockfd := sockets.Socket(S.VAL(Int32, sockets.AfInet), S.VAL(Int32, sockets.SockStream), Null); + IF sockfd < 0 THEN + Out.String("error opening socket") + ELSE + Out.String("socket created.") + END; + Out.Ln; + + types.IntegerToInt16(sockets.AfInet, afinet); + types.IntegerToInt16(Port, port); + ServAddr.SinFamily := afinet; + ServAddr.SinPort := port; + Out.String("listening on port ");Out.Int(S.VAL(INTEGER, ServAddr.SinPort), 0); Out.Ln; + ServAddr.SinAddr.SAddr := 0(*sockets.InAddrAny*); + + res := sockets.Bind(sockfd, S.VAL(sockets.SockAddr, ServAddr), (SIZE(sockets.SockAddrIn))); + IF res < 0 THEN + Out.String("error on binding") + ELSE + Out.String("binding completed.") + END; + Out.Ln; + + res := sockets.Listen(sockfd, maxQueue); + + IF res # 0 THEN + Out.String("listen() failed"); + ELSE + Out.String("listen okay"); + END; + Out.Ln; + clilen := SIZE(sockets.SockAddrIn); + LOOP + newsockfd := sockets.Accept(sockfd, S.VAL(sockets.SockAddr, ServAddr), clilen); + IF newsockfd < 0 THEN + Out.String("error on accept") + ELSE + Out.String("accept okay") + END; + Out.Ln; + + pid := Unix.Fork(); + IF pid < 0 THEN + Out.String("error on fork") + ELSIF pid = 0 THEN + Out.String("forked okay"); Out.Ln; + res := Unix.Close(sockfd); + DoSmth(newsockfd); + EXIT + ELSE + res := Unix.Close(newsockfd); + END; + END; + + +END serve; + + +BEGIN + +serve; + +END s. diff --git a/src/test/server/sockets.Mod b/src/test/server/sockets.Mod new file mode 100644 index 00000000..4cba806e --- /dev/null +++ b/src/test/server/sockets.Mod @@ -0,0 +1,119 @@ +MODULE sockets; +IMPORT types, SYS := SYSTEM; + +TYPE + Int16* = types.Int16; (* INTEGER on 32 bit platform *) + Int32* = types.Int32; + Int64* = types.Int64; + +CONST + SockStream* = 1; + SockDgram* = 2; + SockRaw* = 3; + SockRdm* = 4; + SockSeqpacket* = 5; + SockDccp* = 6; + SockPacket* = 10; + + AfUnscec* = 0; (* Unspecified. *) + AfLocal* = 1; (* Local to host (pipes and file-domain). *) + AfUnix* = 1; (* POSIX name for PF_LOCAL. *) + AfFile* = 1; (* Another non-standard name for PF_LOCAL. *) + AfInet* = 2; (* IP protocol family. *) + AfAx25* = 3; (* Amateur Radio AX.25. *) + AfIpx* = 4; (* Novell Internet Protocol. *) + AfAppletalk* = 5; (* Appletalk DDP. *) + AfNetrom* = 6; (* Amateur radio NetROM. *) + AfBridge* = 7; (* Multiprotocol bridge. *) + AfAtmpvc* = 8; (* ATM PVCs. *) + AfX25* = 9; (* Reserved for X.25 project. *) + AfInet6* = 10; (* IP version 6. *) + AfRose* = 11; (* Amateur Radio X.25 PLP. *) + AfDecnet* = 12; (* Reserved for DECnet project. *) + AfNetbeui*= 13; (* Reserved for 802.2LLC project. *) + AfSecurity*=14; (* Security callback pseudo AF. *) + AfKey* = 15; (* PF_KEY key management API. *) + AfNetlink*= 16; + AfRoute* = 16; (* Alias to emulate 4.4BSD. *) + AfPacket = 17; (* Packet family. *) + AfAsh = 18; (* Ash. *) + AfEconet* = 19; (* Acorn Econet. *) + AfAtmsvc* = 20; (* ATM SVCs. *) + AfRds* = 21; (* RDS sockets. *) + AfSna = 22; (* Linux SNA Project *) + AfIrda* = 23; (* IRDA sockets. *) + AfPppox = 24; (* PPPoX sockets. *) + AfWanpipe*= 25; (* Wanpipe API sockets. *) + AfLlc* = 26; (* Linux LLC. *) + AfCan* = 29; (* Controller Area Network. *) + AfTipc* = 30; (* TIPC sockets. *) + AfBluetooth* = 31; (* Bluetooth sockets. *) + AfIucv* = 32; (* IUCV sockets. *) + AfRxrpc* = 33; (* RxRPC sockets. *) + AfIsdn* = 34; (* mISDN sockets. *) + AfPhonet* = 35; (* Phonet sockets. *) + AfIeee802154* = 36; (* IEEE 802.15.4 sockets. *) + AfCaif* = 37; (* CAIF sockets. *) + AfAlg* = 38; (* Algorithm sockets. *) + AfNfc* = 39; (* NFC sockets. *) + AfVsock* = 40; (* vSockets. *) + AfMax* = 41; (* For now.. *) + + InAddrAny* = 0; + +TYPE + + (* /usr/include/netinet/in.h *) + InAddr* = RECORD + SAddr* : Int32; + END; + + SockAddrIn* = RECORD + SinFamily* : Int16; + SinPort* : Int16; + SinAddr* : InAddr; + SinZero* : ARRAY 8 OF CHAR; + END; + (* /usr/include/sys/socket.h *) + + SockAddr* = RECORD + SaFamily* : Int16; + SaData* : ARRAY 14 OF CHAR + END; + + PROCEDURE -socket(domain, type, protocol: Int32): Int32 + "(int)socket(domain, type, protocol)"; + + PROCEDURE Socket*(domain, type, protocol: Int32): Int32; + BEGIN + RETURN socket(domain, type, protocol) + END Socket; + + PROCEDURE -bind(sockfd: Int32; VAR addr: SockAddr; addrlen: Int32): Int32 + "(int)bind(sockfd, addr, addrlen)"; + + PROCEDURE Bind*(sockfd: Int32; VAR addr: SockAddr; addrlen: Int32): Int32; + BEGIN + RETURN bind(sockfd, addr, addrlen) + END Bind; + + PROCEDURE -listen(sockfd, backlog: Int32): Int32 + "(int)listen(sockfd, backlog)"; + + PROCEDURE Listen*(sockfd, backlog: Int32): Int32; + BEGIN + RETURN listen(sockfd, backlog) + END Listen; + + PROCEDURE -accept(sockfd: Int32; VAR addr: SockAddr; VAR addrlen: Int32): Int32 + "(int)accept(sockfd, addr, addrlen)"; + + PROCEDURE Accept*(sockfd: Int32; VAR addr: SockAddr; VAR addrlen: Int32): Int32; + BEGIN + RETURN accept(sockfd, addr, addrlen) + END Accept; + +BEGIN + + +END sockets. diff --git a/src/test/server/types.Mod b/src/test/server/types.Mod new file mode 100644 index 00000000..cece8767 --- /dev/null +++ b/src/test/server/types.Mod @@ -0,0 +1,32 @@ +MODULE types; +IMPORT SYS := SYSTEM; + + +TYPE + intarr64 = ARRAY 8 OF SYS.BYTE; (* to emulate int16 on x86_64; -- noch *) + intarr32 = ARRAY 4 OF SYS.BYTE; + intarr16 = ARRAY 2 OF SYS.BYTE; + Int16* = intarr16; (* INTEGER on 32 bit platform *) + Int32* = INTEGER; + Int64* = LONGINT; + String* = ARRAY 256 OF CHAR; + + PROCEDURE LongintToInt16*(int: LONGINT; VAR int16: Int16)(* : Int16*); + VAR longintarr : intarr64; + BEGIN + (*RETURN SYS.VAL(Int16, int)*) + longintarr := SYS.VAL(intarr64, int); + int16[0] := longintarr[0]; + int16[1] := longintarr[1]; (* this will work for little endian -- noch *) + END LongintToInt16; + + PROCEDURE IntegerToInt16*(int: INTEGER; VAR int16: Int16)(* : Int16*); + VAR intarr : intarr32; + BEGIN + (*RETURN SYS.VAL(Int16, int)*) + intarr := SYS.VAL(intarr32, int); + int16[0] := intarr[0]; + int16[1] := intarr[1]; (* this will work for little endian -- noch *) + END IntegerToInt16; + +END types.