sockets.pas 12 KB

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