sockets.pp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  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. 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. fpSocketPair := -1;
  178. end;
  179. Function CloseSocket(Sock:Longint):Longint;
  180. var i : longint;
  181. begin
  182. i := Winsock.CloseSocket (Sock);
  183. if i <> 0 then
  184. begin
  185. SocketError:=WSAGetLastError;
  186. CloseSocket := i;
  187. end else
  188. begin
  189. CloseSocket := 0;
  190. SocketError := 0;
  191. end;
  192. end;
  193. Function Bind(Sock:Longint;Const Addr;AddrLen:Longint):Boolean;
  194. begin
  195. bind:=fpBind(Sock,@Addr,AddrLen)=0;
  196. end;
  197. Function Listen(Sock,MaxConnect:Longint):Boolean;
  198. begin
  199. Listen:=fplisten(Sock,MaxConnect)=0;
  200. end;
  201. Function Accept(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  202. begin
  203. Accept:=FPAccept(sock,@addr,@addrlen);
  204. end;
  205. Function Shutdown(Sock:Longint;How:Longint):Longint;
  206. begin
  207. shutdown:=fpshutdown(sock,how);
  208. end;
  209. Function Connect(Sock:Longint;Const Addr;Addrlen:Longint):Boolean;
  210. begin
  211. connect:=fpconnect(sock,@addr,addrlen)=0;
  212. end;
  213. Function GetSocketName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  214. begin
  215. GetSocketName:=fpGetSockName(sock,@addr,@addrlen);
  216. end;
  217. Function GetPeerName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  218. begin
  219. GetPeerName:=fpGetPeerName(Sock,@addr,@addrlen);
  220. end;
  221. Function GetSocketOptions(Sock,Level,OptName:Longint;Var OptVal;Var optlen:longint):Longint;
  222. begin
  223. GetSocketOptions:=fpGetSockOpt(sock,level,optname,@optval,@optlen);
  224. end;
  225. Function SetSocketOptions(Sock,Level,OptName:Longint;Const OptVal;optlen:longint):Longint;
  226. begin
  227. SetSocketOptions:=fpsetsockopt(sock,level,optname,@optval,optlen);
  228. end;
  229. Function SocketPair(Domain,SocketType,Protocol:Longint;var Pair:TSockArray):Longint;
  230. begin
  231. // SocketPair:=SocketCall(Socket_Sys_SocketPair,Domain,SocketType,Protocol,longint(@Pair),0,0);
  232. SocketPair := -1;
  233. end;
  234. {$ifdef unix}
  235. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  236. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  237. begin
  238. fpWrite := dword(WinSock.send(handle, bufptr, size, 0));
  239. if fpWrite = dword(SOCKET_ERROR) then
  240. begin
  241. SocketError := WSAGetLastError;
  242. fpWrite := 0;
  243. end
  244. else
  245. SocketError := 0;
  246. end;
  247. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  248. var
  249. d : dword;
  250. begin
  251. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  252. begin
  253. SocketError:=WSAGetLastError;
  254. fpRead:=0;
  255. exit;
  256. end;
  257. if d>0 then
  258. begin
  259. if size>d then
  260. size:=d;
  261. fpRead := dword(WinSock.recv(handle, bufptr, size, 0));
  262. if fpRead = dword(SOCKET_ERROR) then
  263. begin
  264. SocketError:= WSAGetLastError;
  265. fpRead := 0;
  266. end else
  267. SocketError:=0;
  268. end
  269. else
  270. SocketError:=0;
  271. end;
  272. {$else}
  273. { mimic the linux fdWrite/fdRead calls for the file/text socket wrapper }
  274. function fdWrite(handle : longint;Const bufptr;size : dword) : dword;
  275. begin
  276. fdWrite := dword(WinSock.send(handle, bufptr, size, 0));
  277. if fdWrite = dword(SOCKET_ERROR) then
  278. begin
  279. SocketError := WSAGetLastError;
  280. fdWrite := 0;
  281. end
  282. else
  283. SocketError := 0;
  284. end;
  285. function fdRead(handle : longint;var bufptr;size : dword) : dword;
  286. var
  287. d : dword;
  288. begin
  289. if ioctlsocket(handle,FIONREAD,@d) = SOCKET_ERROR then
  290. begin
  291. SocketError:=WSAGetLastError;
  292. fdRead:=0;
  293. exit;
  294. end;
  295. if d>0 then
  296. begin
  297. if size>d then
  298. size:=d;
  299. fdRead := dword(WinSock.recv(handle, bufptr, size, 0));
  300. if fdRead = dword(SOCKET_ERROR) then
  301. begin
  302. SocketError:= WSAGetLastError;
  303. fdRead := 0;
  304. end else
  305. SocketError:=0;
  306. end
  307. else
  308. SocketError:=0;
  309. end;
  310. {$endif}
  311. {$i sockets.inc}
  312. { winsocket stack needs an init. and cleanup code }
  313. var
  314. wsadata : twsadata;
  315. initialization
  316. WSAStartUp($2,wsadata);
  317. finalization
  318. WSACleanUp;
  319. end.