shithub: riscv

Download patch

ref: 62fb4f97177d8e76f1fd49bb9d0073007b7c9bcc
parent: 76918f348fbe29f0fc3a997106c644470023532e
author: cinap_lenrek <[email protected]>
date: Tue Jan 10 12:26:31 EST 2012

libc: restoring simple sequential version of dial()

--- a/sys/src/libc/9sys/dial.c
+++ b/sys/src/libc/9sys/dial.c
@@ -1,24 +1,16 @@
-/*
- * dial - connect to a service (parallel version)
- */
 #include <u.h>
 #include <libc.h>
 
-typedef struct Conn Conn;
-typedef struct Dest Dest;
 typedef struct DS DS;
 
+static int	call(char*, char*, DS*);
+static int	csdial(DS*);
+static void	_dial_string_parse(char*, DS*);
+
 enum
 {
 	Maxstring	= 128,
 	Maxpath		= 256,
-
-	Maxcsreply	= 64*80,	/* this is probably overly generous */
-	/*
-	 * this should be a plausible slight overestimate for non-interactive
-	 * use even if it's ridiculously long for interactive use.
-	 */
-	Maxconnms	= 20*60*1000,	/* 20 minutes */
 };
 
 struct DS {
@@ -34,42 +26,12 @@
 	int	*cfdp;
 };
 
-/*
- * malloc these; they need to be writable by this proc & all children.
- * the stack is private to each proc, and static allocation in the data
- * segment would not permit concurrent dials within a multi-process program.
- */
-struct Conn {
-	int	pid;
-	int	dead;
 
-	int	dfd;
-	int	cfd;
-	char	dir[NETPATHLEN];
-	char	err[ERRMAX];
-};
-struct Dest {
-	Conn	*conn;			/* allocated array */
-	Conn	*connend;
-	int	nkid;
-
-	QLock	winlck;
-	int	winner;			/* index into conn[] */
-
-	char	*nextaddr;
-	char	addrlist[Maxcsreply];
-};
-
-static int	call(char*, char*, DS*, Dest*, Conn*);
-static int	csdial(DS*);
-static void	_dial_string_parse(char*, DS*);
-
-
 /*
  *  the dialstring is of the form '[/net/]proto!dest'
  */
-static int
-dialimpl(char *dest, char *local, char *dir, int *cfdp)
+int
+dial(char *dest, char *local, char *dir, int *cfdp)
 {
 	DS ds;
 	int rv;
@@ -107,225 +69,12 @@
 	return rv;
 }
 
-/*
- * the thread library can't cope with rfork(RFMEM|RFPROC),
- * so it must override this with a private version of dial.
- */
-int (*_dial)(char *, char *, char *, int *) = dialimpl;
-
-int
-dial(char *dest, char *local, char *dir, int *cfdp)
-{
-	return (*_dial)(dest, local, dir, cfdp);
-}
-
 static int
-connsalloc(Dest *dp, int addrs)
-{
-	free(dp->conn);
-	dp->connend = nil;
-	assert(addrs > 0);
-
-	dp->conn = mallocz(addrs * sizeof *dp->conn, 1);
-	if(dp->conn == nil)
-		return -1;
-	dp->connend = dp->conn + addrs;
-	return 0;
-}
-
-static void
-freedest(Dest *dp)
-{
-	if (dp != nil) {
-		free(dp->conn);
-		free(dp);
-	}
-}
-
-static void
-closeopenfd(int *fdp)
-{
-	if (*fdp > 0) {
-		close(*fdp);
-		*fdp = -1;
-	}
-}
-
-static void
-notedeath(Dest *dp, char *exitsts)
-{
-	int i, n, pid;
-	char *fields[5];			/* pid + 3 times + error */
-	Conn *conn;
-
-	for (i = 0; i < nelem(fields); i++)
-		fields[i] = "";
-	n = tokenize(exitsts, fields, nelem(fields));
-	if (n < 4)
-		return;
-	pid = atoi(fields[0]);
-	if (pid <= 0)
-		return;
-	for (conn = dp->conn; conn < dp->connend; conn++)
-		if (conn->pid == pid && !conn->dead) {  /* it's one we know? */
-			if (conn - dp->conn != dp->winner) {
-				closeopenfd(&conn->dfd);
-				closeopenfd(&conn->cfd);
-			}
-			strncpy(conn->err, fields[4], sizeof conn->err);
-			conn->dead = 1;
-			return;
-		}
-	/* not a proc that we forked */
-}
-
-static int
-outstandingprocs(Dest *dp)
-{
-	Conn *conn;
-
-	for (conn = dp->conn; conn < dp->connend; conn++)
-		if (!conn->dead)
-			return 1;
-	return 0;
-}
-
-static int
-reap(Dest *dp)
-{
-	char exitsts[2*ERRMAX];
-
-	if (outstandingprocs(dp) && await(exitsts, sizeof exitsts) >= 0) {
-		notedeath(dp, exitsts);
-		return 0;
-	}
-	return -1;
-}
-
-static int
-fillinds(DS *ds, Dest *dp)
-{
-	Conn *conn;
-
-	if (dp->winner < 0)
-		return -1;
-	conn = &dp->conn[dp->winner];
-	if (ds->cfdp)
-		*ds->cfdp = conn->cfd;
-	if (ds->dir)
-		strncpy(ds->dir, conn->dir, NETPATHLEN);
-	return conn->dfd;
-}
-
-static int
-connectwait(Dest *dp, char *besterr)
-{
-	Conn *conn;
-
-	/* wait for a winner or all attempts to time out */
-	while (dp->winner < 0 && reap(dp) >= 0)
-		;
-
-	/* kill all of our still-live kids & reap them */
-	for (conn = dp->conn; conn < dp->connend; conn++)
-		if (!conn->dead)
-			postnote(PNPROC, conn->pid, "die");
-	while (reap(dp) >= 0)
-		;
-
-	/* rummage about and report some error string */
-	for (conn = dp->conn; conn < dp->connend; conn++)
-		if (conn - dp->conn != dp->winner && conn->dead &&
-		    conn->err[0]) {
-			strncpy(besterr, conn->err, ERRMAX);
-			break;
-		}
-	return dp->winner;
-}
-
-static int
-parsecs(Dest *dp, char **clonep, char **destp)
-{
-	char *dest, *p;
-
-	dest = strchr(dp->nextaddr, ' ');
-	if(dest == nil)
-		return -1;
-	*dest++ = '\0';
-	p = strchr(dest, '\n');
-	if(p == nil)
-		return -1;
-	*p++ = '\0';
-	*clonep = dp->nextaddr;
-	*destp = dest;
-	dp->nextaddr = p;		/* advance to next line */
-	return 0;
-}
-
-static void
-pickuperr(char *besterr, char *err)
-{
-	err[0] = '\0';
-	errstr(err, ERRMAX);
-	if(strstr(err, "does not exist") == 0)
-		strcpy(besterr, err);
-}
-
-/*
- * try all addresses in parallel and take the first one that answers;
- * this helps when systems have ip v4 and v6 addresses but are
- * only reachable from here on one (or some) of them.
- */
-static int
-dialmulti(DS *ds, Dest *dp)
-{
-	int rv, kid, kidme;
-	char *clone, *dest;
-	char err[ERRMAX], besterr[ERRMAX];
-
-	dp->winner = -1;
-	dp->nkid = 0;
-	while(dp->winner < 0 && *dp->nextaddr != '\0' &&
-	    parsecs(dp, &clone, &dest) >= 0) {
-		kidme = dp->nkid++;		/* make private copy on stack */
-		kid = rfork(RFPROC|RFMEM);	/* spin off a call attempt */
-		if (kid < 0)
-			--dp->nkid;
-		else if (kid == 0) {
-			alarm(Maxconnms);
-			*besterr = '\0';
-			rv = call(clone, dest, ds, dp, &dp->conn[kidme]);
-			if(rv < 0)
-				pickuperr(besterr, err);
-			_exits(besterr);	/* avoid atexit callbacks */
-		}
-	}
-	rv = connectwait(dp, besterr);
-	if(rv < 0 && *besterr)
-		werrstr("%s", besterr);
-	else
-		werrstr("%s", err);
-	return rv;
-}
-
-static int
 csdial(DS *ds)
 {
-	int n, fd, rv, addrs, bleft;
-	char c;
-	char *addrp, *clone2, *dest;
-	char buf[Maxstring], clone[Maxpath], err[ERRMAX], besterr[ERRMAX];
-	Dest *dp;
+	int n, fd, rv;
+	char *p, buf[Maxstring], clone[Maxpath], err[ERRMAX], besterr[ERRMAX];
 
-	dp = mallocz(sizeof *dp, 1);
-	if(dp == nil)
-		return -1;
-	dp->winner = -1;
-	if (connsalloc(dp, 1) < 0) {		/* room for a single conn. */
-		freedest(dp);
-		return -1;
-	}
-
 	/*
 	 *  open connection server
 	 */
@@ -334,10 +83,7 @@
 	if(fd < 0){
 		/* no connection server, don't translate */
 		snprint(clone, sizeof(clone), "%s/%s/clone", ds->netdir, ds->proto);
-		rv = call(clone, ds->rem, ds, dp, &dp->conn[0]);
-		fillinds(ds, dp);
-		freedest(dp);
-		return rv;
+		return call(clone, ds->rem, ds);
 	}
 
 	/*
@@ -346,57 +92,41 @@
 	snprint(buf, sizeof(buf), "%s!%s", ds->proto, ds->rem);
 	if(write(fd, buf, strlen(buf)) < 0){
 		close(fd);
-		freedest(dp);
 		return -1;
 	}
 
 	/*
-	 *  read all addresses from the connection server.
+	 *  loop through each address from the connection server till
+	 *  we get one that works.
 	 */
+	*besterr = 0;
+	rv = -1;
 	seek(fd, 0, 0);
-	addrs = 0;
-	addrp = dp->nextaddr = dp->addrlist;
-	bleft = sizeof dp->addrlist - 2;	/* 2 is room for \n\0 */
-	while(bleft > 0 && (n = read(fd, addrp, bleft)) > 0) {
-		if (addrp[n-1] != '\n')
-			addrp[n++] = '\n';
-		addrs++;
-		addrp += n;
-		bleft -= n;
+	while((n = read(fd, buf, sizeof(buf) - 1)) > 0){
+		buf[n] = 0;
+		p = strchr(buf, ' ');
+		if(p == 0)
+			continue;
+		*p++ = 0;
+		rv = call(buf, p, ds);
+		if(rv >= 0)
+			break;
+		err[0] = '\0';
+		errstr(err, sizeof err);
+		if(strstr(err, "does not exist") == 0)
+			strcpy(besterr, err);
 	}
-	/*
-	 * if we haven't read all of cs's output, assume the last line might
-	 * have been truncated and ignore it.  we really don't expect this
-	 * to happen.
-	 */
-	if (addrs > 0 && bleft <= 0 && read(fd, &c, 1) == 1)
-		addrs--;
 	close(fd);
 
-	*besterr = 0;
-	rv = -1;				/* pessimistic default */
-	if (addrs == 0)
-		werrstr("no address to dial");
-	else if (addrs == 1) {
-		/* common case: dial one address without forking */
-		if (parsecs(dp, &clone2, &dest) >= 0 &&
-		    (rv = call(clone2, dest, ds, dp, &dp->conn[0])) < 0) {
-			pickuperr(besterr, err);
-			werrstr("%s", besterr);
-		}
-	} else if (connsalloc(dp, addrs) >= 0)
-		rv = dialmulti(ds, dp);
-
-	/* fill in results */
-	if (rv >= 0 && dp->winner >= 0)
-		rv = fillinds(ds, dp);
-
-	freedest(dp);
+	if(rv < 0 && *besterr)
+		werrstr("%s", besterr);
+	else
+		werrstr("%s", err);
 	return rv;
 }
 
 static int
-call(char *clone, char *dest, DS *ds, Dest *dp, Conn *conn)
+call(char *clone, char *dest, DS *ds)
 {
 	int fd, cfd, n;
 	char cname[Maxpath], name[Maxpath], data[Maxpath], *p;
@@ -412,8 +142,7 @@
 		p = clone;
 	snprint(cname, sizeof cname, "%s/%s", ds->netdir, p);
 
-	conn->pid = getpid();
-	conn->cfd = cfd = open(cname, ORDWR);
+	cfd = open(cname, ORDWR);
 	if(cfd < 0)
 		return -1;
 
@@ -420,7 +149,7 @@
 	/* get directory name */
 	n = read(cfd, name, sizeof(name)-1);
 	if(n < 0){
-		closeopenfd(&conn->cfd);
+		close(cfd);
 		return -1;
 	}
 	name[n] = 0;
@@ -430,7 +159,7 @@
 	p = strrchr(cname, '/');
 	*p = 0;
 	if(ds->dir)
-		snprint(conn->dir, NETPATHLEN, "%s/%s", cname, name);
+		snprint(ds->dir, NETPATHLEN, "%s/%s", cname, name);
 	snprint(data, sizeof(data), "%s/%s/data", cname, name);
 
 	/* connect */
@@ -439,23 +168,20 @@
 	else
 		snprint(name, sizeof(name), "connect %s", dest);
 	if(write(cfd, name, strlen(name)) < 0){
-		closeopenfd(&conn->cfd);
+		close(cfd);
 		return -1;
 	}
 
 	/* open data connection */
-	conn->dfd = fd = open(data, ORDWR);
+	fd = open(data, ORDWR);
 	if(fd < 0){
-		closeopenfd(&conn->cfd);
+		close(cfd);
 		return -1;
 	}
-	if(ds->cfdp == nil)
-		closeopenfd(&conn->cfd);
-
-	qlock(&dp->winlck);
-	if (dp->winner < 0 && conn < dp->connend)
-		dp->winner = conn - dp->conn;
-	qunlock(&dp->winlck);
+	if(ds->cfdp)
+		*ds->cfdp = cfd;
+	else
+		close(cfd);
 	return fd;
 }
 
--- a/sys/src/libthread/dial.c
+++ /dev/null
@@ -1,221 +1,0 @@
-/*
- * old single-process version of dial that libthread can cope with
- */
-#include <u.h>
-#include <libc.h>
-
-typedef struct DS DS;
-
-static int	call(char*, char*, DS*);
-static int	csdial(DS*);
-static void	_dial_string_parse(char*, DS*);
-
-enum
-{
-	Maxstring	= 128,
-	Maxpath		= 256,
-};
-
-struct DS {
-	/* dist string */
-	char	buf[Maxstring];
-	char	*netdir;
-	char	*proto;
-	char	*rem;
-
-	/* other args */
-	char	*local;
-	char	*dir;
-	int	*cfdp;
-};
-
-
-/*
- *  the dialstring is of the form '[/net/]proto!dest'
- */
-int
-_threaddial(char *dest, char *local, char *dir, int *cfdp)
-{
-	DS ds;
-	int rv;
-	char err[ERRMAX], alterr[ERRMAX];
-
-	ds.local = local;
-	ds.dir = dir;
-	ds.cfdp = cfdp;
-
-	_dial_string_parse(dest, &ds);
-	if(ds.netdir)
-		return csdial(&ds);
-
-	ds.netdir = "/net";
-	rv = csdial(&ds);
-	if(rv >= 0)
-		return rv;
-	err[0] = '\0';
-	errstr(err, sizeof err);
-	if(strstr(err, "refused") != 0){
-		werrstr("%s", err);
-		return rv;
-	}
-	ds.netdir = "/net.alt";
-	rv = csdial(&ds);
-	if(rv >= 0)
-		return rv;
-
-	alterr[0] = 0;
-	errstr(alterr, sizeof alterr);
-	if(strstr(alterr, "translate") || strstr(alterr, "does not exist"))
-		werrstr("%s", err);
-	else
-		werrstr("%s", alterr);
-	return rv;
-}
-
-static int
-csdial(DS *ds)
-{
-	int n, fd, rv;
-	char *p, buf[Maxstring], clone[Maxpath], err[ERRMAX], besterr[ERRMAX];
-
-	/*
-	 *  open connection server
-	 */
-	snprint(buf, sizeof(buf), "%s/cs", ds->netdir);
-	fd = open(buf, ORDWR);
-	if(fd < 0){
-		/* no connection server, don't translate */
-		snprint(clone, sizeof(clone), "%s/%s/clone", ds->netdir, ds->proto);
-		return call(clone, ds->rem, ds);
-	}
-
-	/*
-	 *  ask connection server to translate
-	 */
-	snprint(buf, sizeof(buf), "%s!%s", ds->proto, ds->rem);
-	if(write(fd, buf, strlen(buf)) < 0){
-		close(fd);
-		return -1;
-	}
-
-	/*
-	 *  loop through each address from the connection server till
-	 *  we get one that works.
-	 */
-	*besterr = 0;
-	rv = -1;
-	seek(fd, 0, 0);
-	while((n = read(fd, buf, sizeof(buf) - 1)) > 0){
-		buf[n] = 0;
-		p = strchr(buf, ' ');
-		if(p == 0)
-			continue;
-		*p++ = 0;
-		rv = call(buf, p, ds);
-		if(rv >= 0)
-			break;
-		err[0] = '\0';
-		errstr(err, sizeof err);
-		if(strstr(err, "does not exist") == 0)
-			strcpy(besterr, err);
-	}
-	close(fd);
-
-	if(rv < 0 && *besterr)
-		werrstr("%s", besterr);
-	else
-		werrstr("%s", err);
-	return rv;
-}
-
-static int
-call(char *clone, char *dest, DS *ds)
-{
-	int fd, cfd, n;
-	char cname[Maxpath], name[Maxpath], data[Maxpath], *p;
-
-	/* because cs is in a different name space, replace the mount point */
-	if(*clone == '/'){
-		p = strchr(clone+1, '/');
-		if(p == nil)
-			p = clone;
-		else 
-			p++;
-	} else
-		p = clone;
-	snprint(cname, sizeof cname, "%s/%s", ds->netdir, p);
-
-	cfd = open(cname, ORDWR);
-	if(cfd < 0)
-		return -1;
-
-	/* get directory name */
-	n = read(cfd, name, sizeof(name)-1);
-	if(n < 0){
-		close(cfd);
-		return -1;
-	}
-	name[n] = 0;
-	for(p = name; *p == ' '; p++)
-		;
-	snprint(name, sizeof(name), "%ld", strtoul(p, 0, 0));
-	p = strrchr(cname, '/');
-	*p = 0;
-	if(ds->dir)
-		snprint(ds->dir, NETPATHLEN, "%s/%s", cname, name);
-	snprint(data, sizeof(data), "%s/%s/data", cname, name);
-
-	/* connect */
-	if(ds->local)
-		snprint(name, sizeof(name), "connect %s %s", dest, ds->local);
-	else
-		snprint(name, sizeof(name), "connect %s", dest);
-	if(write(cfd, name, strlen(name)) < 0){
-		close(cfd);
-		return -1;
-	}
-
-	/* open data connection */
-	fd = open(data, ORDWR);
-	if(fd < 0){
-		close(cfd);
-		return -1;
-	}
-	if(ds->cfdp)
-		*ds->cfdp = cfd;
-	else
-		close(cfd);
-	return fd;
-}
-
-/*
- *  parse a dial string
- */
-static void
-_dial_string_parse(char *str, DS *ds)
-{
-	char *p, *p2;
-
-	strncpy(ds->buf, str, Maxstring);
-	ds->buf[Maxstring-1] = 0;
-
-	p = strchr(ds->buf, '!');
-	if(p == 0) {
-		ds->netdir = 0;
-		ds->proto = "net";
-		ds->rem = ds->buf;
-	} else {
-		if(*ds->buf != '/' && *ds->buf != '#'){
-			ds->netdir = 0;
-			ds->proto = ds->buf;
-		} else {
-			for(p2 = p; *p2 != '/'; p2--)
-				;
-			*p2++ = 0;
-			ds->netdir = ds->buf;
-			ds->proto = p2;
-		}
-		*p = 0;
-		ds->rem = p + 1;
-	}
-}
--- a/sys/src/libthread/main.c
+++ b/sys/src/libthread/main.c
@@ -17,10 +17,7 @@
 static void mainlauncher(void*);
 extern void (*_sysfatal)(char*, va_list);
 extern void (*__assert)(char*);
-extern int (*_dial)(char*, char*, char*, int*);
 
-extern int _threaddial(char*, char*, char*, int*);
-
 static Proc **mainp;
 
 void
@@ -38,7 +35,6 @@
 	_systhreadinit();
 	_qlockinit(_threadrendezvous);
 	_sysfatal = _threadsysfatal;
-	_dial = _threaddial;
 	__assert = _threadassert;
 	notify(_threadnote);
 	if(mainstacksize == 0)
--- a/sys/src/libthread/mkfile
+++ b/sys/src/libthread/mkfile
@@ -8,7 +8,6 @@
 	chanprint.$O\
 	create.$O\
 	debug.$O\
-	dial.$O\
 	exec.$O\
 	exit.$O\
 	id.$O\