sockets.pp 9.1 KB

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