[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‚ª
-  Žg—p‚³‚ê‚Ü‚·B‚±‚̕ϐ”‚Ì’l‚Ìdefault‚́A9010‚Å‚·B
+   ‚È‚¨A<PORT>‚ðÈ—ª‚µ‚½ê‡Aiiimcf-server-control-default-port‚ª
+  Žg—p‚³‚ê‚Ü‚·B‚±‚̕ϐ”‚Ì’l‚Ìdefault‚́A9010‚Å‚·B‚Ü‚½A<PROTO>‚ð
+  È—ª‚µ‚½ê‡Aiiimcf-server-control-default-protocol‚ªŽg—p‚³‚ê‚Ü‚·B
+  ‚±‚̕ϐ”‚Ì’l‚Ìdefault‚́Atcp‚Å‚·B
+
+  "unix/:9010"‚ðŽw’肵‚½ê‡‚́Aunix domain socket Œo—R‚ł̐ڑ±‚ðŽŽ‚Ý‚Ü‚·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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.