cudcv@daisy.warwick.ac.uk (Rob McMahon) (03/15/88)
<munch> 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. The second problem is if I change major mode in the buffer created in the server emacs, it calls kill-all-local-variables, which includes server-buffer-clients, which means C-x# doesn't work any more. I know I can usually end up in the right mode by tacking things onto auto-mode-alist, or by setting default-major-mode, but often I want to switch modes: I'm replying to someone's mail, and I want to include a bit of C, so I switch to c-mode for a while: I'm writing a C program and I want to insert a block comment, so I switch to text-mode for a while. Is there any way round this ? Can I protect server-buffer-clients for a while, or can I 'push' a mode and then exit it leaving all my variables the way they were before ? Or do I have to write my own alternatives to c-mode and text-mode (and tex-mode, and ...) that don't call kill-all-local-variables ? Thanks, Rob -- UUCP: ...!mcvax!ukc!warwick!cudcv PHONE: +44 203 523037 JANET: cudcv@uk.ac.warwick.cu ARPA: cudcv@cu.warwick.ac.uk Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England
pinkas@cadev4.intel.com (Israel Pinkas ~) (03/19/88)
In article <480@sol.warwick.ac.uk> cudcv@cu.warwick.ac.uk (Rob McMahon) writes: ><munch> > >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_<user>, where <user> 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
jbw@bucsb.UUCP (Joe Wells) (03/19/88)
In article <480@sol.warwick.ac.uk> cudcv@cu.warwick.ac.uk (Rob McMahon) writes: >The second problem is if I change major mode in the buffer created in >the server emacs, it calls kill-all-local-variables, which includes >server-buffer-clients, which means C-x# doesn't work any more. > >Is there any way round this ? Can I protect server-buffer-clients for a >while, or can I 'push' a mode and then exit it leaving all my variables >the way they were before ? Or do I have to write my own alternatives to >c-mode and text-mode (and tex-mode, and ...) that don't call >kill-all-local-variables ? > >UUCP: ...!mcvax!ukc!warwick!cudcv PHONE: +44 203 523037 >JANET: cudcv@uk.ac.warwick.cu ARPA: cudcv@cu.warwick.ac.uk >Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England I have run into this same problem in the past. My solution was to rewrite kill-all-local-variables so that it left my variables alone. This is not straightforward, since there is no function to kill a single local variable. kill-all-local-variables is one of the C functions, so my function had to use the original kill-all-local-variables, and then restore the variables that I wanted to keep. My version of kill-all-local-variables follows. ---- Joe Wells can be reached at: UUCP: ..!harvard!bu-cs!bucsb!jbw _ /| ARPANET: jbw@bucsb.bu.edu \`o_O' CSNET: jbw%bucsb@bu-cs ( ) "Ack! Phft!" BITNET: clxj9lc@bostonu U ;;; save the original kill-all-local-variables ;;; must check if we have already changed it (if (not (fboundp 'old-kill-all-local-variables)) (fset 'old-kill-all-local-variables (symbol-function 'kill-all-local-variables))) (defun kill-all-local-variables () "Eliminate all the buffer-local variable values of the current buffer. This buffer will then see the default values of all variables. NOTE: This function has been modified to ignore buffer-local variables which match the regexp in save-local-variables." (let ((oldvars (buffer-local-variables))) (old-kill-all-local-variables) (while oldvars (let* ((elem (car oldvars)) (var (car elem)) (value (cdr elem))) (cond ((string-match save-local-variables (symbol-name var)) (make-local-variable var) (set var value)))) (setq oldvars (cdr oldvars))))) (defvar save-local-variables "" "This is a regexp which is used each time kill-local-variables is called to determine which variables not to kill. The variable name is matched against the regexp.")
mike@turing.UNM.EDU (Michael I. Bushnell) (03/22/88)
In article <1894@mipos3.intel.com> pinkas@cadev4.UUCP (Israel Pinkas ~) writes: >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. The NFS spec does not dal with special files. Correct. But it does deal with sockets (in a strange way). Socket != Spec. file. My directory is on another machine. All my processes are on this one, and everything works fine. The emacsclient must be started on the same machine as the emacs itself. This will also prevent the creation of another .emacs_server from another client. The socket is actually created on the server, but the connect/accept/listen must all occur on the same machine. But NOT necessarily the server itself. The "solution" is thus not necessary. Michael I. Bushnell HASA - "A" division 14308 Skyline Rd NE Computer Science Dept. Albuquerque, NM 87123 OR Farris Engineering Ctr. OR University of New Mexico mike@turing.unm.edu Albuquerque, NM 87131 {ucbvax,gatech}!unmvax!turing.unm.edu!mike
cudcv@daisy.warwick.ac.uk (Rob McMahon) (04/03/88)
I did try to reply to this, but the mailer was having none of it ... In article <1894@mipos3.intel.com> pinkas@cadev4.UUCP (Israel Pinkas ~) writes: |[Re: problems with having the same socket name on multiple machines |when in and NFS environment] |I changed the name of the server file ... to /tmp/.emacs_server_<user>, Thanks for the patches, but: |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. |... |My reasoning [for moving the socket to /tmp] is that the /tmp directory |should be local. (... 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.) I'm confused. I sit here now on my diskless machine using emacsclient, emacs version 18.50, with no patches, and with the socket in my home directory, NFS mounted. All works fine. Maybe Sun have changed the NFS spec since the VAX version ? After all, I can't think of any good reason for it to fail, all it wants from the socket is it's mode and filehandle. Rob -- UUCP: ...!mcvax!ukc!warwick!cudcv PHONE: +44 203 523037 JANET: cudcv@uk.ac.warwick.cu ARPA: cudcv@cu.warwick.ac.uk Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England -- UUCP: ...!mcvax!ukc!warwick!cudcv PHONE: +44 203 523037 JANET: cudcv@uk.ac.warwick.cu ARPA: cudcv@cu.warwick.ac.uk Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England