sockets.pp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  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 fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  55. begin
  56. fpSocket:=WinSock.Socket(Domain,xtype,ProtoCol);
  57. if fpSocket<0 then
  58. SocketError:=WSAGetLastError
  59. else
  60. SocketError:=0;
  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. if fpSend<0 then
  66. SocketError:=WSAGetLastError
  67. else
  68. SocketError:=0;
  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:=WinSock.SendTo(S,msg,Len,Flags,Winsock.TSockAddr(tox^),toLen);
  74. if fpSendTo<0 then
  75. SocketError:=WSAGetLastError
  76. else
  77. SocketError:=0;
  78. end;
  79. function fprecv (s:cint; buf: pointer; len: size_t; flags: cint):ssize_t;
  80. begin
  81. fpRecv:=WinSock.Recv(S,Buf,Len,Flags);
  82. if fpRecv<0 then
  83. SocketError:=WSAGetLastError
  84. else
  85. SocketError:=0;
  86. end;
  87. function fprecvfrom (s:cint; buf: pointer; len: size_t; flags: cint; from : psockaddr; fromlen : psocklen):ssize_t;
  88. begin
  89. fpRecvFrom:=WinSock.RecvFrom(S,Buf,Len,Flags,Winsock.TSockAddr(from^),FromLen^);
  90. if fpRecvFrom<0 then
  91. SocketError:=WSAGetLastError
  92. else
  93. SocketError:=0;
  94. end;
  95. function fpconnect (s:cint; name : psockaddr; namelen : tsocklen):cint;
  96. begin
  97. fpConnect:=WinSock.Connect(S,WinSock.TSockAddr(name^),nameLen);
  98. if fpConnect<0 then
  99. SocketError:=WSAGetLastError
  100. else
  101. SocketError:=0;
  102. end;
  103. function fpshutdown (s:cint; how:cint):cint;
  104. begin
  105. fpShutDown:=WinSock.ShutDown(S,How);
  106. if fpShutDown<0 then
  107. SocketError:=WSAGetLastError
  108. else
  109. SocketError:=0;
  110. end;
  111. Function socket(Domain,SocketType,Protocol:Longint):Longint;
  112. begin
  113. socket:=fpsocket(Domain,sockettype,protocol);
  114. end;
  115. Function Send(Sock:Longint;Const Buf;BufLen,Flags:Longint):Longint;
  116. begin
  117. send:=fpsend(sock,@buf,buflen,flags);
  118. end;
  119. Function SendTo(Sock:Longint;Const Buf;BufLen,Flags:Longint;Var Addr; AddrLen : Longint):Longint;
  120. begin
  121. sendto:=fpsendto(sock,@buf,buflen,flags,@addr,addrlen);
  122. end;
  123. Function Recv(Sock:Longint;Var Buf;BufLen,Flags:Longint):Longint;
  124. begin
  125. Recv:=fpRecv(Sock,@Buf,BufLen,Flags);
  126. end;
  127. Function RecvFrom(Sock : Longint; Var Buf; Buflen,Flags : Longint; Var Addr; var AddrLen : longint) : longint;
  128. begin
  129. RecvFrom:=fpRecvFrom(Sock,@Buf,BufLen,Flags,@Addr,@AddrLen);
  130. end;
  131. function fpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint;
  132. begin
  133. fpbind:=WinSock.Bind(S,WinSock.PSockAddr(Addrx),AddrLen);
  134. if fpbind<0 then
  135. SocketError:=WSAGetLastError
  136. else
  137. SocketError:=0;
  138. end;
  139. function fplisten (s:cint; backlog : cint):cint;
  140. begin
  141. fplisten:=WinSock.Listen(S,backlog);
  142. if fplisten<0 then
  143. SocketError:=WSAGetLastError
  144. else
  145. SocketError:=0;
  146. end;
  147. function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint;
  148. begin
  149. fpAccept:=WinSock.Accept(S,WinSock.PSockAddr(Addrx),plongint(AddrLen));
  150. if fpAccept<0 then
  151. SocketError:=WSAGetLastError
  152. else
  153. SocketError:=0;
  154. end;
  155. function fpgetsockname (s:cint; name : psockaddr; namelen : psocklen):cint;
  156. begin
  157. fpGetSockName:=WinSock.GetSockName(S,WinSock.TSockAddr(name^),nameLen^);
  158. if fpGetSockName<0 then
  159. SocketError:=WSAGetLastError
  160. else
  161. SocketError:=0;
  162. end;
  163. function fpgetpeername (s:cint; name : psockaddr; namelen : psocklen):cint;
  164. begin
  165. fpGetPeerName:=WinSock.GetPeerName(S,WinSock.TSockAddr(name^),NameLen^);
  166. if fpGetPeerName<0 then
  167. SocketError:=WSAGetLastError
  168. else
  169. SocketError:=0;
  170. end;
  171. function fpgetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen : psocklen):cint;
  172. begin
  173. fpGetSockOpt:=WinSock.GetSockOpt(S,Level,OptName,OptVal,OptLen^);
  174. if fpGetSockOpt<0 then
  175. SocketError:=WSAGetLastError
  176. else
  177. SocketError:=0;
  178. end;
  179. function fpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint;
  180. begin
  181. fpSetSockOpt:=WinSock.SetSockOpt(S,Level,OptName,OptVal,OptLen);
  182. if fpSetSockOpt<0 then
  183. SocketError:=WSAGetLastError
  184. else
  185. SocketError:=0;
  186. end;
  187. function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint;
  188. begin
  189. fpSocketPair := -1;
  190. end;
  191. Function CloseSocket(Sock:Longint):Longint;
  192. var i : longint;
  193. begin
  194. i := Winsock.CloseSocket (Sock);
  195. if i <> 0 then
  196. begin
  197. SocketError:=WSAGetLastError;
  198. CloseSocket := i;
  199. end else
  200. begin
  201. CloseSocket := 0;
  202. SocketError := 0;
  203. end;
  204. end;
  205. Function Bind(Sock:Longint;Const Addr;AddrLen:Longint):Boolean;
  206. begin
  207. bind:=fpBind(Sock,@Addr,AddrLen)=0;
  208. end;
  209. Function Listen(Sock,MaxConnect:Longint):Boolean;
  210. begin
  211. Listen:=fplisten(Sock,MaxConnect)=0;
  212. end;
  213. Function Accept(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  214. begin
  215. Accept:=FPAccept(sock,@addr,@addrlen);
  216. end;
  217. Function Shutdown(Sock:Longint;How:Longint):Longint;
  218. begin
  219. shutdown:=fpshutdown(sock,how);
  220. end;
  221. Function Connect(Sock:Longint;Const Addr;Addrlen:Longint):Boolean;
  222. begin
  223. connect:=fpconnect(sock,@addr,addrlen)=0;
  224. end;
  225. Function GetSocketName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  226. begin
  227. GetSocketName:=fpGetSockName(sock,@addr,@addrlen);
  228. end;
  229. Function GetPeerName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  230. begin
  231. GetPeerName:=fpGetPeerName(Sock,@addr,@addrlen);
  232. end;
  233. Function GetSocketOptions(Sock,Level,OptName:Longint;Var OptVal;Var optlen:longint):Longint;
  234. begin
  235. GetSocketOptions:=fpGetSockOpt(sock,level,optname,@optval,@optlen);
  236. end;
  237. Function SetSocketOptions(Sock,Level,OptName:Longint;Const OptVal;optlen:longint):Longint;
  238. begin
  239. SetSocketOptions:=fpsetsockopt(sock,level,optname,@optval,optlen);
  240. end;
  241. Function SocketPair(Domain,SocketType,Protocol:Longint;var Pair:TSockArray):Longint;
  242. begin
  243. // SocketPair:=SocketCall(Socket_Sys_SocketPair,Domain,SocketType,Protocol,longint(@Pair),0,0);
  244. SocketPair := -1;
  245. end;
  246. {$ifdef unix}
  247. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  248. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  249. begin
  250. fpWrite := dword(WinSock.send(handle, bufptr, size, 0));
  251. if fpWrite = dword(SOCKET_ERROR) then
  252. begin
  253. SocketError := WSAGetLastError;
  254. fpWrite := 0;
  255. end
  256. else
  257. SocketError := 0;
  258. end;
  259. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  260. var
  261. d : dword;
  262. begin
  263. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  264. begin
  265. SocketError:=WSAGetLastError;
  266. fpRead:=0;
  267. exit;
  268. end;
  269. if d>0 then
  270. begin
  271. if size>d then
  272. size:=d;
  273. fpRead := dword(WinSock.recv(handle, bufptr, size, 0));
  274. if fpRead = dword(SOCKET_ERROR) then
  275. begin
  276. SocketError:= WSAGetLastError;
  277. fpRead := 0;
  278. end else
  279. SocketError:=0;
  280. end
  281. else
  282. SocketError:=0;
  283. end;
  284. {$else}
  285. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  286. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  287. begin
  288. fpWrite := dword(WinSock.send(handle, bufptr, size, 0));
  289. if fpWrite = dword(SOCKET_ERROR) then
  290. begin
  291. SocketError := WSAGetLastError;
  292. fpWrite := 0;
  293. end
  294. else
  295. SocketError := 0;
  296. end;
  297. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  298. var
  299. d : dword;
  300. begin
  301. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  302. begin
  303. SocketError:=WSAGetLastError;
  304. fpRead:=0;
  305. exit;
  306. end;
  307. if d>0 then
  308. begin
  309. if size>d then
  310. size:=d;
  311. fpRead := dword(WinSock.recv(handle, bufptr, size, 0));
  312. if fpRead = dword(SOCKET_ERROR) then
  313. begin
  314. SocketError:= WSAGetLastError;
  315. fpRead := 0;
  316. end else
  317. SocketError:=0;
  318. end
  319. else
  320. SocketError:=0;
  321. end;
  322. {$endif}
  323. {$i sockets.inc}
  324. { winsocket stack needs an init. and cleanup code }
  325. var
  326. wsadata : twsadata;
  327. initialization
  328. WSAStartUp($2,wsadata);
  329. finalization
  330. WSACleanUp;
  331. end.