sockets.pp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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. {$i netwsockh.inc}
  30. {$i socketsh.inc}
  31. Implementation
  32. { Include filerec and textrec structures }
  33. {$i filerec.inc}
  34. {$i textrec.inc}
  35. {******************************************************************************
  36. Basic Socket Functions
  37. ******************************************************************************}
  38. //function fprecvmsg (s:cint; msg: pmsghdr; flags:cint):ssize_t;
  39. //function fpsendmsg (s:cint; hdr: pmsghdr; flags:cint):ssize;
  40. //function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  41. function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  42. begin
  43. fpSocket:=WinSock.Socket(Domain,xtype,ProtoCol);
  44. if fpSocket<0 then
  45. SocketError:=WSAGetLastError
  46. else
  47. SocketError:=0;
  48. end;
  49. function fpsend (s:cint; msg:pointer; len:size_t; flags:cint):ssize_t;
  50. begin
  51. fpSend:=WinSock.Send(S,msg,len,flags);
  52. if fpSend<0 then
  53. SocketError:=WSAGetLastError
  54. else
  55. SocketError:=0;
  56. end;
  57. function fpsendto (s:cint; msg:pointer; len:size_t; flags:cint; tox :psockaddr; tolen: tsocklen):ssize_t;
  58. begin
  59. // Dubious construct, this should be checked. (IPV6 fails ?)
  60. fpSendTo:=WinSock.SendTo(S,msg,Len,Flags,Winsock.TSockAddr(tox^),toLen);
  61. if fpSendTo<0 then
  62. SocketError:=WSAGetLastError
  63. else
  64. SocketError:=0;
  65. end;
  66. function fprecv (s:cint; buf: pointer; len: size_t; flags: cint):ssize_t;
  67. begin
  68. fpRecv:=WinSock.Recv(S,Buf,Len,Flags);
  69. if fpRecv<0 then
  70. SocketError:=WSAGetLastError
  71. else
  72. SocketError:=0;
  73. end;
  74. function fprecvfrom (s:cint; buf: pointer; len: size_t; flags: cint; from : psockaddr; fromlen : psocklen):ssize_t;
  75. begin
  76. fpRecvFrom:=WinSock.RecvFrom(S,Buf,Len,Flags,Winsock.TSockAddr(from^),FromLen^);
  77. if fpRecvFrom<0 then
  78. SocketError:=WSAGetLastError
  79. else
  80. SocketError:=0;
  81. end;
  82. function fpconnect (s:cint; name : psockaddr; namelen : tsocklen):cint;
  83. begin
  84. fpConnect:=WinSock.Connect(S,WinSock.TSockAddr(name^),nameLen);
  85. if fpConnect<0 then
  86. SocketError:=WSAGetLastError
  87. else
  88. SocketError:=0;
  89. end;
  90. function fpshutdown (s:cint; how:cint):cint;
  91. begin
  92. fpShutDown:=WinSock.ShutDown(S,How);
  93. if fpShutDown<0 then
  94. SocketError:=WSAGetLastError
  95. else
  96. SocketError:=0;
  97. end;
  98. Function socket(Domain,SocketType,Protocol:Longint):Longint;
  99. begin
  100. socket:=fpsocket(Domain,sockettype,protocol);
  101. end;
  102. Function Send(Sock:Longint;Const Buf;BufLen,Flags:Longint):Longint;
  103. begin
  104. send:=fpsend(sock,@buf,buflen,flags);
  105. end;
  106. Function SendTo(Sock:Longint;Const Buf;BufLen,Flags:Longint;Var Addr; AddrLen : Longint):Longint;
  107. begin
  108. sendto:=fpsendto(sock,@buf,buflen,flags,@addr,addrlen);
  109. end;
  110. Function Recv(Sock:Longint;Var Buf;BufLen,Flags:Longint):Longint;
  111. begin
  112. Recv:=fpRecv(Sock,@Buf,BufLen,Flags);
  113. end;
  114. Function RecvFrom(Sock : Longint; Var Buf; Buflen,Flags : Longint; Var Addr; var AddrLen : longint) : longint;
  115. begin
  116. RecvFrom:=fpRecvFrom(Sock,@Buf,BufLen,Flags,@Addr,@AddrLen);
  117. end;
  118. function fpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint;
  119. begin
  120. fpbind:=WinSock.Bind(S,WinSock.PSockAddr(Addrx),AddrLen);
  121. if fpbind<0 then
  122. SocketError:=WSAGetLastError
  123. else
  124. SocketError:=0;
  125. end;
  126. function fplisten (s:cint; backlog : cint):cint;
  127. begin
  128. fplisten:=WinSock.Listen(S,backlog);
  129. if fplisten<0 then
  130. SocketError:=WSAGetLastError
  131. else
  132. SocketError:=0;
  133. end;
  134. function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint;
  135. begin
  136. fpAccept:=WinSock.Accept(S,WinSock.PSockAddr(Addrx),plongint(AddrLen));
  137. if fpAccept<0 then
  138. SocketError:=WSAGetLastError
  139. else
  140. SocketError:=0;
  141. end;
  142. function fpgetsockname (s:cint; name : psockaddr; namelen : psocklen):cint;
  143. begin
  144. fpGetSockName:=WinSock.GetSockName(S,WinSock.TSockAddr(name^),nameLen^);
  145. if fpGetSockName<0 then
  146. SocketError:=WSAGetLastError
  147. else
  148. SocketError:=0;
  149. end;
  150. function fpgetpeername (s:cint; name : psockaddr; namelen : psocklen):cint;
  151. begin
  152. fpGetPeerName:=WinSock.GetPeerName(S,WinSock.TSockAddr(name^),NameLen^);
  153. if fpGetPeerName<0 then
  154. SocketError:=WSAGetLastError
  155. else
  156. SocketError:=0;
  157. end;
  158. function fpgetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen : psocklen):cint;
  159. begin
  160. fpGetSockOpt:=WinSock.GetSockOpt(S,Level,OptName,OptVal,OptLen^);
  161. if fpGetSockOpt<0 then
  162. SocketError:=WSAGetLastError
  163. else
  164. SocketError:=0;
  165. end;
  166. function fpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint;
  167. begin
  168. fpSetSockOpt:=WinSock.SetSockOpt(S,Level,OptName,OptVal,OptLen);
  169. if fpSetSockOpt<0 then
  170. SocketError:=WSAGetLastError
  171. else
  172. SocketError:=0;
  173. end;
  174. function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint;
  175. begin
  176. fpSocketPair := -1;
  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);
  231. SocketPair := -1;
  232. end;
  233. {$ifdef unix}
  234. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  235. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  236. begin
  237. fpWrite := dword(WinSock.send(handle, bufptr, size, 0));
  238. if fpWrite = dword(SOCKET_ERROR) then
  239. begin
  240. SocketError := WSAGetLastError;
  241. fpWrite := 0;
  242. end
  243. else
  244. SocketError := 0;
  245. end;
  246. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  247. var
  248. d : dword;
  249. begin
  250. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  251. begin
  252. SocketError:=WSAGetLastError;
  253. fpRead:=0;
  254. exit;
  255. end;
  256. if d>0 then
  257. begin
  258. if size>d then
  259. size:=d;
  260. fpRead := dword(WinSock.recv(handle, bufptr, size, 0));
  261. if fpRead = dword(SOCKET_ERROR) then
  262. begin
  263. SocketError:= WSAGetLastError;
  264. fpRead := 0;
  265. end else
  266. SocketError:=0;
  267. end
  268. else
  269. SocketError:=0;
  270. end;
  271. {$else}
  272. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  273. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  274. begin
  275. fpWrite := dword(WinSock.send(handle, bufptr, size, 0));
  276. if fpWrite = dword(SOCKET_ERROR) then
  277. begin
  278. SocketError := WSAGetLastError;
  279. fpWrite := 0;
  280. end
  281. else
  282. SocketError := 0;
  283. end;
  284. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  285. var
  286. d : dword;
  287. begin
  288. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  289. begin
  290. SocketError:=WSAGetLastError;
  291. fpRead:=0;
  292. exit;
  293. end;
  294. if d>0 then
  295. begin
  296. if size>d then
  297. size:=d;
  298. fpRead := dword(WinSock.recv(handle, bufptr, size, 0));
  299. if fpRead = dword(SOCKET_ERROR) then
  300. begin
  301. SocketError:= WSAGetLastError;
  302. fpRead := 0;
  303. end else
  304. SocketError:=0;
  305. end
  306. else
  307. SocketError:=0;
  308. end;
  309. {$endif}
  310. {$i sockets.inc}
  311. { winsocket stack needs an init. and cleanup code }
  312. var
  313. wsadata : twsadata;
  314. initialization
  315. WSAStartUp($2,wsadata);
  316. finalization
  317. WSACleanUp;
  318. end.