sockets.pp 9.1 KB

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