123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- /* Copyright (c) 2003 Tungsten Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files ("the
- * Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions: The above copyright notice, the Tungsten
- * Graphics splash screen, and this permission notice shall be included
- * in all copies or substantial portions of the Software. THE SOFTWARE
- * IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
- * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
- * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
- /*
- * Simple IPC API
- * Brian Paul
- */
-
-
- #include <assert.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <sys/socket.h>
- #include "ipc.h"
-
- #if defined(IRIX) || defined(irix)
- typedef int socklen_t;
- #endif
-
- #define NO_DELAY 1
-
- #define DEFAULT_MASTER_PORT 7011
-
-
- /*
- * Return my hostname in <nameOut>.
- * Return 1 for success, 0 for error.
- */
- int
- MyHostName(char *nameOut, int maxNameLength)
- {
- int k = gethostname(nameOut, maxNameLength);
- return k==0;
- }
-
-
- /*
- * Create a socket attached to a port. Later, we can call AcceptConnection
- * on the socket returned from this function.
- * Return the new socket number or -1 if error.
- */
- int
- CreatePort(int *port)
- {
- char hostname[1000];
- struct sockaddr_in servaddr;
- struct hostent *hp;
- int so_reuseaddr = 1;
- int tcp_nodelay = 1;
- int sock, k;
-
- /* create socket */
- sock = socket(AF_INET, SOCK_STREAM, 0);
- assert(sock > 2);
-
- /* get my host name */
- k = gethostname(hostname, 1000);
- assert(k == 0);
-
- /* get hostent info */
- hp = gethostbyname(hostname);
- assert(hp);
-
- /* initialize the servaddr struct */
- memset(&servaddr, 0, sizeof(servaddr) );
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons((unsigned short) (*port));
- memcpy((char *) &servaddr.sin_addr, hp->h_addr,
- sizeof(servaddr.sin_addr));
-
- /* deallocate when we exit */
- k = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (char *) &so_reuseaddr, sizeof(so_reuseaddr));
- assert(k==0);
-
- /* send packets immediately */
- #if NO_DELAY
- k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
- (char *) &tcp_nodelay, sizeof(tcp_nodelay));
- assert(k==0);
- #endif
-
- if (*port == 0)
- *port = DEFAULT_MASTER_PORT;
-
- k = 1;
- while (k && (*port < 65534)) {
- /* bind our address to the socket */
- servaddr.sin_port = htons((unsigned short) (*port));
- k = bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
- if (k)
- *port = *port + 1;
- }
-
- #if 0
- printf("###### Real Port: %d\n", *port);
- #endif
-
- /* listen for connections */
- k = listen(sock, 100);
- assert(k == 0);
-
- return sock;
- }
-
-
- /*
- * Accept a connection on the named socket.
- * Return a new socket for the new connection, or -1 if error.
- */
- int
- AcceptConnection(int socket)
- {
- struct sockaddr addr;
- socklen_t addrLen;
- int newSock;
-
- addrLen = sizeof(addr);
- newSock = accept(socket, &addr, &addrLen);
- if (newSock == 1)
- return -1;
- else
- return newSock;
- }
-
-
- /*
- * Contact the server running on the given host on the named port.
- * Return socket number or -1 if error.
- */
- int
- Connect(const char *hostname, int port)
- {
- struct sockaddr_in servaddr;
- struct hostent *hp;
- int sock, k;
- int tcp_nodelay = 1;
-
- assert(port);
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
- assert(sock >= 0);
-
- hp = gethostbyname(hostname);
- assert(hp);
-
- memset(&servaddr, 0, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons((unsigned short) port);
- memcpy((char *) &servaddr.sin_addr, hp->h_addr, sizeof(servaddr.sin_addr));
-
- k = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
- if (k != 0) {
- perror("Connect:");
- return -1;
- }
-
- #if NO_DELAY
- /* send packets immediately */
- k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
- (char *) &tcp_nodelay, sizeof(tcp_nodelay));
- assert(k==0);
- #endif
-
- return sock;
- }
-
-
- void
- CloseSocket(int socket)
- {
- close(socket);
- }
-
-
- int
- SendData(int socket, const void *data, int bytes)
- {
- int sent = 0;
- int b;
-
- while (sent < bytes) {
- b = write(socket, (char *) data + sent, bytes - sent);
- if (b <= 0)
- return -1; /* something broke */
- sent += b;
- }
- return sent;
- }
-
-
- int
- ReceiveData(int socket, void *data, int bytes)
- {
- int received = 0, b;
-
- while (received < bytes) {
- b = read(socket, (char *) data + received, bytes - received);
- if (b <= 0)
- return -1;
- received += b;
- }
- return received;
- }
-
-
- int
- SendString(int socket, const char *str)
- {
- const int len = strlen(str);
- int sent, b;
-
- /* first, send a 4-byte length indicator */
- b = write(socket, &len, sizeof(len));
- if (b <= 0)
- return -1;
-
- sent = SendData(socket, str, len);
- assert(sent == len);
- return sent;
- }
-
-
- int
- ReceiveString(int socket, char *str, int maxLen)
- {
- int len, received, b;
-
- /* first, read 4 bytes to see how long of string to receive */
- b = read(socket, &len, sizeof(len));
- if (b <= 0)
- return -1;
-
- assert(len <= maxLen); /* XXX fix someday */
- assert(len >= 0);
- received = ReceiveData(socket, str, len);
- assert(received != -1);
- assert(received == len);
- str[len] = 0;
- return received;
- }
|