sockets.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2002 Yuri Prokushev
  4. Copyright (c) 2005 Soren Ager
  5. Sockets implementation for OS/2
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$MODE ObjFPC}
  13. { $DEFINE notUnix} // To make ssockets.pp compile
  14. unit Sockets;
  15. Interface
  16. Uses
  17. so32dll,ctypes;
  18. Const
  19. // AF_LOCAL = so32dll.AF_LOCAL;
  20. AF_UNSPEC = so32dll.AF_UNSPEC;
  21. AF_LOCAL = so32dll.AF_LOCAL;
  22. AF_UNIX = so32dll.AF_UNIX;
  23. AF_OS2 = so32dll.AF_OS2;
  24. AF_IMPLINK = so32dll.AF_IMPLINK; // arpanet imp addresses
  25. AF_PUP = so32dll.AF_PUP; // pup protocols: e.g. BSP
  26. AF_CHAOS = so32dll.AF_CHAOS; // mit CHAOS protocols
  27. AF_NS = so32dll.AF_NS; // XEROX NS protocols
  28. AF_ISO = so32dll.AF_ISO; // ISO protocols
  29. AF_OSI = so32dll.AF_OSI;
  30. AF_ECMA = so32dll.AF_ECMA; // european computer manufacturers
  31. AF_DATAKIT = so32dll.AF_DATAKIT; // datakit protocols
  32. AF_CCITT = so32dll.AF_CCITT; // CCITT protocols, X.25 etc
  33. AF_SNA = so32dll.AF_SNA; // IBM SNA
  34. AF_DECnet = so32dll.AF_DECnet; // DECnet
  35. AF_DLI = so32dll.AF_DLI; // DEC Direct data link interface
  36. AF_LAT = so32dll.AF_LAT; // LAT
  37. AF_HYLINK = so32dll.AF_HYLINK; // NSC Hyperchannel
  38. AF_APPLETALK = so32dll.AF_APPLETALK; // Apple Talk
  39. AF_NB = so32dll.AF_NB; // Netbios
  40. AF_NETBIOS = so32dll.AF_NETBIOS; // Netbios
  41. AF_LINK = so32dll.AF_LINK; // Link layer interface
  42. pseudo_AF_XTP = so32dll.pseudo_AF_XTP; // eXpress Transfer Protocol (no AF)
  43. AF_COIP = so32dll.AF_COIP; // connection-oriented IP, aka ST II
  44. AF_CNT = so32dll.AF_CNT; // Computer Network Technology
  45. pseudo_AF_RTIP = so32dll.pseudo_AF_RTIP; // Help Identify RTIP packets
  46. AF_IPX = so32dll.AF_IPX; // Novell Internet Protocol
  47. AF_SIP = so32dll.AF_SIP; // Simple Internet Protocol
  48. AF_INET6 = so32dll.AF_INET6;
  49. pseudo_AF_PIP = so32dll.pseudo_AF_PIP; // Help Identify PIP packets
  50. AF_ROUTE = so32dll.AF_ROUTE; // Internal Routing Protocol
  51. AF_FWIP = so32dll.AF_FWIP; // firewall support
  52. AF_IPSEC = so32dll.AF_IPSEC; // IPSEC and encryption techniques
  53. AF_DES = so32dll.AF_DES; // DES
  54. AF_MD5 = so32dll.AF_MD5;
  55. AF_CDMF = so32dll.AF_CDMF;
  56. AF_MAX = so32dll.AF_MAX;
  57. // PF_LOCAL = so32dll.PF_LOCAL;
  58. PF_OS2 = so32dll.PF_OS2;
  59. PF_IMPLINK = so32dll.PF_IMPLINK;
  60. PF_PUP = so32dll.PF_PUP;
  61. PF_CHAOS = so32dll.PF_CHAOS;
  62. PF_NS = so32dll.PF_NS;
  63. PF_ISO = so32dll.PF_ISO;
  64. PF_OSI = so32dll.PF_OSI;
  65. PF_ECMA = so32dll.PF_ECMA;
  66. PF_DATAKIT = so32dll.PF_DATAKIT;
  67. PF_CCITT = so32dll.PF_CCITT;
  68. PF_SNA = so32dll.PF_SNA;
  69. PF_DECnet = so32dll.PF_DECnet;
  70. PF_DLI = so32dll.PF_DLI;
  71. PF_LAT = so32dll.PF_LAT;
  72. PF_HYLINK = so32dll.PF_HYLINK;
  73. PF_APPLETALK = so32dll.PF_APPLETALK;
  74. PF_NETBIOS = so32dll.PF_NB;
  75. PF_NB = so32dll.PF_NB;
  76. PF_ROUTE = so32dll.PF_ROUTE;
  77. PF_LINK = so32dll.PF_LINK;
  78. PF_XTP = so32dll.PF_XTP; // really just proto family, no AF
  79. PF_COIP = so32dll.PF_COIP;
  80. PF_CNT = so32dll.PF_CNT;
  81. PF_SIP = so32dll.PF_SIP;
  82. PF_INET6 = so32dll.PF_INET6;
  83. PF_IPX = so32dll.PF_IPX; // same format as AF_NS
  84. PF_RTIP = so32dll.PF_RTIP; // same format as AF_INET
  85. PF_PIP = so32dll.PF_PIP;
  86. PF_MAX = so32dll.PF_MAX;
  87. Type
  88. cushort=word;
  89. cuint16=word;
  90. cuint32=cardinal;
  91. size_t =cuint32;
  92. ssize_t=cuint16;
  93. cint =longint;
  94. pcint =^cint;
  95. tsocklen=cint;
  96. psocklen=^tsocklen;
  97. // OS/2 stack based on BSD stack
  98. {$DEFINE BSD}
  99. {$I socketsh.inc}
  100. Implementation
  101. {Include filerec and textrec structures}
  102. {$I filerec.inc}
  103. {$I textrec.inc}
  104. {******************************************************************************
  105. Basic Socket Functions
  106. ******************************************************************************}
  107. Function socket(Domain,SocketType,Protocol:Longint):Longint;
  108. begin
  109. Socket:=so32dll.Socket(Domain,SocketType,ProtoCol);
  110. if Socket<0 then
  111. SocketError:=so32dll.sock_errno
  112. else
  113. SocketError:=0;
  114. end;
  115. Function Send(Sock:Longint;Const Buf;BufLen,Flags:Longint):Longint;
  116. begin
  117. Send:=fpSend(Sock,@Buf,BufLen,Flags);
  118. end;
  119. Function SendTo(Sock:Longint;Const Buf;BufLen,Flags:Longint;Var Addr; AddrLen : Longint):Longint;
  120. begin
  121. SendTo:=fpSendTo(Sock,@Buf,BufLen,Flags,@Addr,AddrLen);
  122. end;
  123. Function Recv(Sock:Longint;Var Buf;BufLen,Flags:Longint):Longint;
  124. begin
  125. Recv:=so32dll.Recv(Sock,Buf,BufLen,Flags);
  126. if Recv<0 then
  127. SocketError:=so32dll.sock_errno
  128. else
  129. SocketError:=0;
  130. end;
  131. Function RecvFrom(Sock : Longint; Var Buf; Buflen,Flags : Longint; Var Addr; var AddrLen : longInt) : longint;
  132. begin
  133. RecvFrom:=so32dll.RecvFrom(Sock,Buf,BufLen,Flags,so32dll.SockAddr(Addr),AddrLen);
  134. if RecvFrom<0 then
  135. SocketError:=so32dll.sock_errno
  136. else
  137. SocketError:=0;
  138. end;
  139. Function Bind(Sock:Longint;Const Addr;AddrLen:Longint):Boolean;
  140. begin
  141. Bind:=fpBind(Sock,@Addr,AddrLen)=0;
  142. end;
  143. Function Listen(Sock,MaxConnect:Longint):Boolean;
  144. var
  145. l : longint;
  146. begin
  147. l:=so32dll.Listen(Sock,MaxConnect);
  148. if l<0 then
  149. begin
  150. SocketError:=so32dll.sock_errno;
  151. Listen:=false;
  152. end else
  153. begin
  154. SocketError:=0;
  155. Listen:=true;
  156. end;
  157. end;
  158. Function Accept(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  159. begin
  160. Accept:=so32dll.Accept(Sock,so32dll.SockAddr(Addr), AddrLen);
  161. if Accept<0 then
  162. SocketError:=so32dll.sock_errno
  163. else
  164. SocketError:=0;
  165. end;
  166. Function Connect(Sock:Longint;const Addr; Addrlen:Longint):Boolean;
  167. begin
  168. Connect:=fpConnect(Sock,@Addr,AddrLen)=0;
  169. end;
  170. Function Shutdown(Sock:Longint;How:Longint):Longint;
  171. begin
  172. ShutDown:=so32dll.ShutDown(Sock,How);
  173. if ShutDown<0 then
  174. SocketError:=so32dll.sock_errno
  175. else
  176. SocketError:=0;
  177. end;
  178. Function GetSocketName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  179. begin
  180. GetSocketName:=so32dll.GetSockName(Sock, so32dll.SockAddr(Addr),AddrLen);
  181. if GetSocketName<0 then
  182. SocketError:=so32dll.sock_errno
  183. else
  184. SocketError:=0;
  185. end;
  186. Function GetPeerName(Sock:Longint;Var Addr;Var Addrlen:Longint):Longint;
  187. begin
  188. GetPeerName:=so32dll.GetPeerName(Sock,so32dll.SockAddr(Addr),AddrLen);
  189. if GetPeerName<0 then
  190. SocketError:=so32dll.sock_errno
  191. else
  192. SocketError:=0;
  193. end;
  194. Function SetSocketOptions(Sock,Level,OptName:Longint;Const OptVal;optlen:longint):Longint;
  195. begin
  196. SetSocketOptions:=fpSetSockOpt(Sock,Level,OptName,@OptVal,OptLen);
  197. end;
  198. Function GetSocketOptions(Sock,Level,OptName:Longint;Var OptVal;Var optlen:longint):Longint;
  199. begin
  200. GetSocketOptions:=so32dll.GetSockOpt(Sock,Level,OptName,OptVal,OptLen);
  201. if GetSocketOptions<0 then
  202. SocketError:=so32dll.sock_errno
  203. else
  204. SocketError:=0;
  205. end;
  206. Function SocketPair(Domain,SocketType,Protocol:Longint;var Pair:TSockArray):Longint;
  207. begin
  208. {!!TODO!!
  209. SocketPair:=so32dll.socketpair(Domain,SocketType,Protocol,Pair);}
  210. //SocketCall(Socket_Sys_SocketPair,Domain,SocketType,Protocol,longint(@Pair),0,0);
  211. SocketPair:=-1;
  212. end;
  213. { mimic the linux fpWrite/fpRead calls for the file/text socket wrapper }
  214. function fpWrite(handle : longint;Const bufptr;size : dword) : dword;
  215. begin
  216. fpWrite := dword(fpsend(handle, @bufptr, size, 0));
  217. if fpWrite = dword(-1) then
  218. begin
  219. SocketError := so32dll.sock_errno;
  220. fpWrite := 0;
  221. end
  222. else
  223. SocketError := 0;
  224. end;
  225. function fpRead(handle : longint;var bufptr;size : dword) : dword;
  226. var
  227. d : dword;
  228. begin
  229. d:=dword(so32dll.os2_ioctl(handle,FIONREAD,d,SizeOf(d)));
  230. if d=dword(-1) then
  231. begin
  232. SocketError:=so32dll.sock_errno;
  233. fpRead:=0;
  234. end else
  235. begin
  236. if size>d then
  237. size:=d;
  238. fpRead := dword(so32dll.recv(handle, bufptr, size, 0));
  239. if fpRead = dword(-1) then
  240. begin
  241. SocketError:= so32dll.sock_errno;
  242. fpRead := 0;
  243. end else
  244. SocketError:=0;
  245. end;
  246. end;
  247. {$i sockets.inc}
  248. function fpsocket (domain:cint; xtype:cint; protocol: cint):cint;
  249. begin
  250. fpSocket:=so32dll.Socket(Domain,xtype,ProtoCol);
  251. if fpSocket<0 then
  252. SocketError:=so32dll.sock_errno
  253. else
  254. SocketError:=0;
  255. end;
  256. function fpsend (s:cint; msg:pointer; len:size_t; flags:cint):ssize_t;
  257. begin
  258. fpSend:=so32dll.Send(S,msg^,len,flags);
  259. if fpSend<0 then
  260. SocketError:=so32dll.sock_errno
  261. else
  262. SocketError:=0;
  263. end;
  264. function fpsendto (s:cint; msg:pointer; len:size_t; flags:cint; tox :psockaddr; tolen: tsocklen):ssize_t;
  265. begin
  266. // Dubious construct, this should be checked. (IPV6 fails ?)
  267. fpSendTo:=so32dll.SendTo(S,msg^,Len,Flags,so32dll.SockAddr(tox^),toLen);
  268. if fpSendTo<0 then
  269. SocketError:=so32dll.sock_errno
  270. else
  271. SocketError:=0;
  272. end;
  273. function fprecv (s:cint; buf: pointer; len: size_t; flags: cint):ssize_t;
  274. begin
  275. fpRecv:=so32dll.Recv(S,Buf,Len,Flags);
  276. if fpRecv<0 then
  277. SocketError:=so32dll.sock_errno
  278. else
  279. SocketError:=0;
  280. end;
  281. function fprecvfrom (s:cint; buf: pointer; len: size_t; flags: cint; from : psockaddr; fromlen : psocklen):ssize_t;
  282. begin
  283. fpRecvFrom:=so32dll.RecvFrom(S,Buf,Len,Flags,so32dll.SockAddr(from^),FromLen^);
  284. if fpRecvFrom<0 then
  285. SocketError:=so32dll.sock_errno
  286. else
  287. SocketError:=0;
  288. end;
  289. function fpconnect (s:cint; name : psockaddr; namelen : tsocklen):cint;
  290. begin
  291. fpConnect:=so32dll.Connect(S,so32dll.SockAddr(name^),nameLen);
  292. if fpConnect<0 then
  293. SocketError:=so32dll.sock_errno
  294. else
  295. SocketError:=0;
  296. end;
  297. function fpshutdown (s:cint; how:cint):cint;
  298. begin
  299. fpShutDown:=so32dll.ShutDown(S,How);
  300. if fpShutDown<0 then
  301. SocketError:=so32dll.sock_errno
  302. else
  303. SocketError:=0;
  304. end;
  305. function fpbind (s:cint; addrx : psockaddr; addrlen : tsocklen):cint;
  306. begin
  307. fpbind:=so32dll.Bind(S,so32dll.SockAddr(Addrx^),AddrLen);
  308. if fpbind<0 then
  309. SocketError:=so32dll.sock_errno
  310. else
  311. SocketError:=0;
  312. end;
  313. function fplisten (s:cint; backlog : cint):cint;
  314. begin
  315. fplisten:=so32dll.Listen(S,backlog);
  316. if fplisten<0 then
  317. SocketError:=so32dll.sock_errno
  318. else
  319. SocketError:=0;
  320. end;
  321. function fpaccept (s:cint; addrx : psockaddr; addrlen : psocklen):cint;
  322. begin
  323. fpAccept:=so32dll.Accept(S,so32dll.SockAddr(Addrx^),longint(@AddrLen));
  324. if fpAccept<0 then
  325. SocketError:=so32dll.sock_errno
  326. else
  327. SocketError:=0;
  328. end;
  329. function fpgetsockname (s:cint; name : psockaddr; namelen : psocklen):cint;
  330. begin
  331. fpGetSockName:=so32dll.GetSockName(S,so32dll.SockAddr(name^),nameLen^);
  332. if fpGetSockName<0 then
  333. SocketError:=so32dll.sock_errno
  334. else
  335. SocketError:=0;
  336. end;
  337. function fpgetpeername (s:cint; name : psockaddr; namelen : psocklen):cint;
  338. begin
  339. fpGetPeerName:=so32dll.GetPeerName(S,so32dll.SockAddr(name^),NameLen^);
  340. if fpGetPeerName<0 then
  341. SocketError:=so32dll.sock_errno
  342. else
  343. SocketError:=0;
  344. end;
  345. function fpgetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen : psocklen):cint;
  346. begin
  347. fpGetSockOpt:=so32dll.GetSockOpt(S,Level,OptName,OptVal,OptLen^);
  348. if fpGetSockOpt<0 then
  349. SocketError:=so32dll.sock_errno
  350. else
  351. SocketError:=0;
  352. end;
  353. function fpsetsockopt (s:cint; level:cint; optname:cint; optval:pointer; optlen :tsocklen):cint;
  354. begin
  355. fpSetSockOpt:=so32dll.SetSockOpt(S,Level,OptName,OptVal,OptLen);
  356. if fpSetSockOpt<0 then
  357. SocketError:=so32dll.sock_errno
  358. else
  359. SocketError:=0;
  360. end;
  361. function fpsocketpair (d:cint; xtype:cint; protocol:cint; sv:pcint):cint;
  362. begin
  363. fpsocketpair:=-1;
  364. end;
  365. Function CloseSocket(Sock:Longint):Longint;
  366. begin
  367. CloseSocket:=so32dll.soclose (Sock);
  368. if CloseSocket<>0 then
  369. begin
  370. SocketError:=so32dll.sock_errno;
  371. end else
  372. begin
  373. CloseSocket := 0;
  374. SocketError := 0;
  375. end;
  376. end;
  377. Begin
  378. so32dll.sock_init;
  379. End.