Path: utzoo!mnetor!uunet!husc6!bbn!mit-eddie!bloom-beacon!think!ames!oliveb!intelca!mipos3!cadev4!pinkas From: pinkas@cadev4.intel.com (Israel Pinkas ~) Newsgroups: comp.emacs Subject: Re: Changing major mode in server mode Message-ID: <1894@mipos3.intel.com> Date: 18 Mar 88 23:57:41 GMT References: <480@sol.warwick.ac.uk> Sender: nobody@mipos3.intel.com Reply-To: pinkas@cadev4.UUCP (Israel Pinkas ~) Organization: Corporate CAD, INTeL Corporation, Santa Clara, CA Lines: 195 In article <480@sol.warwick.ac.uk> cudcv@cu.warwick.ac.uk (Rob McMahon) writes: > > >I've just installed emacs 18.50, and have a couple of problems with M-x >server-start/emacsclient. > >The first is more a comment than a problem. In an NFS environment, you >can't have a server running on more than one machine, because each uses >the same rendezvous point, and each new invocation of the server removes >the socket the other machine had created. Maybe it should be using >something like ("%s/.emacsclient.%s", getenv("HOME"), gethostname()) ? >This isn't much of a problem for me, since I do most of the things I'd >want a server for on the same machine. I have this same problem. I sent some mail to the GNU people about a year ago, telling them what I had to do with GNU Emacs 17, but the changes never made it into v18. Anyway, here is the problem. The NFS spec does not provide for special files to be accessed across NFS. Thus, creating, reading, and writing a socket are not possible over NFS. In our environment, we have a large number of workstations mounting directories from a large VAX. Almost all the users home directories are mounted in this way. This means that ~/.emacs_server is not feasible to use unless emacs happens to be running on the file server, shich is not desirable. My solution was to change the three files that deal with the server/client. They are: etc/emacsclient.c, etc/server.c, and lisp/server.el. I changed the name of the server file in each of these to /tmp/.emacs_server_, where is the environment variable USER if available, the return value of getuid() otherwise. My reasoning is that the /tmp directory should be local. (We run X on all of our workstations, and X10 puts a socket file in /tmp. I figured that if /tmp is not local, we have bigger problems than emacs servers not running.) Diskless nodes should be OK as they do not mount / via NFS. (This is not tested, though.) Following are the diffs I put into 18.49. When I get 18.50, I will look into what problems might be caused on sysV (which I understand iis supported, but we have some nodes running NFS also). Note that you may still only have one emacs server per user per machine. Thus, if you have a group account, and two users run emacs, the second one to start the server will receive all subsequent requests. Other things might be messed up. Since this was a limitation in the original code, I don't mind this. And I am wary. The reason that I didn't do anything about this is that I couldn't figure out how to make the clients know which server to talk to. A possibility for resolving this could be: If under X, encode $DISPLAY in the server filename. All clients on that window would get the same server. Since I don't anticipate two users on the same window in the same account not being able to use the same emacs, this should work. Something similar could be done for Suns and other windowing systems. Otherwise, we must be running the server on the same terminal as the client. (I don't know what to do in the case of layers/emacs terminal emulation. Suggestions welcome.) Place the name of the terminal in the server filename. For ptys (layers, terminal-mode) the terminal name of the real terminal might be used. -Israel Cut here and make sure that Pnews did not add a .signature below ------------------------------------------------------------------ *** lisp/server.el.orig Sun Feb 21 13:00:39 1988 --- lisp/server.el Fri Mar 18 15:23:31 1988 *************** *** 108,114 (progn (set-process-sentinel server-process nil) (condition-case () (delete-process server-process) (error nil)))) ! (condition-case () (delete-file "~/.emacs_server") (error nil)) ;; If we already had a server, clear out associated status. (while server-clients (let ((buffer (nth 1 (car server-clients)))) --- 108,114 ----- (progn (set-process-sentinel server-process nil) (condition-case () (delete-process server-process) (error nil)))) ! (condition-case () (delete-file "/tmp/.emacs_server_$USER") (error nil)) ;; If we already had a server, clear out associated status. (while server-clients (let ((buffer (nth 1 (car server-clients)))) *** etc/server.c.orig Thu Feb 25 10:56:33 1988 --- etc/server.c Fri Mar 18 15:19:00 1988 *************** *** 55,61 { int s, infd, fromlen; struct sockaddr_un server, fromunix; ! char *homedir; char *str, string[BUFSIZ], code[BUFSIZ]; FILE *infile; FILE **openfiles; --- 55,61 ----- { int s, infd, fromlen; struct sockaddr_un server, fromunix; ! char *username; char *str, string[BUFSIZ], code[BUFSIZ]; FILE *infile; FILE **openfiles; *************** *** 78,90 exit (1); } server.sun_family = AF_UNIX; ! if ((homedir = getenv ("HOME")) == NULL) ! { ! fprintf (stderr,"No home directory\n"); ! exit (1); ! } ! strcpy (server.sun_path, homedir); ! strcat (server.sun_path, "/.emacs_server"); if (bind (s, &server, strlen (server.sun_path) + 2) < 0) { perror ("bind"); --- 78,87 ----- exit (1); } server.sun_family = AF_UNIX; ! if ((username = getenv ("USER")) == NULL) ! sprintf(server.sun_path, "/tmp/.emacs_server_%d", getuid()); ! else ! sprintf(server.sun_path, "/tmp/.emacs_server_%s", username); if (bind (s, &server, strlen (server.sun_path) + 2) < 0) { perror ("bind"); *** etc/emacsclient.c.orig Fri Mar 18 15:06:56 1988 --- etc/emacsclient.c Fri Mar 18 15:20:34 1988 *************** *** 48,54 int s, n, i; FILE *out; struct sockaddr_un server; ! char *homedir, *cwd, *str; char string[BUFSIZ]; char *getenv (), *getwd (); --- 48,54 ----- int s, n, i; FILE *out; struct sockaddr_un server; ! char *username, *cwd, *str; char string[BUFSIZ]; char *getenv (), *getwd (); *************** *** 69,81 exit (1); } server.sun_family = AF_UNIX; ! if ((homedir = getenv ("HOME")) == NULL) ! { ! fprintf (stderr, "No home directory\n"); ! exit (1); ! } ! strcpy (server.sun_path, homedir); ! strcat (server.sun_path, "/.emacs_server"); if (connect (s, &server, strlen (server.sun_path) + 2) < 0) { perror ("connect"); --- 69,78 ----- exit (1); } server.sun_family = AF_UNIX; ! if ((username = getenv ("USER")) == NULL) ! sprintf(server.sun_path, "/tmp/.emacs_server_%d", getuid()); ! else ! sprintf(server.sun_path, "/tmp/.emacs_server_%s", username); if (connect (s, &server, strlen (server.sun_path) + 2) < 0) { perror ("connect"); ---------------------------------------------------------------------- Disclaimer: The above are my personal opinions, and in no way represent the opinions of Intel Corporation. In no way should the above be taken to be a statement of Intel. UUCP: {amdcad,decwrl,hplabs,oliveb,pur-ee,qantel}!intelca!mipos3!cadev4!pinkas ARPA: pinkas%cadev4.intel.com@relay.cs.net CSNET: pinkas%cadev4.intel.com --------- "You can do more with a kind word and a gun than with just a kind word" -Al Capone