static Int file_no(int sno, Term t2 USES_REGS) { int f = Yap_GetStreamFd(sno); Term rc = MkIntTerm(f); if (!IsVarTerm(t2) && !IsIntTerm(t2)) { return false; } return Yap_unify_constant(t2, rc); }
static Int p_socket_listen(USES_REGS1) { Term t1 = Deref(ARG1); Term t2 = Deref(ARG2); int sno; socket_info status; int fd; Int j; if ((sno = Yap_CheckSocketStream(t1, "socket_listen/2")) < 0) { return (FALSE); } if (IsVarTerm(t2)) { Yap_Error(INSTANTIATION_ERROR,t2,"socket_listen/2"); return(FALSE); } if (!IsIntTerm(t2)) { Yap_Error(TYPE_ERROR_INTEGER,t2,"socket_listen/2"); return(FALSE); } j = IntOfTerm(t2); if (j < 0) { Yap_Error(DOMAIN_ERROR_STREAM,t1,"socket_listen/2"); return(FALSE); } fd = Yap_GetStreamFd(sno); status = Yap_GetSocketStatus(sno); if (status != server_socket) { /* ok, this should be an error, as you are trying to bind */ return(FALSE); } if (listen(fd,j) < 0) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_listen/2 (listen: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_listen/2 (listen)"); #endif } return(TRUE); }
static Int p_socket_buffering(USES_REGS1) { Term t1 = Deref(ARG1); Term t2 = Deref(ARG2); Term t4 = Deref(ARG4); Atom mode; int fd; int writing; #if _WIN32 || defined(__MINGW32__) int bufsize; int len; #else unsigned int bufsize; unsigned int len; #endif int sno; if ((sno = Yap_CheckSocketStream(t1, "socket_buffering/4")) < 0) { return (FALSE); } if (IsVarTerm(t2)) { Yap_Error(INSTANTIATION_ERROR,t2,"socket_buffering/4"); return(FALSE); } if (!IsAtomTerm(t2)) { Yap_Error(TYPE_ERROR_ATOM,t2,"socket_buffering/4"); return(FALSE); } mode = AtomOfTerm(t2); if (mode == AtomRead) writing = FALSE; else if (mode == AtomWrite) writing = TRUE; else { Yap_Error(DOMAIN_ERROR_IO_MODE,t2,"socket_buffering/4"); return(FALSE); } fd = Yap_GetStreamFd(sno); if (writing) { getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&bufsize, &len); } else { getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&bufsize, &len); } if (!Yap_unify(ARG3,MkIntegerTerm(bufsize))) return(FALSE); if (IsVarTerm(t4)) { bufsize = BUFSIZ; } else { Int siz; if (!IsIntegerTerm(t4)) { Yap_Error(TYPE_ERROR_INTEGER,t4,"socket_buffering/4"); return(FALSE); } siz = IntegerOfTerm(t4); if (siz < 0) { Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO,t4,"socket_buffering/4"); return(FALSE); } bufsize = siz; } if (writing) { setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&bufsize, sizeof(bufsize)); } else { setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&bufsize, sizeof(bufsize)); } return(TRUE); }
static Int p_socket_accept(USES_REGS1) { Term t1 = Deref(ARG1); int sno; socket_info status; socket_domain domain; int ofd, fd; Term out; if ((sno = Yap_CheckSocketStream(t1, "socket_accept/3")) < 0) { return (FALSE); } ofd = Yap_GetStreamFd(sno); status = Yap_GetSocketStatus(sno); if (status != server_socket) { /* ok, this should be an error, as you are trying to bind */ return(FALSE); } domain = Yap_GetSocketDomain(sno); #if HAVE_SYS_UN_H if (domain == af_unix) { struct sockaddr_un caddr; unsigned int len; memset((void *)&caddr,(int) 0, sizeof(caddr)); if ((fd=accept(ofd, (struct sockaddr *)&caddr, &len)) < 0) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_accept/3 (accept: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_accept/3 (accept)"); #endif } /* ignore 2nd argument */ out = Yap_InitSocketStream(fd, server_session_socket, af_unix ); } else #endif if (domain == af_inet) { struct sockaddr_in caddr; Term tcli; char *s; #if _WIN32 || defined(__MINGW32__) int len; #else unsigned int len; #endif len = sizeof(caddr); memset((void *)&caddr,(int) 0, sizeof(caddr)); if (invalid_socket_fd(fd=accept(ofd, (struct sockaddr *)&caddr, &len))) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_accept/3 (accept: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_accept/3 (accept)"); #endif return(FALSE); } if ((s = inet_ntoa(caddr.sin_addr)) == NULL) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_accept/3 (inet_ntoa: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_accept/3 (inet_ntoa)"); #endif } tcli = MkAtomTerm(Yap_LookupAtom(s)); if (!Yap_unify(ARG2,tcli)) return(FALSE); out = Yap_InitSocketStream(fd, server_session_socket, af_inet ); } else return(FALSE); if (out == TermNil) return(FALSE); return(Yap_unify(out,ARG3)); }
static Int p_socket_connect(USES_REGS1) { Term t1 = Deref(ARG1); Term t2 = Deref(ARG2); Functor fun; int sno; socket_info status; int fd; int flag; Term out; if ((sno = Yap_CheckSocketStream(t1, "socket_connect/3")) < 0) { return (FALSE); } if (IsVarTerm(t2)) { Yap_Error(INSTANTIATION_ERROR,t2,"socket_connect/3"); return(FALSE); } if (!IsApplTerm(t2)) { Yap_Error(DOMAIN_ERROR_STREAM,t2,"socket_connect/3"); return(FALSE); } fun = FunctorOfTerm(t2); fd = Yap_GetStreamFd(sno); status = Yap_GetSocketStatus(sno); if (status != new_socket) { /* ok, this should be an error, as you are trying to bind */ return(FALSE); } #if HAVE_SYS_UN_H if (fun == FunctorAfUnix) { struct sockaddr_un sock; Term taddr = ArgOfTerm(1, t2); char *s; int len; if (IsVarTerm(taddr)) { Yap_Error(INSTANTIATION_ERROR,t2,"socket_connect/3"); return(FALSE); } if (!IsAtomTerm(taddr)) { Yap_Error(TYPE_ERROR_ATOM,taddr,"socket_connect/3"); return(FALSE); } s = RepAtom(AtomOfTerm(taddr))->StrOfAE; sock.sun_family = AF_UNIX; if ((len = strlen(s)) > 107) /* beat me with a broomstick */ { Yap_Error(DOMAIN_ERROR_STREAM,taddr,"socket_connect/3"); return(FALSE); } sock.sun_family=AF_UNIX; strcpy(sock.sun_path,s); if ((flag = connect(fd, (struct sockaddr *)(&sock), ((size_t) (((struct sockaddr_un *) 0)->sun_path) + len))) < 0) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (connect: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (connect)"); #endif return(FALSE); } Yap_UpdateSocketStream(sno, client_socket, af_unix); } else #endif if (fun == FunctorAfInet) { Term thost = ArgOfTerm(1, t2); Term tport = ArgOfTerm(2, t2); char *shost; struct hostent *he; struct sockaddr_in saddr; unsigned short int port; memset((void *)&saddr,(int) 0, sizeof(saddr)); if (IsVarTerm(thost)) { Yap_Error(INSTANTIATION_ERROR,thost,"socket_connect/3"); return(FALSE); } else if (!IsAtomTerm(thost)) { Yap_Error(TYPE_ERROR_ATOM,thost,"socket_connect/3"); return(FALSE); } else { shost = RepAtom(AtomOfTerm(thost))->StrOfAE; if((he=gethostbyname(shost))==NULL) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (gethostbyname: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (gethostbyname)"); #endif return(FALSE); } memcpy((void *)&saddr.sin_addr, (void *)he->h_addr_list[0], he->h_length); } if (IsVarTerm(tport)) { Yap_Error(INSTANTIATION_ERROR,tport,"socket_connect/3"); return(FALSE); } else if (!IsIntegerTerm(tport)) { Yap_Error(TYPE_ERROR_INTEGER,tport,"socket_connect/3"); return(FALSE); } else { port = (unsigned short int)IntegerOfTerm(tport); } saddr.sin_port = htons(port); saddr.sin_family = AF_INET; #if ENABLE_SO_LINGER { struct linger ling; /* For making sockets linger. */ /* disabled: I see why no reason why we should throw things away by default!! */ ling.l_onoff = 1; ling.l_linger = 0; if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (void *) &ling, sizeof(ling)) < 0) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (setsockopt_linger: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (setsockopt_linger)"); #endif return FALSE; } } #endif { int one = 1; /* code by David MW Powers */ if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void *)&one, sizeof(one))) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (setsockopt_broadcast: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (setsockopt_broadcast)"); #endif return FALSE; } } flag = connect(fd,(struct sockaddr *)&saddr, sizeof(saddr)); if(flag<0) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (connect: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_connect/3 (connect)"); #endif return FALSE; } Yap_UpdateSocketStream(sno, client_socket, af_inet); } else return(FALSE); out = t1; return(Yap_unify(out,ARG3)); }
static Int p_socket_bind(USES_REGS1) { Term t1 = Deref(ARG1); Term t2 = Deref(ARG2); int sno; Functor fun; socket_info status; int fd; if ((sno = Yap_CheckSocketStream(t1, "socket_bind/2")) < 0) { return (FALSE); } status = Yap_GetSocketStatus(sno); fd = Yap_GetStreamFd(sno); if (status != new_socket) { /* ok, this should be an error, as you are trying to bind */ return(FALSE); } if (IsVarTerm(t2)) { Yap_Error(INSTANTIATION_ERROR,t2,"socket_bind/2"); return(FALSE); } if (!IsApplTerm(t2)) { Yap_Error(DOMAIN_ERROR_STREAM,t2,"socket_bind/2"); return(FALSE); } fun = FunctorOfTerm(t2); #if HAVE_SYS_UN_H if (fun == FunctorAfUnix || fun == FunctorAfLocal) { struct sockaddr_un sock; Term taddr = ArgOfTerm(1, t2); char *s; int len; if (IsVarTerm(taddr)) { Yap_Error(INSTANTIATION_ERROR,t2,"socket_bind/2"); return(FALSE); } if (!IsAtomTerm(taddr)) { Yap_Error(TYPE_ERROR_ATOM,taddr,"socket_bind/2"); return(FALSE); } s = RepAtom(AtomOfTerm(taddr))->StrOfAE; sock.sun_family = AF_UNIX; if ((len = strlen(s)) > 107) /* hit me with a broomstick */ { Yap_Error(DOMAIN_ERROR_STREAM,taddr,"socket_bind/2"); return(FALSE); } sock.sun_family=AF_UNIX; strcpy(sock.sun_path,s); if (bind(fd, (struct sockaddr *)(&sock), ((size_t) (((struct sockaddr_un *) 0)->sun_path) + len)) < 0) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_bind/2 (bind: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_bind/2 (bind)"); #endif return(FALSE); } Yap_UpdateSocketStream(sno, server_socket, af_unix); return(TRUE); } else #endif if (fun == FunctorAfInet) { Term thost = ArgOfTerm(1, t2); Term tport = ArgOfTerm(2, t2); char *shost; struct hostent *he; struct sockaddr_in saddr; Int port; memset((void *)&saddr,(int) 0, sizeof(saddr)); if (IsVarTerm(thost)) { saddr.sin_addr.s_addr = INADDR_ANY; } else if (!IsAtomTerm(thost)) { Yap_Error(TYPE_ERROR_ATOM,thost,"socket_bind/2"); return(FALSE); } else { shost = RepAtom(AtomOfTerm(thost))->StrOfAE; if((he=gethostbyname(shost))==NULL) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_bind/2 (gethostbyname: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_bind/2 (gethostbyname)"); #endif return(FALSE); } memcpy((void *)&saddr.sin_addr, (void *)he->h_addr_list[0], he->h_length); } if (IsVarTerm(tport)) { port = 0; } else { port = IntOfTerm(tport); } saddr.sin_port = htons(port); saddr.sin_family = AF_INET; if(bind(fd,(struct sockaddr *)&saddr, sizeof(saddr))==-1) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_bind/2 (bind: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_bind/2 (bind)"); #endif return(FALSE); } if (IsVarTerm(tport)) { /* get the port number */ #if _WIN32 || defined(__MINGW32__) int namelen; #else unsigned int namelen; #endif Term t; if (getsockname(fd, (struct sockaddr *)&saddr, &namelen) < 0) { #if HAVE_STRERROR Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_bind/2 (getsockname: %s)", strerror(socket_errno)); #else Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "socket_bind/2 (getsockname)"); #endif return(FALSE); } t = MkIntTerm(ntohs(saddr.sin_port)); Yap_unify(ArgOfTermCell(2, t2),t); } Yap_UpdateSocketStream(sno, server_socket, af_inet); return(TRUE); } else return(FALSE); }