sockets.pp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. // the common socket functions are defined as size_t.
  19. // without defining them for Windows this way, the
  20. // sockets unit is not crossplatform. This is not a mistake
  21. // wrt 64-bit, the types are "INT" in the headers.
  22. // Mantis #22834
  23. size_t = cuint32;
  24. ssize_t = cint32;
  25. tsocklen= cint;
  26. psocklen= ^tsocklen;
  27. const
  28. EsockEINTR = WSAEINTR;
  29. EsockEBADF = WSAEBADF;
  30. EsockEFAULT = WSAEFAULT;
  31. EsockEINVAL = WSAEINVAL;
  32. EsockEACCESS = WSAEACCES;
  33. EsockEMFILE = WSAEMFILE;
  34. EsockEMSGSIZE = WSAEMSGSIZE;
  35. EsockENOBUFS = WSAENOBUFS;
  36. EsockENOTCONN = WSAENOTCONN;
  37. EsockENOTSOCK = WSAENOTSOCK;
  38. EsockEPROTONOSUPPORT = WSAEPROTONOSUPPORT;
  39. EsockEWOULDBLOCK = WSAEWOULDBLOCK;
  40. SHUT_RD = SD_RECEIVE; // aliases so we are cross-platform
  41. SHUT_WR = SD_SEND;
  42. SHUT_RDWR = SD_BOTH;
  43. {$i socketsh.inc}
  44. {$i fpwinsockh.inc}
  45. // finalizing Winsock2 stack might upset other DLLS. Mantis #22597
  46. var
  47. NoWinsockCleanupCall : Boolean = false;
  48. Implementation
  49. { Include filerec and textrec structures }
  50. {$i filerec.inc}
  51. {$i textrec.inc}
  52. {******************************************************************************
  53. Basic Socket Functions
  54. ******************************************************************************}
  55. //function fprecvmsg (s:cint; msg: pmsghdr; flags:cint):ssize_t;
  56. //function fpsendmsg (s:cint; hdr: pmsghdr; flags:cint):ssize;
  57. //function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  58. function socketerror:cint;
  59. begin
  60. result:=wsagetlasterror;
  61. end;
  62. function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  63. begin
  64. fpSocket:=WinSock2.Socket(Domain,xtype,ProtoCol);
  65. end;
  66. function fpsend (s:cint; msg:pointer; len:size_t; flags:cint):ssize_t;
  67. begin
  68. fpSend:=WinSock2.Send(S,msg,len,flags);
  69. end;
  70. function fpsendto (s:cint; msg:pointer; len:size_t; flags:cint; tox :psockaddr; tolen: tsocklen):ssize_t;
  71. begin
  72. // Dubious construct, this should be checked. (IPV6 fails ?)
  73. fpSendTo:=WinSock2.SendTo(S,msg,Len,Flags,Winsock2.PSockAddr(tox),toLen);
  74. end;
  75. function fprecv (s:cint; buf: pointer; len: size_t; flags: cint):ssize_t;
  76. begin
  77. fpRecv:=WinSock2.Recv(S,Buf,Len,Flags);
  78. end;
  79. function fprecvfrom (s:cint; buf: pointer; len: size_t; flags: cint; from : psockaddr; fromlen : psocklen):ssize_t;
  80. begin
  81. fpRecvFrom:=WinSock2.RecvFrom(S,Buf,Len,Flags,WinSock2.PSockAddr(From),FromLen);
  82. end;
  83. function fpconnect (s:cint; name : psockaddr; namelen : tsocklen):cint;
  84. begin
  85. fpConnect:=Winsock2.Connect(S,WinSock2.PSockAddr(name),nameLen);
  86. end;
  87. function fpshutdown (s:cint; how:cint):cint;
  88. begin
  89. fpShutDown:=Winsock2.ShutDown(S,How);
  90. end;
  91. Function socket(Domain,SocketType,Protocol:Longint):Longint;
  92. begin
  93. socket:=fpsocket(Domain,sockettype,protocol);
  94. end;
  95. Function Send(Sock:Longint;Const Buf;BufLen,Flags:Longint):Longint;
  96. begin
  97. send:=fpsend(sock,@buf,buflen,flags);
  98. end;
  99. Function SendTo(Sock:Longint;Const Buf;BufLen,Flags:Longint;Var Addr; AddrLen : Longint):Longint;
  100. begin
  101. sendto:=fpsendto(sock,@buf,buflen,flags,@addr,addrlen);
  102. end;
  103. Function Recv(Sock:Longint;Var Buf;BufLen,Flags:Longint):Longint;
  104. begin
  105. Recv:=fpRecv(Sock,@Buf,BufLen,Flags);
  106. end;
  107. Function RecvFrom(Sock : Longint; Var Buf; Buflen,Flags : Longint; Var Addr; var AddrLen : longint) : longint;
  108. begin
  109. RecvFrom:=fpRecvFrom(Sock,@Buf,BufLen,Flags,@Addr,@AddrLen);
  110. end;
  111. function fpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint;
  112. begin
  113. fpbind:=Winsock2.Bind(S,Winsock2.PSockAddr(Addrx),AddrLen);
  114. end;
  115. function fplisten (s:cint; backlog : cint):cint;
  116. begin
  117. fplisten:=Winsock2.Listen(S,backlog);
  118. end;
  119. function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint;
  120. begin
  121. fpAccept:=Winsock2.Accept(S,Winsock2.PSockAddr(Addrx), AddrLen);
  122. end;
  123. function fpgetsockname (s:cint; name : psockaddr; namelen : psocklen):cint;
  124. begin
  125. fpGetSockName:=Winsock2.GetSockName(S,Winsock2.TSockAddr(name^),nameLen^);
  126. end;
  127. function fpgetpeername (s:cint; name : psockaddr; namelen : psocklen):cint;
  128. begin
  129. fpGetPeerName:=Winsock2.GetPeerName(S,Winsock2.TSockAddr(name^),NameLen^);
  130. end;
  131. function fpgetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen : psocklen):cint;
  132. begin
  133. fpGetSockOpt:=Winsock2.GetSockOpt(S,Level,OptName,OptVal,OptLen^);
  134. end;
  135. function fpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint;
  136. begin
  137. fpSetSockOpt:=Winsock2.SetSockOpt(S,Level,OptName,OptVal,OptLen);
  138. end;
  139. function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint;
  140. begin
  141. fpsocketpair:=-1;
  142. WSASetLastError(EOPNOTSUPP); // so that wsagetlasterror retrieves it
  143. end;
  144. Function CloseSocket(Sock:Longint):Longint;
  145. begin
  146. result := Winsock2.CloseSocket (Sock);
  147. end;
  148. Function Bind(Sock:Longint;Const Addr;AddrLen:Longint):Boolean;
  149. begin
  150. bind:=fpBind(Sock,@Addr,AddrLen)=0;
  151. end;
  152. Function Listen(Sock,MaxConnect:Longint):Boolean;
  153. begin
  154. Listen:=fplisten(Sock,MaxConnect)=0;
  155. end;
  156. Function Accept(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  157. begin
  158. Accept:=FPAccept(sock,@addr,@addrlen);
  159. end;
  160. Function Shutdown(Sock:Longint;How:Longint):Longint;
  161. begin
  162. shutdown:=fpshutdown(sock,how);
  163. end;
  164. Function Connect(Sock:Longint;Const Addr;Addrlen:Longint):Boolean;
  165. begin
  166. connect:=fpconnect(sock,@addr,addrlen)=0;
  167. end;
  168. Function GetSocketName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  169. begin
  170. GetSocketName:=fpGetSockName(sock,@addr,@addrlen);
  171. end;
  172. Function GetPeerName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  173. begin
  174. GetPeerName:=fpGetPeerName(Sock,@addr,@addrlen);
  175. end;
  176. Function GetSocketOptions(Sock,Level,OptName:Longint;Var OptVal;Var optlen:longint):Longint;
  177. begin
  178. GetSocketOptions:=fpGetSockOpt(sock,level,optname,@optval,@optlen);
  179. end;
  180. Function SetSocketOptions(Sock,Level,OptName:Longint;Const OptVal;optlen:longint):Longint;
  181. begin
  182. SetSocketOptions:=fpsetsockopt(sock,level,optname,@optval,optlen);
  183. end;
  184. Function SocketPair(Domain,SocketType,Protocol:Longint;var Pair:TSockArray):Longint;
  185. begin
  186. SocketPair:=fpsocketpair(domain,sockettype,protocol,@pair[1]);
  187. end;
  188. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  189. begin
  190. fpWrite := dword(Winsock2.send(handle, bufptr, size, 0));
  191. if fpWrite = dword(winsock2.SOCKET_ERROR) then
  192. fpWrite := 0;
  193. end;
  194. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  195. var
  196. d : dword;
  197. begin
  198. if ioctlsocket(handle,FIONREAD,@d) = winsock2.SOCKET_ERROR then
  199. begin
  200. fpRead:=0;
  201. exit;
  202. end;
  203. if d>0 then
  204. begin
  205. if size>d then
  206. size:=d;
  207. fpRead := dword(Winsock2.recv(handle, bufptr, size, 0));
  208. if fpRead = dword(winsock2.SOCKET_ERROR) then
  209. fpRead := 0;
  210. end;
  211. end;
  212. {$i sockets.inc}
  213. { Winsocket stack needs an init. and cleanup code }
  214. var
  215. wsadata : twsadata;
  216. initialization
  217. WSAStartUp(WINSOCK_VERSION,wsadata);
  218. finalization
  219. If Not NoWinsockCleanupCall Then
  220. WSACleanUp;
  221. end.