cd.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* $NetBSD: cd.c,v 1.34 2003/11/14 20:00:28 dsl Exp $ */ 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*- 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 1991, 1993 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The Regents of the University of California. All rights reserved. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code is derived from software contributed to Berkeley by 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Kenneth Almquist. 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met: 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * documentation and/or other materials provided with the distribution. 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * may be used to endorse or promote products derived from this software 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * without specific prior written permission. 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE. 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/cdefs.h> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef lint 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95"; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: cd.c,v 1.34 2003/11/14 20:00:28 dsl Exp $"); 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* not lint */ 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The cd and pwd commands. 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "shell.h" 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "var.h" 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "nodes.h" /* for jobs.h */ 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "jobs.h" 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "options.h" 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "output.h" 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "memalloc.h" 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "error.h" 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "exec.h" 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "redir.h" 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mystring.h" 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "show.h" 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "cd.h" 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int docd(char *, int); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC char *getcomponent(void); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void updatepwd(char *); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void find_curdir(int noerror); 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *curdir = NULL; /* current working directory */ 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *prevdir; /* previous working directory */ 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC char *cdcomppath; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcdcmd(int argc, char **argv) 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *dest; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *path; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p, *d; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat statb; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int print = cdprint; /* set -cdprint to enable */ 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nextopt(nullstr); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Try (quite hard) to have 'curdir' defined, nothing has set 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * it on entry to the shell, but we want 'cd fred; cd -' to work. 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getpwd(1); 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dest = *argptr; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (dest == NULL) { 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dest = bltinlookup("HOME", 1); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (dest == NULL) 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("HOME not set"); 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argptr[1]) { 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* Do 'ksh' style substitution */ 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!curdir) 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("PWD not set"); 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = strstr(curdir, dest); 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!p) 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("bad substitution"); 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = stalloc(strlen(curdir) + strlen(argptr[1]) + 1); 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(d, curdir, p - curdir); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(d + (p - curdir), argptr[1]); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcat(d, p + strlen(dest)); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dest = d; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print = 1; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (dest[0] == '-' && dest[1] == '\0') { 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dest = prevdir ? prevdir : curdir; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print = 1; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*dest == '\0') 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dest = "."; 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL) 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project path = nullstr; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((p = padvance(&path, dest)) != NULL) { 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!print) { 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * XXX - rethink 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p[0] == '.' && p[1] == '/' && p[2] != '\0') 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += 2; 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print = strcmp(p, dest); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (docd(p, print) >= 0) 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("can't cd to %s", dest); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* NOTREACHED */ 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Actually do the chdir. In an interactive shell, print the 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * directory name if "print" is nonzero. 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC int 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdocd(char *dest, int print) 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *q; 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *component; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat statb; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int first; 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int badstat; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRACE(("docd(\"%s\", %d) called\n", dest, print)); 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Check each component of the path. If we find a symlink or 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * something we can't stat, clear curdir to force a getcwd() 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * next time we get the value of the current directory. 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project badstat = 0; 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cdcomppath = stalloc(strlen(dest) + 1); 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project scopy(dest, cdcomppath); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STARTSTACKSTR(p); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*dest == '/') { 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC('/', p); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cdcomppath++; 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project first = 1; 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((q = getcomponent()) != NULL) { 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0')) 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (! first) 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC('/', p); 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project first = 0; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project component = q; 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*q) 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC(*q++, p); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (equal(component, "..")) 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STACKSTRNUL(p); 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((lstat(stackblock(), &statb) < 0) 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || (S_ISLNK(statb.st_mode))) { 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* print = 1; */ 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project badstat = 1; 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (chdir(dest) < 0) { 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project updatepwd(badstat ? NULL : dest); 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (print && iflag && curdir) 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1fmt("%s\n", curdir); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Get the next component of the path name pointed to by cdcomppath. 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This routine overwrites the string pointed to by cdcomppath. 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC char * 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetcomponent() 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *start; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((p = cdcomppath) == NULL) 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project start = cdcomppath; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*p != '/' && *p != '\0') 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p++; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*p == '\0') { 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cdcomppath = NULL; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *p++ = '\0'; 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cdcomppath = p; 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return start; 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Update curdir (the name of the current directory) in response to a 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * cd command. We also call hashcd to let the routines in exec.c know 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * that the current directory has changed. 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectupdatepwd(char *dir) 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *new; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hashcd(); /* update command hash table */ 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If our argument is NULL, we don't know the current directory 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * any more because we traversed a symbolic link or something 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * we couldn't stat(). 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (dir == NULL || curdir == NULL) { 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (prevdir) 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ckfree(prevdir); 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project prevdir = curdir; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project curdir = NULL; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getpwd(1); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (curdir) 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setvar("PWD", curdir, VEXPORT); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsetvar("PWD", 0); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cdcomppath = stalloc(strlen(dir) + 1); 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project scopy(dir, cdcomppath); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STARTSTACKSTR(new); 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*dir != '/') { 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = curdir; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*p) 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC(*p++, new); 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (p[-1] == '/') 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STUNPUTC(new); 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((p = getcomponent()) != NULL) { 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (equal(p, "..")) { 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (new > stackblock() && (STUNPUTC(new), *new) != '/'); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (*p != '\0' && ! equal(p, ".")) { 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC('/', new); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (*p) 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC(*p++, new); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (new == stackblock()) 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STPUTC('/', new); 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project STACKSTRNUL(new); 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (prevdir) 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ckfree(prevdir); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project prevdir = curdir; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project curdir = savestr(stackblock()); 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setvar("PWD", curdir, VEXPORT); 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Posix says the default should be 'pwd -L' (as below), however 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the 'cd' command (above) does something much nearer to the 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * posix 'cd -P' (not the posix default of 'cd -L'). 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If 'cd' is changed to support -P/L then the default here 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * needs to be revisited if the historic behaviour is to be kept. 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpwdcmd(int argc, char **argv) 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char opt = 'L'; 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((i = nextopt("LP")) != '\0') 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project opt = i; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (*argptr) 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("unexpected argument"); 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (opt == 'L') 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getpwd(0); 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project find_curdir(0); 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setvar("PWD", curdir, VEXPORT); 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1str(curdir); 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project out1c('\n'); 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MAXPWD 256 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Find out what the current directory is. If we already know the current 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * directory, this routine returns immediately. 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetpwd(int noerror) 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *pwd; 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat stdot, stpwd; 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static int first = 1; 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (curdir) 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (first) { 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project first = 0; 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pwd = getenv("PWD"); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pwd && *pwd == '/' && stat(".", &stdot) != -1 && 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stat(pwd, &stpwd) != -1 && 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdot.st_dev == stpwd.st_dev && 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stdot.st_ino == stpwd.st_ino) { 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project curdir = savestr(pwd); 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project find_curdir(noerror); 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfind_curdir(int noerror) 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *pwd; 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Things are a bit complicated here; we could have just used 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * getcwd, but traditionally getcwd is implemented using popen 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * to /bin/pwd. This creates a problem for us, since we cannot 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * keep track of the job if it is being ran behind our backs. 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * So we re-implement getcwd(), and we suppress interrupts 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * throughout the process. This is not completely safe, since 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the user can still break out of it by killing the pwd program. 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * We still try to use getcwd for systems that we know have a 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * c implementation of getcwd, that does not open a pipe to 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * /bin/pwd. 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__NetBSD__) || defined(__SVR4) || defined(__linux__) 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = MAXPWD;; i *= 2) { 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pwd = stalloc(i); 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (getcwd(pwd, i) != NULL) { 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project curdir = savestr(pwd); 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stunalloc(pwd); 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno == ERANGE) 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!noerror) 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("getcwd() failed: %s", strerror(errno)); 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int status; 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct job *jp; 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pip[2]; 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pwd = stalloc(MAXPWD); 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTOFF; 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pipe(pip) < 0) 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("Pipe call failed"); 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project jp = makejob((union node *)NULL, 1); 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (forkshell(jp, (union node *)NULL, FORK_NOJOB) == 0) { 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) close(pip[0]); 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pip[1] != 1) { 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(1); 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project copyfd(pip[1], 1); 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(pip[1]); 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) execl("/bin/pwd", "pwd", (char *)0); 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sh_warn("Cannot exec /bin/pwd"); 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) close(pip[1]); 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pip[1] = -1; 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = pwd; 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((i = read(pip[0], p, pwd + MAXPWD - p)) > 0 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project || (i == -1 && errno == EINTR)) { 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i > 0) 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += i; 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void) close(pip[0]); 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pip[0] = -1; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project status = waitforjob(jp); 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (status != 0) 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error((char *)0); 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i < 0 || p == pwd || p[-1] != '\n') { 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (noerror) { 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project error("pwd command failed"); 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p[-1] = '\0'; 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project INTON; 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project curdir = savestr(pwd); 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 447