2
0

sockets.pp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2004 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. {$R-}
  16. Uses
  17. winsock;
  18. Type
  19. cushort=word;
  20. cuint8 =byte;
  21. cuint16=word;
  22. cuint32=cardinal;
  23. size_t =cuint32;
  24. ssize_t=cuint16;
  25. cint =longint;
  26. pcint =^cint;
  27. tsocklen=cint;
  28. psocklen=^tsocklen;
  29. const
  30. EsockEINTR = WSAEINTR;
  31. EsockEBADF = WSAEBADF;
  32. EsockEFAULT = WSAEFAULT;
  33. EsockEINVAL = WSAEINVAL;
  34. EsockEACCESS = WSAEACCES;
  35. EsockEMFILE = WSAEMFILE;
  36. EsockEMSGSIZE = WSAEMSGSIZE;
  37. EsockENOBUFS = WSAENOBUFS;
  38. EsockENOTCONN = WSAENOTCONN;
  39. EsockENOTSOCK = WSAENOTSOCK;
  40. EsockEPROTONOSUPPORT = WSAEPROTONOSUPPORT;
  41. EsockEWOULDBLOCK = WSAEWOULDBLOCK;
  42. {$i netwsockh.inc}
  43. {$i socketsh.inc}
  44. Implementation
  45. { Include filerec and textrec structures }
  46. {$i filerec.inc}
  47. {$i textrec.inc}
  48. {******************************************************************************
  49. Basic Socket Functions
  50. ******************************************************************************}
  51. //function fprecvmsg (s:cint; msg: pmsghdr; flags:cint):ssize_t;
  52. //function fpsendmsg (s:cint; hdr: pmsghdr; flags:cint):ssize;
  53. //function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  54. function SocketError: cint;
  55. begin
  56. SocketError := WSAGetLastError;
  57. end;
  58. function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  59. begin
  60. fpSocket:=WinSock.Socket(Domain,xtype,ProtoCol);
  61. end;
  62. function fpsend (s:cint; msg:pointer; len:size_t; flags:cint):ssize_t;
  63. begin
  64. fpSend:=WinSock.Send(S,msg,len,flags);
  65. end;
  66. function fpsendto (s:cint; msg:pointer; len:size_t; flags:cint; tox :psockaddr; tolen: tsocklen):ssize_t;
  67. begin
  68. // Dubious construct, this should be checked. (IPV6 fails ?)
  69. fpSendTo:=WinSock.SendTo(S,msg,Len,Flags,Winsock.TSockAddr(tox^),toLen);
  70. end;
  71. function fprecv (s:cint; buf: pointer; len: size_t; flags: cint):ssize_t;
  72. begin
  73. fpRecv:=WinSock.Recv(S,Buf,Len,Flags);
  74. end;
  75. function fprecvfrom (s:cint; buf: pointer; len: size_t; flags: cint; from : psockaddr; fromlen : psocklen):ssize_t;
  76. begin
  77. fpRecvFrom:=WinSock.RecvFrom(S,Buf,Len,Flags,Winsock.TSockAddr(from^),FromLen^);
  78. end;
  79. function fpconnect (s:cint; name : psockaddr; namelen : tsocklen):cint;
  80. begin
  81. fpConnect:=WinSock.Connect(S,WinSock.TSockAddr(name^),nameLen);
  82. end;
  83. function fpshutdown (s:cint; how:cint):cint;
  84. begin
  85. fpShutDown:=WinSock.ShutDown(S,How);
  86. end;
  87. Function socket(Domain,SocketType,Protocol:Longint):Longint;
  88. begin
  89. socket:=fpsocket(Domain,sockettype,protocol);
  90. end;
  91. Function Send(Sock:Longint;Const Buf;BufLen,Flags:Longint):Longint;
  92. begin
  93. send:=fpsend(sock,@buf,buflen,flags);
  94. end;
  95. Function SendTo(Sock:Longint;Const Buf;BufLen,Flags:Longint;Var Addr; AddrLen : Longint):Longint;
  96. begin
  97. sendto:=fpsendto(sock,@buf,buflen,flags,@addr,addrlen);
  98. end;
  99. Function Recv(Sock:Longint;Var Buf;BufLen,Flags:Longint):Longint;
  100. begin
  101. Recv:=fpRecv(Sock,@Buf,BufLen,Flags);
  102. end;
  103. Function RecvFrom(Sock : Longint; Var Buf; Buflen,Flags : Longint; Var Addr; var AddrLen : longint) : longint;
  104. begin
  105. RecvFrom:=fpRecvFrom(Sock,@Buf,BufLen,Flags,@Addr,@AddrLen);
  106. end;
  107. function fpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint;
  108. begin
  109. fpbind:=WinSock.Bind(S,WinSock.PSockAddr(Addrx),AddrLen);
  110. end;
  111. function fplisten (s:cint; backlog : cint):cint;
  112. begin
  113. fplisten:=WinSock.Listen(S,backlog);
  114. end;
  115. function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint;
  116. begin
  117. fpAccept:=WinSock.Accept(S,WinSock.PSockAddr(Addrx),plongint(AddrLen));
  118. end;
  119. function fpgetsockname (s:cint; name : psockaddr; namelen : psocklen):cint;
  120. begin
  121. fpGetSockName:=WinSock.GetSockName(S,WinSock.TSockAddr(name^),nameLen^);
  122. end;
  123. function fpgetpeername (s:cint; name : psockaddr; namelen : psocklen):cint;
  124. begin
  125. fpGetPeerName:=WinSock.GetPeerName(S,WinSock.TSockAddr(name^),NameLen^);
  126. end;
  127. function fpgetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen : psocklen):cint;
  128. begin
  129. fpGetSockOpt:=WinSock.GetSockOpt(S,Level,OptName,OptVal,OptLen^);
  130. end;
  131. function fpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint;
  132. begin
  133. fpSetSockOpt:=WinSock.SetSockOpt(S,Level,OptName,OptVal,OptLen);
  134. end;
  135. function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint;
  136. begin
  137. fpSocketPair := -1;
  138. end;
  139. Function CloseSocket(Sock:Longint):Longint;
  140. begin
  141. CloseSocket := Winsock.CloseSocket (Sock);
  142. end;
  143. Function Bind(Sock:Longint;Const Addr;AddrLen:Longint):Boolean;
  144. begin
  145. bind:=fpBind(Sock,@Addr,AddrLen)=0;
  146. end;
  147. Function Listen(Sock,MaxConnect:Longint):Boolean;
  148. begin
  149. Listen:=fplisten(Sock,MaxConnect)=0;
  150. end;
  151. Function Accept(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  152. begin
  153. Accept:=FPAccept(sock,@addr,@addrlen);
  154. end;
  155. Function Shutdown(Sock:Longint;How:Longint):Longint;
  156. begin
  157. shutdown:=fpshutdown(sock,how);
  158. end;
  159. Function Connect(Sock:Longint;Const Addr;Addrlen:Longint):Boolean;
  160. begin
  161. connect:=fpconnect(sock,@addr,addrlen)=0;
  162. end;
  163. Function GetSocketName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  164. begin
  165. GetSocketName:=fpGetSockName(sock,@addr,@addrlen);
  166. end;
  167. Function GetPeerName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  168. begin
  169. GetPeerName:=fpGetPeerName(Sock,@addr,@addrlen);
  170. end;
  171. Function GetSocketOptions(Sock,Level,OptName:Longint;Var OptVal;Var optlen:longint):Longint;
  172. begin
  173. GetSocketOptions:=fpGetSockOpt(sock,level,optname,@optval,@optlen);
  174. end;
  175. Function SetSocketOptions(Sock,Level,OptName:Longint;Const OptVal;optlen:longint):Longint;
  176. begin
  177. SetSocketOptions:=fpsetsockopt(sock,level,optname,@optval,optlen);
  178. end;
  179. Function SocketPair(Domain,SocketType,Protocol:Longint;var Pair:TSockArray):Longint;
  180. begin
  181. // SocketPair:=SocketCall(Socket_Sys_SocketPair,Domain,SocketType,Protocol,longint(@Pair),0,0);
  182. SocketPair := -1;
  183. end;
  184. {$ifdef unix}
  185. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  186. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  187. begin
  188. fpWrite := dword(WinSock.send(handle, bufptr, size, 0));
  189. if fpWrite = dword(SOCKET_ERROR) then
  190. fpWrite := 0;
  191. end;
  192. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  193. var
  194. d : dword;
  195. begin
  196. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  197. begin
  198. fpRead:=0;
  199. exit;
  200. end;
  201. if d>0 then
  202. begin
  203. if size>d then
  204. size:=d;
  205. fpRead := dword(WinSock.recv(handle, bufptr, size, 0));
  206. if fpRead = dword(SOCKET_ERROR) then
  207. fpRead := 0;
  208. end;
  209. end;
  210. {$else}
  211. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  212. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  213. begin
  214. fpWrite := dword(WinSock.send(handle, bufptr, size, 0));
  215. if fpWrite = dword(SOCKET_ERROR) then
  216. fpWrite := 0;
  217. end;
  218. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  219. var
  220. d : dword;
  221. begin
  222. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  223. begin
  224. fpRead:=0;
  225. exit;
  226. end;
  227. if d>0 then
  228. begin
  229. if size>d then
  230. size:=d;
  231. fpRead := dword(WinSock.recv(handle, bufptr, size, 0));
  232. if fpRead = dword(SOCKET_ERROR) then
  233. fpRead := 0;
  234. end;
  235. end;
  236. {$endif}
  237. {$i sockets.inc}
  238. { winsocket stack needs an init. and cleanup code }
  239. var
  240. wsadata : twsadata;
  241. initialization
  242. WSAStartUp($2,wsadata);
  243. finalization
  244. WSACleanUp;
  245. end.