From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lucio De Re To: 9fans mailing list <9fans@cse.psu.edu> Message-ID: <20030215174605.I9084@cackle.proxima.alt.za> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Subject: [9fans] Ugly hack Date: Sat, 15 Feb 2003 17:46:05 +0200 Topicbox-Message-UUID: 61e08442-eacb-11e9-9e20-41e7f4b1d025 An ugly hack to Tom Duff's little jewel, rc(1). I've found the ability to limit shell command line argument expansion (only in English can one write something so succintly and so ugly) to directories rather than all directory entries by suffixing the last part with a "/". This is normal behaviour in the NetBSD shells. For example: broken! lc mkfile rdesktop-1.1.0.tar trim openldap-2.0.22 rx-1.5 trim.c rdesktop-1.1.0 term.8 trim.out broken! cd rdesk* Usage: cd [directory] broken! echo rdesk* rdesktop-1.1.0 rdesktop-1.1.0.tar broken! cd rdesk*/ broken! pwd /usr/lucio/Projects/Sundry/rdesktop-1.1.0 broken! Note how the trailing slash allows me to supply the cd command with a single argument. I have hacked plan9.c, glob.c and fns.h in /sys/src/cmd/rc to achive this and I'd appreciate some feedback: is this useful to anyone else? Does it work properly (I have tested a few limit cases, but I'm not sure Ive covered all possibilities)? The patch is not vast, it largely required modifying the Readdir() function to be rearranged and I'd appreciate comments on possible improvements to my choice of coding. All comments (not flames) appreciated. I hope my sources for rc(1) are not too far out of date. term% diff plan9.c `{yesterday plan9.c} 321c321 < int Readdir(int f, char *p, int dironly) --- > int Readdir(int f, char *p) 326,345c326,334 < for (;;) { < if (dir[f].i==dir[f].n){ /* read */ < free(dir[f].dbuf); < dir[f].i=0; < dir[f].dbuf=0; < if ((n=dirread(f, &dir[f].dbuf)) <= 0){ < dir[f].n=0; < return 0; < } else < dir[f].n=n; < } < while(dir[f].i if(dir[f].i==dir[f].n){ /* read */ > free(dir[f].dbuf); > dir[f].dbuf=0; > n=dirread(f, &dir[f].dbuf); > if(n>=0) > dir[f].n=n; > else > dir[f].n=0; > dir[f].i=0; 347c336,340 < return 0; --- > if(dir[f].i==dir[f].n) > return 0; > strcpy(p, dir[f].dbuf[dir[f].i].name); > dir[f].i++; > return 1; term% diff glob.c `{yesterday glob.c} 37c37 < void globdir(char *p, char *namep, int dironly) --- > void globdir(char *p, char *namep) 64c64 < /* read the directory and recurse for any entry that matches */ --- > /* read the directory and recur for any entry that matches */ 68,69c68 < // print ("D: %s\n", dironly?"yes":"no"); < while(Readdir(f, namep, dironly)){ --- > while(Readdir(f, namep)){ 72c71 < globdir(newp, t, dironly); --- > globdir(newp, t); 84d82 < int dironly; 93,99c91 < dironly=strlen(p)-1; < // print ("G: '%s(%d)'\n", p, dironly); < if (dironly>0 && p[dironly]=='/'){ < dironly=1; < } else < dironly=0; < globdir(p, globname, dironly); --- > globdir(p, globname); term% diff fns.h `{yesterday fns.h} 16c16 < int Readdir(int, char*, int); --- > int Readdir(int, char*);