sockets.pp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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. Implementation
  46. { Include filerec and textrec structures }
  47. {$i filerec.inc}
  48. {$i textrec.inc}
  49. {******************************************************************************
  50. Basic Socket Functions
  51. ******************************************************************************}
  52. //function fprecvmsg (s:cint; msg: pmsghdr; flags:cint):ssize_t;
  53. //function fpsendmsg (s:cint; hdr: pmsghdr; flags:cint):ssize;
  54. //function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  55. function socketerror:cint;
  56. begin
  57. result:=wsagetlasterror;
  58. end;
  59. function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  60. begin
  61. fpSocket:=WinSock2.Socket(Domain,xtype,ProtoCol);
  62. end;
  63. function fpsend (s:cint; msg:pointer; len:size_t; flags:cint):ssize_t;
  64. begin
  65. fpSend:=WinSock2.Send(S,msg,len,flags);
  66. end;
  67. function fpsendto (s:cint; msg:pointer; len:size_t; flags:cint; tox :psockaddr; tolen: tsocklen):ssize_t;
  68. begin
  69. // Dubious construct, this should be checked. (IPV6 fails ?)
  70. fpSendTo:=WinSock2.SendTo(S,msg,Len,Flags,Winsock2.PSockAddr(tox),toLen);
  71. end;
  72. function fprecv (s:cint; buf: pointer; len: size_t; flags: cint):ssize_t;
  73. begin
  74. fpRecv:=WinSock2.Recv(S,Buf,Len,Flags);
  75. end;
  76. function fprecvfrom (s:cint; buf: pointer; len: size_t; flags: cint; from : psockaddr; fromlen : psocklen):ssize_t;
  77. begin
  78. fpRecvFrom:=WinSock2.RecvFrom(S,Buf,Len,Flags,WinSock2.PSockAddr(From),FromLen);
  79. end;
  80. function fpconnect (s:cint; name : psockaddr; namelen : tsocklen):cint;
  81. begin
  82. fpConnect:=Winsock2.Connect(S,WinSock2.PSockAddr(name),nameLen);
  83. end;
  84. function fpshutdown (s:cint; how:cint):cint;
  85. begin
  86. fpShutDown:=Winsock2.ShutDown(S,How);
  87. end;
  88. Function socket(Domain,SocketType,Protocol:Longint):Longint;
  89. begin
  90. socket:=fpsocket(Domain,sockettype,protocol);
  91. end;
  92. Function Send(Sock:Longint;Const Buf;BufLen,Flags:Longint):Longint;
  93. begin
  94. send:=fpsend(sock,@buf,buflen,flags);
  95. end;
  96. Function SendTo(Sock:Longint;Const Buf;BufLen,Flags:Longint;Var Addr; AddrLen : Longint):Longint;
  97. begin
  98. sendto:=fpsendto(sock,@buf,buflen,flags,@addr,addrlen);
  99. end;
  100. Function Recv(Sock:Longint;Var Buf;BufLen,Flags:Longint):Longint;
  101. begin
  102. Recv:=fpRecv(Sock,@Buf,BufLen,Flags);
  103. end;
  104. Function RecvFrom(Sock : Longint; Var Buf; Buflen,Flags : Longint; Var Addr; var AddrLen : longint) : longint;
  105. begin
  106. RecvFrom:=fpRecvFrom(Sock,@Buf,BufLen,Flags,@Addr,@AddrLen);
  107. end;
  108. function fpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint;
  109. begin
  110. fpbind:=Winsock2.Bind(S,Winsock2.PSockAddr(Addrx),AddrLen);
  111. end;
  112. function fplisten (s:cint; backlog : cint):cint;
  113. begin
  114. fplisten:=Winsock2.Listen(S,backlog);
  115. end;
  116. function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint;
  117. begin
  118. fpAccept:=Winsock2.Accept(S,Winsock2.PSockAddr(Addrx), AddrLen);
  119. end;
  120. function fpgetsockname (s:cint; name : psockaddr; namelen : psocklen):cint;
  121. begin
  122. fpGetSockName:=Winsock2.GetSockName(S,Winsock2.TSockAddr(name^),nameLen^);
  123. end;
  124. function fpgetpeername (s:cint; name : psockaddr; namelen : psocklen):cint;
  125. begin
  126. fpGetPeerName:=Winsock2.GetPeerName(S,Winsock2.TSockAddr(name^),NameLen^);
  127. end;
  128. function fpgetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen : psocklen):cint;
  129. begin
  130. fpGetSockOpt:=Winsock2.GetSockOpt(S,Level,OptName,OptVal,OptLen^);
  131. end;
  132. function fpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint;
  133. begin
  134. fpSetSockOpt:=Winsock2.SetSockOpt(S,Level,OptName,OptVal,OptLen);
  135. end;
  136. function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint;
  137. begin
  138. fpsocketpair:=-1;
  139. WSASetLastError(EOPNOTSUPP); // so that wsagetlasterror retrieves it
  140. end;
  141. Function CloseSocket(Sock:Longint):Longint;
  142. begin
  143. result := Winsock2.CloseSocket (Sock);
  144. end;
  145. Function Bind(Sock:Longint;Const Addr;AddrLen:Longint):Boolean;
  146. begin
  147. bind:=fpBind(Sock,@Addr,AddrLen)=0;
  148. end;
  149. Function Listen(Sock,MaxConnect:Longint):Boolean;
  150. begin
  151. Listen:=fplisten(Sock,MaxConnect)=0;
  152. end;
  153. Function Accept(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  154. begin
  155. Accept:=FPAccept(sock,@addr,@addrlen);
  156. end;
  157. Function Shutdown(Sock:Longint;How:Longint):Longint;
  158. begin
  159. shutdown:=fpshutdown(sock,how);
  160. end;
  161. Function Connect(Sock:Longint;Const Addr;Addrlen:Longint):Boolean;
  162. begin
  163. connect:=fpconnect(sock,@addr,addrlen)=0;
  164. end;
  165. Function GetSocketName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  166. begin
  167. GetSocketName:=fpGetSockName(sock,@addr,@addrlen);
  168. end;
  169. Function GetPeerName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  170. begin
  171. GetPeerName:=fpGetPeerName(Sock,@addr,@addrlen);
  172. end;
  173. Function GetSocketOptions(Sock,Level,OptName:Longint;Var OptVal;Var optlen:longint):Longint;
  174. begin
  175. GetSocketOptions:=fpGetSockOpt(sock,level,optname,@optval,@optlen);
  176. end;
  177. Function SetSocketOptions(Sock,Level,OptName:Longint;Const OptVal;optlen:longint):Longint;
  178. begin
  179. SetSocketOptions:=fpsetsockopt(sock,level,optname,@optval,optlen);
  180. end;
  181. Function SocketPair(Domain,SocketType,Protocol:Longint;var Pair:TSockArray):Longint;
  182. begin
  183. SocketPair:=fpsocketpair(domain,sockettype,protocol,@pair[1]);
  184. end;
  185. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  186. begin
  187. fpWrite := dword(Winsock2.send(handle, bufptr, size, 0));
  188. if fpWrite = dword(winsock2.SOCKET_ERROR) then
  189. fpWrite := 0;
  190. end;
  191. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  192. var
  193. d : dword;
  194. begin
  195. if ioctlsocket(handle,FIONREAD,@d) = winsock2.SOCKET_ERROR then
  196. begin
  197. fpRead:=0;
  198. exit;
  199. end;
  200. if d>0 then
  201. begin
  202. if size>d then
  203. size:=d;
  204. fpRead := dword(Winsock2.recv(handle, bufptr, size, 0));
  205. if fpRead = dword(winsock2.SOCKET_ERROR) then
  206. fpRead := 0;
  207. end;
  208. end;
  209. {$i sockets.inc}
  210. { Winsocket stack needs an init. and cleanup code }
  211. var
  212. wsadata : twsadata;
  213. initialization
  214. WSAStartUp(WINSOCK_VERSION,wsadata);
  215. finalization
  216. WSACleanUp;
  217. end.