From 32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3 Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Thu, 15 Apr 1999 18:05:35 +0000 Subject: zsh-3.1.5 --- Src/compat.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 Src/compat.c (limited to 'Src/compat.c') diff --git a/Src/compat.c b/Src/compat.c new file mode 100644 index 000000000..ca9c57aac --- /dev/null +++ b/Src/compat.c @@ -0,0 +1,285 @@ +/* + * compat.c - compatibiltiy routines for the deprived + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 1992-1997 Paul Falstad + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Paul Falstad or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Paul Falstad and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Paul Falstad and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Paul Falstad and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "zsh.mdh" +#include "compat.pro" + +/* Return pointer to first occurence of string t * + * in string s. Return NULL if not present. */ + +#ifndef HAVE_STRSTR +char * +strstr(const char *s, const char *t) +{ + char *p1, *p2; + + for (; *s; s++) { + for (p1 = s, p2 = t; *p2; p1++, p2++) + if (*p1 != *p2) + break; + if (!*p2) + return (char *)s; + } + return NULL; +} +#endif + + +#ifndef HAVE_GETHOSTNAME +int +gethostname(char *name, size_t namelen) +{ + struct utsname uts; + + uname(&uts); + if(strlen(uts.nodename) >= namelen) { + errno = EINVAL; + return -1; + } + strcpy(name, uts.nodename); + return 0; +} +#endif + + +#ifndef HAVE_GETTIMEOFDAY +int +gettimeofday(struct timeval *tv, struct timezone *tz) +{ + tv->tv_usec = 0; + tv->tv_sec = (long)time((time_t) 0); + return 0; +} +#endif + + +/* compute the difference between two calendar times */ + +#ifndef HAVE_DIFFTIME +double +difftime(time_t t2, time_t t1) +{ + return ((double)t2 - (double)t1); +} +#endif + + +#ifndef HAVE_STRERROR +extern char *sys_errlist[]; + +/* Get error message string associated with a particular * + * error number, and returns a pointer to that string. * + * This is not a particularly robust version of strerror. */ + +char * +strerror(int errnum) +{ + return (sys_errlist[errnum]); +} +#endif + + +/**/ +char * +zgetdir(struct dirsav *d) +{ + char nbuf[PATH_MAX+3]; + char *buf; + int bufsiz, pos, len; + struct stat sbuf; + struct dirent *de; + DIR *dir; + ino_t ino, pino; + dev_t dev, pdev; + + buf = halloc(bufsiz = PATH_MAX); + pos = bufsiz - 1; + buf[pos] = '\0'; + strcpy(nbuf, "../"); + if (stat(".", &sbuf) < 0) { + if (d) + return NULL; + buf[0] = '.'; + buf[1] = '\0'; + return buf; + } + + pino = sbuf.st_ino; + pdev = sbuf.st_dev; + if (d) + d->ino = pino, d->dev = pdev; +#ifdef HAVE_FCHDIR + else +#endif + holdintr(); + + for (;;) { + if (stat("..", &sbuf) < 0) + break; + + ino = pino; + dev = pdev; + pino = sbuf.st_ino; + pdev = sbuf.st_dev; + + if (ino == pino && dev == pdev) { + if (!buf[pos]) + buf[--pos] = '/'; + if (d) { +#ifndef HAVE_FCHDIR + zchdir(buf + pos); + noholdintr(); +#endif + return d->dirname = ztrdup(buf + pos); + } + zchdir(buf + pos); + noholdintr(); + return buf + pos; + } + + if (!(dir = opendir(".."))) + break; + + while ((de = readdir(dir))) { + char *fn = de->d_name; + /* Ignore `.' and `..'. */ + if (fn[0] == '.' && + (fn[1] == '\0' || + (fn[1] == '.' && fn[2] == '\0'))) + continue; +#ifdef HAVE_STRUCT_DIRENT_D_STAT + if(de->d_stat.st_dev == dev && de->d_stat.st_ino == ino) { + strncpy(nbuf + 3, fn, PATH_MAX); + break; + } +#else /* !HAVE_STRUCT_DIRENT_D_STAT */ +# ifdef HAVE_STRUCT_DIRENT_D_INO + if (dev != pdev || (ino_t) de->d_ino == ino) +# endif /* HAVE_STRUCT_DIRENT_D_INO */ + { + strncpy(nbuf + 3, fn, PATH_MAX); + lstat(nbuf, &sbuf); + if (sbuf.st_dev == dev && sbuf.st_ino == ino) + break; + } +#endif /* !HAVE_STRUCT_DIRENT_D_STAT */ + } + closedir(dir); + if (!de) + break; + len = strlen(nbuf + 2); + pos -= len; + while (pos <= 1) { + char *newbuf = halloc(2*bufsiz); + memcpy(newbuf + bufsiz, buf, bufsiz); + buf = newbuf; + pos += bufsiz; + bufsiz *= 2; + } + memcpy(buf + pos, nbuf + 2, len); +#ifdef HAVE_FCHDIR + if (d) + return d->dirname = ztrdup(buf + pos + 1); +#endif + if (chdir("..")) + break; + } + if (d) { +#ifndef HAVE_FCHDIR + if (*buf) + zchdir(buf + pos + 1); + noholdintr(); +#endif + return NULL; + } + if (*buf) + zchdir(buf + pos + 1); + noholdintr(); + buf[0] = '.'; + buf[1] = '\0'; + return buf; +} + +/**/ +char * +zgetcwd(void) +{ + return zgetdir(NULL); +} + +/* chdir with arbitrary long pathname. Returns 0 on success, 0 on normal * + * faliliure and -2 when chdir failed and the current directory is lost. */ + +/**/ +int +zchdir(char *dir) +{ + char *s; + int currdir = -2; + + for (;;) { + if (!*dir) + return 0; + if (!chdir(dir)) + return 0; + if ((errno != ENAMETOOLONG && errno != ENOMEM) || + strlen(dir) < PATH_MAX) + break; + for (s = dir + PATH_MAX - 1; s > dir && *s != '/'; s--); + if (s == dir) + break; +#ifdef HAVE_FCHDIR + if (currdir == -2) + currdir = open(".", O_RDONLY|O_NOCTTY); +#endif + *s = '\0'; + if (chdir(dir)) { + *s = '/'; + break; + } +#ifndef HAVE_FCHDIR + currdir = -1; +#endif + *s = '/'; + while (*++s == '/'); + dir = s; + } +#ifdef HAVE_FCHDIR + if (currdir == -1 || (currdir >= 0 && fchdir(currdir))) { + if (currdir >= 0) + close(currdir); + return -2; + } + if (currdir >= 0) + close(currdir); + return -1; +#else + return currdir == -2 ? -1 : -2; +#endif +} -- cgit 1.4.1