[openi18n-im:01160] Re: iiimf Client Emacs (IIIMECF) improvement
Hiroshi Miura <[email protected]>
| Newsgroups | gmane.comp.internationalization.input-methods |
|---|---|
| Message-ID | <87hdlgvh6q.wl%[email protected]> |
Thanks for improvement.
But I independently improved it on same point of view, too.
I also modified iiimp.el to be configurable like as
Example: (setq iiimcf-server-control-hostlist
'("localhost" "tcp/iiim:9010" "iiim.foo.com:9000" "unix/:9010"))
Miura
At Mon, 17 Jan 2005 12:48:21 +0900,
Motonobu Ichimura wrote:
>
> [1 <text/plain; US-ASCII (7bit)>]
> Hi.
>
> thanks for your good work for supporting unix domain socket to IIIMECF.
>
> Since htt_server may reply multiple messages to the client at once,
> do send one message, then wait one message style may cause a dead lock.
> would you try attached patch?
>
--
Hiroshi Miura --- http://www.da-cha.org/ --- [email protected]
NTTDATA Corp. OpenSource Software Center. --- [email protected]
NTTDATA Intellilink Corp. OpenSource Engineering Dev. -- [email protected]
Key fingerprint = 9117 9407 5684 FBF1 4063 15B4 401D D077 04AB 8617
iiimecf-0.6-0.7.diff
(application/octet-stream, 15.7 KB)
diff -urN -x .svn -x '*~' im-sdk/iiimecf/ChangeLog iiimecf/iiimecf/ChangeLog --- im-sdk/iiimecf/ChangeLog 2004-12-10 08:21:36.000000000 +0900 +++ iiimecf/iiimecf/ChangeLog 2005-01-15 23:58:44.000000000 +0900 @@ -1,3 +1,10 @@ +2005-01-15 Hiroshi Miura <[email protected]> + + * iiimp.el: Support unix domain socket. + * util/udclient.c, util/udclient.h, util/Makefile: helper program + to communicate with unix domain socket. + * README, README.ja: add description about unix domain socket. + 2001-07-02 MIYASHITA Hisashi <[email protected]> * IIIMECF 0.6 Release. diff -urN -x .svn -x '*~' im-sdk/iiimecf/README iiimecf/iiimecf/README --- im-sdk/iiimecf/README 2004-12-10 08:21:38.000000000 +0900 +++ iiimecf/iiimecf/README 2005-01-15 23:58:44.000000000 +0900 @@ -2,6 +2,8 @@ IIIMECF (Internet/Intranet Input Method Emacs Client Framework) Brief manual. + Modified by Hiroshi Miura ([email protected]) + on 2005/1/15. Written by MIYASHITA Hisashi ([email protected]) on 2000/9/8. -------------------------------------------------------------- @@ -82,16 +84,19 @@ iiimcf-server-control-hostlist The default value is '("localhost") - Specifies IIIM servers. The format is like "<SERVER>:<PORT>". + Specifies IIIM servers. The format is like "<PROTO>/<SERVER>:<PORT>". You can specify more than one server. Although, currently, iiim-sc tries to connect the first server, it will be able to switch servers dynamically in the future. Example: (setq iiimcf-server-control-hostlist - '("localhost" "iiim:9010" "iiim.foo.com:9000" )) + '("localhost" "tcp/iiim:9010" "iiim.foo.com:9000" "unix/:9010")) If you omit <PORT>, use iiimcf-server-control-default-port. - The default value of this variable is 9010. + The default value of this variable is 9010. If you omit <PROTO>, + use iiimcf-server-control-default-protocol. The default value of this is tcp. + + If you specify "unix/:9010", it tries to connect through unix domain socket. iiimcf-server-control-username The default value is (user-login-name)@(system-name) diff -urN -x .svn -x '*~' im-sdk/iiimecf/README.ja iiimecf/iiimecf/README.ja --- im-sdk/iiimecf/README.ja 2004-12-10 08:21:36.000000000 +0900 +++ iiimecf/iiimecf/README.ja 2005-01-15 23:58:44.000000000 +0900 @@ -2,6 +2,8 @@ IIIMECF (Internet/Intranet Input Method Emacs Client Framework) Brief manual. + Modified by Hiroshi Miura ([email protected]) + on 2005/1/15. Written by MIYASHITA Hisashi ([email protected]) on 2000/9/8. -------------------------------------------------------------- @@ -84,15 +86,20 @@ iiimcf-server-control-hostlist defaultÅA'("localhost") - IIIM serverðwèµÜ·B`®ÍA"<SERVER>:<PORT>"Ìæ¤ÉwèµA - ¡ÌT[o[ðwè·é±ÆªoÜ·B(»óÅÍAÅÉwèµ½ - T[o[ɵ©Ú±ðÝÈ¢ªA«IÉÍ©®IÉØèÖ¦é\è) + IIIM serverðwèµÜ·B`®ÍA"<PROTO>/<SERVER>:<PORT>"Ìæ¤ + ÉwèµA¡ÌT[o[ðwè·é±ÆªoÜ·B(»óÅÍAÅÉ + wèµ½T[o[ɵ©Ú±ðÝÈ¢ªA«IÉÍ©®IÉØèÖ¦é + \è) á: (setq iiimcf-server-control-hostlist - '("localhost" "iiim:9010" "iiim.foo.com:9000" )) + '("localhost" "tcp/iiim:9010" "iiim.foo.com:9000" "unix/:9010")) - ȨA<PORT>ðȪµ½êAiiimcf-server-control-default-portª - gp³êÜ·B±ÌÏÌlÌdefaultÍA9010Å·B + ȨA<PORT>ðȪµ½êAiiimcf-server-control-default-portª + gp³êÜ·B±ÌÏÌlÌdefaultÍA9010Å·BܽA<PROTO>ð + Ȫµ½êAiiimcf-server-control-default-protocolªgp³êÜ·B + ±ÌÏÌlÌdefaultÍAtcpÅ·B + + "unix/:9010"ðwèµ½êÍAunix domain socket oRÅÌÚ±ðÝÜ·B iiimcf-server-control-username defaultÍA(user-login-name)@(system-name) diff -urN -x .svn -x '*~' im-sdk/iiimecf/lisp/iiimcf-sc.el iiimecf/iiimecf/lisp/iiimcf-sc.el --- im-sdk/iiimecf/lisp/iiimcf-sc.el 2004-12-10 08:21:36.000000000 +0900 +++ iiimecf/iiimecf/lisp/iiimcf-sc.el 2005-01-16 17:11:36.000000000 +0900 @@ -46,6 +46,11 @@ :tag "Default port for IIIMCF Server Control" :group 'iiimcf-server-control :type 'integer) +(defcustom iiimcf-server-control-default-proto "tcp" + "*Default protocol socket domain for IIIM server." + :tag "Default protocol socket domain for IIIMCF Server Control" + :group 'iiimcf-server-control :type 'string) + (defcustom iiimcf-server-control-hostlist '("localhost") "*A list of IIIM Server hosts. If each hostname has the form of \"HOSTNAME:N\", use N-th port." @@ -178,13 +183,37 @@ ;;; (defun iiimcf-server-control-parse-hostname (hostname) - (if (string-match ":" hostname) - (list - (substring hostname 0 (match-beginning 0)) - (string-to-number (substring hostname (match-end 0)))) - (list - hostname - iiimcf-server-control-default-port))) + (let ((name-b 0) + (name-e 0) + (proto-b 0) + (proto-e 0)) + (if (string-match ":" hostname) + (setq name-b (match-beginning 0) + name-e (match-end 0))) + (if (string-match "/" hostname) + (setq proto-b (match-beginning 0) + proto-e (match-end 0))) + (cond ((and (> name-b 0) (> proto-b 0)) + (list + (substring hostname 0 proto-b) + (substring hostname proto-e name-b) + (string-to-number (substring hostname name-e)))) + ((and (= name-b 0) (> proto-b 0)) + (list + (substring hostname 0 proto-b) + (substring hostname proto-e) + iiimcf-server-control-default-port)) + ((and (= name-b 0) (= proto-b 0)) + (list + iiimcf-server-control-default-proto + hostname + iiimcf-server-control-default-port)) + (t + (list + iiimcf-server-control-default-proto + (substringt hostname 0 name-b) + (string-to-number (substring hostname name-e))))) +)) (defun iiimcf-server-control-setup-event-flow-mode (mes) (setq iiimcf-server-control-dynamic-event-flow-p t)) @@ -610,8 +639,10 @@ (defun iiimcf-server-control-draw-aux-data (mes) (let ((name (iiimp-message-aux-im-name mes)) (strs (iiimp-message-aux-string-list mes))) - (cond ((string-match "^jp\\.co\\.justsystem\\..*LookupAux$" + (cond ((or (string-match "^jp\\.co\\.justsystem\\..*LookupAux$" name) + (string-match "^jp\\.co\\.justsystem\\..*GenericAux$" + name)) (if strs (let ((i 1) (s (cdr strs)) diff -urN -x .svn -x '*~' im-sdk/iiimecf/lisp/iiimcf.el iiimecf/iiimecf/lisp/iiimcf.el --- im-sdk/iiimecf/lisp/iiimcf.el 2004-12-10 08:21:36.000000000 +0900 +++ iiimecf/iiimecf/lisp/iiimcf.el 2005-01-16 17:12:41.000000000 +0900 @@ -1100,9 +1100,9 @@ ;;; create/delete handles ;;; -(defun iiimcf-connect-com (host port) +(defun iiimcf-connect-com (proto host port) (let ((com-id - (iiimp-create-network-channel host port))) + (iiimp-create-network-channel proto host port))) (iiimcf-register-com-id com-id) com-id)) diff -urN -x .svn -x '*~' im-sdk/iiimecf/lisp/iiimp.el iiimecf/iiimecf/lisp/iiimp.el --- im-sdk/iiimecf/lisp/iiimp.el 2004-12-10 08:21:36.000000000 +0900 +++ iiimecf/iiimecf/lisp/iiimp.el 2005-01-16 18:08:03.000000000 +0900 @@ -68,6 +68,10 @@ (defvar iiimp-text-warning-char ?!) +(defvar iiimp-helper-path "udclient") + +(defvar iiimp-unixdomain-socket-path "/var/run/iiim/.iiimp-unix/") + (defconst iiimp-basic-opcode-spec-list '((iiimp-im-no-protocol 0 (nil . nil) @@ -301,15 +305,15 @@ ;; COM-ID := [<PROCESS> <BUFFER> <HOST> <PORT> <END-POINT>] -(defun iiimp-construct-com-id (proc buf host port) +(defun iiimp-construct-com-id (proc buf proto host port) (let ((obuf (current-buffer))) (if (eq obuf buf) (setq iiimp-current-com-id - (vector proc buf host port (point-min))) + (vector proc buf proto host port (point-min))) (prog2 (set-buffer buf) (setq iiimp-current-com-id - (vector proc buf host port (point-min))) + (vector proc buf proto host port (point-min))) (set-buffer obuf))))) (defsubst iiimp-com-id-process (com-id) @@ -318,17 +322,20 @@ (defsubst iiimp-com-id-buffer (com-id) (aref com-id 1)) -(defsubst iiimp-com-id-host (com-id) +(defsubst iiimp-com-id-proto (com-id) (aref com-id 2)) -(defsubst iiimp-com-id-port (com-id) +(defsubst iiimp-com-id-host (com-id) (aref com-id 3)) -(defsubst iiimp-com-id-end-point (com-id) +(defsubst iiimp-com-id-port (com-id) (aref com-id 4)) +(defsubst iiimp-com-id-end-point (com-id) + (aref com-id 5)) + (defsubst iiimp-record-end-point (com-id pt) - (aset com-id 4 pt) + (aset com-id 5 pt) com-id) ;; IM-ID := (id._NUMBER_of_IM COM-ID) @@ -360,8 +367,9 @@ ;;; network I/O (defsubst iiimp-check-channel-connection (com-id) - (eq (process-status (iiimp-com-id-process com-id)) 'open)) - + (or (eq (process-status (iiimp-com-id-process com-id)) 'open) + (eq (process-status (iiimp-com-id-process com-id)) 'run))) + (defun iiimp-proc-to-com-id (proc) (let ((oldbuf (current-buffer)) (nbuf (process-buffer proc))) @@ -381,7 +389,7 @@ (iiimp-disable-async-invocation com-id) (iiimp-connection-error "sentinel" com-id))))) -(defun iiimp-open-network-channel (host port buf) +(defun iiimp-open-network-channel (proto host port buf) (let ((coding-system-for-read nil) (coding-system-for-write nil) proc) @@ -391,7 +399,13 @@ (set-buffer-multibyte nil)) (buffer-disable-undo buf) (setq proc - (open-network-stream iiimp-process-name buf host port)) + (cond ((string= proto "unix") + (let ((process-connection-type nil)) + (start-process iiimp-process-name buf + iiimp-helper-path + (format "%s%d" iiimp-unixdomain-socket-path port) + ))) + (t (open-network-stream iiimp-process-name buf host port)))) (process-kill-without-query proc) (set-process-coding-system proc 'binary 'binary) (set-process-sentinel @@ -399,15 +413,16 @@ (set-marker-insertion-type (process-mark proc) t)) proc)) -(defun iiimp-create-network-channel (host port) +(defun iiimp-create-network-channel (proto host port) (let* ((buf (generate-new-buffer " *IIIMP*")) - (proc (iiimp-open-network-channel host port buf))) - (iiimp-construct-com-id proc buf host port))) + (proc (iiimp-open-network-channel proto host port buf))) + (iiimp-construct-com-id proc buf proto host port))) (defun iiimp-destroy-network-channel (com-id) (let* ((proc (iiimp-com-id-process com-id)) (stat (process-status proc))) - (while (not (or (eq stat 'closed) + (while (not (or (or (eq stat 'closed) + (eq stat 'exit)) (eq stat nil))) (set-process-sentinel proc nil) (delete-process proc) diff -urN -x .svn -x '*~' im-sdk/iiimecf/util/Makefile iiimecf/iiimecf/util/Makefile --- im-sdk/iiimecf/util/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ iiimecf/iiimecf/util/Makefile 2005-01-15 23:58:44.000000000 +0900 @@ -0,0 +1,22 @@ +TARGET=udclient +SOURCE=udclient.c +INCLUDE=udclient.h + +prefix=/usr/local + +INSTALL=install +MKDIR=install -d + +all: build + +build:$(TARGET) + +$(TARGET): $(SOURCE) $(INCLUDE) + gcc -o $(TARGET) $(SOURCE) + +install: + $(MKDIR) ${prefix}/bin + $(INSTALL) -m 555 $(TARGET) ${prefix}/bin/${TARGET} + +clean: + $(RM) $(TARGET) diff -urN -x .svn -x '*~' im-sdk/iiimecf/util/udclient.c iiimecf/iiimecf/util/udclient.c --- im-sdk/iiimecf/util/udclient.c 1970-01-01 09:00:00.000000000 +0900 +++ iiimecf/iiimecf/util/udclient.c 2005-01-15 23:58:44.000000000 +0900 @@ -0,0 +1,185 @@ +/* udclient.c + * VERSION: 0.5 + * AUTHOR: [email protected] + * DATE: 2005.01.15 + * + * repeater to communicate with unix domain socket + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/select.h> +#include <stdio.h> +#include <sys/un.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +#include "udclient.h" + +#define BFSZ (4096) /* buffer size */ + +#define COMMAND "udclient" +#define VERSION "0.5" + +/* + * data transport routin + */ +static ssize_t ud_transport(int in, int out) +{ + char* buf = NULL; /* data buffer */ + ssize_t len = BFSZ; /* data length */ + int count = -1; /* read count */ + + /* read input */ + while (len == BFSZ) { + count++; + /* allocate data buffer */ + if ((buf = (char*)realloc(buf, (count + 1) * BFSZ)) == NULL) { + perror("realloc"); + exit(1); + } + /* read input to data buffer */ + if ((len = read(in, buf + count * BFSZ, BFSZ)) < 0) { + perror("read"); + exit(1); + } + } + len += count * BFSZ; + /* write output */ + if (len > 0 && write(out, buf, len) < 0) { + perror("write"); + exit(1); + } + /* destroy data buffer */ + free(buf); + return len; +} + +/* unix domain client routine for SOCK_STREAM */ +int ud_cli(FILE *in, FILE *out, int sockfd) +{ + int maxfd, in_eof; + fd_set rset; + + in_eof = 0; + FD_ZERO(&rset); + for ( ; ; ) { + if (in_eof == 0) { + FD_SET(fileno(in), &rset); + } + FD_SET(sockfd, &rset); + maxfd = max(fileno(in), sockfd) + 1; + select(maxfd, &rset, NULL, NULL, NULL); + + if (FD_ISSET(sockfd, &rset)) { /*socket is readable */ + if (ud_transport(sockfd, fileno(out)) == 0) { + if (in_eof == 1) { /* normal termination */ + return 0; + } else { + perror("ud_cli: server terminated prematurely"); + exit(1); + } + } + } + if (FD_ISSET(fileno(in), &rset)) { /* stdin is readable */ + if (ud_transport(fileno(in), sockfd) == 0) { + in_eof = 1; + shutdown(sockfd, SHUT_WR); /* send FIN */ + FD_CLR(fileno(in), &rset); + } + } + } + + /* NOREACH */ + return 1; +} + +static void print_help(void) +{ + fprintf(stderr, "usage: " COMMAND " [-v|-h] path\n" + "\n" + "-h\t show this message.\n" + "-v\t print version.\n" + "\n" + "Communication with server through unix domain socket\n" + "specified by path argument.\n" + "Writtend by Hiroshi Miura <[email protected]>, Jan. 2005\n" + ); +} + +static int proc_opt(int argc, char *argv[]) +{ + int i = 1; + char c; + + if (argc < 2) + return 0; + + while (1) { + if ((c = getopt(argc, argv, "hv")) == -1) + break; + + switch (c) { + case 'h': + return 0; + case 'v': + fprintf(stderr, COMMAND ": Version " VERSION "\n"); + return -1; + default: + fprintf(stderr, "Error: unknown option(s).\n\n"); + return 0; + } + } + + if ( argc == i + 1 ) + return i; + + if ( argc > i + 1 ) { + fprintf(stderr, "Error: too many argument(s).\n\n"); + } else { + fprintf(stderr, "Error: socket pathname is needed.\n\n"); + } + return 0; +} + +int main(int argc, char *argv[]) +{ + int sockfd; + int pathname_i; + struct sockaddr_un svaddr; + FILE *in, *out; + int proto = SOCK_STREAM; + + if ((pathname_i = proc_opt(argc, argv)) <= 0) { + if (pathname_i == 0) + print_help(); + exit(1); + } + + in = stdin; out = stdout; + + /* create unix domain socket and connect server*/ + bzero(&svaddr, sizeof(svaddr)); + svaddr.sun_family = AF_LOCAL; + strncpy(svaddr.sun_path, argv[pathname_i], sizeof(svaddr.sun_path) - 1); + + if ((sockfd = socket(PF_LOCAL, proto, 0)) < 0) { + perror("socket"); + exit(1); + } + if (connect(sockfd, (struct sockaddr*)&svaddr, SUN_LEN(&svaddr)) < 0) { + perror("connect"); + close(sockfd); + exit(1); + } + + /* transport data */ + if (!ud_cli(in, out, sockfd)){ + close(sockfd); + exit(1); + } + + close(sockfd); + exit(0); +} diff -urN -x .svn -x '*~' im-sdk/iiimecf/util/udclient.h iiimecf/iiimecf/util/udclient.h --- im-sdk/iiimecf/util/udclient.h 1970-01-01 09:00:00.000000000 +0900 +++ iiimecf/iiimecf/util/udclient.h 2005-01-15 23:58:44.000000000 +0900 @@ -0,0 +1,23 @@ +#ifndef __UDCLIENT_H__ +#define __UDCLIENT_H__ + +int ud_conect(char* path); +int ud_cli(FILE *in, FILE *out, int sockfd); + +/* Posix.1g renames "Unix domain" as "local IPC". + But not all systems define AF_LOCAL and AF_LOCAL. */ +#ifndef AF_LOCAL +#define AF_LOCAL AF_UNIX +#endif +#ifndef PF_LOCAL +#define PF_LOCAL PF_UNIX +#endif +/* Posix.1g defines SHUT_* constants. + But not all systems define SHUT_* constants. */ +#ifndef SHUT_WR +#define SHUT_WR (1) +#endif + +#define max(a,b) ((a) > (b) ? (a) : (b)) + +#endif