~ubuntu-branches/ubuntu/maverick/uim/maverick

« back to all changes in this revision

Viewing changes to uim/uim-helper-server.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2008-06-25 19:56:33 UTC
  • mfrom: (3.1.18 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080625195633-8jljph4rfq00l8o7
Tags: 1:1.5.1-2
* uim-tcode: provide tutcode-custom.scm, tutcode-bushudic.scm
  and tutcode-rule.scm (Closes: #482659)
* Fix FTBFS: segv during compile (Closes: #483078).
  I personally think this bug is not specific for uim but is a optimization
  problem on gcc-4.3.1. (https://bugs.freedesktop.org/show_bug.cgi?id=16477)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
  uim-helper-server.c: This file will be renamed uim-helper-messagebus.c later.
3
3
 
4
 
  Copyright (c) 2003-2006 uim Project http://uim.freedesktop.org/
 
4
  Copyright (c) 2003-2008 uim Project http://code.google.com/p/uim/
5
5
 
6
6
  All rights reserved.
7
7
 
37
37
#include <pwd.h>
38
38
#include <sys/socket.h>
39
39
#include <sys/un.h>
 
40
#include <sys/param.h>
40
41
#include <netinet/in.h>
41
42
#include <netdb.h>
42
43
#include <stdlib.h>
52
53
#endif
53
54
 
54
55
#include "uim.h"
 
56
#include "uim-internal.h"
55
57
#include "uim-helper.h"
56
58
 
57
59
 
72
74
static fd_set s_fdset_read;
73
75
static fd_set s_fdset_write;
74
76
static int s_max_fd;
75
 
 
76
77
static int nr_client_slots;
77
78
static struct client *clients;
78
 
 
79
79
static char read_buf[BUFFER_SIZE];
80
80
 
81
 
/*
82
 
  initialize server's file descriptor.
83
 
*/
84
81
static int
85
82
init_server_fd(char *path)
86
83
{
87
 
  int foo;
88
 
  int fd;
89
 
  int flag;
 
84
  int fd, flag;
90
85
  struct sockaddr_un myhost;
91
86
  struct passwd *pw;
92
87
  char *logname;
96
91
    perror("failed in socket()");
97
92
    return -1;
98
93
  }
 
94
  fchmod(fd, S_IRUSR | S_IWUSR);
99
95
 
100
 
  bzero(&myhost, sizeof(myhost));
 
96
  memset(&myhost, 0, sizeof(myhost));
101
97
  myhost.sun_family = PF_UNIX;
102
98
  strlcpy(myhost.sun_path, path, sizeof(myhost.sun_path));
103
99
 
104
 
  foo = bind(fd, (struct sockaddr *)&myhost, SUN_LEN(&myhost));
105
 
  if (foo < -1) {
 
100
  if (bind(fd, (struct sockaddr *)&myhost, SUN_LEN(&myhost)) < 0) {
106
101
    perror("failed in bind()");
107
102
    return -1;
108
103
  }
109
104
 
110
 
  chmod(path, S_IRUSR|S_IWUSR);
111
 
 
112
105
  logname = getenv("LOGNAME");
113
106
  if (logname) {
114
107
    pw = getpwnam(logname);
115
108
    if (pw)
116
 
      chown(path, pw->pw_uid, -1);
 
109
      fchown(fd, pw->pw_uid, -1);
117
110
  }
118
111
 
119
 
  if ((flag = fcntl(fd, F_GETFL)) == -1) {
 
112
  if ((flag = fcntl(fd, F_GETFL)) < 0) {
120
113
    close(fd);
121
114
    return -1;
122
115
  }
123
116
 
124
117
  flag |= O_NONBLOCK;
125
 
  if (fcntl(fd, F_SETFL, flag) == -1) {
 
118
  if (fcntl(fd, F_SETFL, flag) < 0) {
126
119
    close(fd);
127
120
    return -1;
128
121
  }
129
122
 
130
 
  foo = listen(fd, 5);
131
 
  if (foo == -1) {
 
123
  if (listen(fd, 5) < 0) {
132
124
    perror("failed in listen()");
133
125
    return -1;
134
126
  }
135
 
  /*  fprintf(stderr,"listen at %s\n",path);*/
 
127
 
136
128
  FD_SET(fd, &s_fdset_read);
137
129
  s_max_fd = fd;
 
130
 
138
131
  return fd;
139
132
}
140
133
 
142
135
get_unused_client(void)
143
136
{
144
137
  int i;
 
138
 
145
139
  for (i = 0; i < nr_client_slots; i++) {
146
 
    if (clients[i].fd == -1) {
 
140
    if (clients[i].fd == -1)
147
141
      return &clients[i];
148
 
    }
149
142
  }
 
143
 
150
144
  nr_client_slots++;
151
 
  clients = realloc(clients, sizeof(struct client) * nr_client_slots);
152
 
  clients[nr_client_slots - 1].rbuf = strdup("");
153
 
  clients[nr_client_slots - 1].wbuf = strdup("");
 
145
  clients = uim_realloc(clients, sizeof(struct client) * nr_client_slots);
 
146
  clients[nr_client_slots - 1].rbuf = uim_strdup("");
 
147
  clients[nr_client_slots - 1].wbuf = uim_strdup("");
 
148
 
154
149
  return &clients[nr_client_slots - 1];
155
150
}
156
151
 
160
155
  close(cl->fd);
161
156
  if (cl->rbuf) {
162
157
    free(cl->rbuf);
163
 
    cl->rbuf = strdup("");
 
158
    cl->rbuf = uim_strdup("");
164
159
  }
165
160
  if (cl->wbuf) {
166
161
    free(cl->wbuf);
167
 
    cl->wbuf = strdup("");
 
162
    cl->wbuf = uim_strdup("");
168
163
  }
169
164
  cl->fd = -1;
170
165
}
188
183
static int
189
184
reflect_message_fragment(struct client *cl)
190
185
{
191
 
  int rc;
 
186
  ssize_t rc;
192
187
  char *msg;
193
188
 
194
189
  /* do read */
195
190
  rc = read(cl->fd, read_buf, sizeof(read_buf));
196
 
  if (rc <= 0) {
197
 
    if (rc < 0 && (errno == EAGAIN || errno == EINTR))
 
191
  if (rc == -1) {
 
192
    if (errno == EAGAIN || errno == EINTR)
198
193
      return 0;
199
194
    return -1;
200
 
  }
 
195
  } else if (rc == 0)
 
196
    return -1;
201
197
 
202
198
  cl->rbuf = uim_helper_buffer_append(cl->rbuf, read_buf, rc);
203
199
 
205
201
    distribute_message(msg, cl);
206
202
    free(msg);
207
203
  }
 
204
 
208
205
  return 1;
209
206
}
210
207
 
213
210
{
214
211
  /* If there's no connection, we can assume user logged out. */
215
212
  int i;
 
213
 
216
214
  for (i = 0; i < nr_client_slots; i++) {
217
 
    if (clients[i].fd != -1) {
 
215
    if (clients[i].fd != -1)
218
216
      return UIM_TRUE;
219
 
    }
220
217
  }
 
218
 
221
219
  return UIM_FALSE; /* User already logged out */
222
220
}
223
221
 
226
224
accept_new_connection(int server_fd)
227
225
{
228
226
  struct sockaddr_un clientsoc;
229
 
  socklen_t len = sizeof(clientsoc);
230
 
  int new_fd;
231
 
  int flag;
 
227
  socklen_t len;
 
228
  int new_fd, flag;
232
229
  struct client *cl;
 
230
 
 
231
  len = sizeof(clientsoc);
233
232
  new_fd = accept(server_fd, (struct sockaddr *)&clientsoc, &len);
234
233
  
235
234
  if (new_fd < 0) {
237
236
    return UIM_FALSE;
238
237
  }
239
238
 
240
 
  if ((flag = fcntl(new_fd, F_GETFL)) == -1) {
 
239
  if ((flag = fcntl(new_fd, F_GETFL)) < 0) {
241
240
    close(new_fd);
242
241
    return UIM_FALSE;
243
242
  }
244
243
 
245
244
  flag |= O_NONBLOCK;
246
 
  if (fcntl(new_fd, F_SETFL, flag) == -1) {
 
245
  if (fcntl(new_fd, F_SETFL, flag) < 0) {
247
246
    close(new_fd);
248
247
    return UIM_FALSE;
249
248
  }
300
299
  }
301
300
  if (out_len == 0) {
302
301
    free(cl->wbuf);
303
 
    cl->wbuf = strdup("");
 
302
    cl->wbuf = uim_strdup("");
304
303
    FD_CLR(cl->fd, &s_fdset_write);    
305
304
  } else {
306
305
    uim_helper_buffer_shift(cl->wbuf, message_len - out_len);
312
311
read_message(struct client *cl)
313
312
{
314
313
  int result;
 
314
 
315
315
  result = reflect_message_fragment(cl);
316
316
  
317
317
  if (result < 0) {
323
323
  }
324
324
}
325
325
 
326
 
 
327
326
static void
328
327
uim_helper_server_process_connection(int server_fd)
329
328
{
331
330
  fd_set readfds, writefds;
332
331
 
333
332
  while (1) {
334
 
    /* Could we replace this memcpy with direct assignment? */
335
333
    /* Copy readfds from s_fdset_read/s_fdset_write because select removes
336
334
       readble/writable fd from readfds/writefds */
337
335
    memcpy(&readfds, &s_fdset_read, sizeof(fd_set));
348
346
    if (FD_ISSET(server_fd, &readfds)) {
349
347
      uim_bool accepted;
350
348
      accepted = accept_new_connection(server_fd);
351
 
      if(accepted == UIM_FALSE) {
352
 
        continue; /* acception failed, go next loop without message processing. */
 
349
      if (accepted == UIM_FALSE) {
 
350
        /* acception failed, go next loop without message processing. */
 
351
        continue;
353
352
      }
354
353
    } else {
355
354
      /* check data to write and from clients reached */
356
355
      for (i = 0; i < nr_client_slots; i++) {
357
 
        if (clients[i].fd != -1 && FD_ISSET(clients[i].fd, &writefds)) {
 
356
        if (clients[i].fd != -1 && FD_ISSET(clients[i].fd, &writefds))
358
357
          write_message(&clients[i]);
359
 
        }
360
 
        if (clients[i].fd != -1 && FD_ISSET(clients[i].fd, &readfds)) {
 
358
 
 
359
        if (clients[i].fd != -1 && FD_ISSET(clients[i].fd, &readfds))
361
360
          read_message(&clients[i]);
362
 
        }
363
361
      }
364
362
    }
365
363
 
366
 
    if(check_session_alive() == UIM_FALSE) {
 
364
    if (!check_session_alive())
367
365
      return;
368
 
    }
369
366
  }
370
367
}
371
368
 
373
370
int
374
371
main(int argc, char **argv)
375
372
{
376
 
  char *path = uim_helper_get_pathname();
 
373
  char path[MAXPATHLEN];
377
374
  int server_fd;
 
375
 
 
376
  uim_init_error();
 
377
 
 
378
  if (!uim_helper_get_pathname(path, sizeof(path)))
 
379
    return 0;
 
380
 
378
381
  unlink(path);
379
382
 
380
383
  clients = NULL;
391
394
  fclose(stdin);
392
395
  fclose(stdout);
393
396
 
394
 
  if (server_fd < 0) {
 
397
  if (server_fd < 0)
395
398
    return 0;
396
 
  }
 
399
 
397
400
  /*  fprintf(stderr,"Waiting for connection at %s\n", path);*/
398
401
 
399
 
  free(path);
400
 
 
401
402
  signal(SIGPIPE, SIG_IGN);
402
 
 
403
403
  uim_helper_server_process_connection(server_fd);
404
404
 
405
405
  return 0;
406
406
}
407
 
 
408