sockets.pp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$mode objfpc}
  11. unit Sockets;
  12. Interface
  13. {$macro on}
  14. {$define maybelibc:=}
  15. Uses
  16. winsock2,ctypes;
  17. Type
  18. size_t = cuint32;
  19. ssize_t = cint32;
  20. tsocklen= cint;
  21. psocklen= ^tsocklen;
  22. const
  23. EsockEINTR = WSAEINTR;
  24. EsockEBADF = WSAEBADF;
  25. EsockEFAULT = WSAEFAULT;
  26. EsockEINVAL = WSAEINVAL;
  27. EsockEACCESS = WSAEACCES;
  28. EsockEMFILE = WSAEMFILE;
  29. EsockEMSGSIZE = WSAEMSGSIZE;
  30. EsockENOBUFS = WSAENOBUFS;
  31. EsockENOTCONN = WSAENOTCONN;
  32. EsockENOTSOCK = WSAENOTSOCK;
  33. EsockEPROTONOSUPPORT = WSAEPROTONOSUPPORT;
  34. EsockEWOULDBLOCK = WSAEWOULDBLOCK;
  35. SHUT_RD = SD_RECEIVE; // aliases so we are cross-platform
  36. SHUT_WR = SD_SEND;
  37. SHUT_RDWR = SD_BOTH;
  38. {$i socketsh.inc}
  39. {$i fpwinsockh.inc}
  40. Implementation
  41. { Include filerec and textrec structures }
  42. {$i filerec.inc}
  43. {$i textrec.inc}
  44. {******************************************************************************
  45. Basic Socket Functions
  46. ******************************************************************************}
  47. //function fprecvmsg (s:cint; msg: pmsghdr; flags:cint):ssize_t;
  48. //function fpsendmsg (s:cint; hdr: pmsghdr; flags:cint):ssize;
  49. //function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  50. function socketerror:cint;
  51. begin
  52. result:=wsagetlasterror;
  53. end;
  54. function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  55. begin
  56. fpSocket:=WinSock2.Socket(Domain,xtype,ProtoCol);
  57. end;
  58. function fpsend (s:cint; msg:pointer; len:size_t; flags:cint):ssize_t;
  59. begin
  60. fpSend:=WinSock2.Send(S,msg,len,flags);
  61. end;
  62. function fpsendto (s:cint; msg:pointer; len:size_t; flags:cint; tox :psockaddr; tolen: tsocklen):ssize_t;
  63. begin
  64. // Dubious construct, this should be checked. (IPV6 fails ?)
  65. fpSendTo:=WinSock2.SendTo(S,msg,Len,Flags,Winsock2.PSockAddr(tox),toLen);
  66. end;
  67. function fprecv (s:cint; buf: pointer; len: size_t; flags: cint):ssize_t;
  68. begin
  69. fpRecv:=WinSock2.Recv(S,Buf,Len,Flags);
  70. end;
  71. function fprecvfrom (s:cint; buf: pointer; len: size_t; flags: cint; from : psockaddr; fromlen : psocklen):ssize_t;
  72. begin
  73. fpRecvFrom:=WinSock2.RecvFrom(S,Buf,Len,Flags,WinSock2.PSockAddr(From),FromLen);
  74. end;
  75. function fpconnect (s:cint; name : psockaddr; namelen : tsocklen):cint;
  76. begin
  77. fpConnect:=Winsock2.Connect(S,WinSock2.PSockAddr(name),nameLen);
  78. end;
  79. function fpshutdown (s:cint; how:cint):cint;
  80. begin
  81. fpShutDown:=Winsock2.ShutDown(S,How);
  82. end;
  83. Function socket(Domain,SocketType,Protocol:Longint):Longint;
  84. begin
  85. socket:=fpsocket(Domain,sockettype,protocol);
  86. end;
  87. Function Send(Sock:Longint;Const Buf;BufLen,Flags:Longint):Longint;
  88. begin
  89. send:=fpsend(sock,@buf,buflen,flags);
  90. end;
  91. Function SendTo(Sock:Longint;Const Buf;BufLen,Flags:Longint;Var Addr; AddrLen : Longint):Longint;
  92. begin
  93. sendto:=fpsendto(sock,@buf,buflen,flags,@addr,addrlen);
  94. end;
  95. Function Recv(Sock:Longint;Var Buf;BufLen,Flags:Longint):Longint;
  96. begin
  97. Recv:=fpRecv(Sock,@Buf,BufLen,Flags);
  98. end;
  99. Function RecvFrom(Sock : Longint; Var Buf; Buflen,Flags : Longint; Var Addr; var AddrLen : longint) : longint;
  100. begin
  101. RecvFrom:=fpRecvFrom(Sock,@Buf,BufLen,Flags,@Addr,@AddrLen);
  102. end;
  103. function fpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint;
  104. begin
  105. fpbind:=Winsock2.Bind(S,Winsock2.PSockAddr(Addrx),AddrLen);
  106. end;
  107. function fplisten (s:cint; backlog : cint):cint;
  108. begin
  109. fplisten:=Winsock2.Listen(S,backlog);
  110. end;
  111. function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint;
  112. begin
  113. fpAccept:=Winsock2.Accept(S,Winsock2.PSockAddr(Addrx), AddrLen);
  114. end;
  115. function fpgetsockname (s:cint; name : psockaddr; namelen : psocklen):cint;
  116. begin
  117. fpGetSockName:=Winsock2.GetSockName(S,Winsock2.TSockAddr(name^),nameLen^);
  118. end;
  119. function fpgetpeername (s:cint; name : psockaddr; namelen : psocklen):cint;
  120. begin
  121. fpGetPeerName:=Winsock2.GetPeerName(S,Winsock2.TSockAddr(name^),NameLen^);
  122. end;
  123. function fpgetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen : psocklen):cint;
  124. begin
  125. fpGetSockOpt:=Winsock2.GetSockOpt(S,Level,OptName,OptVal,OptLen^);
  126. end;
  127. function fpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint;
  128. begin
  129. fpSetSockOpt:=Winsock2.SetSockOpt(S,Level,OptName,OptVal,OptLen);
  130. end;
  131. function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint;
  132. begin
  133. fpsocketpair:=-1;
  134. WSASetLastError(EOPNOTSUPP); // so that wsagetlasterror retrieves it
  135. end;
  136. Function CloseSocket(Sock:Longint):Longint;
  137. begin
  138. result := Winsock2.CloseSocket (Sock);
  139. end;
  140. Function Bind(Sock:Longint;Const Addr;AddrLen:Longint):Boolean;
  141. begin
  142. bind:=fpBind(Sock,@Addr,AddrLen)=0;
  143. end;
  144. Function Listen(Sock,MaxConnect:Longint):Boolean;
  145. begin
  146. Listen:=fplisten(Sock,MaxConnect)=0;
  147. end;
  148. Function Accept(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  149. begin
  150. Accept:=FPAccept(sock,@addr,@addrlen);
  151. end;
  152. Function Shutdown(Sock:Longint;How:Longint):Longint;
  153. begin
  154. shutdown:=fpshutdown(sock,how);
  155. end;
  156. Function Connect(Sock:Longint;Const Addr;Addrlen:Longint):Boolean;
  157. begin
  158. connect:=fpconnect(sock,@addr,addrlen)=0;
  159. end;
  160. Function GetSocketName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  161. begin
  162. GetSocketName:=fpGetSockName(sock,@addr,@addrlen);
  163. end;
  164. Function GetPeerName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  165. begin
  166. GetPeerName:=fpGetPeerName(Sock,@addr,@addrlen);
  167. end;
  168. Function GetSocketOptions(Sock,Level,OptName:Longint;Var OptVal;Var optlen:longint):Longint;
  169. begin
  170. GetSocketOptions:=fpGetSockOpt(sock,level,optname,@optval,@optlen);
  171. end;
  172. Function SetSocketOptions(Sock,Level,OptName:Longint;Const OptVal;optlen:longint):Longint;
  173. begin
  174. SetSocketOptions:=fpsetsockopt(sock,level,optname,@optval,optlen);
  175. end;
  176. Function SocketPair(Domain,SocketType,Protocol:Longint;var Pair:TSockArray):Longint;
  177. begin
  178. SocketPair:=fpsocketpair(domain,sockettype,protocol,@pair[1]);
  179. end;
  180. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  181. begin
  182. fpWrite := dword(Winsock2.send(handle, bufptr, size, 0));
  183. if fpWrite = dword(winsock2.SOCKET_ERROR) then
  184. fpWrite := 0;
  185. end;
  186. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  187. var
  188. d : dword;
  189. begin
  190. if ioctlsocket(handle,FIONREAD,@d) = winsock2.SOCKET_ERROR then
  191. begin
  192. fpRead:=0;
  193. exit;
  194. end;
  195. if d>0 then
  196. begin
  197. if size>d then
  198. size:=d;
  199. fpRead := dword(Winsock2.recv(handle, bufptr, size, 0));
  200. if fpRead = dword(winsock2.SOCKET_ERROR) then
  201. fpRead := 0;
  202. end;
  203. end;
  204. {$i sockets.inc}
  205. { Winsocket stack needs an init. and cleanup code }
  206. var
  207. wsadata : twsadata;
  208. initialization
  209. WSAStartUp(WINSOCK_VERSION,wsadata);
  210. finalization
  211. WSACleanUp;
  212. end.