sockets.pp 9.2 KB

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