197403Sobrien/*- 297403Sobrien * SPDX-License-Identifier: BSD-3-Clause 3169691Skan * 4169691Skan * Copyright (c) 1991, 1993, 1994 597403Sobrien * The Regents of the University of California. All rights reserved. 697403Sobrien * 797403Sobrien * Redistribution and use in source and binary forms, with or without 897403Sobrien * modification, are permitted provided that the following conditions 997403Sobrien * are met: 1097403Sobrien * 1. Redistributions of source code must retain the above copyright 1197403Sobrien * notice, this list of conditions and the following disclaimer. 1297403Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1397403Sobrien * notice, this list of conditions and the following disclaimer in the 1497403Sobrien * documentation and/or other materials provided with the distribution. 1597403Sobrien * 3. Neither the name of the University nor the names of its contributors 1697403Sobrien * may be used to endorse or promote products derived from this software 1797403Sobrien * without specific prior written permission. 1897403Sobrien * 19169691Skan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2097403Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2197403Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2297403Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2397403Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2497403Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2597403Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2697403Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2797403Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2897403Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2997403Sobrien * SUCH DAMAGE. 3097403Sobrien */ 31169691Skan 3297403Sobrien#include <sys/param.h> 3397403Sobrien#include <sys/stat.h> 3497403Sobrien#include <sys/types.h> 3597403Sobrien 3697403Sobrien#include <err.h> 37169691Skan#include <errno.h> 38169691Skan#include <stdio.h> 3997403Sobrien#include <stdlib.h> 4097403Sobrien#include <unistd.h> 41169691Skan 42169691Skanstatic char *getcwd_logical(void); 43169691Skanvoid usage(void); 44169691Skan 45132720Skanint 46132720Skanmain(int argc, char *argv[]) 4797403Sobrien{ 4897403Sobrien int physical; 4997403Sobrien int ch; 5097403Sobrien char *p; 5197403Sobrien 5297403Sobrien physical = 1; 5397403Sobrien while ((ch = getopt(argc, argv, "LP")) != -1) 5497403Sobrien switch (ch) { 5597403Sobrien case 'L': 5697403Sobrien physical = 0; 5797403Sobrien break; 5897403Sobrien case 'P': 5997403Sobrien physical = 1; 6097403Sobrien break; 6197403Sobrien case '?': 6297403Sobrien default: 6397403Sobrien usage(); 6497403Sobrien } 6597403Sobrien argc -= optind; 6697403Sobrien argv += optind; 6797403Sobrien 68169691Skan if (argc != 0) 69169691Skan usage(); 7097403Sobrien 7197403Sobrien /* 7297403Sobrien * If we're trying to find the logical current directory and that 7397403Sobrien * fails, behave as if -P was specified. 7497403Sobrien */ 7597403Sobrien if ((!physical && (p = getcwd_logical()) != NULL) || 7697403Sobrien (p = getcwd(NULL, 0)) != NULL) 7797403Sobrien printf("%s\n", p); 7897403Sobrien else 7997403Sobrien err(1, "."); 8097403Sobrien 8197403Sobrien exit(0); 8297403Sobrien} 8397403Sobrien 84169691Skanvoid __dead2 85169691Skanusage(void) 86132720Skan{ 87 88 (void)fprintf(stderr, "usage: pwd [-L | -P]\n"); 89 exit(1); 90} 91 92static char * 93getcwd_logical(void) 94{ 95 struct stat lg, phy; 96 char *pwd; 97 98 /* 99 * Check that $PWD is an absolute logical pathname referring to 100 * the current working directory. 101 */ 102 if ((pwd = getenv("PWD")) != NULL && *pwd == '/') { 103 if (stat(pwd, &lg) == -1 || stat(".", &phy) == -1) 104 return (NULL); 105 if (lg.st_dev == phy.st_dev && lg.st_ino == phy.st_ino) 106 return (pwd); 107 } 108 109 errno = ENOENT; 110 return (NULL); 111} 112