6bc40adc955743e7c9e34817a4f593acfb634246
[framework/uifw/xorg/lib/libice.git] / src / accept.c
1 /******************************************************************************
2
3
4 Copyright 1993, 1998  The Open Group
5
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
25
26 Author: Ralph Mor, X Consortium
27 ******************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 #include <X11/ICE/ICElib.h>
33 #include "ICElibint.h"
34 #include <X11/Xtrans/Xtrans.h>
35
36
37 IceConn
38 IceAcceptConnection (
39         IceListenObj    listenObj,
40         IceAcceptStatus *statusRet
41 )
42 {
43     IceConn             iceConn;
44     XtransConnInfo      newconn;
45     iceByteOrderMsg     *pMsg;
46     int                 endian, status;
47
48     /*
49      * Accept the connection.
50      */
51
52     if ((newconn = _IceTransAccept (listenObj->trans_conn, &status)) == NULL)
53     {
54         if (status == TRANS_ACCEPT_BAD_MALLOC)
55             *statusRet = IceAcceptBadMalloc;
56         else
57             *statusRet = IceAcceptFailure;
58         return (NULL);
59     }
60
61
62     /*
63      * Set close-on-exec so that programs that fork() don't get confused.
64      */
65
66     _IceTransSetOption (newconn, TRANS_CLOSEONEXEC, 1);
67
68
69     /*
70      * Create an ICE object for this connection.
71      */
72
73     if ((iceConn = (IceConn) malloc (sizeof (struct _IceConn))) == NULL)
74     {
75         _IceTransClose (newconn);
76         *statusRet = IceAcceptBadMalloc;
77         return (NULL);
78     }
79
80     iceConn->listen_obj = listenObj;
81
82     iceConn->waiting_for_byteorder = True;
83     iceConn->connection_status = IceConnectPending;
84     iceConn->io_ok = True;
85     iceConn->dispatch_level = 0;
86     iceConn->context = NULL;
87     iceConn->my_ice_version_index = 0;
88
89     iceConn->trans_conn = newconn;
90     iceConn->send_sequence = 0;
91     iceConn->receive_sequence = 0;
92
93     iceConn->connection_string = strdup(listenObj->network_id);
94
95     if (iceConn->connection_string == NULL)
96     {
97         _IceTransClose (newconn);
98         free ((char *) iceConn);
99         *statusRet = IceAcceptBadMalloc;
100         return (NULL);
101     }
102
103     iceConn->vendor = NULL;
104     iceConn->release = NULL;
105
106     if ((iceConn->inbuf = iceConn->inbufptr =
107         (char *) malloc (ICE_INBUFSIZE)) != NULL)
108     {
109         iceConn->inbufmax = iceConn->inbuf + ICE_INBUFSIZE;
110     }
111     else
112     {
113         _IceTransClose (newconn);
114         free ((char *) iceConn);
115         *statusRet = IceAcceptBadMalloc;
116         return (NULL);
117     }
118
119     if ((iceConn->outbuf = iceConn->outbufptr =
120         (char *) malloc (ICE_OUTBUFSIZE)) != NULL)
121     {
122         iceConn->outbufmax = iceConn->outbuf + ICE_OUTBUFSIZE;
123     }
124     else
125     {
126         _IceTransClose (newconn);
127         free (iceConn->inbuf);
128         free ((char *) iceConn);
129         *statusRet = IceAcceptBadMalloc;
130         return (NULL);
131     }
132
133     iceConn->scratch = NULL;
134     iceConn->scratch_size = 0;
135
136     iceConn->open_ref_count = 1;
137     iceConn->proto_ref_count = 0;
138
139     iceConn->skip_want_to_close = False;
140     iceConn->want_to_close = False;
141     iceConn->free_asap = False;
142
143     iceConn->saved_reply_waits = NULL;
144     iceConn->ping_waits = NULL;
145
146     iceConn->process_msg_info = NULL;
147
148     iceConn->connect_to_you = NULL;
149     iceConn->protosetup_to_you = NULL;
150
151     iceConn->connect_to_me = NULL;
152     iceConn->protosetup_to_me = NULL;
153
154
155     /*
156      * Send our byte order.
157      */
158
159     IceGetHeader (iceConn, 0, ICE_ByteOrder,
160         SIZEOF (iceByteOrderMsg), iceByteOrderMsg, pMsg);
161
162     endian = 1;
163     if (*(char *) &endian)
164         pMsg->byteOrder = IceLSBfirst;
165     else
166         pMsg->byteOrder = IceMSBfirst;
167
168     IceFlush (iceConn);
169
170
171     if (_IceWatchProcs)
172     {
173         /*
174          * Notify the watch procedures that an iceConn was opened.
175          */
176
177         _IceConnectionOpened (iceConn);
178     }
179
180     *statusRet = IceAcceptSuccess;
181
182     return (iceConn);
183 }