This is socket.c in view mode; [Download] [Up]
/* Copyright Massachusetts Institute of Technology 1988 */ /* * THIS IS AN OS DEPENDENT FILE! It should work on 4.2BSD derived * systems. VMS and System V should plan to have their own version. * * This code was cribbed from lib/X/XConnDis.c. * Compile using * % cc -c socket.c -DUNIXCONN * * Change Log * ============================================================================ * Author Date Change * sbb 15 Sep 95 More hacks to get around cruft of HP-UX (missing * getdtablesize). * * sbb 6 Jun 95 Switched to new file naming scheme. * * sbb 7 May 95 Altered the FD_SET usage -- the code now guesses that * if the FD_SET macro is defined the fd_set datatype * will be too. * */ #include <stdio.h> #ifndef COMPILE_ONLY #include <X11/Xos.h> #include <X11/Xproto.h> #else #include <sys/types.h> #endif #include <errno.h> #include <netinet/in.h> #include <sys/ioctl.h> #include <netdb.h> #include <sys/socket.h> #ifndef hpux /* ??? what should we do on HPUX? */ # if defined(LITTLE_ENDIAN) # undef LITTLE_ENDIAN /* remove warnings on some Linuxes */ # endif # include <netinet/tcp.h> # include <arpa/inet.h> #endif #include <sys/types.h> #include <sys/time.h> #include "gst.h" #include "gstpub.h" #if !defined(HAVE_GETDTABLESIZE) # include "sysdep.h" /* only for getdtablesize */ #endif static int connect_to_server(); static int waitForSocket(); extern int errno; /* Certain (broken) OS's don't have this */ /* decl in errno.h */ #ifdef UNIXCONN #include <sys/un.h> #ifndef X_UNIX_PATH #define X_UNIX_PATH "/tmp/.X11-unix/X" #endif /* X_UNIX_PATH */ #endif /* UNIXCONN */ void bcopy(); void defineSocket() { defineCFunc("connectToServer", connect_to_server); defineCFunc("waitForSocket", waitForSocket); } /* * Attempts to connect to server, given host and display. Returns file * descriptor (network socket) or 0 if connection fails. */ static int connect_to_server (host, display) char *host; int display; { struct sockaddr_in inaddr; /* INET socket address. */ struct sockaddr *addr; /* address to connect to */ struct hostent *host_ptr; int addrlen; /* length of address */ #ifdef UNIXCONN struct sockaddr_un unaddr; /* UNIX socket address. */ #endif extern char *getenv(); extern struct hostent *gethostbyname(); int fd; /* Network socket */ #ifndef COMPILE_ONLY { #ifdef UNIXCONN if ((host[0] == '\0') || (strcmp("unix", host) == 0)) { /* Connect locally using Unix domain. */ unaddr.sun_family = AF_UNIX; (void) strcpy(unaddr.sun_path, X_UNIX_PATH); sprintf(&unaddr.sun_path[strlen(unaddr.sun_path)], "%d", display); addr = (struct sockaddr *) &unaddr; addrlen = strlen(unaddr.sun_path) + 2; /* * Open the network connection. */ if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0) return(-1); /* errno set by system call. */ } else #endif { /* Get the statistics on the specified host. */ if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1) { if ((host_ptr = gethostbyname(host)) == NULL) { /* No such host! */ errno = EINVAL; return(-1); } /* Check the address type for an internet host. */ if (host_ptr->h_addrtype != AF_INET) { /* Not an Internet host! */ errno = EPROTOTYPE; return(-1); } /* Set up the socket data. */ inaddr.sin_family = host_ptr->h_addrtype; memcpy((char *)&inaddr.sin_addr, (char *)host_ptr->h_addr, sizeof(inaddr.sin_addr)); } else { inaddr.sin_family = AF_INET; } addr = (struct sockaddr *) &inaddr; addrlen = sizeof (struct sockaddr_in); inaddr.sin_port = display + X_TCP_PORT; inaddr.sin_port = htons(inaddr.sin_port); /* * Open the network connection. */ if ((fd = socket((int) addr->sa_family, SOCK_STREAM, 0)) < 0){ return(-1); /* errno set by system call. */} /* make sure to turn off TCP coalescence */ #ifdef TCP_NODELAY { int mi = 1; setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &mi, sizeof (int)); } #endif } /* * Changed 9/89 to retry connection if system call was interrupted. This * is necessary for multiprocessing implementations that use timers, * since the timer results in a SIGALRM. -- jdi */ while (connect(fd, addr, addrlen) == -1) { if (errno != EINTR) { (void) close (fd); return(-1); /* errno set by system call. */ } } } /* * Return the id if the connection succeeded. */ #endif return(fd); } /* * static int waitForSocket(fd, timeout) * * Description * * Waits for some data to be available on the given socket. * * Inputs * * fd : File descriptor for socket to wait on * timeout: * Value in milliseconds to wait before timing out. If zero, wait * until there's input with no timeout. * * Outputs * * True if there was input available, false if it timed out. */ static int waitForSocket(fd, timeout) int fd, timeout; { struct timeval time, *timePtr; #ifdef FD_SET fd_set fds; FD_ZERO(&fds); FD_SET(fd, &fds); #else int fds; fds = 1 << (fd - 1); #endif if (timeout) { time.tv_sec = timeout / 1000; time.tv_usec = (timeout % 1000) * 1000; timePtr = &time; } else { timePtr = NULL; } if (select(getdtablesize(), &fds, NULL, NULL, timePtr)) { return (1); } else { return (0); } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.