1 1.23 kre /* $NetBSD: pwd.c,v 1.23 2021/11/16 16:57:15 kre Exp $ */ 2 1.7 cgd 3 1.1 cgd /* 4 1.6 mycroft * Copyright (c) 1991, 1993, 1994 5 1.6 mycroft * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.16 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.8 christos #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.21 lukem __COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\ 35 1.21 lukem The Regents of the University of California. All rights reserved."); 36 1.1 cgd #endif /* not lint */ 37 1.1 cgd 38 1.1 cgd #ifndef lint 39 1.7 cgd #if 0 40 1.7 cgd static char sccsid[] = "@(#)pwd.c 8.3 (Berkeley) 4/1/94"; 41 1.7 cgd #else 42 1.23 kre __RCSID("$NetBSD: pwd.c,v 1.23 2021/11/16 16:57:15 kre Exp $"); 43 1.7 cgd #endif 44 1.1 cgd #endif /* not lint */ 45 1.1 cgd 46 1.15 jschauma #include <sys/param.h> 47 1.15 jschauma #include <sys/stat.h> 48 1.12 kleink #include <sys/types.h> 49 1.14 wiz 50 1.6 mycroft #include <err.h> 51 1.12 kleink #include <errno.h> 52 1.20 christos #include <locale.h> 53 1.5 jtc #include <stdio.h> 54 1.5 jtc #include <stdlib.h> 55 1.12 kleink #include <string.h> 56 1.1 cgd #include <unistd.h> 57 1.15 jschauma 58 1.19 dsl static char *getcwd_logical(void); 59 1.22 joerg __dead static void usage(void); 60 1.11 wsanchez 61 1.19 dsl /* 62 1.19 dsl * Note that EEE Std 1003.1, 2003 requires that the default be -L. 63 1.19 dsl * This is inconsistent with the historic behaviour of everything 64 1.19 dsl * except the ksh builtin. 65 1.19 dsl * To avoid breaking scripts the default has been kept as -P. 66 1.19 dsl * (Some scripts run /bin/pwd in order to get 'pwd -P'.) 67 1.19 dsl */ 68 1.1 cgd 69 1.5 jtc int 70 1.14 wiz main(int argc, char *argv[]) 71 1.1 cgd { 72 1.14 wiz int ch, lFlag; 73 1.12 kleink const char *p; 74 1.1 cgd 75 1.14 wiz setprogname(argv[0]); 76 1.20 christos (void)setlocale(LC_ALL, ""); 77 1.20 christos 78 1.14 wiz lFlag = 0; 79 1.19 dsl while ((ch = getopt(argc, argv, "LP")) != -1) { 80 1.6 mycroft switch (ch) { 81 1.11 wsanchez case 'L': 82 1.14 wiz lFlag = 1; 83 1.11 wsanchez break; 84 1.6 mycroft case 'P': 85 1.14 wiz lFlag = 0; 86 1.6 mycroft break; 87 1.6 mycroft case '?': 88 1.6 mycroft default: 89 1.6 mycroft usage(); 90 1.6 mycroft } 91 1.19 dsl } 92 1.6 mycroft argc -= optind; 93 1.6 mycroft argv += optind; 94 1.6 mycroft 95 1.6 mycroft if (argc != 0) 96 1.6 mycroft usage(); 97 1.5 jtc 98 1.11 wsanchez if (lFlag) 99 1.19 dsl p = getcwd_logical(); 100 1.11 wsanchez else 101 1.19 dsl p = NULL; 102 1.19 dsl if (p == NULL) 103 1.11 wsanchez p = getcwd(NULL, 0); 104 1.11 wsanchez 105 1.12 kleink if (p == NULL) 106 1.13 drochner err(EXIT_FAILURE, NULL); 107 1.11 wsanchez 108 1.18 jschauma (void)printf("%s\n", p); 109 1.11 wsanchez 110 1.23 kre (void)fflush(stdout); 111 1.23 kre if (ferror(stdout)) 112 1.23 kre err(EXIT_FAILURE, "stdout"); 113 1.23 kre 114 1.12 kleink exit(EXIT_SUCCESS); 115 1.10 mycroft /* NOTREACHED */ 116 1.11 wsanchez } 117 1.11 wsanchez 118 1.12 kleink static char * 119 1.19 dsl getcwd_logical(void) 120 1.11 wsanchez { 121 1.12 kleink char *pwd; 122 1.19 dsl struct stat s_pwd, s_dot; 123 1.12 kleink 124 1.12 kleink /* Check $PWD -- if it's right, it's fast. */ 125 1.19 dsl pwd = getenv("PWD"); 126 1.19 dsl if (pwd == NULL) 127 1.19 dsl return NULL; 128 1.19 dsl if (pwd[0] != '/') 129 1.19 dsl return NULL; 130 1.19 dsl if (strstr(pwd, "/./") != NULL) 131 1.19 dsl return NULL; 132 1.19 dsl if (strstr(pwd, "/../") != NULL) 133 1.19 dsl return NULL; 134 1.19 dsl if (stat(pwd, &s_pwd) == -1 || stat(".", &s_dot) == -1) 135 1.19 dsl return NULL; 136 1.19 dsl if (s_pwd.st_dev != s_dot.st_dev || s_pwd.st_ino != s_dot.st_ino) 137 1.19 dsl return NULL; 138 1.19 dsl return pwd; 139 1.6 mycroft } 140 1.6 mycroft 141 1.12 kleink static void 142 1.14 wiz usage(void) 143 1.6 mycroft { 144 1.14 wiz (void)fprintf(stderr, "usage: %s [-LP]\n", getprogname()); 145 1.12 kleink exit(EXIT_FAILURE); 146 1.10 mycroft /* NOTREACHED */ 147 1.1 cgd } 148