tvarious tweaks. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d51419bf4397cf13d0c50bf84c125477c6bed307
 (DIR) parent c1973705501d05e906bd14a0dc25cc4472b5871f
 (HTM) Author: rsc <devnull@localhost>
       Date:   Mon,  9 Feb 2004 19:33:05 +0000
       
       various tweaks.
       
       Diffstat:
         M LICENSE                             |       3 ++-
         M bin/9c                              |       1 +
         M bin/bundle                          |       8 ++++----
         A include/complete.h                  |      15 +++++++++++++++
         M src/lib9/dial.c                     |       5 +++++
         A src/libcomplete/complete.c          |     139 ++++++++++++++++++++++++++++++
         A src/libcomplete/mkfile              |      10 ++++++++++
         M src/libdraw/openfont.c              |       1 +
         M src/libthread/iocall.c              |       5 ++++-
         M src/libthread/iodial.c              |       7 +++++--
         M src/libthread/iowrite.c             |       7 ++++---
         M src/libthread/mkfile                |       2 ++
         M src/libthread/note.c                |       2 +-
       
       13 files changed, 193 insertions(+), 12 deletions(-)
       ---
 (DIR) diff --git a/LICENSE b/LICENSE
       t@@ -3,7 +3,8 @@ under the Lucent Public License, Version 1.02, reproduced below.
        
        There are a few exceptions: libutf, libfmt, and libregexp are distributed
        under simpler BSD-like boilerplates.  See the LICENSE files in those
       -directories.
       +directories.  There are other exceptions, also marked with LICENSE files
       +in their directories.
        
        The bitmap fonts in the font/lucida directory are copyright B&H Inc. and Y&Y Inc.
        and distributed under the following exception to the Lucent license:
 (DIR) diff --git a/bin/9c b/bin/9c
       t@@ -11,6 +11,7 @@ usegcc()
                        -Wno-parentheses \
                        -Wno-missing-braces \
                        -Wno-switch \
       +                -Wno-comment \
                        -Wno-sign-compare \
                "
        }
 (DIR) diff --git a/bin/bundle b/bin/bundle
       t@@ -2,8 +2,8 @@
        echo '# To unbundle, run this file'
        for i
        do
       -        echo 'echo '$i
       -        echo 'sed ''s/.//'' >'$i' <<''//GO.SYSIN DD '$i''''
       -        sed 's/^/-/' $i
       -        echo '//GO.SYSIN DD '$i
       +        echo "echo $i"
       +        echo "sed 's/.//' >$i <<'//GO.SYSIN DD $i'"
       +        sed "s/^/-/" $i
       +        echo "//GO.SYSIN DD $i"
        done
 (DIR) diff --git a/include/complete.h b/include/complete.h
       t@@ -0,0 +1,15 @@
       +#pragma        lib        "libcomplete.a"
       +#pragma src "/sys/src/libcomplete"
       +
       +typedef struct Completion Completion;
       +
       +struct Completion{
       +        uchar advance;                /* whether forward progress has been made */
       +        uchar complete;        /* whether the completion now represents a file or directory */
       +        char *string;                /* the string to advance, suffixed " " or "/" for file or directory */
       +        int nfile;                        /* number of files that matched */
       +        char **filename;        /* their names */
       +};
       +
       +Completion* complete(char *dir, char *s);
       +void freecompletion(Completion*);
 (DIR) diff --git a/src/lib9/dial.c b/src/lib9/dial.c
       t@@ -12,6 +12,7 @@
        
        #include <sys/socket.h>
        #include <netinet/in.h>
       +#include <netinet/tcp.h>
        #include <sys/un.h>
        #include <netdb.h>
        
       t@@ -68,6 +69,10 @@ p9dial(char *addr, char *dummy1, char *dummy2, int *dummy3)
                        close(s);
                        return -1;
                }
       +        if(proto == SOCK_STREAM){
       +                int one = 1;
       +                setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one);
       +        }
                return s;
        
        Unix:
 (DIR) diff --git a/src/libcomplete/complete.c b/src/libcomplete/complete.c
       t@@ -0,0 +1,139 @@
       +#include <u.h>
       +#include <libc.h>
       +#include "complete.h"
       +
       +static int
       +longestprefixlength(char *a, char *b, int n)
       +{
       +        int i, w;
       +        Rune ra, rb;
       +
       +        for(i=0; i<n; i+=w){
       +                w = chartorune(&ra, a);
       +                chartorune(&rb, b);
       +                if(ra != rb)
       +                        break;
       +                a += w;
       +                b += w;
       +        }
       +        return i;
       +}
       +
       +void
       +freecompletion(Completion *c)
       +{
       +        if(c){
       +                free(c->filename);
       +                free(c);
       +        }
       +}
       +
       +static int
       +strpcmp(const void *va, const void *vb)
       +{
       +        char *a, *b;
       +
       +        a = *(char**)va;
       +        b = *(char**)vb;
       +        return strcmp(a, b);
       +}
       +
       +Completion*
       +complete(char *dir, char *s)
       +{
       +        long i, l, n, nmatch, len, nbytes;
       +        int fd, minlen;
       +        Dir *dirp;
       +        char **name, *p;
       +        ulong* mode;
       +        Completion *c;
       +
       +        if(strchr(s, '/') != nil){
       +                werrstr("slash character in name argument to complete()");
       +                return nil;
       +        }
       +
       +        fd = open(dir, OREAD);
       +        if(fd < 0)
       +                return nil;
       +
       +        n = dirreadall(fd, &dirp);
       +        if(n <= 0)
       +                return nil;
       +
       +        /* find longest string, for allocation */
       +        len = 0;
       +        for(i=0; i<n; i++){
       +                l = strlen(dirp[i].name) + 1 + 1; /* +1 for /   +1 for \0 */
       +                if(l > len)
       +                        len = l;
       +        }
       +
       +        name = malloc(n*sizeof(char*));
       +        mode = malloc(n*sizeof(ulong));
       +        c = malloc(sizeof(Completion) + len);
       +        if(name == nil || mode == nil || c == nil)
       +                goto Return;
       +        memset(c, 0, sizeof(Completion));
       +
       +        /* find the matches */
       +        len = strlen(s);
       +        nmatch = 0;
       +        minlen = 1000000;
       +        for(i=0; i<n; i++)
       +                if(strncmp(s, dirp[i].name, len) == 0){
       +                        name[nmatch] = dirp[i].name;
       +                        mode[nmatch] = dirp[i].mode;
       +                        if(minlen > strlen(dirp[i].name))
       +                                minlen = strlen(dirp[i].name);
       +                        nmatch++;
       +                }
       +
       +        if(nmatch > 0) {
       +                /* report interesting results */
       +                /* trim length back to longest common initial string */
       +                for(i=1; i<nmatch; i++)
       +                        minlen = longestprefixlength(name[0], name[i], minlen);
       +
       +                /* build the answer */
       +                c->complete = (nmatch == 1);
       +                c->advance = c->complete || (minlen > len);
       +                c->string = (char*)(c+1);
       +                memmove(c->string, name[0]+len, minlen-len);
       +                if(c->complete)
       +                        c->string[minlen++ - len] = (mode[0]&DMDIR)? '/' : ' ';
       +                c->string[minlen - len] = '\0';
       +        } else {
       +                /* no match, so return all possible strings */
       +                for(i=0; i<n; i++){
       +                        name[i] = dirp[i].name;
       +                        mode[i] = dirp[i].mode;
       +                }
       +                nmatch = n;
       +        }
       +
       +        /* attach list of names */
       +        nbytes = nmatch * sizeof(char*);
       +        for(i=0; i<nmatch; i++)
       +                nbytes += strlen(name[i]) + 1 + 1;
       +        c->filename = malloc(nbytes);
       +        if(c->filename == nil)
       +                goto Return;
       +        p = (char*)(c->filename + nmatch);
       +        for(i=0; i<nmatch; i++){
       +                c->filename[i] = p;
       +                strcpy(p, name[i]);
       +                p += strlen(p);
       +                if(mode[i] & DMDIR)
       +                        *p++ = '/';
       +                *p++ = '\0';
       +        }
       +        c->nfile = nmatch;
       +        qsort(c->filename, c->nfile, sizeof(c->filename[0]), strpcmp);
       +
       +  Return:
       +        free(name);
       +        free(mode);
       +        free(dirp);
       +        return c;
       +}
 (DIR) diff --git a/src/libcomplete/mkfile b/src/libcomplete/mkfile
       t@@ -0,0 +1,10 @@
       +PLAN9=../..
       +<$PLAN9/src/mkhdr
       +
       +LIB=libcomplete.a
       +OFILES=\
       +        complete.$O\
       +
       +HFILES=$PLAN9/include/complete.h
       +
       +<$PLAN9/src/mksyslib
 (DIR) diff --git a/src/libdraw/openfont.c b/src/libdraw/openfont.c
       t@@ -19,6 +19,7 @@ openfont(Display *d, char *name)
                        if(nambuf == nil)
                                return 0;
                        if((fd = open(nambuf, OREAD)) < 0){
       +fprint(2, "failed at %s\n", nambuf);
                                free(nambuf);
                                return 0;
                        }
 (DIR) diff --git a/src/libthread/iocall.c b/src/libthread/iocall.c
       t@@ -3,6 +3,7 @@
        long
        iocall(Ioproc *io, long (*op)(va_list*), ...)
        {
       +        char e[ERRMAX];
                int ret, inted;
                Ioproc *msg;
        
       t@@ -39,11 +40,13 @@ iocall(Ioproc *io, long (*op)(va_list*), ...)
                va_end(io->arg);
                ret = io->ret;
                if(ret < 0)
       -                errstr(io->err, sizeof io->err);
       +                strecpy(e, e+sizeof e, io->err);
                io->inuse = 0;
        
                /* release resources */
                while(send(io->creply, &io) == -1)
                        ;
       +        if(ret < 0)
       +                errstr(e, sizeof e);
                return ret;
        }
 (DIR) diff --git a/src/libthread/iodial.c b/src/libthread/iodial.c
       t@@ -4,14 +4,17 @@ static long
        _iodial(va_list *arg)
        {
                char *addr, *local, *dir;
       -        int *cdfp;
       +        int *cdfp, fd;
        
                addr = va_arg(*arg, char*);
                local = va_arg(*arg, char*);
                dir = va_arg(*arg, char*);
                cdfp = va_arg(*arg, int*);
        
       -        return dial(addr, local, dir, cdfp);
       +fprint(2, "before dial\n");
       +        fd = dial(addr, local, dir, cdfp);
       +fprint(2, "after dial\n");
       +        return fd;
        }
        
        int
 (DIR) diff --git a/src/libthread/iowrite.c b/src/libthread/iowrite.c
       t@@ -5,13 +5,14 @@ _iowrite(va_list *arg)
        {
                int fd;
                void *a;
       -        long n;
       +        long n, nn;
        
                fd = va_arg(*arg, int);
                a = va_arg(*arg, void*);
                n = va_arg(*arg, long);
       -        n = write(fd, a, n);
       -        return n;
       +        nn = write(fd, a, n);
       +fprint(2, "_iowrite %d %d %r\n", n, nn);
       +        return nn;
        }
        
        long
 (DIR) diff --git a/src/libthread/mkfile b/src/libthread/mkfile
       t@@ -16,10 +16,12 @@ OFILES=\
                id.$O\
                iocall.$O\
                ioclose.$O\
       +        iodial.$O\
                ioopen.$O\
                ioproc.$O\
                ioread.$O\
                ioreadn.$O\
       +        iosleep.$O\
                iowrite.$O\
                kill.$O\
                lib.$O\
 (DIR) diff --git a/src/libthread/note.c b/src/libthread/note.c
       t@@ -92,7 +92,7 @@ _threadnote(void *v, char *s)
        //                _exits(_threadexitsallstatus);
        //        }
        
       -        if(strcmp(s, "threadint")==0)
       +        if(strcmp(s, "threadint")==0 || strcmp(s, "interrupt")==0)
                        noted(NCONT);
        
                p = _threadgetproc();