summaryrefslogtreecommitdiffstats
path: root/contrib/tcsh/sh.file.c
diff options
context:
space:
mode:
authormp <mp@FreeBSD.org>2007-03-11 22:33:41 +0000
committermp <mp@FreeBSD.org>2007-03-11 22:33:41 +0000
commita40980339b13e3b506c2317b5b4864127039eb2c (patch)
tree34aefea92d30b614247ef1f2671f2362f4761785 /contrib/tcsh/sh.file.c
parent32837fb336d4709f0a121130a3a78f29be0db5ed (diff)
downloadFreeBSD-src-a40980339b13e3b506c2317b5b4864127039eb2c.zip
FreeBSD-src-a40980339b13e3b506c2317b5b4864127039eb2c.tar.gz
Import of tcsh-6.15.00
Diffstat (limited to 'contrib/tcsh/sh.file.c')
-rw-r--r--contrib/tcsh/sh.file.c408
1 files changed, 155 insertions, 253 deletions
diff --git a/contrib/tcsh/sh.file.c b/contrib/tcsh/sh.file.c
index 2412197..6955358 100644
--- a/contrib/tcsh/sh.file.c
+++ b/contrib/tcsh/sh.file.c
@@ -1,4 +1,4 @@
-/* $Header: /src/pub/tcsh/sh.file.c,v 3.28 2005/01/05 16:06:13 christos Exp $ */
+/* $Header: /p/tcsh/cvsroot/tcsh/sh.file.c,v 3.35 2006/08/23 15:03:14 christos Exp $ */
/*
* sh.file.c: File completion for csh. This file is not used in tcsh.
*/
@@ -33,7 +33,7 @@
#include "sh.h"
#include "ed.h"
-RCSID("$Id: sh.file.c,v 3.28 2005/01/05 16:06:13 christos Exp $")
+RCSID("$tcsh: sh.file.c,v 3.35 2006/08/23 15:03:14 christos Exp $")
#if defined(FILEC) && defined(TIOCSTI)
@@ -59,26 +59,23 @@ typedef enum {
LIST, RECOGNIZE
} COMMAND;
-static void setup_tty __P((int));
-static void back_to_col_1 __P((void));
-static void pushback __P((Char *));
-static void catn __P((Char *, Char *, int));
-static void copyn __P((Char *, Char *, int));
-static int filetype __P((Char *, Char *));
-static void print_by_column __P((Char *, Char *[], size_t));
-static Char *tilde __P((Char *, Char *));
-static void retype __P((void));
-static void beep __P((void));
-static void print_recognized_stuff __P((Char *));
-static void extract_dir_and_name __P((Char *, Char *, Char *));
-static Char *getitem __P((DIR *, int));
-static void free_items __P((Char **, size_t));
-static int tsearch __P((Char *, COMMAND, int));
-static int compare __P((const ptr_t, const ptr_t));
-static int recognize __P((Char *, Char *, int, size_t));
-static int is_prefix __P((Char *, Char *));
-static int is_suffix __P((Char *, Char *));
-static int ignored __P((Char *));
+static void setup_tty (int);
+static void back_to_col_1 (void);
+static void pushback (const Char *);
+static int filetype (const Char *, const Char *);
+static void print_by_column (const Char *, Char *[], size_t);
+static Char *tilde (const Char *);
+static void retype (void);
+static void beep (void);
+static void print_recognized_stuff (const Char *);
+static void extract_dir_and_name (const Char *, Char **, const Char **);
+static Char *getitem (DIR *, int);
+static size_t tsearch (Char *, COMMAND, size_t);
+static int compare (const void *, const void *);
+static int recognize (Char **, Char *, size_t, size_t);
+static int is_prefix (const Char *, const Char *);
+static int is_suffix (const Char *, const Char *);
+static int ignored (const Char *);
/*
@@ -89,8 +86,7 @@ static int ignored __P((Char *));
int filec = 0;
static void
-setup_tty(on)
- int on;
+setup_tty(int on)
{
#ifdef TERMIO
# ifdef POSIX
@@ -131,7 +127,7 @@ setup_tty(on)
# endif /* POSIX */
}
# ifdef POSIX
- (void) tcsetattr(SHIN, on, &tchars);
+ (void) xtcsetattr(SHIN, on, &tchars);
# else
(void) ioctl(SHIN, on, (ioctl_t) &tchars);
# endif /* POSIX */
@@ -164,7 +160,7 @@ setup_tty(on)
* Move back to beginning of current line
*/
static void
-back_to_col_1()
+back_to_col_1(void)
{
#ifdef TERMIO
# ifdef POSIX
@@ -176,11 +172,8 @@ back_to_col_1()
struct sgttyb tty, tty_normal;
#endif /* TERMIO */
-# ifdef BSDSIGS
- sigmask_t omask = sigblock(sigmask(SIGINT));
-# else
- (void) sighold(SIGINT);
-# endif /* BSDSIGS */
+ pintr_disabled++;
+ cleanup_push(&pintr_disabled, disabled_cleanup);
#ifdef TERMIO
# ifdef POSIX
@@ -192,13 +185,13 @@ back_to_col_1()
tty.c_iflag &= ~INLCR;
tty.c_oflag &= ~ONLCR;
# ifdef POSIX
- (void) tcsetattr(SHOUT, TCSANOW, &tty);
+ (void) xtcsetattr(SHOUT, TCSANOW, &tty);
# else
(void) ioctl(SHOUT, TCSETAW, (ioctl_t) &tty);
# endif /* POSIX */
- (void) write(SHOUT, "\r", 1);
+ (void) xwrite(SHOUT, "\r", 1);
# ifdef POSIX
- (void) tcsetattr(SHOUT, TCSANOW, &tty_normal);
+ (void) xtcsetattr(SHOUT, TCSANOW, &tty_normal);
# else
(void) ioctl(SHOUT, TCSETAW, (ioctl_t) &tty_normal);
# endif /* POSIX */
@@ -207,25 +200,20 @@ back_to_col_1()
tty_normal = tty;
tty.sg_flags &= ~CRMOD;
(void) ioctl(SHIN, TIOCSETN, (ioctl_t) & tty);
- (void) write(SHOUT, "\r", 1);
+ (void) xwrite(SHOUT, "\r", 1);
(void) ioctl(SHIN, TIOCSETN, (ioctl_t) & tty_normal);
#endif /* TERMIO */
-# ifdef BSDSIGS
- (void) sigsetmask(omask);
-# else
- (void) sigrelse(SIGINT);
-# endif /* BSDISGS */
+ cleanup_until(&pintr_disabled);
}
/*
* Push string contents back into tty queue
*/
static void
-pushback(string)
- Char *string;
+pushback(const Char *string)
{
- Char *p;
+ const Char *p;
#ifdef TERMIO
# ifdef POSIX
struct termios tty, tty_normal;
@@ -236,11 +224,8 @@ pushback(string)
struct sgttyb tty, tty_normal;
#endif /* TERMIO */
-#ifdef BSDSIGS
- sigmask_t omask = sigblock(sigmask(SIGINT));
-#else
- (void) sighold(SIGINT);
-#endif /* BSDSIGS */
+ pintr_disabled++;
+ cleanup_push(&pintr_disabled, disabled_cleanup);
#ifdef TERMIO
# ifdef POSIX
@@ -251,7 +236,7 @@ pushback(string)
tty_normal = tty;
tty.c_lflag &= ~(ECHOKE | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOCTL);
# ifdef POSIX
- (void) tcsetattr(SHOUT, TCSANOW, &tty);
+ (void) xtcsetattr(SHOUT, TCSANOW, &tty);
# else
(void) ioctl(SHOUT, TCSETAW, (ioctl_t) &tty);
# endif /* POSIX */
@@ -265,7 +250,7 @@ pushback(string)
(void) ioctl(SHOUT, TIOCSTI, (ioctl_t) &buf[i]);
}
# ifdef POSIX
- (void) tcsetattr(SHOUT, TCSANOW, &tty_normal);
+ (void) xtcsetattr(SHOUT, TCSANOW, &tty_normal);
# else
(void) ioctl(SHOUT, TCSETAW, (ioctl_t) &tty_normal);
# endif /* POSIX */
@@ -280,61 +265,26 @@ pushback(string)
(void) ioctl(SHOUT, TIOCSETN, (ioctl_t) & tty_normal);
#endif /* TERMIO */
-# ifdef BSDSIGS
- (void) sigsetmask(omask);
-# else
- (void) sigrelse(SIGINT);
-# endif /* BSDISGS */
-}
-
-/*
- * Concatenate src onto tail of des.
- * Des is a string whose maximum length is count.
- * Always null terminate.
- */
-static void
-catn(des, src, count)
- Char *des, *src;
- int count;
-{
- while (--count >= 0 && *des)
- des++;
- while (--count >= 0)
- if ((*des++ = *src++) == 0)
- return;
- *des = '\0';
-}
-
-/*
- * Like strncpy but always leave room for trailing \0
- * and always null terminate.
- */
-static void
-copyn(des, src, count)
- Char *des, *src;
- int count;
-{
- while (--count >= 0)
- if ((*des++ = *src++) == 0)
- return;
- *des = '\0';
+ cleanup_until(&pintr_disabled);
}
static int
-filetype(dir, file)
- Char *dir, *file;
+filetype(const Char *dir, const Char *file)
{
- Char path[MAXPATHLEN];
+ Char *path;
+ char *spath;
struct stat statb;
- catn(Strcpy(path, dir), file, sizeof(path) / sizeof(Char));
- if (lstat(short2str(path), &statb) == 0) {
+ path = Strspl(dir, file);
+ spath = short2str(path);
+ xfree(path);
+ if (lstat(spath, &statb) == 0) {
switch (statb.st_mode & S_IFMT) {
case S_IFDIR:
return ('/');
case S_IFLNK:
- if (stat(short2str(path), &statb) == 0 && /* follow it out */
+ if (stat(spath, &statb) == 0 && /* follow it out */
S_ISDIR(statb.st_mode))
return ('>');
else
@@ -351,16 +301,13 @@ filetype(dir, file)
return (' ');
}
-static struct winsize win;
-
/*
* Print sorted down columns
*/
static void
-print_by_column(dir, items, count)
- Char *dir, *items[];
- size_t count;
+print_by_column(const Char *dir, Char *items[], size_t count)
{
+ struct winsize win;
size_t i;
int rows, r, c, maxwidth = 0, columns;
@@ -400,35 +347,37 @@ print_by_column(dir, items, count)
* home_directory_of_person/mumble
*/
static Char *
-tilde(new, old)
- Char *new, *old;
+tilde(const Char *old)
{
- Char *o, *p;
+ const Char *o, *home;
struct passwd *pw;
- static Char person[40];
if (old[0] != '~')
- return (Strcpy(new, old));
+ return (Strsave(old));
+ old++;
- for (p = person, o = &old[1]; *o && *o != '/'; *p++ = *o++);
- *p = '\0';
- if (person[0] == '\0')
- (void) Strcpy(new, varval(STRhome));
+ for (o = old; *o != '\0' && *o != '/'; o++)
+ ;
+ if (o == old)
+ home = varval(STRhome);
else {
- pw = getpwnam(short2str(person));
+ Char *person;
+
+ person = Strnsave(old, o - old);
+ pw = xgetpwnam(short2str(person));
+ xfree(person);
if (pw == NULL)
return (NULL);
- (void) Strcpy(new, str2short(pw->pw_dir));
+ home = str2short(pw->pw_dir);
}
- (void) Strcat(new, o);
- return (new);
+ return Strspl(home, o);
}
/*
* Cause pending line to be printed
*/
static void
-retype()
+retype(void)
{
#ifdef TERMIO
# ifdef POSIX
@@ -444,7 +393,7 @@ retype()
tty.c_lflag |= PENDIN;
# ifdef POSIX
- (void) tcsetattr(SHOUT, TCSANOW, &tty);
+ (void) xtcsetattr(SHOUT, TCSANOW, &tty);
# else
(void) ioctl(SHOUT, TCSETAW, (ioctl_t) &tty);
# endif /* POSIX */
@@ -456,15 +405,15 @@ retype()
}
static void
-beep()
+beep(void)
{
if (adrof(STRnobeep) == 0)
#ifdef IS_ASCII
- (void) write(SHOUT, "\007", 1);
+ (void) xwrite(SHOUT, "\007", 1);
#else
{
unsigned char beep_ch = CTL_ESC('\007');
- (void) write(SHOUT, &beep_ch, 1);
+ (void) xwrite(SHOUT, &beep_ch, 1);
}
#endif
}
@@ -474,8 +423,7 @@ beep()
* print the recognized part of the string
*/
static void
-print_recognized_stuff(recognized_part)
- Char *recognized_part;
+print_recognized_stuff(const Char *recognized_part)
{
/* An optimized erasing of that silly ^[ */
(void) putraw('\b');
@@ -507,26 +455,21 @@ print_recognized_stuff(recognized_part)
* Should leave final slash (/) at end of dir.
*/
static void
-extract_dir_and_name(path, dir, name)
- Char *path, *dir, *name;
+extract_dir_and_name(const Char *path, Char **dir, const Char **name)
{
- Char *p;
+ const Char *p;
p = Strrchr(path, '/');
- if (p == NULL) {
- copyn(name, path, MAXNAMLEN);
- dir[0] = '\0';
- }
- else {
- copyn(name, ++p, MAXNAMLEN);
- copyn(dir, path, p - path);
- }
+ if (p == NULL)
+ p = path;
+ else
+ p++;
+ *name = p;
+ *dir = Strnsave(path, p - path);
}
static Char *
-getitem(dir_fd, looking_for_lognames)
- DIR *dir_fd;
- int looking_for_lognames;
+getitem(DIR *dir_fd, int looking_for_lognames)
{
struct passwd *pw;
struct dirent *dirp;
@@ -545,102 +488,64 @@ getitem(dir_fd, looking_for_lognames)
return (NULL);
}
-static void
-free_items(items, numitems)
- Char **items;
- size_t numitems;
-{
- size_t i;
-
- for (i = 0; i < numitems; i++)
- xfree((ptr_t) items[i]);
- xfree((ptr_t) items);
-}
-
-#ifdef BSDSIGS
-# define FREE_ITEMS(items, numitems) { \
- sigmask_t omask;\
-\
- omask = sigblock(sigmask(SIGINT));\
- free_items(items, numitems);\
- (void) sigsetmask(omask);\
-}
-#else
-# define FREE_ITEMS(items, numitems) { \
- (void) sighold(SIGINT);\
- free_items(items, numitems);\
- (void) sigrelse(SIGINT);\
-}
-#endif /* BSDSIGS */
-
/*
* Perform a RECOGNIZE or LIST command on string "word".
*/
-static int
-tsearch(word, command, max_word_length)
- Char *word;
- int max_word_length;
- COMMAND command;
+static size_t
+tsearch(Char *word, COMMAND command, size_t max_word_length)
{
DIR *dir_fd;
int ignoring = TRUE, nignored = 0;
- int name_length, looking_for_lognames;
- Char tilded_dir[MAXPATHLEN + 1], dir[MAXPATHLEN + 1];
- Char name[MAXNAMLEN + 1], extended_name[MAXNAMLEN + 1];
- Char *item;
- Char **items = NULL;
- size_t numitems = 0, maxitems = 0;
+ int looking_for_lognames;
+ Char *tilded_dir = NULL, *dir = NULL;
+ Char *extended_name = NULL;
+ const Char *name;
+ Char *item;
+ struct blk_buf items = BLK_BUF_INIT;
+ size_t name_length;
looking_for_lognames = (*word == '~') && (Strchr(word, '/') == NULL);
if (looking_for_lognames) {
#ifdef HAVE_GETPWENT
(void) setpwent();
#endif
- copyn(name, &word[1], MAXNAMLEN); /* name sans ~ */
+ name = word + 1; /* name sans ~ */
dir_fd = NULL;
+ cleanup_push(dir, xfree);
}
else {
- extract_dir_and_name(word, dir, name);
- if (tilde(tilded_dir, dir) == 0)
- return (0);
+ extract_dir_and_name(word, &dir, &name);
+ cleanup_push(dir, xfree);
+ tilded_dir = tilde(dir);
+ if (tilded_dir == NULL)
+ goto end;
+ cleanup_push(tilded_dir, xfree);
dir_fd = opendir(*tilded_dir ? short2str(tilded_dir) : ".");
if (dir_fd == NULL)
- return (0);
+ goto end;
}
-again: /* search for matches */
name_length = Strlen(name);
- for (numitems = 0;
- (item = getitem(dir_fd, looking_for_lognames)) != NULL;) {
+ cleanup_push(&extended_name, xfree_indirect);
+ cleanup_push(&items, bb_cleanup);
+again: /* search for matches */
+ while ((item = getitem(dir_fd, looking_for_lognames)) != NULL) {
if (!is_prefix(name, item))
continue;
/* Don't match . files on null prefix match */
if (name_length == 0 && item[0] == '.' &&
!looking_for_lognames)
continue;
- if (command == LIST) {
- if (numitems >= maxitems) {
- maxitems += 1024;
- if (items == NULL)
- items = (Char **) xmalloc(sizeof(*items) * maxitems);
- else
- items = (Char **) xrealloc((ptr_t) items,
- sizeof(*items) * maxitems);
- }
- items[numitems] = (Char *) xmalloc((size_t) (Strlen(item) + 1) *
- sizeof(Char));
- copyn(items[numitems], item, MAXNAMLEN);
- numitems++;
- }
+ if (command == LIST)
+ bb_append(&items, Strsave(item));
else { /* RECOGNIZE command */
if (ignoring && ignored(item))
nignored++;
- else if (recognize(extended_name,
- item, name_length, ++numitems))
+ else if (recognize(&extended_name, item, name_length, ++items.len))
break;
}
}
- if (ignoring && numitems == 0 && nignored > 0) {
+ if (ignoring && items.len == 0 && nignored > 0) {
ignoring = FALSE;
nignored = 0;
if (looking_for_lognames) {
@@ -657,51 +562,47 @@ again: /* search for matches */
(void) endpwent();
#endif
} else
- (void) closedir(dir_fd);
- if (numitems == 0)
- return (0);
- if (command == RECOGNIZE) {
- if (looking_for_lognames)
- copyn(word, STRtilde, 1);
- else
- /* put back dir part */
- copyn(word, dir, max_word_length);
- /* add extended name */
- catn(word, extended_name, max_word_length);
- return (numitems);
- }
- else { /* LIST */
- qsort((ptr_t) items, numitems, sizeof(items[0]),
- (int (*) __P((const void *, const void *))) compare);
- print_by_column(looking_for_lognames ? NULL : tilded_dir,
- items, numitems);
- if (items != NULL)
- FREE_ITEMS(items, numitems);
+ xclosedir(dir_fd);
+ if (items.len != 0) {
+ if (command == RECOGNIZE) {
+ if (looking_for_lognames)
+ copyn(word, STRtilde, 2);/*FIXBUF, sort of */
+ else
+ /* put back dir part */
+ copyn(word, dir, max_word_length);/*FIXBUF*/
+ /* add extended name */
+ catn(word, extended_name, max_word_length);/*FIXBUF*/
+ }
+ else { /* LIST */
+ qsort(items.vec, items.len, sizeof(items.vec[0]), compare);
+ print_by_column(looking_for_lognames ? NULL : tilded_dir,
+ items.vec, items.len);
+ }
}
- return (0);
+ end:
+ cleanup_until(dir);
+ return items.len;
}
static int
-compare(p, q)
- const ptr_t p, q;
+compare(const void *p, const void *q)
{
#ifdef WIDE_STRINGS
errno = 0;
- return (wcscoll(*(Char **) p, *(Char **) q));
+ return (wcscoll(*(Char *const *) p, *(Char *const *) q));
#else
char *p1, *q1;
int res;
- p1 = strsave(short2str(*(Char **) p));
- q1 = strsave(short2str(*(Char **) q));
-# if defined(NLS) && !defined(NOSTRCOLL)
- errno = 0; /* strcoll sets errno, another brain-damage */
+ p1 = strsave(short2str(*(Char *const *) p));
+ q1 = strsave(short2str(*(Char *const *) q));
+# if defined(NLS) && defined(HAVE_STRCOLL)
res = strcoll(p1, q1);
# else
res = strcmp(p1, q1);
-# endif /* NLS && !NOSTRCOLL */
+# endif /* NLS && HAVE_STRCOLL */
xfree (p1);
xfree (q1);
return res;
@@ -717,18 +618,16 @@ compare(p, q)
* If we shorten it back to the prefix length, stop searching.
*/
static int
-recognize(extended_name, item, name_length, numitems)
- Char *extended_name, *item;
- int name_length;
- size_t numitems;
+recognize(Char **extended_name, Char *item, size_t name_length,
+ size_t numitems)
{
if (numitems == 1) /* 1st match */
- copyn(extended_name, item, MAXNAMLEN);
+ *extended_name = Strsave(item);
else { /* 2nd & subsequent matches */
Char *x, *ent;
- int len = 0;
+ size_t len = 0;
- x = extended_name;
+ x = *extended_name;
for (ent = item; *x && *x == *ent++; x++, len++);
*x = '\0'; /* Shorten at 1st Char diff */
if (len == name_length) /* Ambiguous to prefix? */
@@ -743,8 +642,7 @@ recognize(extended_name, item, name_length, numitems)
* it matches anything.
*/
static int
-is_prefix(check, template)
- Char *check, *template;
+is_prefix(const Char *check, const Char *template)
{
do
if (*check == 0)
@@ -758,10 +656,9 @@ is_prefix(check, template)
* end of check, I.e., are it's suffix.
*/
static int
-is_suffix(check, template)
- Char *check, *template;
+is_suffix(const Char *check, const Char *template)
{
- Char *c, *t;
+ const Char *c, *t;
for (c = check; *c++;);
for (t = template; *t++;);
@@ -773,30 +670,36 @@ is_suffix(check, template)
}
}
-int
-tenex(inputline, inputline_size)
- Char *inputline;
- int inputline_size;
+static void
+setup_tty_cleanup(void *dummy)
{
- int numitems, num_read;
- char tinputline[BUFSIZE + 1];
+ USE(dummy);
+ setup_tty(OFF);
+}
+size_t
+tenex(Char *inputline, size_t inputline_size)
+{
+ size_t numitems;
+ ssize_t num_read;
+ char tinputline[BUFSIZE + 1];/*FIXBUF*/
setup_tty(ON);
+ cleanup_push(&num_read, setup_tty_cleanup); /* num_read is only a marker */
- while ((num_read = read(SHIN, tinputline, BUFSIZE)) > 0) {
- static Char delims[] = {' ', '\'', '"', '\t', ';', '&', '<',
+ while ((num_read = xread(SHIN, tinputline, BUFSIZE)) > 0) {/*FIXBUF*/
+ static const Char delims[] = {' ', '\'', '"', '\t', ';', '&', '<',
'>', '(', ')', '|', '^', '%', '\0'};
Char *str_end, *word_start, last_Char, should_retype;
- int space_left;
+ size_t space_left;
COMMAND command;
tinputline[num_read] = 0;
- Strcpy(inputline, str2short(tinputline));
+ Strcpy(inputline, str2short(tinputline));/*FIXBUF*/
num_read = Strlen(inputline);
- last_Char = inputline[num_read - 1] & ASCII;
+ last_Char = CTL_ESC(ASC(inputline[num_read - 1]) & ASCII);
- if (last_Char == '\n' || num_read == inputline_size)
+ if (last_Char == '\n' || (size_t)num_read == inputline_size)
break;
command = (last_Char == ESC) ? RECOGNIZE : LIST;
if (command == LIST)
@@ -840,13 +743,12 @@ tenex(inputline, inputline_size)
if (should_retype)
retype();
}
- setup_tty(OFF);
+ cleanup_until(&num_read);
return (num_read);
}
static int
-ignored(item)
- Char *item;
+ignored(const Char *item)
{
struct varent *vp;
Char **cp;
OpenPOWER on IntegriCloud