(file) Return to Socket.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Executor

  1 kumpf 1.2 /*
  2 martin 1.6 //%LICENSE////////////////////////////////////////////////////////////////
  3 kumpf  1.2 // 
  4 martin 1.6 // Licensed to The Open Group (TOG) under one or more contributor license
  5            // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  6            // this work for additional information regarding copyright ownership.
  7            // Each contributor licenses this file to you under the OpenPegasus Open
  8            // Source License; you may not use this file except in compliance with the
  9            // License.
 10            // 
 11            // Permission is hereby granted, free of charge, to any person obtaining a
 12            // copy of this software and associated documentation files (the "Software"),
 13            // to deal in the Software without restriction, including without limitation
 14            // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 15            // and/or sell copies of the Software, and to permit persons to whom the
 16            // Software is furnished to do so, subject to the following conditions:
 17            // 
 18            // The above copyright notice and this permission notice shall be included
 19            // in all copies or substantial portions of the Software.
 20            // 
 21            // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 22            // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 23            // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 24            // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 25 martin 1.6 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 26            // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 27            // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 28            // 
 29            //////////////////////////////////////////////////////////////////////////
 30 kumpf  1.2 */
 31            
 32            #ifndef _Executor_Socket_h
 33            #define _Executor_Socket_h
 34            
 35            #include <stdlib.h>
 36            #include <sys/socket.h>
 37            #include <string.h>
 38 kumpf  1.4 #include <errno.h>
 39            #include <unistd.h>
 40            #include <Executor/Defines.h>
 41            
 42            #ifdef PEGASUS_ENABLE_PRIVILEGE_SEPARATION
 43 kumpf  1.2 
 44            EXECUTOR_LINKAGE
 45            int SetNonBlocking(int sock);
 46            
 47            EXECUTOR_LINKAGE
 48            int SetBlocking(int sock);
 49            
 50            EXECUTOR_LINKAGE
 51 kumpf  1.5 int WaitForReadEnable(int sock, long timeoutMsec);
 52            
 53            EXECUTOR_LINKAGE
 54 kumpf  1.2 ssize_t RecvNonBlock(int sock, void* buffer, size_t size);
 55            
 56            EXECUTOR_LINKAGE
 57            ssize_t SendNonBlock(int sock, const void* buffer, size_t size);
 58            
 59            EXECUTOR_LINKAGE
 60            int CloseOnExec(int fd);
 61            
 62            EXECUTOR_LINKAGE
 63            ssize_t SendDescriptorArray(int sock, int descriptors[], size_t count);
 64            
 65            EXECUTOR_LINKAGE
 66            int CreateSocketPair(int pair[2]);
 67            
 68            static int RecvDescriptorArray(int sock, int descriptors[], size_t count)
 69            {
 70                struct iovec iov[1];
 71                char dummy;
 72                struct msghdr mh;
 73                ssize_t n;
 74            #if defined(HAVE_MSG_CONTROL)
 75 kumpf  1.2     size_t size;
 76                char* data;
 77 kumpf  1.3     struct cmsghdr* cmh;
 78 kumpf  1.2 
 79                /*
 80                 * This control data begins with a cmsghdr struct followed by the data
 81                 * (a descriptor in this case). The union ensures that the data is
 82                 * aligned suitably for the leading cmsghdr struct. The descriptor
 83                 * itself is properly aligned since the cmsghdr ends on a boundary
 84                 * that is suitably aligned for any type (including int).
 85                 *
 86                 *     ControlData = [ cmsghdr | int ]
 87                 */
 88            
 89                size = CMSG_SPACE(sizeof(int) * count);
 90                data = (char*)malloc(size);
 91            
 92                /* Define a msghdr that refers to the control data, which is filled in
 93                 * by calling recvmsg() below.
 94                 */
 95            
 96                memset(&mh, 0, sizeof(mh));
 97                mh.msg_control = data;
 98                mh.msg_controllen = size;
 99 kumpf  1.2 
100            #else /* !defined(HAVE_MSG_CONTROL) */
101            
102                memset(&mh, 0, sizeof(mh));
103                mh.msg_accrights = (caddr_t)descriptors;
104                mh.msg_accrightslen = sizeof(int) * count;
105            
106            #endif /* defined(HAVE_MSG_CONTROL) */
107            
108                /*
109                 * The other process sends a single-byte message. This byte is not
110                 * used since we only need the control data (the descriptor) but we
111                 * must request at least one byte from recvmsg().
112                 */
113            
114                memset(iov, 0, sizeof(iov));
115                iov[0].iov_base = &dummy;
116                iov[0].iov_len = 1;
117                mh.msg_iov = iov;
118                mh.msg_iovlen = 1;
119            
120 kumpf  1.2     /* Receive the message from the other process. */
121            
122                n = recvmsg(sock, &mh, 0);
123            
124                if (n <= 0)
125 kumpf  1.3     {
126            #if defined(HAVE_MSG_CONTROL)
127                    free(data);
128            #endif
129 kumpf  1.2         return -1;
130 kumpf  1.3     }
131 kumpf  1.2 
132                /* Get a pointer to control message. Return if the header is null or
133                 * does not contain what we expect.
134                 */
135            
136            #if defined(HAVE_MSG_CONTROL)
137            
138                cmh = CMSG_FIRSTHDR(&mh);
139            
140                if (!cmh ||
141                    cmh->cmsg_len != CMSG_LEN(sizeof(int) * count) ||
142                    cmh->cmsg_level != SOL_SOCKET ||
143                    cmh->cmsg_type != SCM_RIGHTS)
144                {
145 kumpf  1.3         free(data);
146 kumpf  1.2         return -1;
147                }
148            
149                /* Copy the data: */
150            
151                memcpy(descriptors, CMSG_DATA(cmh), sizeof(int) * count);
152            
153 kumpf  1.3     free(data);
154            
155 kumpf  1.2 #else /* !defined(HAVE_MSG_CONTROL) */
156            
157                if (mh.msg_accrightslen != sizeof(int) * count)
158                    return -1;
159            
160                memcpy(descriptors, mh.msg_accrights, sizeof(int) * count);
161            
162            #endif /* defined(HAVE_MSG_CONTROL) */
163            
164                return 0;
165            }
166            
167 kumpf  1.4 #endif
168            
169            /*
170                These functions are used by the PAM cimservera implementation regardless
171                of whether privilege separation is enabled.
172            */
173            
174            static ssize_t RecvBlock(int sock, void* buffer, size_t size)
175            {
176                size_t r = size;
177                char* p = (char*)buffer;
178            
179                if (size == 0)
180                    return -1;
181            
182                while (r)
183                {
184                    ssize_t n;
185            
186                    EXECUTOR_RESTART(read(sock, p, r), n);
187            
188 kumpf  1.4         if (n == -1)
189                        return -1;
190                    else if (n == 0)
191                        return size - r;
192            
193                    r -= n;
194                    p += n;
195                }
196            
197                return size - r;
198            }
199            
200            static ssize_t SendBlock(int sock, void* buffer, size_t size)
201            {
202                size_t r = size;
203                char* p = (char*)buffer;
204            
205                while (r)
206                {
207                    ssize_t n;
208                    EXECUTOR_RESTART(write(sock, p, r), n);
209 kumpf  1.4 
210                    if (n == -1)
211                        return -1;
212                    else if (n == 0)
213                        return size - r;
214            
215                    r -= n;
216                    p += n;
217                }
218            
219                return size - r;
220            }
221            
222 kumpf  1.2 #endif /* _Executor_Socket_h */

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2