1/* 2 * realpath -- canonicalize pathnames, resolving symlinks 3 * 4 * usage: realpath [-csv] pathname [pathname...] 5 * 6 * options: -c check whether or not each resolved path exists 7 * -s no output, exit status determines whether path is valid 8 * -v produce verbose output 9 * 10 * 11 * exit status: 0 if all pathnames resolved 12 * 1 if any of the pathname arguments could not be resolved 13 * 14 * 15 * Bash loadable builtin version 16 * 17 * Chet Ramey 18 * chet@po.cwru.edu 19 */ 20 21#include "config.h" 22 23#include <sys/types.h> 24#include <sys/stat.h> 25 26#include <stdio.h> 27#ifdef HAVE_UNISTD_H 28# include <unistd.h> 29#endif 30#include "bashansi.h" 31#include <maxpath.h> 32#include <errno.h> 33 34#include "builtins.h" 35#include "shell.h" 36#include "bashgetopt.h" 37 38#ifndef errno 39extern int errno; 40#endif 41 42extern char *sh_realpath(); 43 44realpath_builtin(list) 45WORD_LIST *list; 46{ 47 int opt, cflag, vflag, sflag, es; 48 char *r, realbuf[PATH_MAX], *p; 49 struct stat sb; 50 51 if (list == 0) { 52 builtin_usage(); 53 return (EX_USAGE); 54 } 55 56 vflag = cflag = sflag = 0; 57 reset_internal_getopt(); 58 while ((opt = internal_getopt (list, "csv")) != -1) { 59 switch (opt) { 60 case 'c': 61 cflag = 1; 62 break; 63 case 's': 64 sflag = 1; 65 break; 66 case 'v': 67 vflag = 1; 68 break; 69 default: 70 usage(); 71 } 72 } 73 74 list = loptend; 75 76 if (list == 0) 77 usage(); 78 79 for (es = EXECUTION_SUCCESS; list; list = list->next) { 80 p = list->word->word; 81 r = sh_realpath(p, realbuf); 82 if (r == 0) { 83 es = EXECUTION_FAILURE; 84 if (sflag == 0) 85 builtin_error("%s: cannot resolve: %s", p, strerror(errno)); 86 continue; 87 } 88 if (cflag && (stat(realbuf, &sb) < 0)) { 89 es = EXECUTION_FAILURE; 90 if (sflag == 0) 91 builtin_error("%s: %s", p, strerror(errno)); 92 continue; 93 } 94 if (sflag == 0) { 95 if (vflag) 96 printf ("%s -> ", p); 97 printf("%s\n", realbuf); 98 } 99 } 100 return es; 101} 102 103char *realpath_doc[] = { 104 "Display the canonicalized version of each PATHNAME argument, resolving", 105 "symbolic links. The -c option checks whether or not each resolved name", 106 "exists. The -s option produces no output; the exit status determines the", 107 "valididty of each PATHNAME. The -v option produces verbose output. The", 108 "exit status is 0 if each PATHNAME was resolved; non-zero otherwise.", 109 (char *)NULL 110}; 111 112struct builtin realpath_struct = { 113 "realpath", /* builtin name */ 114 realpath_builtin, /* function implementing the builtin */ 115 BUILTIN_ENABLED, /* initial flags for builtin */ 116 realpath_doc, /* array of long documentation strings */ 117 "realpath [-csv] pathname [pathname...]", /* usage synopsis */ 118 0 /* reserved for internal use */ 119}; 120