~ubuntu-branches/ubuntu/oneiric/mesa-demos/oneiric

« back to all changes in this revision

Viewing changes to src/xdemos/ipc.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2010-09-27 16:18:27 UTC
  • Revision ID: james.westby@ubuntu.com-20100927161827-1yfgolc1oy9sjhi8
Tags: upstream-8.0.1
ImportĀ upstreamĀ versionĀ 8.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2003 Tungsten Graphics, Inc.
 
2
 * 
 
3
 * Permission is hereby granted, free of charge, to any person obtaining
 
4
 * a copy of this software and associated documentation files ("the
 
5
 * Software"), to deal in the Software without restriction, including
 
6
 * without limitation the rights to use, copy, modify, merge, publish,
 
7
 * distribute, sublicense, and/or sell copies of the Software, and to
 
8
 * permit persons to whom the Software is furnished to do so, subject to
 
9
 * the following conditions:  The above copyright notice, the Tungsten
 
10
 * Graphics splash screen, and this permission notice shall be included
 
11
 * in all copies or substantial portions of the Software.  THE SOFTWARE
 
12
 * IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 
13
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
14
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT
 
15
 * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 
16
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
17
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 
18
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
19
 */
 
20
 
 
21
/*
 
22
 * Simple IPC API
 
23
 * Brian Paul
 
24
 */
 
25
 
 
26
 
 
27
#include <assert.h>
 
28
#include <stdio.h>
 
29
#include <string.h>
 
30
#include <sys/types.h>
 
31
#include <netinet/in.h>
 
32
#include <netinet/tcp.h>
 
33
#include <arpa/inet.h>
 
34
#include <netdb.h>
 
35
#include <unistd.h>
 
36
#include <sys/socket.h>
 
37
#include "ipc.h"
 
38
 
 
39
#if defined(IRIX) || defined(irix)
 
40
typedef int socklen_t;
 
41
#endif
 
42
 
 
43
#define NO_DELAY 1
 
44
 
 
45
#define DEFAULT_MASTER_PORT 7011
 
46
 
 
47
 
 
48
/*
 
49
 * Return my hostname in <nameOut>.
 
50
 * Return 1 for success, 0 for error.
 
51
 */
 
52
int
 
53
MyHostName(char *nameOut, int maxNameLength)
 
54
{
 
55
    int k = gethostname(nameOut, maxNameLength);
 
56
    return k==0;
 
57
}
 
58
 
 
59
 
 
60
/*
 
61
 * Create a socket attached to a port.  Later, we can call AcceptConnection
 
62
 * on the socket returned from this function.
 
63
 * Return the new socket number or -1 if error.
 
64
 */
 
65
int
 
66
CreatePort(int *port)
 
67
{
 
68
    char hostname[1000];
 
69
    struct sockaddr_in servaddr;
 
70
    struct hostent *hp;
 
71
    int so_reuseaddr = 1;
 
72
    int tcp_nodelay = 1;
 
73
    int sock, k;
 
74
 
 
75
    /* create socket */
 
76
    sock = socket(AF_INET, SOCK_STREAM, 0);
 
77
    assert(sock > 2);
 
78
 
 
79
    /* get my host name */
 
80
    k = gethostname(hostname, 1000);
 
81
    assert(k == 0);
 
82
 
 
83
    /* get hostent info */
 
84
    hp = gethostbyname(hostname);
 
85
    assert(hp);
 
86
 
 
87
    /* initialize the servaddr struct */
 
88
    memset(&servaddr, 0, sizeof(servaddr) );
 
89
    servaddr.sin_family = AF_INET;
 
90
    servaddr.sin_port = htons((unsigned short) (*port));
 
91
    memcpy((char *) &servaddr.sin_addr, hp->h_addr,
 
92
           sizeof(servaddr.sin_addr));
 
93
 
 
94
    /* deallocate when we exit */
 
95
    k = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
 
96
                   (char *) &so_reuseaddr, sizeof(so_reuseaddr));
 
97
    assert(k==0);
 
98
 
 
99
    /* send packets immediately */
 
100
#if NO_DELAY
 
101
    k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
 
102
                   (char *) &tcp_nodelay, sizeof(tcp_nodelay));
 
103
    assert(k==0);
 
104
#endif
 
105
 
 
106
    if (*port == 0)
 
107
        *port = DEFAULT_MASTER_PORT;
 
108
 
 
109
    k = 1;
 
110
    while (k && (*port < 65534)) {
 
111
        /* bind our address to the socket */
 
112
        servaddr.sin_port = htons((unsigned short) (*port));
 
113
        k = bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
 
114
        if (k)
 
115
           *port = *port + 1;
 
116
    }
 
117
 
 
118
#if 0
 
119
    printf("###### Real Port: %d\n", *port);
 
120
#endif
 
121
 
 
122
    /* listen for connections */
 
123
    k = listen(sock, 100);
 
124
    assert(k == 0);
 
125
 
 
126
    return sock;
 
127
}
 
128
 
 
129
 
 
130
/*
 
131
 * Accept a connection on the named socket.
 
132
 * Return a new socket for the new connection, or -1 if error.
 
133
 */
 
134
int
 
135
AcceptConnection(int socket)
 
136
{
 
137
    struct sockaddr addr;
 
138
    socklen_t addrLen;
 
139
    int newSock;
 
140
 
 
141
    addrLen = sizeof(addr);
 
142
    newSock = accept(socket, &addr, &addrLen);
 
143
    if (newSock == 1)
 
144
        return -1;
 
145
    else
 
146
        return newSock;
 
147
}
 
148
 
 
149
 
 
150
/*
 
151
 * Contact the server running on the given host on the named port.
 
152
 * Return socket number or -1 if error.
 
153
 */
 
154
int
 
155
Connect(const char *hostname, int port)
 
156
{
 
157
    struct sockaddr_in servaddr;
 
158
    struct hostent *hp;
 
159
    int sock, k;
 
160
    int tcp_nodelay = 1;
 
161
 
 
162
    assert(port);
 
163
 
 
164
    sock = socket(AF_INET, SOCK_STREAM, 0);
 
165
    assert(sock >= 0);
 
166
 
 
167
    hp = gethostbyname(hostname);
 
168
    assert(hp);
 
169
 
 
170
    memset(&servaddr, 0, sizeof(servaddr));
 
171
    servaddr.sin_family = AF_INET;
 
172
    servaddr.sin_port = htons((unsigned short) port);
 
173
    memcpy((char *) &servaddr.sin_addr, hp->h_addr, sizeof(servaddr.sin_addr));
 
174
 
 
175
    k = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
 
176
    if (k != 0) {
 
177
       perror("Connect:");
 
178
       return -1;
 
179
    }
 
180
 
 
181
#if NO_DELAY
 
182
    /* send packets immediately */
 
183
    k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
 
184
                   (char *) &tcp_nodelay, sizeof(tcp_nodelay));
 
185
    assert(k==0);
 
186
#endif
 
187
 
 
188
    return sock;
 
189
}
 
190
 
 
191
 
 
192
void
 
193
CloseSocket(int socket)
 
194
{
 
195
    close(socket);
 
196
}
 
197
 
 
198
 
 
199
int
 
200
SendData(int socket, const void *data, int bytes)
 
201
{
 
202
    int sent = 0;
 
203
    int b;
 
204
 
 
205
    while (sent < bytes) {
 
206
        b = write(socket, (char *) data + sent, bytes - sent);
 
207
        if (b <= 0)
 
208
            return -1; /* something broke */
 
209
        sent += b;
 
210
    }
 
211
    return sent;
 
212
}
 
213
 
 
214
 
 
215
int
 
216
ReceiveData(int socket, void *data, int bytes)
 
217
{
 
218
    int received = 0, b;
 
219
 
 
220
    while (received < bytes) {
 
221
        b = read(socket, (char *) data + received, bytes - received);
 
222
        if (b <= 0)
 
223
            return -1;
 
224
        received += b;
 
225
    }
 
226
    return received;
 
227
}
 
228
 
 
229
 
 
230
int
 
231
SendString(int socket, const char *str)
 
232
{
 
233
    const int len = strlen(str);
 
234
    int sent, b;
 
235
 
 
236
    /* first, send a 4-byte length indicator */
 
237
    b = write(socket, &len, sizeof(len));
 
238
    if (b <= 0)
 
239
        return -1;
 
240
 
 
241
    sent = SendData(socket, str, len);
 
242
    assert(sent == len);
 
243
    return sent;
 
244
}
 
245
 
 
246
 
 
247
int
 
248
ReceiveString(int socket, char *str, int maxLen)
 
249
{
 
250
    int len, received, b;
 
251
 
 
252
    /* first, read 4 bytes to see how long of string to receive */
 
253
    b = read(socket, &len, sizeof(len));
 
254
    if (b <= 0)
 
255
        return -1;
 
256
 
 
257
    assert(len <= maxLen);  /* XXX fix someday */
 
258
    assert(len >= 0);
 
259
    received = ReceiveData(socket, str, len);
 
260
    assert(received != -1);
 
261
    assert(received == len);
 
262
    str[len] = 0;
 
263
    return received;
 
264
}