Jan Vroonhof <vroonhof(a)math.ethz.ch> writes:
"Greg J. Badros" <gjb(a)cs.washington.edu> writes:
> I'm trying to get multiple gnuserv processes running on the same machine
> at different ports so that I can selectively connect to a specific one.
I just helped somebody with exactly the same problems... You even
thought of the same solution...
> My attempt to make this work has been to set GNU_PORT to a distinguished
> number before starting the XEmacs processes. Then I was hoping to be able
> to use, e.g.,
>
> gnuclient -p 21033
>
> [Discovered that you need -h to force internet sockets]
>
> [patch proposed to disable "-nw" check which incompatible with -h]
I instead propose the patch appended at the end of this message. That
should make just specifying "-p" work. It is untested but "obvious".
Could you try this out? (the "-nw" check should also check that
hostname != unix, but I didn't to that)
Ahhh, yes, the "obvious" patch. :-)
Unfortunately, it'll segfault when doing the strcmp on the NULL argument
when hostarg is NULL, but portarg is specified. You minimally need
something else like:
if (!hostarg)
hostarg = getenv("HOST");
After the one-line change below. (It might be better to use
gethostname(2) ).
With that above change, your patch works for me (but see mine, below).
> any) of this suggestion, but it seems likely that mangling the
UID +
> some user-specified number would be a nice way to provide this
> capability in a fairly clean way.
There already is a UID in the name of the directory where the named
pipe resides. I intend to allow a second name pipe in that dir that
depends on the Emacs PID. That should allow multiple gnuservs with
Unix domain type connections.
This would be nice, but not quite perfect as figuring out the PID of the
gnuserv processes is more troublesome than it needs to be (imagine the
script that starts the XEmacs running the gnus-process).
I've a slightly different approach that uses $GNUSERV_ID if that's in
the environment instead of the PID. See patches below. With them, I
can do:
GNUSERV_ID=0 xemacs -f gnus &
GNUSERV_ID=1 xemacs dissertation.tex &
# my .emacs does gnuserv-start
and then:
gnuclient -P 0 -nw # connects to the XEmacs w/ gnus running
gnuclient -P 1 -nw # connects to the XEmacs w/ dissertation.tex
Note that I use numbers instead of an arbitrary string to avoid any
possible issues with strange filenames, etc. My apologies for not
patching the documentation.
Greg J. Badros
gjb(a)cs.washington.edu
Seattle, WA USA
http://www.cs.washington.edu/homes/gjb
Wed Mar 8 09:30:07 2000 Greg J. Badros <gjb(a)cs.washington.edu>
* gnuserv.c, gnuslib.c, gnuclient.c: Added extra gnuservid
argument to make_connection, and let new [-P number] argument
set the gnuservid. Use the gnuservid as the XXX suffix to the
/tmp/gsrvdir???/gsrvXXX filename. This permits multiple gnuserv
processes to coexist, and lets `gnuclient -P XXX' selectively
connect to a specific one. Make gnuserv use $GNUSERV_ID
environment variable to pick the XXX of the filename, or use the
pid, otherwise.
--- gnuclient.c 2000/03/08 17:23:43 1.1
+++ gnuclient.c 2000/03/08 17:24:58
@@ -76,6 +76,7 @@
static char *cp = NULL; /* ptr into valid bit of cwd above */
static pid_t emacs_pid; /* Process id for emacs process */
+static int gnuservid = 0; /* gnuserv id of server process to connect */
void initialize_signals (void);
@@ -91,7 +92,7 @@
/* We want emacs to realize that we are resuming */
signal(SIGCONT, tell_emacs_to_resume);
- connect_type = make_connection (NULL, (u_short) 0, &s);
+ connect_type = make_connection (NULL, (u_short) 0, gnuservid, &s);
sprintf(buffer,"(gnuserv-eval '(resume-pid-console %d))",
(int)getpid());
send_string(s, buffer);
@@ -323,6 +324,7 @@
char *path;
int rflg = 0; /* pathname given on cmdline */
char *portarg;
+ char *gnuservidarg;
u_short port = 0; /* port to server */
#endif /* INTERNET_DOMAIN_SOCKETS */
#ifdef SYSV_IPC
@@ -428,6 +430,10 @@
GET_ARGUMENT (portarg, "-p");
port = atoi (portarg);
break;
+ case 'P':
+ GET_ARGUMENT (gnuservidarg, "-P");
+ gnuservid = atoi (gnuservidarg);
+ break;
case 'r':
GET_ARGUMENT (remotearg, "-r");
strcpy (remotepath, remotearg);
@@ -447,7 +453,7 @@
#ifdef INTERNET_DOMAIN_SOCKETS
"usage: %s [-nw] [-display display] [-q] [-v] [-l library]\n"
" [-batch] [-f function] [-eval form]\n"
- " [-h host] [-p port] [-r remote-path] [[+line] file] ...\n",
+ " [-h host] [-p port] [-P gnuservid] [-r remote-path] [[+line] file]
...\n",
#else /* !INTERNET_DOMAIN_SOCKETS */
"usage: %s [-nw] [-q] [-v] [-l library] [-f function] [-eval form] "
"[[+line] path] ...\n",
@@ -472,9 +478,9 @@
if (eval_function || eval_form || load_library)
{
#if defined(INTERNET_DOMAIN_SOCKETS)
- connect_type = make_connection (hostarg, port, &s);
+ connect_type = make_connection (hostarg, port, gnuservid, &s);
#else
- connect_type = make_connection (NULL, (u_short) 0, &s);
+ connect_type = make_connection (NULL, (u_short) 0, gnuservid, &s);
#endif
sprintf (command, "(gnuserv-eval%s '(progn ", quick ?
"-quickly" : "");
send_string (s, command);
@@ -510,9 +516,9 @@
int nb;
#if defined(INTERNET_DOMAIN_SOCKETS)
- connect_type = make_connection (hostarg, port, &s);
+ connect_type = make_connection (hostarg, port, gnuservid, &s);
#else
- connect_type = make_connection (NULL, (u_short) 0, &s);
+ connect_type = make_connection (NULL, (u_short) 0, gnuservid, &s);
#endif
sprintf (command, "(gnuserv-eval%s '(progn ", quick ?
"-quickly" : "");
send_string (s, command);
@@ -544,9 +550,9 @@
exit (1);
}
#if defined(INTERNET_DOMAIN_SOCKETS)
- connect_type = make_connection (hostarg, port, &s);
+ connect_type = make_connection (hostarg, port, gnuservid, &s);
#else
- connect_type = make_connection (NULL, (u_short) 0, &s);
+ connect_type = make_connection (NULL, (u_short) 0, gnuservid, &s);
#endif
send_string (s, "(gnuserv-eval '(emacs-pid))");
send_string (s, EOT_STR);
@@ -569,9 +575,9 @@
} /* suppress_windows_system */
#if defined(INTERNET_DOMAIN_SOCKETS)
- connect_type = make_connection (hostarg, port, &s);
+ connect_type = make_connection (hostarg, port, gnuservid, &s);
#else
- connect_type = make_connection (NULL, (u_short) 0, &s);
+ connect_type = make_connection (NULL, (u_short) 0, gnuservid, &s);
#endif
#ifdef INTERNET_DOMAIN_SOCKETS
--- gnuserv.c 2000/03/08 16:21:55 1.1
+++ gnuserv.c 2000/03/08 17:04:41
@@ -743,7 +743,8 @@
/* Set up address structure for the listen socket. */
#ifdef HIDE_UNIX_SOCKET
- sprintf(server.sun_path,"%s/gsrvdir%d",tmpdir,(int)geteuid());
+ sprintf(server.sun_path,"%s/gsrvdir%d",
+ tmpdir,(int)geteuid());
if (mkdir(server.sun_path, 0700) < 0)
{
/* assume it already exists, and try to set perms */
@@ -755,7 +756,15 @@
exit(1);
}
}
+ { /* scope */
+ char *szId = getenv("GNUSERV_ID");
+ int gnuservid;
+ if (szId) gnuservid = atoi(szId);
+ else gnuservid = getpid();
strcat(server.sun_path,"/gsrv");
+ sprintf(server.sun_path+strlen(server.sun_path),
+ "%d",gnuservid);
+ } /* end scope */
unlink(server.sun_path); /* remove old file if it exists */
#else /* HIDE_UNIX_SOCKET */
sprintf(server.sun_path,"%s/gsrv%d",tmpdir,(int)geteuid());
--- gnuslib.c 2000/03/08 17:36:51 1.1
+++ gnuslib.c 2000/03/08 17:36:58
@@ -40,7 +40,7 @@
static int connect_to_ipc_server (void);
#endif
#ifdef UNIX_DOMAIN_SOCKETS
-static int connect_to_unix_server (void);
+static int connect_to_unix_server (int gnuservid);
#endif
#ifdef INTERNET_DOMAIN_SOCKETS
static int connect_to_internet_server (char *serverhost, u_short port);
@@ -76,9 +76,10 @@
char *progname = NULL;
-int make_connection(hostarg, portarg, s)
+int make_connection(hostarg, portarg, gnuservid, s)
char *hostarg;
int portarg;
+ int gnuservid;
int *s;
{
#ifdef INTERNET_DOMAIN_SOCKETS
@@ -89,12 +90,14 @@
portarg = atoi(ptr);
#endif
- if (hostarg != NULL) {
+ if (hostarg != NULL || portarg) {
+ if (!hostarg)
+ hostarg = getenv("HOST");
/* hostname was given explicitly, via cmd line arg or GNU_HOST,
* so obey it. */
#ifdef UNIX_DOMAIN_SOCKETS
if (!strcmp(hostarg, "unix")) {
- *s = connect_to_unix_server();
+ *s = connect_to_unix_server(gnuservid);
return (int) CONN_UNIX;
}
#endif /* UNIX_DOMAIN_SOCKETS */
@@ -109,7 +112,7 @@
/* no hostname given. Use unix-domain/sysv-ipc, or
* internet-domain connection to local host if they're not available. */
#if defined(UNIX_DOMAIN_SOCKETS)
- *s = connect_to_unix_server();
+ *s = connect_to_unix_server(gnuservid);
return (int) CONN_UNIX;
#elif defined(SYSV_IPC)
*s = connect_to_ipc_server();
@@ -252,7 +255,7 @@
domain socket. Returns socket descriptor for server
if successful.
*/
-static int connect_to_unix_server (void)
+static int connect_to_unix_server (int gnuservid)
{
int s; /* connected socket descriptor */
struct sockaddr_un server; /* for unix connections */
@@ -265,7 +268,8 @@
server.sun_family = AF_UNIX;
#ifdef HIDE_UNIX_SOCKET
- sprintf(server.sun_path,"%s/gsrvdir%d/gsrv",tmpdir,(int)geteuid());
+ sprintf(server.sun_path,"%s/gsrvdir%d/gsrv%d",
+ tmpdir,(int)geteuid(),gnuservid);
#else /* HIDE_UNIX_SOCKET */
sprintf(server.sun_path,"%s/gsrv%d",tmpdir,(int)geteuid());
#endif /* HIDE_UNIX_SOCKET */