[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