mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
Changes from Richard Frith-Macdonald. See ChangeLog Apr 24 10:30:00
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2312 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
9741450810
commit
7a544f5957
4 changed files with 741 additions and 53 deletions
18
ChangeLog
18
ChangeLog
|
@ -33,6 +33,24 @@ Sat May 3 12:28:48 1997 Andrew McCallum <mccallum@jprc.com>
|
||||||
Use NSBundle's pathForResource:ofType:inDirectory method properly.
|
Use NSBundle's pathForResource:ofType:inDirectory method properly.
|
||||||
(Reported by Stevo Crvenkovski <stevoc@lotus.mpt.com.mk>.)
|
(Reported by Stevo Crvenkovski <stevoc@lotus.mpt.com.mk>.)
|
||||||
|
|
||||||
|
Thu Apr 24 10:30:00 1997 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* src/Makefile.in: Added stuff to build and install the name
|
||||||
|
server (gdomap).
|
||||||
|
|
||||||
|
* src/RunLoop.m: Minor change to ensure that repeated timers are
|
||||||
|
not lost.
|
||||||
|
|
||||||
|
* src/TcpPort.m: Major changes to support use of a name server for
|
||||||
|
handling TCP port numbers and fix a few bugs.
|
||||||
|
|
||||||
|
* src/gdomap.c: This is the name server source.
|
||||||
|
|
||||||
|
* src/gdomap.h: This is the name server header file.
|
||||||
|
|
||||||
|
* src/include/NSRunLoop.h: Added methods for monitoring file
|
||||||
|
descriptors.
|
||||||
|
|
||||||
Sat Mar 29 00:43:18 1997 Yoo C. Chung <wacko@laplace.snu.ac.kr>
|
Sat Mar 29 00:43:18 1997 Yoo C. Chung <wacko@laplace.snu.ac.kr>
|
||||||
|
|
||||||
* src/NSZone.m: New e-mail address. Default default zone
|
* src/NSZone.m: New e-mail address. Default default zone
|
||||||
|
|
|
@ -31,6 +31,7 @@ VPATH = @srcdir@
|
||||||
# Installation locations
|
# Installation locations
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
bindir = $(exec_prefix)/bin
|
||||||
libdir = @libdir@
|
libdir = @libdir@
|
||||||
gnustep_libdir = $(libdir)/gnustep
|
gnustep_libdir = $(libdir)/gnustep
|
||||||
includedir = @includedir@
|
includedir = @includedir@
|
||||||
|
@ -522,7 +523,11 @@ DIST_FILES = \
|
||||||
|
|
||||||
# Targets
|
# Targets
|
||||||
|
|
||||||
all: gnustep/base Foundation lib$(LIBRARY_NAME)$(LIBEXT) @SHARED_LIBRARY@
|
all: \
|
||||||
|
gnustep/base Foundation \
|
||||||
|
lib$(LIBRARY_NAME)$(LIBEXT) \
|
||||||
|
@SHARED_LIBRARY@ \
|
||||||
|
gdomap
|
||||||
|
|
||||||
lib$(LIBRARY_NAME).so.$(VERSION): $(HEADERS_INSTALL) $(OBJS_INSTALL_PIC)
|
lib$(LIBRARY_NAME).so.$(VERSION): $(HEADERS_INSTALL) $(OBJS_INSTALL_PIC)
|
||||||
$(CC) -o lib$(LIBRARY_NAME).so.$(VERSION) $(CFLAGS_SHAREDLIB) \
|
$(CC) -o lib$(LIBRARY_NAME).so.$(VERSION) $(CFLAGS_SHAREDLIB) \
|
||||||
|
@ -559,6 +564,8 @@ Foundation: ../configure $(HEADERS_INSTALL)
|
||||||
$(LN_S) $(srcdir)/include Foundation
|
$(LN_S) $(srcdir)/include Foundation
|
||||||
|
|
||||||
install: installdirs all
|
install: installdirs all
|
||||||
|
# Install the Distributed Objects name server
|
||||||
|
$(INSTALL_PROGRAM) -o root -m 04755 gdomap $(bindir)
|
||||||
# Install the library
|
# Install the library
|
||||||
$(INSTALL_DATA) lib$(LIBRARY_NAME)$(LIBEXT) $(libdir)
|
$(INSTALL_DATA) lib$(LIBRARY_NAME)$(LIBEXT) $(libdir)
|
||||||
$(RANLIB) $(libdir)/lib$(LIBRARY_NAME)$(LIBEXT); \
|
$(RANLIB) $(libdir)/lib$(LIBRARY_NAME)$(LIBEXT); \
|
||||||
|
@ -606,6 +613,9 @@ $(NSNUMBER_MFILES) : NSConcreteNumber.m
|
||||||
echo '#define TYPE_ORDER' `echo $@ | sed -e "s,[^0-9],,g"` >$@
|
echo '#define TYPE_ORDER' `echo $@ | sed -e "s,[^0-9],,g"` >$@
|
||||||
cat $(srcdir)/NSConcreteNumber.m >> $@
|
cat $(srcdir)/NSConcreteNumber.m >> $@
|
||||||
|
|
||||||
|
gdomap: gdomap.c gdomap.h
|
||||||
|
$(CC) $(ALL_CPPFLAGS) $(DEFS) $(ALL_OBJCFLAGS) -w -o $@ $<
|
||||||
|
|
||||||
NXStringTable_scan.c: NXStringTable_scan.l
|
NXStringTable_scan.c: NXStringTable_scan.l
|
||||||
$(LEX) $(LEXFLAGS) -t $(srcdir)/NXStringTable_scan.l \
|
$(LEX) $(LEXFLAGS) -t $(srcdir)/NXStringTable_scan.l \
|
||||||
> NXStringTable_scan.temp
|
> NXStringTable_scan.temp
|
||||||
|
@ -705,6 +715,7 @@ mostlyclean:
|
||||||
clean: mostlyclean
|
clean: mostlyclean
|
||||||
rm -f lib$(LIBRARY_NAME)$(LIBEXT) *${OEXT}
|
rm -f lib$(LIBRARY_NAME)$(LIBEXT) *${OEXT}
|
||||||
rm -f $(NSVALUE_MFILES) $(NSNUMBER_MFILES)
|
rm -f $(NSVALUE_MFILES) $(NSNUMBER_MFILES)
|
||||||
|
rm -f gdomap
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f Makefile
|
rm -f Makefile
|
||||||
rm -f dynamic-load.h
|
rm -f dynamic-load.h
|
||||||
|
|
|
@ -359,7 +359,6 @@ static RunLoop *current_run_loop;
|
||||||
[min_timer fire];
|
[min_timer fire];
|
||||||
if ([min_timer isValid])
|
if ([min_timer isValid])
|
||||||
{
|
{
|
||||||
if ([[min_timer fireDate] timeIntervalSinceNow] > 0)
|
|
||||||
[timers addObject: min_timer];
|
[timers addObject: min_timer];
|
||||||
}
|
}
|
||||||
[min_timer release];
|
[min_timer release];
|
||||||
|
|
754
Source/TcpPort.m
754
Source/TcpPort.m
|
@ -1,5 +1,5 @@
|
||||||
/* Implementation of network port object based on TCP sockets
|
/* Implementation of network port object based on TCP sockets
|
||||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||||
Created: February 1996
|
Created: February 1996
|
||||||
|
@ -26,15 +26,14 @@
|
||||||
weirdness. */
|
weirdness. */
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
Make the sockets non-blocking.
|
|
||||||
Change so we don't wait on incoming packet prefix.
|
Change so we don't wait on incoming packet prefix.
|
||||||
All the abort()'s should be Exceptions.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gnustep/base/preface.h>
|
#include <gnustep/base/preface.h>
|
||||||
#include <gnustep/base/TcpPort.h>
|
#include <gnustep/base/TcpPort.h>
|
||||||
#include <gnustep/base/Array.h>
|
#include <gnustep/base/Array.h>
|
||||||
#include <gnustep/base/Notification.h>
|
#include <gnustep/base/Notification.h>
|
||||||
|
#include <gnustep/base/NSException.h>
|
||||||
#include <gnustep/base/RunLoop.h>
|
#include <gnustep/base/RunLoop.h>
|
||||||
#include <gnustep/base/Invocation.h>
|
#include <gnustep/base/Invocation.h>
|
||||||
#include <Foundation/NSDate.h>
|
#include <Foundation/NSDate.h>
|
||||||
|
@ -44,11 +43,28 @@
|
||||||
#include <unistd.h> /* for gethostname() */
|
#include <unistd.h> /* for gethostname() */
|
||||||
#include <sys/param.h> /* for MAXHOSTNAMELEN */
|
#include <sys/param.h> /* for MAXHOSTNAMELEN */
|
||||||
#include <arpa/inet.h> /* for inet_ntoa() */
|
#include <arpa/inet.h> /* for inet_ntoa() */
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
/*
|
||||||
|
* Stuff for setting the sockets into non-blocking mode.
|
||||||
|
*/
|
||||||
|
#ifdef __POSIX_SOURCE
|
||||||
|
#define NBLK_OPT O_NONBLOCK
|
||||||
|
#else
|
||||||
|
#define NBLK_OPT FNDELAY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GDOMAP 1 /* Use name server. */
|
||||||
|
#define stringify_it(X) #X
|
||||||
|
#define make_gdomap_cmd(X) stringify_it(X) "/bin/gdomap -p &"
|
||||||
|
#define make_gdomap_err(X) "check that " stringify_it(X) "/bin/gdomap is running and owned by root."
|
||||||
|
|
||||||
#endif /* !__WIN32__ */
|
#endif /* !__WIN32__ */
|
||||||
#include <string.h> /* for memset() and strchr() */
|
#include <string.h> /* for memset() and strchr() */
|
||||||
#ifndef __WIN32__
|
#ifndef __WIN32__
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
#endif /* !__WIN32__ */
|
#endif /* !__WIN32__ */
|
||||||
|
|
||||||
/* On some systems FD_ZERO is a macro that uses bzero().
|
/* On some systems FD_ZERO is a macro that uses bzero().
|
||||||
|
@ -57,6 +73,14 @@
|
||||||
|
|
||||||
static int debug_tcp_port = 0;
|
static int debug_tcp_port = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@interface TcpPrefPacket : TcpInPacket
|
||||||
|
@end
|
||||||
|
@implementation TcpPrefPacket
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Private interfaces */
|
/* Private interfaces */
|
||||||
|
|
||||||
|
@ -109,7 +133,498 @@ static int debug_tcp_port = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Our current, sad excuse for a name server. */
|
#ifdef GDOMAP
|
||||||
|
/*
|
||||||
|
* Code to contact distributed objects name server.
|
||||||
|
*/
|
||||||
|
#include "gdomap.h"
|
||||||
|
|
||||||
|
extern int errno; /* For systems where it is not in the include */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name - tryRead()
|
||||||
|
* Purpose - Attempt to read from a non blocking channel.
|
||||||
|
* Time out in specified time.
|
||||||
|
* If length of data is zero then just wait for
|
||||||
|
* descriptor to be readable.
|
||||||
|
* If the length is negative then attempt to
|
||||||
|
* read the absolute value of length but return
|
||||||
|
* as soon as anything is read.
|
||||||
|
*
|
||||||
|
* Return -1 on failure
|
||||||
|
* Return -2 on timeout
|
||||||
|
* Return number of bytes read
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
tryRead(int desc, int tim, unsigned char* dat, int len)
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
fd_set fds;
|
||||||
|
void *to;
|
||||||
|
int rval;
|
||||||
|
int pos = 0;
|
||||||
|
time_t when = 0;
|
||||||
|
int neg = 0;
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
neg = 1;
|
||||||
|
len = -len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First time round we do a select with an instant timeout to see
|
||||||
|
* if the descriptor is already readable.
|
||||||
|
*/
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
to = &timeout;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(desc, &fds);
|
||||||
|
|
||||||
|
rval = select(FD_SETSIZE, &fds, 0, 0, to);
|
||||||
|
if (rval == 0) {
|
||||||
|
time_t now = time(0);
|
||||||
|
|
||||||
|
if (when == 0) {
|
||||||
|
when = now;
|
||||||
|
}
|
||||||
|
else if (now - when >= tim) {
|
||||||
|
return(-2); /* Timed out. */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Set the timeout for a new call to select next time round
|
||||||
|
* the loop. */
|
||||||
|
timeout.tv_sec = tim - (now - when);
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (rval < 0) {
|
||||||
|
return(-1); /* Error in select. */
|
||||||
|
}
|
||||||
|
else if (len > 0) {
|
||||||
|
rval = read(desc, &dat[pos], len - pos);
|
||||||
|
if (rval < 0) {
|
||||||
|
if (errno != EWOULDBLOCK) {
|
||||||
|
return(-1); /* Error in read. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (rval == 0) {
|
||||||
|
return(-1); /* End of file. */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos += rval;
|
||||||
|
if (pos == len || neg == 1) {
|
||||||
|
return(pos); /* Read as needed. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return(0); /* Not actually asked to read. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name - tryWrite()
|
||||||
|
* Purpose - Attempt to write to a non blocking channel.
|
||||||
|
* Time out in specified time.
|
||||||
|
* If length of data is zero then just wait for
|
||||||
|
* descriptor to be writable.
|
||||||
|
* If the length is negative then attempt to
|
||||||
|
* write the absolute value of length but return
|
||||||
|
* as soon as anything is written.
|
||||||
|
*
|
||||||
|
* Return -1 on failure
|
||||||
|
* Return -2 on timeout
|
||||||
|
* Return number of bytes written
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
tryWrite(int desc, int tim, unsigned char* dat, int len)
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
fd_set fds;
|
||||||
|
void *to;
|
||||||
|
int rval;
|
||||||
|
int pos = 0;
|
||||||
|
time_t when = 0;
|
||||||
|
int neg = 0;
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
neg = 1;
|
||||||
|
len = -len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First time round we do a select with an instant timeout to see
|
||||||
|
* if the descriptor is already writable.
|
||||||
|
*/
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
to = &timeout;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(desc, &fds);
|
||||||
|
|
||||||
|
rval = select(FD_SETSIZE, 0, &fds, 0, to);
|
||||||
|
if (rval == 0) {
|
||||||
|
time_t now = time(0);
|
||||||
|
|
||||||
|
if (when == 0) {
|
||||||
|
when = now;
|
||||||
|
}
|
||||||
|
else if (now - when >= tim) {
|
||||||
|
return(-2); /* Timed out. */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Set the timeout for a new call to select next time round
|
||||||
|
* the loop. */
|
||||||
|
timeout.tv_sec = tim - (now - when);
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (rval < 0) {
|
||||||
|
return(-1); /* Error in select. */
|
||||||
|
}
|
||||||
|
else if (len > 0) {
|
||||||
|
int (*ifun)();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should be able to write this short a message immediately, but
|
||||||
|
* if the connection is lost we will get a signal we must trap.
|
||||||
|
*/
|
||||||
|
ifun = signal(SIGPIPE, SIG_IGN);
|
||||||
|
rval = write(desc, &dat[pos], len - pos);
|
||||||
|
signal(SIGPIPE, ifun);
|
||||||
|
|
||||||
|
if (rval <= 0) {
|
||||||
|
if (errno != EWOULDBLOCK) {
|
||||||
|
return(-1); /* Error in write. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos += rval;
|
||||||
|
if (pos == len || neg == 1) {
|
||||||
|
return(pos); /* Written as needed. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return(0); /* Not actually asked to write. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name - tryHost()
|
||||||
|
* Purpose - Perform a name server operation with a given
|
||||||
|
* request packet to a server at specified address.
|
||||||
|
* On error - return non-zero with reason in 'errno'
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
tryHost(unsigned char op, unsigned char len, const unsigned char* name,
|
||||||
|
struct sockaddr_in* addr, unsigned short* p, unsigned char **v)
|
||||||
|
{
|
||||||
|
int desc = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
int e = 0;
|
||||||
|
unsigned short port = *p;
|
||||||
|
unsigned char buf[GDO_REQ_SIZE];
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
*p = 0;
|
||||||
|
if (desc < 0) {
|
||||||
|
return(1); /* Couldn't create socket. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((e = fcntl(desc, F_GETFL, 0)) >= 0) {
|
||||||
|
e |= NBLK_OPT;
|
||||||
|
if (fcntl(desc, F_SETFL, e) < 0) {
|
||||||
|
e = errno;
|
||||||
|
close(desc);
|
||||||
|
errno = e;
|
||||||
|
return(2); /* Couldn't set non-blocking. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e = errno;
|
||||||
|
close(desc);
|
||||||
|
errno = e;
|
||||||
|
return(2); /* Couldn't set non-blocking. */
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&sin, addr, sizeof(sin));
|
||||||
|
if (connect(desc, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
|
||||||
|
if (errno == EINPROGRESS) {
|
||||||
|
e = tryWrite(desc, 10, 0, 0);
|
||||||
|
if (e == -2) {
|
||||||
|
e = errno;
|
||||||
|
close(desc);
|
||||||
|
errno = e;
|
||||||
|
return(3); /* Connect timed out. */
|
||||||
|
}
|
||||||
|
else if (e == -1) {
|
||||||
|
e = errno;
|
||||||
|
close(desc);
|
||||||
|
errno = e;
|
||||||
|
return(3); /* Select failed. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e = errno;
|
||||||
|
close(desc);
|
||||||
|
errno = e;
|
||||||
|
return(3); /* Failed connect. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, '\0', GDO_REQ_SIZE);
|
||||||
|
buf[0] = op;
|
||||||
|
buf[1] = len;
|
||||||
|
if (op != GDO_REGISTER) {
|
||||||
|
port = 0;
|
||||||
|
}
|
||||||
|
*((unsigned short*)&buf[2]) = htons(port);
|
||||||
|
memcpy(&buf[4], name, len);
|
||||||
|
|
||||||
|
e = tryWrite(desc, 10, buf, GDO_REQ_SIZE);
|
||||||
|
if (e != GDO_REQ_SIZE) {
|
||||||
|
e = errno;
|
||||||
|
close(desc);
|
||||||
|
errno = e;
|
||||||
|
return(4);
|
||||||
|
}
|
||||||
|
e = tryRead(desc, 3, (unsigned char*)p, 2);
|
||||||
|
if (e != 2) {
|
||||||
|
e = errno;
|
||||||
|
close(desc);
|
||||||
|
errno = e;
|
||||||
|
return(5); /* Read timed out. */
|
||||||
|
}
|
||||||
|
*p = ntohs(*p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special case for GDO_SERVERS - allocate buffer and read list.
|
||||||
|
*/
|
||||||
|
if (op == GDO_SERVERS) {
|
||||||
|
int len = *p * sizeof(struct in_addr);
|
||||||
|
unsigned char* b;
|
||||||
|
|
||||||
|
b = (unsigned char*)objc_malloc(len);
|
||||||
|
if (tryRead(desc, 3, b, len) != len) {
|
||||||
|
objc_free(b);
|
||||||
|
e = errno;
|
||||||
|
close(desc);
|
||||||
|
errno = e;
|
||||||
|
return(5);
|
||||||
|
}
|
||||||
|
*v = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(desc);
|
||||||
|
errno = 0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name - nameFail()
|
||||||
|
* Purpose - If given a failure status from tryHost()
|
||||||
|
* raise an appropriate exception.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
nameFail(int why)
|
||||||
|
{
|
||||||
|
switch (why) {
|
||||||
|
case 0: break;
|
||||||
|
case 1:
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"failed to contact name server - socket - %s - %s",
|
||||||
|
strerror(errno),
|
||||||
|
make_gdomap_err(GNUSTEP_INSTALL_PREFIX)];
|
||||||
|
case 2:
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"failed to contact name server - socket - %s - %s",
|
||||||
|
strerror(errno),
|
||||||
|
make_gdomap_err(GNUSTEP_INSTALL_PREFIX)];
|
||||||
|
case 3:
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"failed to contact name server - socket - %s - %s",
|
||||||
|
strerror(errno),
|
||||||
|
make_gdomap_err(GNUSTEP_INSTALL_PREFIX)];
|
||||||
|
case 4:
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"failed to contact name server - socket - %s - %s",
|
||||||
|
strerror(errno),
|
||||||
|
make_gdomap_err(GNUSTEP_INSTALL_PREFIX)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name - nameServer()
|
||||||
|
* Purpose - Perform name server lookup or registration.
|
||||||
|
* Return success/failure status and set up an
|
||||||
|
* address structure for use in bind or connect.
|
||||||
|
* Restrictions - 0xffff byte name limit
|
||||||
|
* Uses old style host lookup - only handles the
|
||||||
|
* primary network interface for each host!
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
nameServer(const char* name, const char* host, int op, struct sockaddr_in* addr, int pnum, int max)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
struct servent* sp;
|
||||||
|
struct hostent* hp;
|
||||||
|
unsigned short p = htons(GDOMAP_PORT);
|
||||||
|
unsigned short port = 0;
|
||||||
|
int len = strlen(name);
|
||||||
|
int multi = 0;
|
||||||
|
int found = 0;
|
||||||
|
int rval;
|
||||||
|
char local_hostname[MAXHOSTNAMELEN];
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"no name specified"];
|
||||||
|
}
|
||||||
|
if (len > 255) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"name length to large (>255 characters)"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure we have port number to connect to name server.
|
||||||
|
* The TCP service name 'gdomap' overrides the default port.
|
||||||
|
*/
|
||||||
|
if ((sp = getservbyname("gdomap", "tcp")) != 0) {
|
||||||
|
p = sp->s_port; /* Network byte order. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The host name '*' matches any host on the local network.
|
||||||
|
*/
|
||||||
|
if (host && host[0] == '*' && host[1] == '\0') {
|
||||||
|
multi = 1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If no host name is given, we use the name of the local host.
|
||||||
|
* NB. This should always be the case for operations other than lookup.
|
||||||
|
*/
|
||||||
|
if (multi || host == 0 || *host == '\0') {
|
||||||
|
char *first_dot;
|
||||||
|
|
||||||
|
if (gethostname(local_hostname, sizeof(local_hostname)) < 0) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"gethostname() failed: %s", strerror(errno)];
|
||||||
|
}
|
||||||
|
first_dot = strchr(local_hostname, '.');
|
||||||
|
if (first_dot) {
|
||||||
|
*first_dot = '\0';
|
||||||
|
}
|
||||||
|
host = local_hostname;
|
||||||
|
}
|
||||||
|
if ((hp = gethostbyname(host)) == 0) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"get host address for %s", host];
|
||||||
|
}
|
||||||
|
if (hp->h_addrtype != AF_INET) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"non-internet network not supported for %s", host];
|
||||||
|
}
|
||||||
|
|
||||||
|
memset((char*)&sin, '\0', sizeof(sin));
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = p;
|
||||||
|
memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length);
|
||||||
|
|
||||||
|
if (multi) {
|
||||||
|
unsigned short num;
|
||||||
|
struct in_addr* b;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A host name of '*' is a special case which should do lookup on
|
||||||
|
* all machines on the local network until one is found which has
|
||||||
|
* the specified server on it.
|
||||||
|
*/
|
||||||
|
rval = tryHost(GDO_SERVERS, 0, 0, &sin, &num, (unsigned char**)&b);
|
||||||
|
/*
|
||||||
|
* If the connection to the local name server fails,
|
||||||
|
* attempt to start it us and retry the lookup.
|
||||||
|
*/
|
||||||
|
if (rval != 0 && host == local_hostname) {
|
||||||
|
system(make_gdomap_cmd(GNUSTEP_INSTALL_PREFIX));
|
||||||
|
sleep(5);
|
||||||
|
rval = tryHost(GDO_SERVERS, 0, 0, &sin, &num, (unsigned char**)&b);
|
||||||
|
}
|
||||||
|
if (rval == 0) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
num = ntohs(num);
|
||||||
|
for (i = 0; found == 0 && i < num; i++) {
|
||||||
|
memset((char*)&sin, '\0', sizeof(sin));
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = p;
|
||||||
|
memcpy((caddr_t)&sin.sin_addr, &b[i], sizeof(struct in_addr));
|
||||||
|
|
||||||
|
if (tryHost(GDO_LOOKUP, len, name, &sin, &port, 0) == 0) {
|
||||||
|
if (port != 0) {
|
||||||
|
memset((char*)&addr[found], '\0', sizeof(*addr));
|
||||||
|
memcpy((caddr_t)&addr[found].sin_addr, &sin.sin_addr,
|
||||||
|
sizeof(sin.sin_addr));
|
||||||
|
addr[found].sin_family = AF_INET;
|
||||||
|
addr[found].sin_port = htons(port);
|
||||||
|
found++;
|
||||||
|
if (found == max) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
objc_free(b);
|
||||||
|
return(found);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nameFail(rval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (op == GDO_REGISTER) {
|
||||||
|
port = (unsigned short)pnum;
|
||||||
|
}
|
||||||
|
rval = tryHost(op, len, name, &sin, &port, 0);
|
||||||
|
/*
|
||||||
|
* If the connection to the local name server fails,
|
||||||
|
* attempt to start it us and retry the lookup.
|
||||||
|
*/
|
||||||
|
if (rval != 0 && host == local_hostname) {
|
||||||
|
system(make_gdomap_cmd(GNUSTEP_INSTALL_PREFIX));
|
||||||
|
sleep(5);
|
||||||
|
if (op == GDO_REGISTER) {
|
||||||
|
port = (unsigned short)pnum;
|
||||||
|
}
|
||||||
|
rval = tryHost(op, len, name, &sin, &port, 0);
|
||||||
|
}
|
||||||
|
nameFail(rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op == GDO_REGISTER) {
|
||||||
|
if (port == 0 || (pnum != 0 && port != pnum)) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"service already registered"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (port == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset((char*)addr, '\0', sizeof(*addr));
|
||||||
|
memcpy((caddr_t)&addr->sin_addr, &sin.sin_addr, sizeof(sin.sin_addr));
|
||||||
|
addr->sin_family = AF_INET;
|
||||||
|
addr->sin_port = htons(port);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* The old hash code for a name server. */
|
||||||
|
|
||||||
static unsigned short
|
static unsigned short
|
||||||
name_2_port_number (const char *name)
|
name_2_port_number (const char *name)
|
||||||
|
@ -125,7 +640,7 @@ name_2_port_number (const char *name)
|
||||||
return (ret % (65535 - IPPORT_USERRESERVED - 1)) + IPPORT_USERRESERVED;
|
return (ret % (65535 - IPPORT_USERRESERVED - 1)) + IPPORT_USERRESERVED;
|
||||||
/* return strlen (name) + IPPORT_USERRESERVED; */
|
/* return strlen (name) + IPPORT_USERRESERVED; */
|
||||||
}
|
}
|
||||||
|
#endif /* GDOMAP */
|
||||||
|
|
||||||
|
|
||||||
/* Both TcpInPort's and TcpOutPort's are entered in this maptable. */
|
/* Both TcpInPort's and TcpOutPort's are entered in this maptable. */
|
||||||
|
@ -188,8 +703,9 @@ static NSMapTable* port_number_2_port;
|
||||||
p->_port_socket = socket (AF_INET, SOCK_STREAM, 0);
|
p->_port_socket = socket (AF_INET, SOCK_STREAM, 0);
|
||||||
if (p->_port_socket < 0)
|
if (p->_port_socket < 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpInPort +newForReceivingFromPortNumber:] socket()");
|
[NSException raise: NSInternalInconsistencyException
|
||||||
abort ();
|
format: @"[TcpInPort +newForReceivingFromPortNumber:] socket(): %s",
|
||||||
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register the port object according to its socket. */
|
/* Register the port object according to its socket. */
|
||||||
|
@ -204,7 +720,12 @@ static NSMapTable* port_number_2_port;
|
||||||
struct hostent *hp;
|
struct hostent *hp;
|
||||||
char hostname[MAXHOSTNAMELEN];
|
char hostname[MAXHOSTNAMELEN];
|
||||||
int len = MAXHOSTNAMELEN;
|
int len = MAXHOSTNAMELEN;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Set the re-use socket option so that we don't get this socket
|
||||||
|
hanging around after we close it (or die) */
|
||||||
|
r = 1;
|
||||||
|
setsockopt(p->_socket,SOL_SOCKET,SO_REUSEADDR,(char*)&r,sizeof(r));
|
||||||
/* Fill in the _LISTENING_ADDRESS with the address this in port on
|
/* Fill in the _LISTENING_ADDRESS with the address this in port on
|
||||||
which will listen for connections. Use INADDR_ANY so that we
|
which will listen for connections. Use INADDR_ANY so that we
|
||||||
will accept connection on any of the machine network addresses;
|
will accept connection on any of the machine network addresses;
|
||||||
|
@ -220,8 +741,29 @@ static NSMapTable* port_number_2_port;
|
||||||
sizeof (p->_listening_address))
|
sizeof (p->_listening_address))
|
||||||
< 0)
|
< 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpInPort +newForReceivingFromPortNumber] bind()");
|
[NSException raise: NSInternalInconsistencyException
|
||||||
abort ();
|
format: @"[TcpInPort +newForReceivingFromPortNumber:] bind(): %s",
|
||||||
|
strerror(errno)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the caller didn't specify a port number, it was chosen for us.
|
||||||
|
Here, find out what number was chosen. */
|
||||||
|
if (!n)
|
||||||
|
/* xxx Perhaps I should do this unconditionally? */
|
||||||
|
{
|
||||||
|
int size = sizeof (p->_listening_address);
|
||||||
|
if (getsockname (p->_socket,
|
||||||
|
(struct sockaddr*)&(p->_listening_address),
|
||||||
|
&size)
|
||||||
|
< 0)
|
||||||
|
{
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpInPort +newForReceivingFromPortNumber:] getsockname(): %s",
|
||||||
|
strerror(errno)];
|
||||||
|
|
||||||
|
}
|
||||||
|
assert (p->_listening_address.sin_port);
|
||||||
|
n = ntohs(p->_listening_address.sin_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now change _LISTENING_ADDRESS to the specific network address of this
|
/* Now change _LISTENING_ADDRESS to the specific network address of this
|
||||||
|
@ -230,8 +772,9 @@ static NSMapTable* port_number_2_port;
|
||||||
unique host address that can identify us across the network. */
|
unique host address that can identify us across the network. */
|
||||||
if (gethostname (hostname, len) < 0)
|
if (gethostname (hostname, len) < 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpInPort +newForReceivingFromPortNumber:] gethostname()");
|
[NSException raise: NSInternalInconsistencyException
|
||||||
abort ();
|
format: @"[TcpInPort +newForReceivingFromPortNumber:] gethostname(): %s",
|
||||||
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
/* Terminate the name at the first dot. */
|
/* Terminate the name at the first dot. */
|
||||||
{
|
{
|
||||||
|
@ -246,6 +789,10 @@ static NSMapTable* port_number_2_port;
|
||||||
memcpy (&(p->_listening_address.sin_addr), hp->h_addr, hp->h_length);
|
memcpy (&(p->_listening_address.sin_addr), hp->h_addr, hp->h_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* Is this right? -am */
|
||||||
|
assert (n);
|
||||||
|
#else
|
||||||
/* If the caller didn't specify a port number, it was chosen for us.
|
/* If the caller didn't specify a port number, it was chosen for us.
|
||||||
Here, find out what number was chosen. */
|
Here, find out what number was chosen. */
|
||||||
if (!n)
|
if (!n)
|
||||||
|
@ -262,13 +809,16 @@ static NSMapTable* port_number_2_port;
|
||||||
}
|
}
|
||||||
assert (p->_listening_address.sin_port);
|
assert (p->_listening_address.sin_port);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set it up to accept connections, let 10 pending connections queue */
|
/* Set it up to accept connections, let 10 pending connections queue */
|
||||||
/* xxx Make this "10" a class variable? */
|
/* xxx Make this "10" a class variable? */
|
||||||
if (listen (p->_port_socket, 10) < 0)
|
if (listen (p->_port_socket, 10) < 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpInPort +newForReceivingFromPortNumber] listen()");
|
[NSException raise: NSInternalInconsistencyException
|
||||||
abort ();
|
format: @"[TcpInPort +newForReceivingFromPortNumber:] "
|
||||||
|
@"listen(): %s",
|
||||||
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the tables for matching socket's to out ports and packets. */
|
/* Initialize the tables for matching socket's to out ports and packets. */
|
||||||
|
@ -287,8 +837,23 @@ static NSMapTable* port_number_2_port;
|
||||||
|
|
||||||
+ newForReceivingFromRegisteredName: (NSString*)name
|
+ newForReceivingFromRegisteredName: (NSString*)name
|
||||||
{
|
{
|
||||||
|
#ifdef GDOMAP
|
||||||
|
TcpInPort* p = [self newForReceivingFromPortNumber: 0];
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
int port = [p portNumber];
|
||||||
|
|
||||||
|
if (nameServer([name cStringNoCopy], 0, GDO_REGISTER, &sin, port, 1) == 0) {
|
||||||
|
[p release];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
#else
|
||||||
return [self newForReceivingFromPortNumber:
|
return [self newForReceivingFromPortNumber:
|
||||||
name_2_port_number ([name cStringNoCopy])];
|
name_2_port_number ([name cStringNoCopy])];
|
||||||
|
+ #endif /* GDOMAP */
|
||||||
}
|
}
|
||||||
|
|
||||||
+ newForReceiving
|
+ newForReceiving
|
||||||
|
@ -369,6 +934,7 @@ static NSMapTable* port_number_2_port;
|
||||||
/* This is a connection request on the original listen()'ing socket. */
|
/* This is a connection request on the original listen()'ing socket. */
|
||||||
int new;
|
int new;
|
||||||
int size;
|
int size;
|
||||||
|
int rval;
|
||||||
volatile id op;
|
volatile id op;
|
||||||
struct sockaddr_in clientname;
|
struct sockaddr_in clientname;
|
||||||
|
|
||||||
|
@ -376,8 +942,27 @@ static NSMapTable* port_number_2_port;
|
||||||
new = accept (_port_socket, (struct sockaddr*)&clientname, &size);
|
new = accept (_port_socket, (struct sockaddr*)&clientname, &size);
|
||||||
if (new < 0)
|
if (new < 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpInPort receivePacketWithTimeout:] accept()");
|
[NSException raise: NSInternalInconsistencyException
|
||||||
abort ();
|
format: @"[TcpInPort receivePacketWithTimeout:] accept(): %s",
|
||||||
|
strerror(errno)];
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Code to ensure that new socket is non-blocking.
|
||||||
|
*/
|
||||||
|
if ((rval = fcntl(new, F_GETFL, 0)) >= 0) {
|
||||||
|
rval |= NBLK_OPT;
|
||||||
|
if (fcntl(new, F_SETFL, rval) < 0) {
|
||||||
|
close(new);
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpInPort receivePacketWithTimeout:] fcntl(SET): %s",
|
||||||
|
strerror(errno)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
close(new);
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpInPort receivePacketWithTimeout:] fcntl(GET): %s",
|
||||||
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
op = [TcpOutPort _newWithAcceptedSocket: new
|
op = [TcpOutPort _newWithAcceptedSocket: new
|
||||||
peeraddr: &clientname
|
peeraddr: &clientname
|
||||||
|
@ -431,6 +1016,7 @@ static NSMapTable* port_number_2_port;
|
||||||
initForReceivingWithCapacity: packet_size
|
initForReceivingWithCapacity: packet_size
|
||||||
receivingInPort: self
|
receivingInPort: self
|
||||||
replyOutPort: reply_port];
|
replyOutPort: reply_port];
|
||||||
|
NSMapInsert(_client_sock_2_packet,(void*)fd_index,(void*)packet);
|
||||||
}
|
}
|
||||||
/* The packet has now been created with correct capacity */
|
/* The packet has now been created with correct capacity */
|
||||||
}
|
}
|
||||||
|
@ -445,6 +1031,7 @@ static NSMapTable* port_number_2_port;
|
||||||
release the packet and invalidate the corresponding
|
release the packet and invalidate the corresponding
|
||||||
port, and keep on waiting for incoming data on
|
port, and keep on waiting for incoming data on
|
||||||
other sockets. */
|
other sockets. */
|
||||||
|
NSMapRemove(_client_sock_2_packet, (void*)fd_index);
|
||||||
[packet release];
|
[packet release];
|
||||||
[(id) NSMapGet (_client_sock_2_out_port, (void*)fd_index)
|
[(id) NSMapGet (_client_sock_2_out_port, (void*)fd_index)
|
||||||
invalidate];
|
invalidate];
|
||||||
|
@ -455,6 +1042,7 @@ static NSMapTable* port_number_2_port;
|
||||||
/* No bytes are remaining to be read for this packet;
|
/* No bytes are remaining to be read for this packet;
|
||||||
the packet is complete; return it. */
|
the packet is complete; return it. */
|
||||||
assert (packet && [packet class]);
|
assert (packet && [packet class]);
|
||||||
|
NSMapRemove(_client_sock_2_packet, (void*)fd_index);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,11 +1079,16 @@ static NSMapTable* port_number_2_port;
|
||||||
/* This is called by the RunLoop when select() says the FD is ready
|
/* This is called by the RunLoop when select() says the FD is ready
|
||||||
for reading. */
|
for reading. */
|
||||||
|
|
||||||
|
#include <Foundation/NSAutoreleasePool.h>
|
||||||
- (void) readyForReadingOnFileDescriptor: (int)fd;
|
- (void) readyForReadingOnFileDescriptor: (int)fd;
|
||||||
{
|
{
|
||||||
|
id arp = [NSAutoreleasePool new];
|
||||||
id packet = [self _tryToGetPacketFromReadableFD: fd];
|
id packet = [self _tryToGetPacketFromReadableFD: fd];
|
||||||
if (packet)
|
if (packet) {
|
||||||
[_packet_invocation invokeWithObject: packet];
|
[_packet_invocation invokeWithObject: packet];
|
||||||
|
}
|
||||||
|
[arp release];
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -585,7 +1178,7 @@ static NSMapTable* port_number_2_port;
|
||||||
closesocket (_port_socket);
|
closesocket (_port_socket);
|
||||||
#else
|
#else
|
||||||
close (_port_socket);
|
close (_port_socket);
|
||||||
#endif
|
#endif /* __WIN32__ */
|
||||||
|
|
||||||
/* These are here, and not in -dealloc, to prevent
|
/* These are here, and not in -dealloc, to prevent
|
||||||
+newForReceivingFromPortNumber: from returning invalid sockets. */
|
+newForReceivingFromPortNumber: from returning invalid sockets. */
|
||||||
|
@ -799,8 +1392,9 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
p->_port_socket = socket (AF_INET, SOCK_STREAM, 0);
|
p->_port_socket = socket (AF_INET, SOCK_STREAM, 0);
|
||||||
if (p->_port_socket < 0)
|
if (p->_port_socket < 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpOutPort newForSendingToSockaddr:...] socket()");
|
[NSException raise: NSInternalInconsistencyException
|
||||||
abort ();
|
format: @"[TcpInPort newForSendingToSockaddr:...] socket(): %s",
|
||||||
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,15 +1425,43 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
already by a previous accept() call. */
|
already by a previous accept() call. */
|
||||||
if (!sock)
|
if (!sock)
|
||||||
{
|
{
|
||||||
|
int rval;
|
||||||
assert (p->_remote_in_port_address.sin_family);
|
assert (p->_remote_in_port_address.sin_family);
|
||||||
if (connect (p->_port_socket,
|
if (connect (p->_port_socket,
|
||||||
(struct sockaddr*)&(p->_remote_in_port_address),
|
(struct sockaddr*)&(p->_remote_in_port_address),
|
||||||
sizeof(p->_remote_in_port_address))
|
sizeof(p->_remote_in_port_address))
|
||||||
< 0)
|
< 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpOutPort newForSendingToSockaddr:...] connect()");
|
close(p->_socket);
|
||||||
abort ();
|
#if 0
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpInPort newForSendingToSockaddr:...] connect(): %s",
|
||||||
|
strerror(errno)];
|
||||||
|
#else
|
||||||
|
[p release];
|
||||||
|
return nil;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure the socket is non-blocking.
|
||||||
|
*/
|
||||||
|
if ((rval = fcntl(p->_socket, F_GETFL, 0)) >= 0) {
|
||||||
|
rval |= NBLK_OPT;
|
||||||
|
if (fcntl(p->_socket, F_SETFL, rval) < 0) {
|
||||||
|
close(p->_socket);
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpInPort newForSendingToSockaddr:...] fcntl(SET): %s",
|
||||||
|
strerror(errno)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
close(p->_socket);
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpInPort newForSendingToSockaddr:...] fcntl(GET): %s",
|
||||||
|
strerror(errno)];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put it in the shared socket->port map table. */
|
/* Put it in the shared socket->port map table. */
|
||||||
|
@ -868,9 +1490,9 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
char *first_dot;
|
char *first_dot;
|
||||||
if (gethostname (local_hostname, len) < 0)
|
if (gethostname (local_hostname, len) < 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpOutPort +newForSendingToPortNumber:onHost:] "
|
[NSException raise: NSInternalInconsistencyException
|
||||||
"gethostname()");
|
format: @"[TcpInPort newForSendingToPortNumber:onHost:] gethostname(): %s",
|
||||||
abort ();
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
host_cstring = local_hostname;
|
host_cstring = local_hostname;
|
||||||
first_dot = strchr (host_cstring, '.');
|
first_dot = strchr (host_cstring, '.');
|
||||||
|
@ -896,9 +1518,26 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
+ newForSendingToRegisteredName: (NSString*)name
|
+ newForSendingToRegisteredName: (NSString*)name
|
||||||
onHost: (NSString*)hostname
|
onHost: (NSString*)hostname
|
||||||
{
|
{
|
||||||
|
#ifdef GDOMAP
|
||||||
|
struct sockaddr_in sin[100];
|
||||||
|
int found;
|
||||||
|
int i;
|
||||||
|
id c = nil;
|
||||||
|
|
||||||
|
found = nameServer([name cStringNoCopy], [hostname cStringNoCopy],
|
||||||
|
GDO_LOOKUP, sin, 0, 100);
|
||||||
|
for (i = 0; c == nil && i < found; i++)
|
||||||
|
{
|
||||||
|
c = [self newForSendingToSockaddr: &sin[i]
|
||||||
|
withAcceptedSocket: 0
|
||||||
|
pollingInPort: nil];
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
#else
|
||||||
return [self newForSendingToPortNumber:
|
return [self newForSendingToPortNumber:
|
||||||
name_2_port_number ([name cStringNoCopy])
|
name_2_port_number ([name cStringNoCopy])
|
||||||
onHost: hostname];;
|
onHost: hostname];;
|
||||||
|
#endif /* GDOMAP */
|
||||||
}
|
}
|
||||||
|
|
||||||
+ _newWithAcceptedSocket: (int)s
|
+ _newWithAcceptedSocket: (int)s
|
||||||
|
@ -912,8 +1551,9 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
/* Get the sockaddr. */
|
/* Get the sockaddr. */
|
||||||
if (getpeername (s, (struct sockaddr*)&addr, &size) < 0)
|
if (getpeername (s, (struct sockaddr*)&addr, &size) < 0)
|
||||||
{
|
{
|
||||||
perror ("[TcpPort +newWithAcceptedSocket:] getsockname()");
|
[NSException raise: NSInternalInconsistencyException
|
||||||
abort ();
|
format: @"[TcpInPort newWithAcceptedSocket:] getsockname(): %s",
|
||||||
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
assert (size == sizeof (struct sockaddr_in));
|
assert (size == sizeof (struct sockaddr_in));
|
||||||
/* xxx Perhaps I have to get peer name here!! */
|
/* xxx Perhaps I have to get peer name here!! */
|
||||||
|
@ -996,10 +1636,11 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
if (closesocket (_port_socket) < 0)
|
if (closesocket (_port_socket) < 0)
|
||||||
#else
|
#else
|
||||||
if (close (_port_socket) < 0)
|
if (close (_port_socket) < 0)
|
||||||
#endif
|
#endif /* __WIN32__ */
|
||||||
{
|
{
|
||||||
perror ("[TcpOutPort -invalidate] close()");
|
[NSException raise: NSInternalInconsistencyException
|
||||||
abort ();
|
format: @"[TcpOutPort -invalidate:] close(): %s",
|
||||||
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
[_polling_in_port _connectedOutPortInvalidated: self];
|
[_polling_in_port _connectedOutPortInvalidated: self];
|
||||||
[_polling_in_port release];
|
[_polling_in_port release];
|
||||||
|
@ -1108,8 +1749,6 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
#define PREFIX_ADDRESS_SIZE sizeof (PREFIX_ADDRESS_TYPE)
|
#define PREFIX_ADDRESS_SIZE sizeof (PREFIX_ADDRESS_TYPE)
|
||||||
#define PREFIX_SIZE (PREFIX_LENGTH_SIZE + PREFIX_ADDRESS_SIZE)
|
#define PREFIX_SIZE (PREFIX_LENGTH_SIZE + PREFIX_ADDRESS_SIZE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@implementation TcpInPacket
|
@implementation TcpInPacket
|
||||||
|
|
||||||
+ (void) _getPacketSize: (int*)packet_size
|
+ (void) _getPacketSize: (int*)packet_size
|
||||||
|
@ -1120,12 +1759,16 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
char prefix_buffer[PREFIX_SIZE];
|
char prefix_buffer[PREFIX_SIZE];
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
#ifdef GDOMAP
|
||||||
|
c = tryRead (s, 3, prefix_buffer, PREFIX_SIZE);
|
||||||
|
#else
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
c = recv (s, prefix_buffer, PREFIX_SIZE, 0);
|
c = recv (s, prefix_buffer, PREFIX_SIZE, 0);
|
||||||
#else
|
#else
|
||||||
c = read (s, prefix_buffer, PREFIX_SIZE);
|
c = read (s, prefix_buffer, PREFIX_SIZE);
|
||||||
#endif
|
#endif /* __WIN32__ */
|
||||||
if (c == 0)
|
#endif /* GDOMAP */
|
||||||
|
if (c <= 0)
|
||||||
{
|
{
|
||||||
*packet_size = EOF; *rp = nil;
|
*packet_size = EOF; *rp = nil;
|
||||||
return;
|
return;
|
||||||
|
@ -1170,14 +1813,19 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
int remaining;
|
int remaining;
|
||||||
|
|
||||||
remaining = size - eof_position;
|
remaining = size - eof_position;
|
||||||
|
#ifdef GDOMAP
|
||||||
|
c = tryRead(s, 1, buffer + prefix + eof_position, -remaining);
|
||||||
|
#else
|
||||||
/* xxx We need to make sure this read() is non-blocking. */
|
/* xxx We need to make sure this read() is non-blocking. */
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
c = recv (s, buffer + prefix + eof_position, remaining, 0);
|
c = recv (s, buffer + prefix + eof_position, remaining, 0);
|
||||||
#else
|
#else
|
||||||
c = read (s, buffer + prefix + eof_position, remaining);
|
c = read (s, buffer + prefix + eof_position, remaining);
|
||||||
#endif
|
#endif /* __WIN32 */
|
||||||
if (c == 0)
|
#endif /* GDOMAP */
|
||||||
|
if (c <= 0) {
|
||||||
return EOF;
|
return EOF;
|
||||||
|
}
|
||||||
eof_position += c;
|
eof_position += c;
|
||||||
return remaining - c;
|
return remaining - c;
|
||||||
}
|
}
|
||||||
|
@ -1210,20 +1858,29 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
memset (buffer + PREFIX_LENGTH_SIZE, 0, PREFIX_ADDRESS_SIZE);
|
memset (buffer + PREFIX_LENGTH_SIZE, 0, PREFIX_ADDRESS_SIZE);
|
||||||
|
|
||||||
/* Write the packet on the socket. */
|
/* Write the packet on the socket. */
|
||||||
#ifdef __WIN32__
|
#ifdef GDOMAP
|
||||||
c = send (s, buffer, prefix + eof_position, 0);
|
c = tryWrite (s, 30, buffer, prefix + eof_position);
|
||||||
#else
|
#else
|
||||||
c = write (s, buffer, prefix + eof_position);
|
#ifdef __WIN32__
|
||||||
#endif
|
c = recv (s, buffer, prefix + eof_position, 0);
|
||||||
if (c < 0)
|
#else
|
||||||
{
|
c = read (s, buffer, prefix + eof_position);
|
||||||
perror ("[TcpOutPort -_writeToSocket:] write()");
|
#endif /* __WIN32__ */
|
||||||
abort ();
|
#endif /* GDOMAP */
|
||||||
|
if (c == -2) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpOutPort -_writeToSocket:] write() timed out"];
|
||||||
|
}
|
||||||
|
else if (c < 0) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpOutPort -_writeToSocket:] write(): %s",
|
||||||
|
strerror(errno)];
|
||||||
|
}
|
||||||
|
if (c != prefix + eof_position) {
|
||||||
|
[NSException raise: NSInternalInconsistencyException
|
||||||
|
format: @"[TcpOutPort -_writeToSocket:] partial write(): %s",
|
||||||
|
strerror(errno)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did we sucessfully write it all? */
|
|
||||||
if (c != prefix + eof_position)
|
|
||||||
[self error: "socket write failed"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -1239,3 +1896,6 @@ InPortClientBecameInvalidNotification =
|
||||||
NSString *
|
NSString *
|
||||||
InPortAcceptedClientNotification =
|
InPortAcceptedClientNotification =
|
||||||
@"InPortAcceptedClientNotification";
|
@"InPortAcceptedClientNotification";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue