~ubuntu-branches/debian/stretch/ion/stretch

« back to all changes in this revision

Viewing changes to ici/daemon/winion.c

  • Committer: Package Import Robot
  • Author(s): Leo Iannacone
  • Date: 2012-02-01 09:46:31 UTC
  • Revision ID: package-import@ubuntu.com-20120201094631-qpfwehc1b7ftkjgx
Tags: upstream-2.5.3~dfsg1
ImportĀ upstreamĀ versionĀ 2.5.3~dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        winion.c:       background ION handle holder for Windows.
 
3
 
 
4
        Author: Scott Burleigh, JPL
 
5
 
 
6
        Copyright (c) 2011, California Institute of Technology.
 
7
        ALL RIGHTS RESERVED.  U.S. Government Sponsorship
 
8
        acknowledged.
 
9
                                                                        */
 
10
#include "ion.h"
 
11
#include <signal.h>
 
12
 
 
13
#define MAX_ION_IPCS    200
 
14
 
 
15
typedef enum
 
16
{
 
17
        IonSmSegment = 1,
 
18
        IonSemaphore
 
19
} IonIpcType;
 
20
 
 
21
typedef struct
 
22
{
 
23
        IonIpcType      type;
 
24
        int             key;
 
25
        HANDLE          handle;
 
26
} IonIpc;
 
27
 
 
28
static int      noteSmSegmentIpc(IonIpc *ipc, int key)
 
29
{
 
30
        char    memName[32];
 
31
 
 
32
        sprintf(memName, "%d.mmap", key);
 
33
        ipc->handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, memName);
 
34
        if (ipc->handle == NULL)        /*      Not found.              */
 
35
        {
 
36
                printf("Can't find memory segment: %u.\n",
 
37
                                (unsigned int) GetLastError());
 
38
                return -1;
 
39
        }
 
40
 
 
41
        return 0;
 
42
}
 
43
 
 
44
static int      noteSemaphoreIpc(IonIpc *ipc, int key)
 
45
{
 
46
        char    semaphoreName[32];
 
47
 
 
48
        sprintf(semaphoreName, "%d.event", key);
 
49
        ipc->handle = OpenEvent(EVENT_ALL_ACCESS, FALSE, semaphoreName);
 
50
        if (ipc->handle == NULL)        /*      Not found.              */
 
51
        {
 
52
                printf("Can't find semaphore %u.\n",
 
53
                                (unsigned int) GetLastError());
 
54
                return -1;
 
55
        }
 
56
 
 
57
        return 0;
 
58
}
 
59
 
 
60
static int      noteIpc(IonIpc *ipc, IonIpcType type, int key)
 
61
{
 
62
        int     result;
 
63
 
 
64
        if (type == IonSmSegment)
 
65
        {
 
66
                result = noteSmSegmentIpc(ipc, key);
 
67
        }
 
68
        else
 
69
        {
 
70
                result = noteSemaphoreIpc(ipc, key);
 
71
        }
 
72
 
 
73
        if (result == 0)
 
74
        {
 
75
                ipc->type = type;
 
76
                ipc->key = key;
 
77
        }
 
78
 
 
79
        return result;
 
80
}
 
81
 
 
82
int     main(int argc, char *argv[])
 
83
{
 
84
        IonIpc          ipcs[MAX_ION_IPCS];
 
85
        int             ipcsCount = 0;
 
86
        HANDLE          hPipe = INVALID_HANDLE_VALUE;
 
87
        int             ionRunning = 1;
 
88
        BOOL            fConnected = FALSE;
 
89
        char            msg[5];
 
90
        DWORD           bytesRead;
 
91
        BOOL            fSuccess = FALSE;
 
92
        IonIpcType      type;
 
93
        DWORD           key;
 
94
        int             i;
 
95
        char            reply[1] = { '\0' };
 
96
        DWORD           bytesWritten;
 
97
 
 
98
        hPipe = CreateNamedPipe("\\\\.\\pipe\\ion.pipe", PIPE_ACCESS_DUPLEX,
 
99
                        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
 
100
                        1, sizeof reply, sizeof msg, 0, NULL);
 
101
        if (hPipe == INVALID_HANDLE_VALUE) 
 
102
        {
 
103
                printf("winion failed creating pipe, error code %u.\n",
 
104
                                (unsigned int) GetLastError()); 
 
105
                return 0;
 
106
        }
 
107
 
 
108
        memset((char *) ipcs, 0, sizeof ipcs);
 
109
        signal(SIGINT, SIG_IGN);
 
110
        while (ionRunning)
 
111
        {
 
112
                fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE
 
113
                                : (GetLastError() == ERROR_PIPE_CONNECTED); 
 
114
                if (!fConnected) 
 
115
                {
 
116
                        printf("winion failed on connect, error code %u.\n",
 
117
                                        (unsigned int) GetLastError()); 
 
118
                        break;
 
119
                }
 
120
 
 
121
                /*      Read one request to retain a handle.            */
 
122
 
 
123
                fSuccess = ReadFile(hPipe, msg, sizeof msg, &bytesRead, NULL);
 
124
                if (!fSuccess || bytesRead == 0)
 
125
                {   
 
126
                        if (GetLastError() == ERROR_BROKEN_PIPE)
 
127
                        {
 
128
                                CloseHandle(hPipe);
 
129
                                continue;
 
130
                        }
 
131
 
 
132
                        printf("winion failed reading msg, error code %u.\n",
 
133
                                        (unsigned int) GetLastError()); 
 
134
                        break;
 
135
                }
 
136
 
 
137
                /*      Parse the message, open and retain the handle.  */
 
138
 
 
139
                reply[0] = 1;                           /*      Okay.   */
 
140
                switch (msg[0])
 
141
                {
 
142
                case 0:                                 /*      Stop.   */
 
143
                        ionRunning = 0;
 
144
                        continue;
 
145
 
 
146
                case 1:
 
147
                        type = IonSmSegment;
 
148
                        break;
 
149
 
 
150
                case 2:
 
151
                        type = IonSemaphore;
 
152
                        break;
 
153
 
 
154
                case '?':
 
155
                        printf("winion retaining %d IPCs.\n", ipcsCount);
 
156
                        reply[0] = 0;                   /*      Dummy.  */
 
157
                        break;
 
158
 
 
159
                default:
 
160
                        reply[0] = 0;                   /*      Fail.   */
 
161
                }
 
162
 
 
163
                if (reply[0])   /*      Valid IPC type.                 */
 
164
                {
 
165
                        memcpy((char *) &key, msg + 1, sizeof(DWORD));
 
166
                        for (i = 0; i < ipcsCount; i++)
 
167
                        {
 
168
                                if (ipcs[i].type == type && ipcs[i].key == key)
 
169
                                {
 
170
                                        break;
 
171
                                }
 
172
                        }
 
173
 
 
174
                        if (i == ipcsCount)     /*      New IPC.        */
 
175
                        {
 
176
                                if (i == MAX_ION_IPCS)
 
177
                                {
 
178
                                        reply[0] = 0;   /*      Fail.   */
 
179
                                }
 
180
                                else
 
181
                                {
 
182
                                        if (noteIpc(&ipcs[i], type, (int) key))
 
183
                                        {
 
184
                                                reply[0] = 0;
 
185
                                        }
 
186
                                        else
 
187
                                        {
 
188
                                                ipcsCount++;
 
189
                                        }
 
190
                                }
 
191
                        }
 
192
                }
 
193
 
 
194
                /*      Tell the client to continue.                    */
 
195
 
 
196
                fSuccess = WriteFile(hPipe, reply, sizeof reply, &bytesWritten,
 
197
                                NULL);
 
198
                if (!fSuccess || bytesWritten != sizeof reply)
 
199
                {
 
200
                        printf("winion failed writing reply, error code %u.\n",
 
201
                                        (unsigned int) GetLastError()); 
 
202
                        break;
 
203
                }
 
204
 
 
205
                /*      Now disconnect pipe so it can be reconnected.   */
 
206
 
 
207
                FlushFileBuffers(hPipe); 
 
208
                DisconnectNamedPipe(hPipe); 
 
209
        }
 
210
 
 
211
        /*      Disconnect pipe and terminate.                          */
 
212
 
 
213
        FlushFileBuffers(hPipe); 
 
214
        DisconnectNamedPipe(hPipe); 
 
215
 
 
216
        /*      Termination of process closes all handles.              */
 
217
 
 
218
        return 0;
 
219
}