22#if HAVE_UNISTD_H && !defined(__MINGW32__) && !_MSC_VER
31#if HAVE_SYS_TIME_H && !defined(__MINGW32__) && !_MSC_VER
39#if _MSC_VER || defined(__MINGW32__)
44#include <sys/socket.h>
53#include <netinet/in.h>
65#include <sys/select.h>
80#define AF_LOCAL AF_UNSPEC
83#define AF_AAL5 AF_UNSPEC
86#define AF_APPLETALK AF_UNSPEC
89#define AF_AX25 AF_UNSPEC
92#define AF_BRIDGE AF_UNSPEC
95#define AF_DECnet AF_UNSPEC
98#define AF_FILE AF_UNSPEC
101#define AF_INET AF_UNSPEC
104#define AF_INET6 AF_UNSPEC
107#define AF_IPX AF_UNSPEC
110#define AF_LOCAL AF_UNSPEC
113#define AF_NETBEUI AF_UNSPEC
116#define AF_NETLINK AF_UNSPEC
119#define AF_NETROM AF_UNSPEC
122#define AF_OSINET AF_UNSPEC
125#define AF_PACKET AF_UNSPEC
128#define AF_ROSE AF_UNSPEC
131#define AF_ROUTE AF_UNSPEC
134#define AF_SECURITY AF_UNSPEC
137#define AF_SNA AF_UNSPEC
140#define AF_UNIX AF_UNSPEC
143#define AF_X25 AF_UNSPEC
147#define SOCK_STREAM -1
158#ifndef SOCK_SEQPACKET
159#define SOCK_SEQPACKET -1
162#define SOCK_PACKET -1
165#ifndef MAXHOSTNAMELEN
166#define MAXHOSTNAMELEN 256
173#if _MSC_VER || defined(__MINGW32__)
174#define socket_errno WSAGetLastError()
175#define invalid_socket_fd(fd) (fd) == INVALID_SOCKET
177#define socket_errno errno
178#define invalid_socket_fd(fd) (fd) < 0
181void Yap_init_socks(
char *host,
long interface_port) {
184 struct sockaddr_in soadr;
189 he = gethostbyname(host);
192 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
193 "can not get address for host %s: %s", host, strerror(h_errno));
195 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"can not get address for host");
200 (void)memset((
void *)&soadr,
'\0',
sizeof(
struct sockaddr_in));
201 soadr.sin_family = AF_INET;
202 soadr.sin_port = htons((
short)interface_port);
205 memmove((
char *)&adr, (
char *)he->h_addr_list[0], (
size_t)he->h_length);
207 adr.s_addr = inet_addr(host);
209 soadr.sin_addr.s_addr = adr.s_addr;
211 s = socket(AF_INET, SOCK_STREAM, 0);
214 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"could not create socket: %s",
217 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"could not create socket");
226 if (setsockopt(s, SOL_SOCKET, SO_LINGER, (
void *)&ling,
sizeof(ling)) < 0) {
228 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
229 "socket_connect/3 (setsockopt_linger: %s)",
230 strerror(socket_errno));
232 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
233 "socket_connect/3 (setsockopt_linger)");
239 r = connect(s, (
struct sockaddr *)&soadr,
sizeof(soadr));
242 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
243 "connect failed, could not connect to interface: %s",
246 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
247 "connect failed, could not connect to interface");
252#if HAVE_DUP2 && !defined(__MINGW32__)
253 if (dup2(s, 0) < 0) {
255 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"could not dup2 stdin: %s",
258 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"could not dup2 stdin");
262 if (dup2(s, 1) < 0) {
264 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"could not dup2 stdout: %s",
267 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"could not dup2 stdout");
271 if (dup2(s, 2) < 0) {
273 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"could not dup2 stderr: %s",
276 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"could not dup2 stderr");
280#elif _MSC_VER || defined(__MINGW32__)
281 if (_dup2(s, 0) < 0) {
282 fprintf(stderr,
"could not dup2 stdin\n");
285 if (_dup2(s, 1) < 0) {
286 fprintf(stderr,
"could not dup2 stdout\n");
289 if (_dup2(s, 2) < 0) {
290 fprintf(stderr,
"could not dup2 stderr\n");
294 if (dup2(s, 0) < 0) {
295 fprintf(stderr,
"could not dup2 stdin\n");
299 yp_iob[0].flags = _YP_IO_SOCK | _YP_IO_READ;
300 if (dup2(s, 1) < 0) {
301 fprintf(stderr,
"could not dup2 stdout\n");
305 yp_iob[1].flags = _YP_IO_SOCK | _YP_IO_WRITE;
306 if (dup2(s, 2) < 0) {
307 fprintf(stderr,
"could not dup2 stderr\n");
311 yp_iob[2].flags = _YP_IO_SOCK | _YP_IO_WRITE;
314#if _MSC_VER || defined(__MINGW32__)
320 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"sockets not installed",
325static Int p_socket(USES_REGS1) {
326 Term t1 = Deref(ARG1);
327 Term t2 = Deref(ARG2);
328 Term t3 = Deref(ARG3);
329 char *sdomain, *stype;
330 Int domain = AF_UNSPEC, type, protocol;
335 Yap_Error(INSTANTIATION_ERROR, t1,
"socket/4");
338 if (!IsAtomTerm(t1)) {
339 Yap_Error(TYPE_ERROR_ATOM, t1,
"socket/4");
343 Yap_Error(INSTANTIATION_ERROR, t2,
"socket/4");
346 if (!IsAtomTerm(t2)) {
347 Yap_Error(TYPE_ERROR_ATOM, t2,
"socket/4");
351 Yap_Error(INSTANTIATION_ERROR, t3,
"socket/4");
354 if (!IsIntTerm(t3)) {
355 Yap_Error(TYPE_ERROR_ATOM, t3,
"socket/4");
358 sdomain = RepAtom(AtomOfTerm(t1))->StrOfAE;
359 if (sdomain[0] !=
'A' || sdomain[1] !=
'F' || sdomain[2] !=
'_')
362 switch (sdomain[0]) {
364 if (strcmp(sdomain,
"AAL5") == 0)
366 else if (strcmp(sdomain,
"APPLETALK") == 0)
367 domain = AF_APPLETALK;
368 else if (strcmp(sdomain,
"AX25") == 0)
372 if (strcmp(sdomain,
"BRIDGE") == 0)
373 domain = AF_APPLETALK;
376 if (strcmp(sdomain,
"DECnet") == 0)
380 if (strcmp(sdomain,
"FILE") == 0)
384 if (strcmp(sdomain,
"INET") == 0)
386 else if (strcmp(sdomain,
"INET6") == 0)
388 else if (strcmp(sdomain,
"IPX") == 0)
392 if (strcmp(sdomain,
"LOCAL") == 0)
396 if (strcmp(sdomain,
"NETBEUI") == 0)
398 else if (strcmp(sdomain,
"NETLINK") == 0)
400 else if (strcmp(sdomain,
"NETROM") == 0)
404 if (strcmp(sdomain,
"OSINET") == 0)
408 if (strcmp(sdomain,
"PACKET") == 0)
412 if (strcmp(sdomain,
"ROSE") == 0)
414 else if (strcmp(sdomain,
"ROUTE") == 0)
418 if (strcmp(sdomain,
"SECURITY") == 0)
419 domain = AF_SECURITY;
420 else if (strcmp(sdomain,
"SNA") == 0)
424 if (strcmp(sdomain,
"UNIX") == 0)
428 if (strcmp(sdomain,
"X25") == 0)
432 stype = RepAtom(AtomOfTerm(t2))->StrOfAE;
433 if (stype[0] !=
'S' || stype[1] !=
'O' || stype[2] !=
'C' ||
434 stype[3] !=
'K' || stype[4] !=
'_')
437 if (strcmp(stype,
"STREAM") == 0)
439 else if (strcmp(stype,
"DGRAM") == 0)
441 else if (strcmp(stype,
"RAW") == 0)
443 else if (strcmp(stype,
"RDM") == 0)
445 else if (strcmp(stype,
"SEQPACKET") == 0)
446 type = SOCK_SEQPACKET;
447 else if (strcmp(stype,
"PACKET") == 0)
451 protocol = IntOfTerm(t3);
454 fd = socket(domain, type, protocol);
455 if (invalid_socket_fd(fd)) {
457 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket/4 (socket: %s)",
458 strerror(socket_errno));
460 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket/4 (socket)");
464 if (domain == AF_UNIX || domain == AF_LOCAL)
465 out = Yap_InitSocketStream(fd, new_socket, af_unix);
466 else if (domain == AF_INET)
467 out = Yap_InitSocketStream(fd, new_socket, af_inet);
470#if _MSC_VER || defined(__MINGW32__)
479 return (Yap_unify(out, ARG4));
482Int Yap_CloseSocket(
int fd, socket_info status, socket_domain domain) {
483#if _MSC_VER || defined(__MINGW32__)
486 if (status == server_session_socket || status == client_socket) {
489 if (shutdown(fd, 1) != 0) {
490 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_close/1 (close)");
495 while (recv(fd, &bfr, 1, 0) > 0)
499 if (shutdown(fd, 0) < 0) {
500 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_close/1 (close)");
505 if (closesocket(fd) != 0) {
507 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_close/1 (close: %s)",
508 strerror(socket_errno));
510 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_close/1 (close)");
514 if (status == server_session_socket || status == client_socket) {
515 if (shutdown(fd, 2) < 0) {
517 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_close/1 (shutdown: %s)",
518 strerror(socket_errno));
520 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_close/1 (shutdown)");
525 if (close(fd) != 0) {
527 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_close/1 (close: %s)",
528 strerror(socket_errno));
530 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_close/1 (close)");
538static Int p_socket_close(USES_REGS1) {
539 Term t1 = Deref(ARG1);
542 if ((sno = Yap_CheckSocketStream(t1,
"socket_close/1")) < 0) {
545 Yap_CloseStream(sno);
549static Int p_socket_bind(USES_REGS1) {
550 Term t1 = Deref(ARG1);
551 Term t2 = Deref(ARG2);
557 if ((sno = Yap_CheckSocketStream(t1,
"socket_bind/2")) < 0) {
560 status = Yap_GetSocketStatus(sno);
561 fd = Yap_GetStreamFd(sno);
562 if (status != new_socket) {
567 Yap_Error(INSTANTIATION_ERROR, t2,
"socket_bind/2");
570 if (!IsApplTerm(t2)) {
571 Yap_Error(DOMAIN_ERROR_STREAM, t2,
"socket_bind/2");
574 fun = FunctorOfTerm(t2);
576 if (fun == FunctorAfUnix || fun == FunctorAfLocal) {
577 struct sockaddr_un sock;
578 Term taddr = ArgOfTerm(1, t2);
582 if (IsVarTerm(taddr)) {
583 Yap_Error(INSTANTIATION_ERROR, t2,
"socket_bind/2");
586 if (!IsAtomTerm(taddr)) {
587 Yap_Error(TYPE_ERROR_ATOM, taddr,
"socket_bind/2");
590 s = RepAtom(AtomOfTerm(taddr))->StrOfAE;
591 sock.sun_family = AF_UNIX;
592 if ((len = strlen(s)) > 107) {
593 Yap_Error(DOMAIN_ERROR_STREAM, taddr,
"socket_bind/2");
596 sock.sun_family = AF_UNIX;
597 strcpy(sock.sun_path, s);
598 if (bind(fd, (
struct sockaddr *)(&sock),
599 ((
size_t)(((
struct sockaddr_un *)0)->sun_path) + len)) < 0) {
601 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_bind/2 (bind: %s)",
602 strerror(socket_errno));
604 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_bind/2 (bind)");
608 Yap_UpdateSocketStream(sno, server_socket, af_unix);
612 if (fun == FunctorAfInet) {
613 Term thost = ArgOfTerm(1, t2);
614 Term tport = ArgOfTerm(2, t2);
617 struct sockaddr_in saddr;
620 memset((
void *)&saddr, (
int)0,
sizeof(saddr));
621 if (IsVarTerm(thost)) {
622 saddr.sin_addr.s_addr = INADDR_ANY;
623 }
else if (!IsAtomTerm(thost)) {
624 Yap_Error(TYPE_ERROR_ATOM, thost,
"socket_bind/2");
627 shost = RepAtom(AtomOfTerm(thost))->StrOfAE;
628 if ((he = gethostbyname(shost)) == NULL) {
630 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
631 "socket_bind/2 (gethostbyname: %s)", strerror(socket_errno));
633 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
634 "socket_bind/2 (gethostbyname)");
638 memmove((
void *)&saddr.sin_addr, (
void *)he->h_addr_list[0], he->h_length);
640 if (IsVarTerm(tport)) {
643 port = IntOfTerm(tport);
645 saddr.sin_port = htons(port);
646 saddr.sin_family = AF_INET;
647 if (bind(fd, (
struct sockaddr *)&saddr,
sizeof(saddr)) == -1) {
649 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_bind/2 (bind: %s)",
650 strerror(socket_errno));
652 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_bind/2 (bind)");
657 if (IsVarTerm(tport)) {
659#if _WIN32 || defined(__MINGW32__)
665 if (getsockname(fd, (
struct sockaddr *)&saddr, &namelen) < 0) {
667 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
668 "socket_bind/2 (getsockname: %s)", strerror(socket_errno));
670 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
671 "socket_bind/2 (getsockname)");
675 t = MkIntTerm(ntohs(saddr.sin_port));
676 Yap_unify(ArgOfTermCell(2, t2), t);
678 Yap_UpdateSocketStream(sno, server_socket, af_inet);
684static Int p_socket_connect(USES_REGS1) {
685 Term t1 = Deref(ARG1);
686 Term t2 = Deref(ARG2);
694 if ((sno = Yap_CheckSocketStream(t1,
"socket_connect/3")) < 0) {
698 Yap_Error(INSTANTIATION_ERROR, t2,
"socket_connect/3");
701 if (!IsApplTerm(t2)) {
702 Yap_Error(DOMAIN_ERROR_STREAM, t2,
"socket_connect/3");
705 fun = FunctorOfTerm(t2);
706 fd = Yap_GetStreamFd(sno);
707 status = Yap_GetSocketStatus(sno);
708 if (status != new_socket) {
713 if (fun == FunctorAfUnix) {
714 struct sockaddr_un sock;
715 Term taddr = ArgOfTerm(1, t2);
719 if (IsVarTerm(taddr)) {
720 Yap_Error(INSTANTIATION_ERROR, t2,
"socket_connect/3");
723 if (!IsAtomTerm(taddr)) {
724 Yap_Error(TYPE_ERROR_ATOM, taddr,
"socket_connect/3");
727 s = RepAtom(AtomOfTerm(taddr))->StrOfAE;
728 sock.sun_family = AF_UNIX;
729 if ((len = strlen(s)) > 107) {
730 Yap_Error(DOMAIN_ERROR_STREAM, taddr,
"socket_connect/3");
733 sock.sun_family = AF_UNIX;
734 strcpy(sock.sun_path, s);
736 fd, (
struct sockaddr *)(&sock),
737 ((
size_t)(((
struct sockaddr_un *)0)->sun_path) + len))) < 0) {
739 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
740 "socket_connect/3 (connect: %s)", strerror(socket_errno));
742 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_connect/3 (connect)");
746 Yap_UpdateSocketStream(sno, client_socket, af_unix);
749 if (fun == FunctorAfInet) {
750 Term thost = ArgOfTerm(1, t2);
751 Term tport = ArgOfTerm(2, t2);
754 struct sockaddr_in saddr;
755 unsigned short int port;
757 memset((
void *)&saddr, (
int)0,
sizeof(saddr));
758 if (IsVarTerm(thost)) {
759 Yap_Error(INSTANTIATION_ERROR, thost,
"socket_connect/3");
761 }
else if (!IsAtomTerm(thost)) {
762 Yap_Error(TYPE_ERROR_ATOM, thost,
"socket_connect/3");
765 shost = RepAtom(AtomOfTerm(thost))->StrOfAE;
766 if ((he = gethostbyname(shost)) == NULL) {
768 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
769 "socket_connect/3 (gethostbyname: %s)",
770 strerror(socket_errno));
772 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
773 "socket_connect/3 (gethostbyname)");
777 memmove((
void *)&saddr.sin_addr, (
void *)he->h_addr_list[0], he->h_length);
779 if (IsVarTerm(tport)) {
780 Yap_Error(INSTANTIATION_ERROR, tport,
"socket_connect/3");
782 }
else if (!IsIntegerTerm(tport)) {
783 Yap_Error(TYPE_ERROR_INTEGER, tport,
"socket_connect/3");
786 port = (
unsigned short int)IntegerOfTerm(tport);
788 saddr.sin_port = htons(port);
789 saddr.sin_family = AF_INET;
797 if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (
void *)&ling,
sizeof(ling)) <
800 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
801 "socket_connect/3 (setsockopt_linger: %s)",
802 strerror(socket_errno));
804 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
805 "socket_connect/3 (setsockopt_linger)");
815 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (
void *)&one,
sizeof(one))) {
817 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
818 "socket_connect/3 (setsockopt_broadcast: %s)",
819 strerror(socket_errno));
821 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
822 "socket_connect/3 (setsockopt_broadcast)");
828 flag = connect(fd, (
struct sockaddr *)&saddr,
sizeof(saddr));
831 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
832 "socket_connect/3 (connect: %s)", strerror(socket_errno));
834 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_connect/3 (connect)");
838 Yap_UpdateSocketStream(sno, client_socket, af_inet);
842 return (Yap_unify(out, ARG3));
845static Int p_socket_listen(USES_REGS1) {
846 Term t1 = Deref(ARG1);
847 Term t2 = Deref(ARG2);
853 if ((sno = Yap_CheckSocketStream(t1,
"socket_listen/2")) < 0) {
857 Yap_Error(INSTANTIATION_ERROR, t2,
"socket_listen/2");
860 if (!IsIntTerm(t2)) {
861 Yap_Error(TYPE_ERROR_INTEGER, t2,
"socket_listen/2");
866 Yap_Error(DOMAIN_ERROR_STREAM, t1,
"socket_listen/2");
869 fd = Yap_GetStreamFd(sno);
870 status = Yap_GetSocketStatus(sno);
871 if (status != server_socket) {
875 if (listen(fd, j) < 0) {
877 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_listen/2 (listen: %s)",
878 strerror(socket_errno));
880 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_listen/2 (listen)");
886static Int p_socket_accept(USES_REGS1) {
887 Term t1 = Deref(ARG1);
890 socket_domain domain;
894 if ((sno = Yap_CheckSocketStream(t1,
"socket_accept/3")) < 0) {
897 ofd = Yap_GetStreamFd(sno);
898 status = Yap_GetSocketStatus(sno);
899 if (status != server_socket) {
903 domain = Yap_GetSocketDomain(sno);
905 if (domain == af_unix) {
906 struct sockaddr_un caddr;
909 memset((
void *)&caddr, (
int)0,
sizeof(caddr));
910 if ((fd = accept(ofd, (
struct sockaddr *)&caddr, &len)) < 0) {
912 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_accept/3 (accept: %s)",
913 strerror(socket_errno));
915 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_accept/3 (accept)");
919 out = Yap_InitSocketStream(fd, server_session_socket, af_unix);
922 if (domain == af_inet) {
923 struct sockaddr_in caddr;
929 memset((
void *)&caddr, (
int)0,
sizeof(caddr));
930 if (invalid_socket_fd(fd = accept(ofd, (
struct sockaddr *)&caddr, &len))) {
932 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_accept/3 (accept: %s)",
933 strerror(socket_errno));
935 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_accept/3 (accept)");
939 if ((s = inet_ntoa(caddr.sin_addr)) == NULL) {
941 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
942 "socket_accept/3 (inet_ntoa: %s)", strerror(socket_errno));
944 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_accept/3 (inet_ntoa)");
947 tcli = MkAtomTerm(Yap_LookupAtom(s));
948 if (!Yap_unify(ARG2, tcli))
950 out = Yap_InitSocketStream(fd, server_session_socket, af_inet);
955 return (Yap_unify(out, ARG3));
958static Int p_socket_buffering(USES_REGS1) {
959 Term t1 = Deref(ARG1);
960 Term t2 = Deref(ARG2);
961 Term t4 = Deref(ARG4);
965#if _WIN32 || defined(__MINGW32__)
968 unsigned int bufsize;
973 if ((sno = Yap_CheckSocketStream(t1,
"socket_buffering/4")) < 0) {
977 Yap_Error(INSTANTIATION_ERROR, t2,
"socket_buffering/4");
980 if (!IsAtomTerm(t2)) {
981 Yap_Error(TYPE_ERROR_ATOM, t2,
"socket_buffering/4");
984 mode = AtomOfTerm(t2);
985 if (mode == AtomRead)
987 else if (mode == AtomWrite)
990 Yap_Error(DOMAIN_ERROR_IO_MODE, t2,
"socket_buffering/4");
993 fd = Yap_GetStreamFd(sno);
995 getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (
void *)&bufsize, &len);
997 getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (
void *)&bufsize, &len);
999 if (!Yap_unify(ARG3, MkIntegerTerm(bufsize)))
1001 if (IsVarTerm(t4)) {
1005 if (!IsIntegerTerm(t4)) {
1006 Yap_Error(TYPE_ERROR_INTEGER, t4,
"socket_buffering/4");
1009 siz = IntegerOfTerm(t4);
1011 Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t4,
"socket_buffering/4");
1017 setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (
void *)&bufsize,
sizeof(bufsize));
1019 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (
void *)&bufsize,
sizeof(bufsize));
1024static Term select_out_list(Term t1, fd_set *readfds_ptr USES_REGS) {
1025 if (t1 == TermNil) {
1030 Term next = select_out_list(TailOfTerm(t1), readfds_ptr PASS_REGS);
1031 Term Head = HeadOfTerm(t1);
1033 sno = Yap_CheckIOStream(Head,
"stream_select/5");
1034 fd = Yap_GetStreamFd(sno);
1035 if (FD_ISSET(fd, readfds_ptr))
1036 return (MkPairTerm(Head, next));
1038 return (MkPairTerm(TermNil, next));
1042static Int p_socket_select(USES_REGS1) {
1043 Term t1 = Deref(ARG1);
1044 Term t2 = Deref(ARG2);
1045 Term t3 = Deref(ARG3);
1046 fd_set readfds, writefds, exceptfds;
1047 struct timeval timeout, *ptime;
1049#if _MSC_VER || defined(__MINGW32__)
1055 Term tout = TermNil, ti, Head;
1057 if (IsVarTerm(t1)) {
1058 Yap_Error(INSTANTIATION_ERROR, t1,
"socket_select/5");
1061 if (!IsPairTerm(t1)) {
1062 Yap_Error(TYPE_ERROR_LIST, t1,
"socket_select/5");
1065 if (IsVarTerm(t2)) {
1066 Yap_Error(INSTANTIATION_ERROR, t2,
"socket_select/5");
1069 if (!IsIntegerTerm(t2)) {
1070 Yap_Error(TYPE_ERROR_INTEGER, t2,
"socket_select/5");
1073 if (IsVarTerm(t3)) {
1074 Yap_Error(INSTANTIATION_ERROR, t3,
"socket_select/5");
1077 if (!IsIntegerTerm(t3)) {
1078 Yap_Error(TYPE_ERROR_INTEGER, t3,
"socket_select/5");
1083 FD_ZERO(&exceptfds);
1086 while (ti != TermNil) {
1087#if _MSC_VER || defined(__MINGW32__)
1094 Head = HeadOfTerm(ti);
1095 sno = Yap_CheckIOStream(Head,
"stream_select/5");
1098 fd = Yap_GetStreamFd(sno);
1099 FD_SET(fd, &readfds);
1102 ti = TailOfTerm(ti);
1105 tsec = IntegerOfTerm(t2);
1106 tusec = IntegerOfTerm(t3);
1110 timeout.tv_sec = tsec;
1111 timeout.tv_usec = tusec;
1115 if (select(fdmax + 1, &readfds, &writefds, &exceptfds, ptime) < 0) {
1117 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_select/5 (select: %s)",
1118 strerror(socket_errno));
1120 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"socket_select/5 (select)");
1123 tout = select_out_list(t1, &readfds PASS_REGS);
1125 return (Yap_unify(ARG4, tout));
1128static Int p_current_host(USES_REGS1) {
1129 char oname[MAXHOSTNAMELEN], *name;
1130 Term t1 = Deref(ARG1), out;
1132 if (!IsVarTerm(t1) && !IsAtomTerm(t1)) {
1133 Yap_Error(TYPE_ERROR_ATOM, t1,
"current_host/2");
1137 if (gethostname(name,
sizeof(oname)) < 0) {
1139 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1140 "current_host/2 (gethostname: %s)", strerror(socket_errno));
1142 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"current_host/2 (gethostname)");
1146 if ((strrchr(name,
'.') == NULL)) {
1150 if ((he = gethostbyname(name)) == NULL) {
1152 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1153 "current_host/2 (gethostbyname: %s)", strerror(socket_errno));
1155 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1156 "current_host/2 (gethostbyname)");
1160 name = (
char *)(he->h_name);
1162 if (IsAtomTerm(t1)) {
1163 char *sin = RepAtom(AtomOfTerm(t1))->StrOfAE;
1164 int faq = (strrchr(sin,
'.') != NULL);
1167#if _MSC_VER || defined(__MINGW32__)
1168 return (_stricmp(name, sin) == 0);
1170 return (strcasecmp(name, sin) == 0);
1173 int isize = strlen(sin);
1175 Yap_Error(SYSTEM_ERROR_INTERNAL, ARG1,
1176 "current_host/2 (input longer than longest FAQ host name)");
1179 if (name[isize] !=
'.')
1182#if _MSC_VER || defined(__MINGW32__)
1183 return (_stricmp(name, sin) == 0);
1185 return (strcasecmp(name, sin) == 0);
1189 out = MkAtomTerm(Yap_LookupAtom(name));
1190 return (Yap_unify(ARG1, out));
1194static Int p_hostname_address(USES_REGS1) {
1196 Term t1 = Deref(ARG1);
1197 Term t2 = Deref(ARG2);
1201 if (!IsVarTerm(t1)) {
1202 if (!IsAtomTerm(t1)) {
1203 Yap_Error(TYPE_ERROR_ATOM, t1,
"hostname_address/2");
1207 }
else if (IsVarTerm(t2)) {
1208 Yap_Error(INSTANTIATION_ERROR, t1,
"hostname_address/5");
1210 }
else if (!IsAtomTerm(t2)) {
1211 Yap_Error(TYPE_ERROR_ATOM, t2,
"hostname_address/2");
1215 s = RepAtom(AtomOfTerm(tin))->StrOfAE;
1216 if (IsVarTerm(t1)) {
1217 if ((he = gethostbyaddr(s, strlen(s), AF_INET)) == NULL) {
1219 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1220 "hostname_address/2 (gethostbyname: %s)",
1221 strerror(socket_errno));
1223 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1224 "hostname_address/2 (gethostbyname)");
1227 out = MkAtomTerm(Yap_LookupAtom((
char *)(he->h_name)));
1228 return (Yap_unify(out, ARG1));
1231 if ((he = gethostbyname(s)) == NULL) {
1233 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1234 "hostname_address/2 (gethostbyname: %s)",
1235 strerror(socket_errno));
1237 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1238 "hostname_address/2 (gethostbyname)");
1242 memmove((
char *)&adr, (
char *)he->h_addr_list[0], (
size_t)he->h_length);
1243 out = MkAtomTerm(Yap_LookupAtom(inet_ntoa(adr)));
1244 return (Yap_unify(out, ARG2));
1249void Yap_InitSocketLayer(
void) {
1251 Yap_InitCPred(
"socket", 4, p_socket, SafePredFlag | SyncPredFlag);
1252 Yap_InitCPred(
"socket_close", 1, p_socket_close, SafePredFlag | SyncPredFlag);
1253 Yap_InitCPred(
"socket_bind", 2, p_socket_bind, SafePredFlag | SyncPredFlag);
1254 Yap_InitCPred(
"socket_connect", 3, p_socket_connect,
1255 SafePredFlag | SyncPredFlag);
1256 Yap_InitCPred(
"socket_listen", 2, p_socket_listen,
1257 SafePredFlag | SyncPredFlag);
1258 Yap_InitCPred(
"socket_accept", 3, p_socket_accept,
1259 SafePredFlag | SyncPredFlag);
1260 Yap_InitCPred(
"$socket_buffering", 4, p_socket_buffering,
1261 SafePredFlag | SyncPredFlag | HiddenPredFlag);
1262 Yap_InitCPred(
"$socket_select", 4, p_socket_select,
1263 SafePredFlag | SyncPredFlag | HiddenPredFlag);
1264 Yap_InitCPred(
"current_host", 1, p_current_host, SafePredFlag);
1265 Yap_InitCPred(
"hostname_address", 2, p_hostname_address, SafePredFlag);
1266#if _MSC_VER || defined(__MINGW32__)
1269 if (WSAStartup(MAKEWORD(2, 1), &info) != 0)