diff options
author | Alan Coopersmith <alan.coopersmith@sun.com> | 2009-05-06 17:10:31 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@sun.com> | 2009-05-06 17:10:31 -0700 |
commit | 0aab8135dae526b090dcb1ffab801023ac4084aa (patch) | |
tree | 3aa615a5196bddc76ff23a5e4b3ae6ab04a40588 /scope.c | |
parent | eb05316a471da962eefe82c9b9a16a7590653ba7 (diff) | |
parent | def948f052a758850cadc022943517742b299441 (diff) | |
download | xscope-0aab8135dae526b090dcb1ffab801023ac4084aa.tar.gz |
Merge branch 'keithp'
Conflicts:
common.c
decode11.c
fd.c
fd.h
print11.c
prtype.c
scope.c
scope.h
server.c
table11.c
x11.h
xscope.man
Diffstat (limited to 'scope.c')
-rw-r--r-- | scope.c | 978 |
1 files changed, 761 insertions, 217 deletions
@@ -55,9 +55,7 @@ #include "scope.h" -#include <errno.h> #include <unistd.h> -#include <netdb.h> #include <sys/param.h> #ifdef SYSV @@ -65,13 +63,29 @@ #define bcopy(s,d,l) memmove(d,s,l) #endif +#include <sys/uio.h> /* for struct iovec, used by socket.h */ +#include <sys/socket.h> /* for AF_INET, SOCK_STREAM, ... */ +#include <sys/ioctl.h> /* for FIONCLEX, FIONBIO, ... */ +#ifdef SVR4 +#include <sys/filio.h> +#endif +#include <fcntl.h> +#include <netinet/in.h> /* struct sockaddr_in */ +#include <netinet/tcp.h> +#include <netdb.h> /* struct servent * and struct hostent * */ +#include <errno.h> /* for EINTR, EADDRINUSE, ... */ +extern int errno; + + +extern InitializePEX(); /* ********************************************** */ /* */ /* ********************************************** */ #define DefaultPort 6000 -static char ServerHostName[MAXHOSTNAMELEN]; + char ServerHostName[MAXHOSTNAMELEN]; + char AudioServerHostName[MAXHOSTNAMELEN]; long ServerBasePort = DefaultPort; static long ServerInPort = 1; static long ServerOutPort = 0; @@ -100,16 +114,562 @@ int decnet_server = 0; #endif static FD ConnectToClient(FD ConnectionSocket); -static FD ConnectToServer(int report); static void SetUpStdin(void); +long TranslateText = 0; +char ScopeEnabled = 1; +char HandleSIGUSR1 = 0; +char DoAudio = 0; +char TerminateClose = 0; +int Interrupt = 0; + +struct FDDescriptor *FDD = 0; +short MaxFD = 0; +short nFDsInUse = 0; +long ReadDescriptors = 0; +long WriteDescriptors = 0; +long BlockedReadDescriptors; +short HighestFD; + +short debuglevel = 0; +short Verbose = 0; +short XVerbose = 0; +short NasVerbose = 0; +int ScopePort = 0; +char *ScopeHost = 0; + + +typedef struct _BreakPoint { + struct _BreakPoint *next; + int number; + unsigned char request; + Boolean enabled; +} BP; + +typedef enum _CMDResult { CMDProceed, CMDDebug, CMDSyntax, CMDError } CMDResult; + +CMDResult CMDStep (); +CMDResult CMDCont (); +CMDResult CMDBreak (); +CMDResult CMDDelete (); +CMDResult CMDDisable (); +CMDResult CMDEnable (); +CMDResult CMDLevel (); +CMDResult CMDAudio (); +CMDResult CMDQuit (); +CMDResult CMDHelp (); + +typedef struct _CMDFunc { + char *name; + char *alias; + CMDResult (*func)(); + char *usage; + char *help; +} CMDFuncRec, *CMDFuncPtr; + +CMDFuncRec CMDFuncs[] = { + "audio", "a", CMDAudio, "[a]udio", + "Set audio output level\n", + "break", "b", CMDBreak, "[b]reak", + "Create breakpoints\n", + "cont", "c", CMDCont, "[c]ont", + "Continue scoping\n", + "delete", "del", CMDDelete, "[del]ete", + "Delete breakpoints\n", + "disable","d", CMDDisable, "[d]isable", + "Disable breakpoints\n", + "enable", "e", CMDEnable, "[e]nable", + "Enable breakpoints\n", + "help", "?", CMDHelp, "help", + "Print this list\n", + "level", "l", CMDLevel, "[l]evel", + "Set output level\n", + "quit", "q", CMDQuit, "[q]uit", + "Quit Xscope\n", + "step", "s", CMDStep, "[s]tep", + "Step trace one request\n", +}; + +#define NumCMDFuncs (sizeof CMDFuncs / sizeof CMDFuncs[0]) + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +static int +CMDStringToInt(s, v) + char *s; + int *v; +{ + int sign = 1; + + switch (*s) { + case '-': + sign = -1; + s++; + break; + case '+': + s++; + break; + } + + if (!strncmp (s, "0x", 2)) + { + sscanf (s + 2, "%x", v); + } + else if (*s == '0') + { + sscanf (s, "%o", v); + } + else if (isdigit (*s)) + { + sscanf (s, "%d", v); + } + else if (*s == '\'') + { + s++; + if (*s == '\\') { + s++; + switch (*s) { + case 'n': + *v = '\n'; + break; + case 't': + *v = '\t'; + break; + default: + *v = (int) *s; + break; + } + } else + *v = (int) *s; + s++; + if (*s != '\'') + return FALSE; + } + else + return FALSE; + *v *= sign; + return TRUE; +} + +static CMDFuncPtr +CMDStringToFunc (name) + char *name; +{ + int i; + for (i = 0; i < NumCMDFuncs; i++) + { + if (!strcmp (name, CMDFuncs[i].name) || + !strcmp (name, CMDFuncs[i].alias)) + { + return &CMDFuncs[i]; + } + } + return 0; +} + +static int +CMDSplitIntoWords(line, argv) + char *line; + char **argv; +{ + char quotechar; + int argc; + + argc = 0; + while (*line) { + while (isspace(*line)) + line++; + if (!*line) + break; + if (*line == '"') + { + quotechar = *line++; + *argv++ = line; + argc++; + while (*line && *line != quotechar) + line++; + if (*line) + *line++ = '\0'; + } + else + { + *argv++ = line; + argc++; + while (*line && !isspace(*line)) + line++; + if (*line) + *line++ = '\0'; + } + } + *argv = 0; + return argc; +} + +CMDResult +CMDHelp(argc, argv) + int argc; + char **argv; +{ + int i; + CMDFuncPtr func; + + if (argc == 1) + { + for (i = 0; i < NumCMDFuncs; i++) + printf("%-10s%s\n", CMDFuncs[i].name, CMDFuncs[i].usage); + } + else + { + for (i = 1; i < argc; i++) + { + func = CMDStringToFunc (argv[i]); + if (!func) + { + printf ("%-10s unknown command\n", argv[i]); + return CMDSyntax; + } + printf ("%-10s %s\n%s", func->name, func->usage, func->help); + } + } + return CMDDebug; +} + +static void +CMDSyntaxError(argc, argv) + int argc; + char **argv; +{ + printf("Syntax error in:"); + while (*argv) + printf(" %s", *argv++); + printf("\n"); +} + +void +ReadCommands () +{ + int argc; + char line[1024]; + char *argv[20]; + CMDResult result; + CMDFuncPtr func; + static int here; + + if (here) + return; + here = 1; + for (;;) { + printf ("> "); + if (!fgets (line, sizeof line, stdin)) + break; + argc = CMDSplitIntoWords(line, argv); + if (argc > 0) { + func = CMDStringToFunc (argv[0]); + if (!func) + CMDSyntaxError (argc, argv); + else + { + result = (*func->func)(argc, argv); + switch (result) { + case CMDSyntax: + CMDSyntaxError(argc, argv); + break; + case CMDError: + printf ("Error\n"); + break; + case CMDProceed: + here = 0; + return; + default: + break; + } + } + } + } + printf("...\n"); + here = 0; +} + +int SingleStep; +int BreakPoint; +BP *breakPoints; +int breakPointNumber; + +void +TestBreakPoints (buf, n) + unsigned char *buf; + long n; +{ + BP *bp; + + for (bp = breakPoints; bp; bp = bp->next) + { + if (bp->request == buf[0]) + { + break; + } + } + if (bp) + { + printf ("Breakpoint on request %d\n", bp->request); + ReadCommands (); + } +} + +void +setBreakPoint () +{ + Boolean b = false; + BP *bp; + FD fd; + + if (SingleStep) + b = true; + else + { + for (bp = breakPoints; bp; bp = bp->next) + { + if (bp->enabled) + { + b = true; + break; + } + } + } + if (b != BreakPoint) + { + BreakPoint = b; + for (fd = 0; fd < HighestFD; fd++) + { + static void DataFromClient(FD fd); + + if (FDD[fd].Busy && FDD[fd].InputHandler == DataFromClient) + { + if (BreakPoint) + SetBufLimit (fd); + else + ClearBufLimit (fd); + } + } + } +} + +CMDResult +CMDBreak (argc, argv) + int argc; + char **argv; +{ + BP *bp, **prev; + int request; + + if (argc == 1) + { + for (bp = breakPoints; bp; bp = bp->next) + { + printf ("%3d: %3d %s\n", bp->number, bp->request, + bp->enabled ? "enabled" : "disabled"); + } + } + else + { + for (prev = &breakPoints; *prev; prev = &(*prev)->next); + while (*++argv) { + request = GetXRequestFromName (*argv); + if (request < 0 && !CMDStringToInt (*argv, &request)) + return CMDSyntax; + bp = (BP *) malloc (sizeof (BP)); + bp->request = request; + bp->number = ++breakPointNumber; + bp->enabled = true; + bp->next = 0; + *prev = bp; + prev = &bp->next; + } + } + setBreakPoint (); + return CMDDebug; +} + +CMDResult +CMDCont (argc, argv) + int argc; + char **argv; +{ + SingleStep = 0; + return CMDProceed; +} + +CMDResult +CMDDisable (argc, argv) + int argc; + char **argv; +{ + BP *bp; + int number; + + if (argc == 1) + { + printf ("Disabling all breakpoints...\n"); + for (bp = breakPoints; bp; bp = bp->next) + bp->enabled = false; + } + else + { + while (*++argv) { + if (!CMDStringToInt (*argv, &number)) + return CMDSyntax; + for (bp = breakPoints; bp; bp = bp->next) + if (bp->number == number) + { + bp->enabled = false; + break; + } + if (!bp) + { + printf ("No such breakpoint %s\n", *argv); + } + } + } + setBreakPoint (); + return CMDDebug; +} + +CMDResult +CMDDelete (argc, argv) + int argc; + char **argv; +{ + BP *bp, **prev; + int number; + + if (argc == 1) + { + printf ("Deleting all breakpoints...\n"); + while (bp = breakPoints) + { + breakPoints = bp->next; + free (bp); + } + } + else + { + while (*++argv) { + if (!CMDStringToInt (*argv, &number)) + return CMDSyntax; + for (prev = &breakPoints; bp = *prev; prev = &bp->next) + { + if (bp->number == number) + { + *prev = bp->next; + free (bp); + break; + } + } + if (!bp) + { + printf ("No such breakpoint %s\n", *argv); + } + } + } + setBreakPoint (); + return CMDDebug; +} + +CMDResult +CMDEnable (argc, argv) + int argc; + char **argv; +{ + BP *bp; + int number; + + if (argc == 1) + { + printf ("Enablingg all breakpoints...\n"); + for (bp = breakPoints; bp; bp = bp->next) + bp->enabled = true; + } + else + { + while (*++argv) { + if (!CMDStringToInt (*argv, &number)) + return CMDSyntax; + for (bp = breakPoints; bp; bp = bp->next) + if (bp->number == number) + { + bp->enabled = true; + break; + } + if (!bp) + { + printf ("No such breakpoint %s\n", *argv); + } + } + } + setBreakPoint (); + return CMDDebug; +} + +CMDResult +CMDStep (argc, argv) + int argc; + char **argv; +{ + SingleStep = 1; + setBreakPoint (); + return CMDProceed; +} + +CMDResult +CMDQuit (argc, argv) + int argc; + char **argv; +{ + printf ("exiting...\n"); + exit (0); +} + +CMDResult +CMDLevel (argc, argv) + int argc; + char **argv; +{ + int level; + + if (argc == 1) + printf ("Level: %d\n", XVerbose); + else if (argc == 2 && CMDStringToInt (argv[1], &level)) + XVerbose = level; + else + return CMDSyntax; + return CMDDebug; +} + +CMDResult +CMDAudio (argc, argv) + int argc; + char **argv; +{ + int level; + + if (argc == 1) + printf ("Audio Level: %d\n", NasVerbose); + else if (argc == 2 && CMDStringToInt (argv[1], &level)) + NasVerbose = level; + else + return CMDSyntax; + return CMDDebug; +} /* ********************************************** */ /* */ /* */ /* ********************************************** */ -static short GetServerport () +short GetServerport () { short port; @@ -159,11 +719,15 @@ Usage() #ifdef RAW_MODE fprintf(stderr, " [-r] -- raw output\n"); #endif + fprintf(stderr, " [-a<n>] -- audio verbose output\n"); fprintf(stderr, " [-q] -- quiet output\n"); fprintf(stderr, " [-D<debug-level>]\n"); + fprintf(stderr, " [-S<n>] -- start/stop on SIGUSR1\n"); + fprintf(stderr, " [-t] -- terminate when all clients close\n"); exit(1); } + static void ScanArgs(argc, argv) int argc; @@ -172,7 +736,8 @@ ScanArgs(argc, argv) #if defined(DNETCONN) || defined(DNETSVR4) char *ss; #endif - Verbose = 1 /* default verbose-ness level */; + XVerbose = 1 /* default verbose-ness level */; + NasVerbose = 1; #ifdef RAW_MODE Raw = 0 ; #endif @@ -197,19 +762,18 @@ ScanArgs(argc, argv) debuglevel = atoi(++*argv); if (debuglevel == 0) debuglevel = 255; - debuglevel |= 1; - Verbose = 7; + XVerbose = 7; debug(1,(stderr, "debuglevel = %d\n", debuglevel)); break; - case 'q': /* quiet mode */ - Verbose = 0; - debug(1,(stderr, "Verbose = %d\n", Verbose)); + case 'S': + HandleSIGUSR1 = 1; + ScopeEnabled = atoi(++*argv); break; - case 'v': /* verbose mode */ - Verbose = atoi(++*argv); - debug(1,(stderr, "Verbose = %d\n", Verbose)); + case 'q': /* quiet mode */ + XVerbose = 0; + debug(1,(stderr, "Verbose = %d\n", XVerbose)); break; #ifdef RAW_MODE @@ -219,6 +783,11 @@ ScanArgs(argc, argv) break; #endif + case 'v': /* verbose mode */ + XVerbose = atoi(++*argv); + debug(1,(stderr, "Verbose = %d\n", XVerbose)); + break; + case 'o': ServerOutPort = atoi(++*argv); if (ServerOutPort <= 0) @@ -261,6 +830,28 @@ ScanArgs(argc, argv) debug(1,(stderr, "ServerHostName=%s\n", ServerHostName)); break; + case 'T': + TranslateText = 1; + break; + + case 'A': + DoAudio = 1; + break; + + case 'a': /* verbose mode */ + NasVerbose = atoi(++*argv); + debug(1,(stderr, "NasVerbose = %d\n", NasVerbose)); + break; + + case 'n': /* NAS server host */ + if (++*argv != NULL && **argv != '\0') + (void)strcpy(AudioServerHostName, *argv); + debug(1,(stderr, "AudioServerHostName=%s\n", AudioServerHostName)); + break; + case 't': + TerminateClose = 1; + break; + default: fprintf(stderr, "Unknown option %c\n", **argv); Usage(); @@ -290,6 +881,8 @@ ScanArgs(argc, argv) /* */ /* ********************************************** */ +int NewAudio (); + main(argc, argv) int argc; char **argv; @@ -297,14 +890,21 @@ main(argc, argv) ScanArgs(argc, argv); InitializeFD(); InitializeX11(); + if (DoAudio) + InitializeAudio(); +#ifdef PEX + InitializePEX(); +#endif SetUpStdin(); #if defined(DNETCONN) || defined(DNETSVR4) if (decnet_in) - SetUpDECnetConnection(GetScopePort()); + SetUpDECnetConnection(GetScopePort(), NewConnection); else - SetUpConnectionSocket(GetScopePort()); + SetUpConnectionSocket(GetScopePort(), NewConnection); #else - SetUpConnectionSocket(GetScopePort()); + SetUpConnectionSocket(GetScopePort(), NewConnection); + if (DoAudio) + SetUpConnectionSocket (GetScopePort() + 2000, NewAudio); SetSignalHandling(); #endif @@ -349,7 +949,7 @@ static void SetUpStdin() { enterprocedure("SetUpStdin"); - UsingFD(fileno(stdin), ReadStdin, NULL); + UsingFD(fileno(stdin), ReadStdin, (int (*)()) NULL, NULL); } /* ************************************************************ */ @@ -366,32 +966,31 @@ SetUpStdin() we get input from one, we can write it to the other. */ -struct fdinfo -{ - Boolean Server; - long ClientNumber; - FD pair; -}; - -static long ClientNumber = 0; -static struct fdinfo FDinfo[StaticMaxFD]; +static long clientNumber = 0; +struct fdinfo FDinfo[StaticMaxFD]; -static void +void SetUpPair(client, server) FD client; FD server; { if (client >= 0) { - ClientNumber += 1; + clientNumber += 1; FDinfo[client].Server = false; FDinfo[client].pair = server; - FDinfo[client].ClientNumber = ClientNumber; + FDinfo[client].ClientNumber = clientNumber; + FDinfo[client].bufcount = 0; + FDinfo[client].buflimit = -1; + FDinfo[client].bufdelivered = 0; if (server >= 0) { FDinfo[server].Server = true; FDinfo[server].pair = client; FDinfo[server].ClientNumber = FDinfo[client].ClientNumber; + FDinfo[server].bufcount = 0; + FDinfo[server].buflimit = -1; + FDinfo[server].bufdelivered = 0; } } else if (server >= 0) @@ -401,11 +1000,31 @@ SetUpPair(client, server) } } + +ResetPair (client, server) + FD client; + FD server; +{ + if (client >= 0) + { + FDinfo[client].bufcount = 0; + FDinfo[client].buflimit = -1; + FDinfo[client].bufdelivered = 0; + } + if (server >= 0) + { + FDinfo[server].bufcount = 0; + FDinfo[server].buflimit = -1; + FDinfo[server].bufdelivered = 0; + } +} + static void CloseConnection(fd) FD fd; { debug(4,(stderr, "close %d and %d\n", fd, FDPair(fd))); + ResetPair (ClientHalf(fd), ServerHalf(fd)); StopClientConnection(ServerHalf(fd)); StopServerConnection(ClientHalf(fd)); @@ -418,6 +1037,8 @@ CloseConnection(fd) #endif NotUsingFD(fd); NotUsingFD(FDPair(fd)); + if (TerminateClose) + exit (0); } /* ************************************************************ */ @@ -449,17 +1070,80 @@ char *ClientName (fd) { static char name[12]; - if (ClientNumber <= 1) + if (clientNumber <= 1) return(""); - sprintf(name, " %d", FDinfo[fd].ClientNumber); + (void)sprintf(name, " %d", FDinfo[fd].ClientNumber); return(name); } +int ClientNumber (fd) + FD fd; +{ + return FDinfo[fd].ClientNumber; +} /* ********************************************** */ /* */ /* ********************************************** */ +/* + * Write as much of the queued data as the receiver will accept + * Block reads from the sender until the receiver gets all of the + * data + */ +void +FlushFD (fd) + FD fd; +{ + long BytesToWrite = FDinfo[fd].bufcount - FDinfo[fd].bufstart; + char *p = FDinfo[fd].buffer + FDinfo[fd].bufstart; + int PeerFD; + + PeerFD = FDPair (fd); + if (FDinfo[fd].buflimit >= 0) + { + if (FDinfo[fd].bufdelivered + BytesToWrite > FDinfo[fd].buflimit) + BytesToWrite = FDinfo[fd].buflimit - FDinfo[fd].bufdelivered; + } + while (BytesToWrite > 0) + { + int n1 = write (fd, (char *)p, (int)BytesToWrite); + debug(4,(stderr, "write %d bytes\n", n1)); + if (n1 < 0) + { + if (errno != EWOULDBLOCK && errno != EAGAIN) + { + perror("Error on write"); + if (PeerFD >= 0) + CloseConnection(PeerFD); + BytesToWrite = 0; + } + break; + } + else + { + FDinfo[fd].bufstart += n1; + FDinfo[fd].bufdelivered += n1; + BytesToWrite -= n1; + p += n1; + } + } + if (FDinfo[fd].bufstart == FDinfo[fd].bufcount) + { + if (PeerFD >= 0) + BlockedReadDescriptors &= ~ (1 << PeerFD); + WriteDescriptors &= ~(1 << fd); + FDinfo[fd].bufcount = FDinfo[fd].bufstart = 0; + } + else + { + if (PeerFD >= 0) + BlockedReadDescriptors |= 1 << PeerFD; + if (FDinfo[fd].buflimit != FDinfo[fd].bufdelivered) + WriteDescriptors |= 1 << fd; + } +} + /* when we get data from a client, we read it in, copy it to the server for this client, then dump it to the client. Note, we don't have to have a server, if there isn't one. */ @@ -468,12 +1152,24 @@ static void DataFromClient(fd) FD fd; { - unsigned char buf[2048]; long n; FD ServerFD; + Verbose = XVerbose; enterprocedure("DataFromClient"); - n = read(fd, (char *)buf, 2048); + ServerFD = FDPair(fd); + if (ServerFD < 0) + { + ServerFD = ConnectToServer(false); + if (ServerFD < 0) + { + CloseConnection(fd); + return; + } + SetUpPair(fd, ServerFD); + } + + n = read(fd, FDinfo[ServerFD].buffer, BUFFER_SIZE); debug(4,(stderr, "read %d bytes from Client%s\n", n, ClientName(fd))); if (n < 0) { @@ -485,58 +1181,18 @@ DataFromClient(fd) if (n == 0) { PrintTime(); - fprintf(stdout, "Client%s --> EOF\n", ClientName(fd)); + if (Verbose >= 0) + fprintf(stdout, "Client%s --> EOF\n", ClientName(fd)); CloseConnection(fd); return; } - ServerFD = FDPair(fd); - if (ServerFD < 0) - { - ServerFD = ConnectToServer(false); - SetUpPair(fd, ServerFD); - } - - /* write bytes from client to server, allow for server to fail */ - if (ServerFD >= 0) - { - long BytesToWrite = n; - unsigned char *p = buf; - - while (BytesToWrite > 0) - { - int n1 = write (ServerFD, (char *)p, (int)BytesToWrite); - debug(4,(stderr, "write %d bytes to Server%s\n", n1, ClientName(fd))); - if (n1 > 0) - { - BytesToWrite -= n1; - p += n1; - } - /* - B U G : 4156754 - - Write may fail with an error code of EAGAIN if - BytesToWrite is less than PIPE_BUF, but bigger - than available free space. This error says, wait - and try again till PIPE is flushed and has more - free space. - */ - else if (errno == EAGAIN) - { - /* Wait for some time and try again */ - sleep (1); - } - else - { - perror("Error on write to Server"); - CloseConnection(fd); - BytesToWrite = 0; - } - } - } + FDinfo[ServerFD].bufcount = n; + FDinfo[ServerFD].bufstart = 0; + FlushFD (ServerFD); /* also report the bytes to standard out */ - ReportFromClient(fd, buf, n); + ReportFromClient(fd, FDinfo[ServerFD].buffer, n); } /* ********************************************** */ @@ -550,12 +1206,19 @@ static void DataFromServer(fd) FD fd; { - unsigned char buf[2048]; long n; FD ClientFD; + Verbose = XVerbose; + ClientFD = FDPair(fd); + if (ClientFD < 0) + { + CloseConnection(fd); + return; + } + enterprocedure("DataFromServer"); - n = read(fd, (char *)buf, 2048); + n = read(fd, (char *)FDinfo[ClientFD].buffer, BUFFER_SIZE); debug(4,(stderr, "read %d bytes from Server%s\n", n, ClientName(fd))); if (n < 0) { @@ -567,56 +1230,18 @@ DataFromServer(fd) if (n == 0) { PrintTime(); - fprintf(stdout, "EOF <-- Server%s\n", ClientName(fd)); + if (Verbose >= 0) + fprintf(stdout, "EOF <-- Server%s\n", ClientName(fd)); CloseConnection(fd); return; } - ClientFD = FDPair(fd); - if (ClientFD < 0) - { - CloseConnection(fd); - return; - } - - /* write bytes from server to client, allow for client to fail */ - { - long BytesToWrite = n; - unsigned char *p = buf; - while (BytesToWrite > 0) - { - int n1 = write (ClientFD, (char *)p, (int)BytesToWrite); - debug(4,(stderr, "write %d bytes to Client%s\n", n1, ClientName(fd))); - if (n1 > 0) - { - BytesToWrite -= n1; - p += n1; - } - /* - B U G : 4156754 - - Write may fail with an error code of EAGAIN if - BytesToWrite is less than PIPE_BUF, but bigger - than available free space. This error says, wait - and try again till PIPE is flushed and has more - free space. - */ - else if (errno == EAGAIN) - { - /* Wait for some time and try again */ - sleep (1); - } - else - { - perror("Error on write to Client"); - CloseConnection(fd); - BytesToWrite = 0; - } - } - } + FDinfo[ClientFD].bufcount = n; + FDinfo[ClientFD].bufstart = 0; + FlushFD (ClientFD); /* also report the bytes to standard out */ - ReportFromServer(fd, buf, n); + ReportFromServer(fd, FDinfo[ClientFD].buffer, n); } @@ -702,7 +1327,7 @@ static FD ConnectToClient(ConnectionSocket) _X11TransSetOption(trans_conn, TRANS_NONBLOCKING, 1); ClientFD = _X11TransGetConnectionNumber(trans_conn); #else - ClientFD = accept(ConnectionSocket, (struct sockaddr *)&from, &len); + ClientFD = AcceptConnection(ConnectionSocket); #endif debug(4,(stderr, "Connect To Client: FD %d\n", ClientFD)); if (ClientFD < 0 && errno == EWOULDBLOCK) @@ -716,7 +1341,7 @@ static FD ConnectToClient(ConnectionSocket) panic("Can't connect to Client"); } - UsingFD(ClientFD, DataFromClient, trans_conn); + UsingFD(ClientFD, DataFromClient, FlushFD, trans_conn); #ifndef USE_XTRANS ioctl(ClientFD, FIOCLEX, 0); ioctl(ClientFD, FIONBIO, &ON); @@ -732,31 +1357,19 @@ static FD ConnectToClient(ConnectionSocket) -static FD ConnectToServer(report) +FD ConnectToServer(report) Boolean report; { FD ServerFD; XtransConnInfo trans_conn = NULL; /* transport connection object */ -#ifdef USE_XTRANS - char address[256]; - int connect_stat; - extern long ServerBasePort; -#else - struct sockaddr_in sin; - struct hostent *hp; -#endif short port; enterprocedure("ConnectToServer"); - /* determine the host machine for this process */ - if (ServerHostName[0] == '\0') - (void) gethostname(ServerHostName, sizeof (ServerHostName)); - debug(4,(stderr, "try to connect on %s\n", ServerHostName)); port = GetServerport (); - if (port == ScopePort - && strcmp(ServerHostName, ScopeHost) == 0) + if (port == ScopePort && + ((ServerHostName[0] == '\0') || strcmp(ServerHostName, ScopeHost) == 0)) { char error_message[100]; sprintf(error_message, "Trying to attach to myself: %s,%d\n", @@ -764,80 +1377,12 @@ static FD ConnectToServer(report) panic(error_message); } -#ifdef USE_XTRANS - snprintf (address, sizeof(address), "%s:%d", ServerHostName, - port - ServerBasePort); - if ( (trans_conn = _X11TransOpenCOTSClient(address)) == NULL ) { - debug(1,(stderr, "OpenCOTSClient failed\n")); - panic("Can't open connection to Server"); - } - if ((connect_stat = _X11TransConnect(trans_conn,address)) < 0 ) { - _X11TransClose(trans_conn); - trans_conn = NULL; - debug(1,(stderr, "TransConnect failed\n")); - panic("Can't open connection to Server"); - } - - ServerFD = _X11TransGetConnectionNumber(trans_conn); -#else - /* establish a socket to the name server for this host */ - bzero((char *)&sin, sizeof(sin)); - ServerFD = socket(AF_INET, SOCK_STREAM, 0); - if (ServerFD < 0) - { - perror("socket() to Server failed"); - debug(1,(stderr, "socket failed\n")); - panic("Can't open connection to Server"); - } - (void) setsockopt(ServerFD, SOL_SOCKET, SO_REUSEADDR, (char *) NULL, 0); - (void) setsockopt(ServerFD, SOL_SOCKET, SO_USELOOPBACK,(char *) NULL, 0); -#ifdef SO_DONTLINGER - (void) setsockopt(ServerFD, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0); -#endif - - hp = gethostbyname(ServerHostName); - if (hp == 0) - { - perror("gethostbyname failed"); - debug(1,(stderr, "gethostbyname failed for %s\n", ServerHostName)); - panic("Can't open connection to Server"); - } - - sin.sin_family = AF_INET; - bcopy((char *)hp->h_addr, (char *)&sin.sin_addr, hp->h_length); - sin.sin_port = htons (port); - - /* ******************************************************** */ - /* try to connect to Server */ - - if (connect(ServerFD, (struct sockaddr *)&sin, sizeof(sin)) < 0) - { - debug(4,(stderr, "connect returns errno of %d\n", errno)); - if (errno != 0) - if (report) - perror("connect"); - switch (errno) - { - case ECONNREFUSED: - /* experience says this is because there is no Server - to connect to */ - close(ServerFD); - debug(1,(stderr, "No Server\n")); - if (report) - warn("Can't open connection to Server"); - return(-1); - - default: - close(ServerFD); - panic("Can't open connection to Server"); - } - } -#endif + ServerFD = MakeConnection (ServerHostName, port, report, &trans_conn); debug(4,(stderr, "Connect To Server: FD %d\n", ServerFD)); if (ServerFD >= 0) { - UsingFD(ServerFD, DataFromServer, trans_conn); + UsingFD(ServerFD, DataFromServer, FlushFD, trans_conn); StartServerConnection(ServerFD); } return(ServerFD); @@ -913,7 +1458,7 @@ FD ConnectToDECnetSVR4Server(report) debug(4,(stderr, "Connect To Server: FD %d\n", ServerFD)); if (ServerFD >= 0) { - UsingFD(ServerFD, DataFromServer, NULL); + UsingFD(ServerFD, DataFromServer, FlushFD, NULL); StartServerConnection(ServerFD); } return(ServerFD); @@ -935,7 +1480,7 @@ FD ConnectToDECnetClient(fd) fprintf(stderr,"xscope: dni: SES_ACCEPT failed\n"); exit(-1); } - UsingFD(fd, DataFromClient, NULL); + UsingFD(fd, DataFromClient, NULL, NULL); StartClientConnection(fd); /* unlike sockets, dni consumes the fd on which it was listening */ /* in order to accept new logical link requests using the same name */ @@ -987,10 +1532,9 @@ FD ConnectToDECnetServer(report) fprintf(stderr,"xscope: dni: cannot connect to server\n"); exit(-1); } - UsingFD(fd, DataFromServer, NULL); + UsingFD(fd, DataFromServer, NULL, NULL); StartServerConnection(fd); return(fd); } #endif - |