[uim-commit] r304 - in trunk: scm uim

tkng@freedesktop.org tkng@freedesktop.org
Sat Jan 15 09:14:33 PST 2005


Author: tkng
Date: 2005-01-15 09:14:22 -0800 (Sat, 15 Jan 2005)
New Revision: 304

Modified:
   trunk/scm/prime-custom.scm
   trunk/scm/prime.scm
   trunk/uim/prime.c
Log:
* uim/prime.c:
 -(prime_init_ud):New function to connect to prime server.
 -(prime_get_ud_path): New function to get the path of unix domain socket
 -(prime_get_ud_command):New function to get prime command string
   with -u option.
 -(prime_read_msg_from_ud);New function to read message from file descriptor
 -(prime_write_msg_to_ud): New function to write message to file descriptor
 -(prime_lib_init): Changed argument. Now it's take an argument. If the
   argument is true, uim-prime uses unix domain socket to communicate
   with PRIME.

* scm/prime.scm:
 -(prime-util-string-split): Allow non-string argument.
 -(prime-engine-send-command):Don't append "\n" here.
 -(prime-init-handler): Pass an argument for prime-lib-init.

* scm/prime-custom.scm:
 -(prime-use-unixdomain?): New custom item for prime.


Modified: trunk/scm/prime-custom.scm
===================================================================
--- trunk/scm/prime-custom.scm	2005-01-15 16:49:15 UTC (rev 303)
+++ trunk/scm/prime-custom.scm	2005-01-15 17:14:22 UTC (rev 304)
@@ -89,6 +89,12 @@
   (_ "Show usage examples of candidate words")
   (_ "long description will be here."))
 
+(define-custom 'prime-use-unixdomain? #f
+  '(prime)
+  '(boolean)
+  (_ "Use Unix Domain Socket to communicate with PRIME")
+  (_ "long description will be here."))
+
 (define-custom 'prime-mask-pending-preedit? #f
   '(prime)
   '(boolean)

Modified: trunk/scm/prime.scm
===================================================================
--- trunk/scm/prime.scm	2005-01-15 16:49:15 UTC (rev 303)
+++ trunk/scm/prime.scm	2005-01-15 17:14:22 UTC (rev 304)
@@ -466,10 +466,10 @@
   (lambda (command)
     (let ((result (prime-lib-send-command command)))
       (let loop ((res result))
-	(if (string=? res "")
-	    (loop (prime-lib-send-command ""))
+ 	(if (string=? res "")
+ 	    (loop (prime-lib-send-command ""))
 	    res
-	    )))))
+ 	    )))))
 
 (define prime-preedit-reset!
   (lambda (context)
@@ -560,17 +560,19 @@
 ;; The second argument separator must be a single character string.
 (define prime-util-string-split
   (lambda (string separator)
-    (let ((result (list))
-	  (node-string ""))
-      (map (lambda (target)
-	     (if (equal? target separator)
-		 (begin
-		   (set! result (cons node-string result))
-		   (set! node-string ""))
-		 (set! node-string (string-append node-string target))))
-	   (reverse (string-to-list string)))
-      (set! result (cons node-string result))
-      (reverse result))))
+    (if (string? string)
+	(let ((result (list))
+	      (node-string ""))
+	  (map (lambda (target)
+		 (if (equal? target separator)
+		     (begin
+		       (set! result (cons node-string result))
+		       (set! node-string ""))
+		     (set! node-string (string-append node-string target))))
+	       (reverse (string-to-list string)))
+	  (set! result (cons node-string result))
+	  (reverse result))
+	"")))
 
 ;;;; ------------------------------------------------------------
 ;;;; prime-uim:
@@ -588,12 +590,14 @@
 ;;;; prime-engine: Functions to connect with a prime server.
 ;;;; ------------------------------------------------------------
 
+;; Don't append "\n" to arg-list in this function. That will cause a
+;; problem with unix domain socket.
 (define prime-engine-send-command
   (lambda (arg-list)
     (cdr 
      (string-split
       (prime-send-command
-       (string-append (prime-util-string-concat arg-list "\t") "\n"))
+       (prime-util-string-concat arg-list "\t"))
       "\n"))))
 
 (define prime-engine-lookup
@@ -621,6 +625,7 @@
 (define prime-engine-session-start
   (lambda ()
     (car (prime-engine-send-command (list "session_start")))))
+
 (define prime-engine-session-end
   (lambda (prime-session)
     (prime-engine-send-command (list "session_end" prime-session))))
@@ -1524,10 +1529,11 @@
 
 (define prime-init-handler
   (lambda (id im arg)
-    (print "prime-init-handler")
-    (let ((context (prime-context-new id im)))
-      (prime-custom-init)
-      context)))
+    (if (prime-lib-init prime-use-unixdomain?)
+	(let ((context (prime-context-new id im)))
+	  (prime-custom-init)
+	  context)
+	#f)))
 
 (define prime-release-handler
   (lambda (context)

Modified: trunk/uim/prime.c
===================================================================
--- trunk/uim/prime.c	2005-01-15 16:49:15 UTC (rev 303)
+++ trunk/uim/prime.c	2005-01-15 17:14:22 UTC (rev 304)
@@ -30,21 +30,149 @@
   SUCH DAMAGE.
 */
 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
+#include "config.h"
 #include "uim-scm.h"
 #include "uim-compat-scm.h"
 #include "context.h"
 #include "plugin.h"
+#include "uim-helper.h"
 
+#define BUFFER_SIZE (4 * 1024)
+
 static FILE *primer = NULL, *primew = NULL;
 static int prime_pid = 0;
 
 static char *prime_command = "prime";
+static char *prime_ud_command;
+static char *prime_ud_path;
+static int prime_fd;
+static int use_unix_domain_socket;
 
+static int
+prime_init_ud(char *path)
+{
+  int fd;
+  struct sockaddr_un server;
+    
+  if(!path)
+    return -1;
+
+  bzero(&server, sizeof(server));
+  server.sun_family = PF_UNIX;
+  strcpy(server.sun_path, path);
+
+  free(path);
+  
+  fd = socket(PF_UNIX, SOCK_STREAM, 0);
+  if (fd < 0) {
+    perror("fail to create socket");
+    return -1;
+  }
+  
+#ifdef LOCAL_CREDS /* for NetBSD */
+  /* Set the socket to receive credentials on the next message */
+  {
+    int on = 1;
+    setsockopt(fd, 0, LOCAL_CREDS, &on, sizeof(on));
+  }
+#endif
+
+  if(connect(fd, (struct sockaddr *)&server,sizeof(server)) == -1){
+    close(fd);
+    printf("connect failed\n");
+    return -1;
+  }
+  
+  if (uim_helper_check_connection_fd(fd)) {
+    close(fd);
+    return -1;
+  }
+  return fd;
+}
+
+static char *
+prime_get_ud_path(void)
+{
+  char *path;
+  char *login;
+  struct passwd *pw = NULL;
+ 
+  login = getenv("LOGNAME");
+  
+  if (!login) {
+    pw = getpwuid(getuid());
+    login = strdup(pw->pw_name);
+  }
+
+  path = (char *)malloc(strlen(login)+ 20);
+  sprintf(path, "/tmp/prime-%s",login);
+  if (pw) {
+    free(login);
+  }
+  return path;
+}
+
+static char *
+prime_get_ud_command(void)
+{
+  char *command = (char *) malloc(strlen(prime_command)
+				  + strlen(prime_ud_path) + 5);
+
+  sprintf(command, "%s -u %s", prime_command, prime_ud_path);
+  return command;
+}
+
+static char *
+prime_read_msg_from_ud(int fd)
+{
+  char *read_buf = strdup("");
+  char buf[BUFFER_SIZE];
+  int rc;
+
+  if(fd == -1)
+    return NULL;
+
+  while(uim_helper_fd_readable(fd) > 0) {
+    
+    rc = read(fd, buf, sizeof(buf)-1);
+    buf[rc] = '\0';
+    
+    if(rc == 0) {
+      fprintf(stderr, "disconnected\n");
+      return NULL;
+    }
+    read_buf = (char *)realloc(read_buf, strlen(read_buf) + strlen(buf)+1);
+    strcat(read_buf, buf);
+  }
+  return read_buf;
+}
+
+static void
+prime_write_msg_to_ud(int fd, const char *message)
+{
+  if(strcmp(message, "") ==0) {
+    return;
+  }
+  if(fd == -1)
+    return;
+
+  uim_helper_send_message(fd, message);
+}
+
+
 static uim_lisp
 prime_send_command(uim_lisp str_)
 {
@@ -52,13 +180,25 @@
   char *result;
   uim_lisp ret;
 
-  result = uim_ipc_send_command(&prime_pid, &primer, &primew, prime_command, str);
+  if(use_unix_domain_socket) {
+    prime_write_msg_to_ud(prime_fd, str);
+    result = prime_read_msg_from_ud(prime_fd);
 
-  if(result == NULL)
-    {
-      return uim_scm_f();
-    }
+    /*    if(!result) {
+      prime_fd = prime_init_ud(prime_ud_path);
+      }*/
+  } else {
+    int len = strlen(str);
+    char *buf = malloc(len + 2);
+    snprintf(buf, len + 2,"%s\n", str);
+    result = uim_ipc_send_command(&prime_pid, &primer, &primew, prime_command, buf);
+    free(buf);
+  }
 
+  if(!result) {
+    return uim_scm_make_str("");
+  }
+
  ret = uim_scm_make_str(result);
  free(result);
  return ret;
@@ -66,33 +206,74 @@
 }
 
 static uim_lisp
-prime_lib_init(void)
+prime_lib_init(uim_lisp use_udp_)
 {
-  prime_pid = uim_ipc_open_command(prime_pid, &primer, &primew, prime_command );
-  if(prime_pid == 0) {
-    return uim_scm_f();
-  }
-  return uim_scm_t();
+#ifdef UIM_SCM_NESTED_EVAL
+  uim_bool use_udp = uim_scm_c_bool(use_udp_);
+  if(use_udp == UIM_TRUE)
+    use_unix_domain_socket = UIM_TRUE;
+  else
+    use_unix_domain_socket = UIM_FALSE;
+#else
+    use_unix_domain_socket = UIM_FALSE;
+#endif
+    if(use_unix_domain_socket == UIM_TRUE) {
+      prime_ud_path = prime_get_ud_path();
+      if(!prime_ud_path)
+	return uim_scm_f();
+      
+      prime_ud_command = prime_get_ud_command();
+      if(!prime_ud_command)
+	return uim_scm_f();
+
+      prime_fd = prime_init_ud(prime_ud_path);
+      if(prime_fd == -1) {
+	prime_pid = uim_ipc_open_command_with_opt(prime_pid, &primer, &primew, prime_command, "-u /tmp/prime-tkng");
+	if(prime_pid == 0) {
+	  return uim_scm_f();
+	} else {
+	  prime_fd = prime_init_ud(prime_ud_path);
+	  while(prime_fd == -1) {
+	    prime_fd = prime_init_ud(prime_ud_path);
+	  }
+	}
+      }
+
+      if(prime_fd == -1)
+	return uim_scm_f();
+      else
+	return uim_scm_t();
+    } else {
+      prime_pid = uim_ipc_open_command(prime_pid, &primer, &primew, prime_command );
+      if(prime_pid == 0) {
+	return uim_scm_f();
+      }
+      return uim_scm_t();
+    }
 }
 
 void
 uim_plugin_instance_init(void)
 {
-  uim_scm_init_subr_0("prime-lib-init", prime_lib_init);
+  uim_scm_init_subr_1("prime-lib-init", prime_lib_init);
   uim_scm_init_subr_1("prime-lib-send-command", prime_send_command);
 }
 
 void
 uim_plugin_instance_quit(void)
 {
-  if(primew) {
-    uim_ipc_send_command(&prime_pid, &primer, &primew, prime_command, "close\n");
-    fclose(primew);
-    primew = NULL;
+  if(use_unix_domain_socket && prime_fd > 0) {
+    prime_write_msg_to_ud(prime_fd, "close\n");
+    prime_fd = -1;
+  } else {
+    if(primew) {
+      uim_ipc_send_command(&prime_pid, &primer, &primew, prime_command, "close\n");
+      fclose(primew);
+      primew = NULL;
+    }    
+    if(primer) {
+      fclose(primer);
+      primer = NULL;
+    }
   }
-
-  if(primer) {
-    fclose(primer);
-    primer = NULL;
-  }
 }



More information about the Uim-commit mailing list