Added function SI:OPEN-UNIX-SOCKET-STREAM and SI:LOOKUP-HOST-ENTRY

This commit is contained in:
jjgarcia 2002-10-15 13:38:18 +00:00
parent 39539e5714
commit f03ef8ae16
3 changed files with 86 additions and 0 deletions

View file

@ -1156,6 +1156,8 @@ cl_symbols[] = {
#ifdef TCP
{"SI::OPEN-CLIENT-STREAM", SI_ORDINARY, NULL, siLopen_client_stream},
{"SI::OPEN-SERVER-STREAM", SI_ORDINARY, NULL, siLopen_server_stream},
{"SI::OPEN-UNIX-SOCKET-STREAM", SI_ORDINARY, NULL, siLopen_unix_socket_stream},
{"SI::LOOKUP-HOST-ENTRY", SI_ORDINARY, NULL, siLlookup_host_entry},
#endif
#ifdef unix

View file

@ -19,12 +19,16 @@
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <sys/ioctl.h>
#include "ecl.h"
/* Maximum length for a unix socket pathname */
#define UNIX_MAX_PATH 107
extern int errno;
/***********************************************************************
@ -277,3 +281,81 @@ make_stream(cl_object host, int fd, enum smmode smm)
}
@(return output)
@)
/************************************************************
* Unix sockets *
************************************************************/
@(defun si::open-unix-socket-stream (path)
int fd; /* file descriptor */
cl_object streamIn, streamOut;
struct sockaddr_un addr;
@
if (type_of(path) != t_string)
FEwrong_type_argument(@'string', path);
if (path->string.fillp > UNIX_MAX_PATH-1)
FEerror("~S is a too long file name.", 1, path);
fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
FEfilesystem_error("Unable to create unix socket", 0);
@(return Cnil)
}
memcpy(addr.sun_path, path->string.self, path->string.fillp);
addr.sun_path[path->string.fillp] = 0;
addr.sun_family = AF_UNIX;
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(fd);
FEfilesystem_error("Unable to connect to unix socket ~A", 1, path);
@(return Cnil)
}
streamIn = make_stream(path, fd, smm_input);
streamOut = make_stream(path, fd, smm_output);
@(return make_two_way_stream(streamIn, streamOut))
@)
/************************************************************
* Hostname resolution *
************************************************************/
@(defun si::lookup-host-entry (host_or_address)
struct hostent *he;
unsigned long l;
cl_object name, aliases, addresses;
int i;
@
switch (type_of(host_or_address)) {
case t_string:
host_or_address->string.self[host_or_address->string.fillp] = 0;
he = gethostbyname(host_or_address->string.self);
break;
case t_fixnum:
l = fix(host_or_address);
he = gethostbyaddr(&l, 4, AF_INET);
break;
case t_bignum:
l = big_to_ulong(host_or_address);
he = gethostbyaddr(&l, 4, AF_INET);
break;
default:
FEerror("LOOKUP-HOST-ENTRY: Number or string expected, got ~S",
1, host_or_address);
}
if (he == NULL)
FEerror("LOOKUP-HOST-ENTRY: Failed to find entry for ~S",
1, host_or_address);
name = make_string_copy(he->h_name);
aliases = Cnil;
for (i = 0; he->h_aliases[i] != 0; i++)
aliases = CONS(make_string_copy(he->h_aliases[i]), aliases);
addresses = Cnil;
for (i = 0; he->h_addr_list[i]; i++) {
unsigned long *s = (unsigned long*)(he->h_addr_list[i]);
l = *s;
addresses = CONS(make_integer(l), addresses);
}
@(return name aliases addresses)
@)

View file

@ -930,6 +930,8 @@ extern cl_object siLXmake_constant _ARGS((int narg, cl_object sym, cl_object val
#ifdef TCP
extern cl_object siLopen_client_stream _ARGS((int narg, cl_object host, cl_object port));
extern cl_object siLopen_server_stream _ARGS((int narg, cl_object port));
extern cl_object siLopen_unix_socket_stream _ARGS((int narg, cl_object path));
extern cl_object siLlookup_host_entry _ARGS((int narg, cl_object host_or_address));
#endif
/* time.c */