sockets.pp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$mode objfpc}
  12. unit Sockets;
  13. Interface
  14. {$macro on}
  15. {$define maybelibc:=}
  16. Uses
  17. windows,winsock;
  18. Type
  19. cushort=word;
  20. cuint16=word;
  21. cuint32=cardinal;
  22. size_t =cuint32;
  23. ssize_t=cuint16;
  24. cint =longint;
  25. pcint =^cint;
  26. tsocklen=cint;
  27. psocklen=^tsocklen;
  28. Const
  29. AF_MAX = WinSock.AF_MAX;
  30. PF_MAX = AF_MAX;
  31. {$i socketsh.inc}
  32. Implementation
  33. { Include filerec and textrec structures }
  34. {$i filerec.inc}
  35. {$i textrec.inc}
  36. {******************************************************************************
  37. Basic Socket Functions
  38. ******************************************************************************}
  39. //function fprecvmsg (s:cint; msg: pmsghdr; flags:cint):ssize_t;
  40. //function fpsendmsg (s:cint; hdr: pmsghdr; flags:cint):ssize;
  41. //function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  42. function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  43. begin
  44. fpSocket:=WinSock.Socket(Domain,xtype,ProtoCol);
  45. if fpSocket<0 then
  46. SocketError:=WSAGetLastError
  47. else
  48. SocketError:=0;
  49. end;
  50. function fpsend (s:cint; msg:pointer; len:size_t; flags:cint):ssize_t;
  51. begin
  52. fpSend:=WinSock.Send(S,msg,len,flags);
  53. if fpSend<0 then
  54. SocketError:=WSAGetLastError
  55. else
  56. SocketError:=0;
  57. end;
  58. function fpsendto (s:cint; msg:pointer; len:size_t; flags:cint; tox :psockaddr; tolen: tsocklen):ssize_t;
  59. begin
  60. // Dubious construct, this should be checked. (IPV6 fails ?)
  61. fpSendTo:=WinSock.SendTo(S,msg,Len,Flags,Winsock.TSockAddr(tox^),toLen);
  62. if fpSendTo<0 then
  63. SocketError:=WSAGetLastError
  64. else
  65. SocketError:=0;
  66. end;
  67. function fprecv (s:cint; buf: pointer; len: size_t; flags: cint):ssize_t;
  68. begin
  69. fpRecv:=WinSock.Recv(S,Buf,Len,Flags);
  70. if fpRecv<0 then
  71. SocketError:=WSAGetLastError
  72. else
  73. SocketError:=0;
  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. if fpRecvFrom<0 then
  79. SocketError:=WSAGetLastError
  80. else
  81. SocketError:=0;
  82. end;
  83. function fpconnect (s:cint; name : psockaddr; namelen : tsocklen):cint;
  84. begin
  85. fpConnect:=WinSock.Connect(S,WinSock.TSockAddr(name^),nameLen);
  86. if fpConnect<0 then
  87. SocketError:=WSAGetLastError
  88. else
  89. SocketError:=0;
  90. end;
  91. function fpshutdown (s:cint; how:cint):cint;
  92. begin
  93. fpShutDown:=WinSock.ShutDown(S,How);
  94. if fpShutDown<0 then
  95. SocketError:=WSAGetLastError
  96. else
  97. SocketError:=0;
  98. end;
  99. Function socket(Domain,SocketType,Protocol:Longint):Longint;
  100. begin
  101. socket:=fpsocket(Domain,sockettype,protocol);
  102. end;
  103. Function Send(Sock:Longint;Const Buf;BufLen,Flags:Longint):Longint;
  104. begin
  105. send:=fpsend(sock,@buf,buflen,flags);
  106. end;
  107. Function SendTo(Sock:Longint;Const Buf;BufLen,Flags:Longint;Var Addr; AddrLen : Longint):Longint;
  108. begin
  109. sendto:=fpsendto(sock,@buf,buflen,flags,@addr,addrlen);
  110. end;
  111. Function Recv(Sock:Longint;Var Buf;BufLen,Flags:Longint):Longint;
  112. begin
  113. Recv:=fpRecv(Sock,@Buf,BufLen,Flags);
  114. end;
  115. Function RecvFrom(Sock : Longint; Var Buf; Buflen,Flags : Longint; Var Addr; var AddrLen : longint) : longint;
  116. begin
  117. RecvFrom:=fpRecvFrom(Sock,@Buf,BufLen,Flags,@Addr,@AddrLen);
  118. end;
  119. function fpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint;
  120. begin
  121. fpbind:=WinSock.Bind(S,WinSock.PSockAddr(Addrx),AddrLen);
  122. if fpbind<0 then
  123. SocketError:=WSAGetLastError
  124. else
  125. SocketError:=0;
  126. end;
  127. function fplisten (s:cint; backlog : cint):cint;
  128. begin
  129. fplisten:=WinSock.Listen(S,backlog);
  130. if fplisten<0 then
  131. SocketError:=WSAGetLastError
  132. else
  133. SocketError:=0;
  134. end;
  135. function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint;
  136. begin
  137. fpAccept:=WinSock.Accept(S,WinSock.PSockAddr(Addrx),plongint(@AddrLen));
  138. if fpAccept<0 then
  139. SocketError:=WSAGetLastError
  140. else
  141. SocketError:=0;
  142. end;
  143. function fpgetsockname (s:cint; name : psockaddr; namelen : psocklen):cint;
  144. begin
  145. fpGetSockName:=WinSock.GetSockName(S,WinSock.TSockAddr(name^),nameLen^);
  146. if fpGetSockName<0 then
  147. SocketError:=WSAGetLastError
  148. else
  149. SocketError:=0;
  150. end;
  151. function fpgetpeername (s:cint; name : psockaddr; namelen : psocklen):cint;
  152. begin
  153. fpGetPeerName:=WinSock.GetPeerName(S,WinSock.TSockAddr(name^),NameLen^);
  154. if fpGetPeerName<0 then
  155. SocketError:=WSAGetLastError
  156. else
  157. SocketError:=0;
  158. end;
  159. function fpgetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen : psocklen):cint;
  160. begin
  161. fpGetSockOpt:=WinSock.GetSockOpt(S,Level,OptName,OptVal,OptLen^);
  162. if fpGetSockOpt<0 then
  163. SocketError:=WSAGetLastError
  164. else
  165. SocketError:=0;
  166. end;
  167. function fpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint;
  168. begin
  169. fpSetSockOpt:=WinSock.SetSockOpt(S,Level,OptName,OptVal,OptLen);
  170. if fpSetSockOpt<0 then
  171. SocketError:=WSAGetLastError
  172. else
  173. SocketError:=0;
  174. end;
  175. function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint;
  176. begin
  177. end;
  178. Function CloseSocket(Sock:Longint):Longint;
  179. var i : longint;
  180. begin
  181. i := Winsock.CloseSocket (Sock);
  182. if i <> 0 then
  183. begin
  184. SocketError:=WSAGetLastError;
  185. CloseSocket := i;
  186. end else
  187. begin
  188. CloseSocket := 0;
  189. SocketError := 0;
  190. end;
  191. end;
  192. Function Bind(Sock:Longint;Const Addr;AddrLen:Longint):Boolean;
  193. begin
  194. bind:=fpBind(Sock,@Addr,AddrLen)=0;
  195. end;
  196. Function Listen(Sock,MaxConnect:Longint):Boolean;
  197. begin
  198. Listen:=fplisten(Sock,MaxConnect)=0;
  199. end;
  200. Function Accept(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  201. begin
  202. Accept:=FPAccept(sock,@addr,@addrlen);
  203. end;
  204. Function Shutdown(Sock:Longint;How:Longint):Longint;
  205. begin
  206. shutdown:=fpshutdown(sock,how);
  207. end;
  208. Function Connect(Sock:Longint;Const Addr;Addrlen:Longint):Boolean;
  209. begin
  210. connect:=fpconnect(sock,@addr,addrlen)=0;
  211. end;
  212. Function GetSocketName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  213. begin
  214. GetSocketName:=fpGetSockName(sock,@addr,@addrlen);
  215. end;
  216. Function GetPeerName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  217. begin
  218. GetPeerName:=fpGetPeerName(Sock,@addr,@addrlen);
  219. end;
  220. Function GetSocketOptions(Sock,Level,OptName:Longint;Var OptVal;Var optlen:longint):Longint;
  221. begin
  222. GetSocketOptions:=fpGetSockOpt(sock,level,optname,@optval,@optlen);
  223. end;
  224. Function SetSocketOptions(Sock,Level,OptName:Longint;Const OptVal;optlen:longint):Longint;
  225. begin
  226. SetSocketOptions:=fpsetsockopt(sock,level,optname,@optval,optlen);
  227. end;
  228. Function SocketPair(Domain,SocketType,Protocol:Longint;var Pair:TSockArray):Longint;
  229. begin
  230. // SocketPair:=SocketCall(Socket_Sys_SocketPair,Domain,SocketType,Protocol,longint(@Pair),0,0);a
  231. end;
  232. {$ifdef unix}
  233. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  234. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  235. begin
  236. fpWrite := dword(WinSock.send(handle, bufptr, size, 0));
  237. if fpWrite = dword(SOCKET_ERROR) then
  238. begin
  239. SocketError := WSAGetLastError;
  240. fpWrite := 0;
  241. end
  242. else
  243. SocketError := 0;
  244. end;
  245. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  246. var
  247. d : dword;
  248. begin
  249. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  250. begin
  251. SocketError:=WSAGetLastError;
  252. fpRead:=0;
  253. exit;
  254. end;
  255. if d>0 then
  256. begin
  257. if size>d then
  258. size:=d;
  259. fpRead := dword(WinSock.recv(handle, bufptr, size, 0));
  260. if fpRead = dword(SOCKET_ERROR) then
  261. begin
  262. SocketError:= WSAGetLastError;
  263. fpRead := 0;
  264. end else
  265. SocketError:=0;
  266. end
  267. else
  268. SocketError:=0;
  269. end;
  270. {$else}
  271. { mimic the linux fdWrite/fdRead calls for the file/text socket wrapper }
  272. function fdWrite(handle : longint;Const bufptr;size : dword) : dword;
  273. begin
  274. fdWrite := dword(WinSock.send(handle, bufptr, size, 0));
  275. if fdWrite = dword(SOCKET_ERROR) then
  276. begin
  277. SocketError := WSAGetLastError;
  278. fdWrite := 0;
  279. end
  280. else
  281. SocketError := 0;
  282. end;
  283. function fdRead(handle : longint;var bufptr;size : dword) : dword;
  284. var
  285. d : dword;
  286. begin
  287. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  288. begin
  289. SocketError:=WSAGetLastError;
  290. fdRead:=0;
  291. exit;
  292. end;
  293. if d>0 then
  294. begin
  295. if size>d then
  296. size:=d;
  297. fdRead := dword(WinSock.recv(handle, bufptr, size, 0));
  298. if fdRead = dword(SOCKET_ERROR) then
  299. begin
  300. SocketError:= WSAGetLastError;
  301. fdRead := 0;
  302. end else
  303. SocketError:=0;
  304. end
  305. else
  306. SocketError:=0;
  307. end;
  308. {$endif}
  309. {$i sockets.inc}
  310. { winsocket stack needs an init. and cleanup code }
  311. var
  312. wsadata : twsadata;
  313. initialization
  314. WSAStartUp($2,wsadata);
  315. finalization
  316. WSACleanUp;
  317. end.
  318. {
  319. $Log$
  320. Revision 1.13 2004-03-16 18:03:37 marco
  321. * first changes sockets units
  322. Revision 1.12 2003/09/17 15:06:36 peter
  323. * stdcall patch
  324. Revision 1.11 2003/03/23 17:47:15 armin
  325. * CloseSocket added
  326. Revision 1.10 2003/01/01 14:34:22 peter
  327. * sendto overload
  328. Revision 1.9 2002/09/07 16:01:29 peter
  329. * old logs removed and tabs fixed
  330. Revision 1.8 2002/07/17 07:28:21 pierre
  331. * avoid constant evaluation problems if cycling with -Cr
  332. Revision 1.7 2002/02/04 21:41:15 michael
  333. + merged ixed syntax
  334. Revision 1.6 2002/02/04 21:29:34 michael
  335. + merged missing sendto/rcvfrom functions
  336. }