]> git.lizzy.rs Git - plan9front.git/commitdiff
libc: restoring simple sequential version of dial()
authorcinap_lenrek <cinap_lenrek@rei2.9hal>
Tue, 10 Jan 2012 16:26:31 +0000 (17:26 +0100)
committercinap_lenrek <cinap_lenrek@rei2.9hal>
Tue, 10 Jan 2012 16:26:31 +0000 (17:26 +0100)
sys/src/libc/9sys/dial.c
sys/src/libthread/dial.c [deleted file]
sys/src/libthread/main.c
sys/src/libthread/mkfile

index 74fc6e6aee5cf99fd3463daca9566dc176c000db..41a1e329ebb2bc3155cb8f94c59a59a4a71c56c4 100644 (file)
@@ -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 @@ struct DS {
        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,224 +69,11 @@ dialimpl(char *dest, char *local, char *dir, int *cfdp)
        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;
-
-       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;
-       }
+       int n, fd, rv;
+       char *p, buf[Maxstring], clone[Maxpath], err[ERRMAX], besterr[ERRMAX];
 
        /*
         *  open connection server
@@ -334,10 +83,7 @@ csdial(DS *ds)
        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 @@ csdial(DS *ds)
        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,15 +142,14 @@ call(char *clone, char *dest, DS *ds, Dest *dp, Conn *conn)
                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;
 
        /* 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 @@ call(char *clone, char *dest, DS *ds, Dest *dp, Conn *conn)
        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 @@ call(char *clone, char *dest, DS *ds, Dest *dp, Conn *conn)
        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;
 }
 
diff --git a/sys/src/libthread/dial.c b/sys/src/libthread/dial.c
deleted file mode 100644 (file)
index d2ca013..0000000
+++ /dev/null
@@ -1,221 +0,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;
-       }
-}
index 72e3a8701e411e5cb4fd7787529aad9b8b670adf..1dcd9c3190da2f9952db53adc4c50f2c08c01947 100644 (file)
@@ -17,9 +17,6 @@ static jmp_buf _mainjmp;
 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;
 
@@ -38,7 +35,6 @@ main(int argc, char **argv)
        _systhreadinit();
        _qlockinit(_threadrendezvous);
        _sysfatal = _threadsysfatal;
-       _dial = _threaddial;
        __assert = _threadassert;
        notify(_threadnote);
        if(mainstacksize == 0)
index 9fe44cd50cc1e97b3f2e4f52278c06d68d43bf47..2869eedbe3e48eca7578eb81f9b9dd3350313bb1 100644 (file)
@@ -8,7 +8,6 @@ OFILES=\
        chanprint.$O\
        create.$O\
        debug.$O\
-       dial.$O\
        exec.$O\
        exit.$O\
        id.$O\