sockets.pp 9.2 KB

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