sbase

suckless unix tools
git clone git://git.2f30.org/sbase.git
Log | Files | Refs | README | LICENSE

commit 3172b979dcac67019a264632f8172ca6399a3944
parent 0a3a8c55e4fbaf0d5330a572ef1df8bfd6840ec6
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Sat May 28 15:37:42 +0100

pwd -LP
Diffstat:
ln.1 | 2+-
ls.c | 4++--
pwd.1 | 9+++++++++
pwd.c | 37+++++++++++++++++++++++++++++++++++--
touch.c | 2+-
5 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/ln.1 b/ln.1 @@ -19,7 +19,7 @@ be linked into the given directory. .SH OPTIONS .TP .B \-s -create a symbolic link. +create a symlink. .SH SEE ALSO .IR cp (1), .IR link (2), diff --git a/ls.c b/ls.c @@ -186,8 +186,8 @@ output(Entry *ent) if(ent->mode & S_IWOTH) mode[8] = 'w'; if(ent->mode & S_IXOTH) mode[9] = 'x'; - if(ent->mode & S_ISUID) mode[3] = (mode[3] == 'x' ? 's' : 'S'); - if(ent->mode & S_ISGID) mode[6] = (mode[6] == 'x' ? 's' : 'S'); + if(ent->mode & S_ISUID) mode[3] = (mode[3] == 'x') ? 's' : 'S'; + if(ent->mode & S_ISGID) mode[6] = (mode[6] == 'x') ? 's' : 'S'; errno = 0; pw = getpwuid(ent->uid); diff --git a/pwd.1 b/pwd.1 @@ -3,8 +3,17 @@ pwd \- print working directory .SH SYNOPSIS .B pwd +.RB [ \-LP ] .SH DESCRIPTION .B pwd prints the path of the current working directory. +.SH OPTIONS +.TP +.B \-L +logical path, uses $PWD (default). +.TP +.B \-P +physical path, avoids all symlinks. .SH SEE ALSO +.IR cd (1), .IR getcwd (3) diff --git a/pwd.c b/pwd.c @@ -1,11 +1,44 @@ /* See LICENSE file for copyright and license details. */ #include <stdio.h> #include <stdlib.h> +#include <unistd.h> +#include <sys/stat.h> #include "util.h" +static const char *getpwd(const char *cwd); + int -main(void) +main(int argc, char *argv[]) { - puts(agetcwd()); + char *cwd, c; + char mode = 'L'; + + while((c = getopt(argc, argv, "LP")) != -1) + switch(c) { + case 'L': + case 'P': + mode = c; + break; + default: + exit(EXIT_FAILURE); + } + cwd = agetcwd(); + puts((mode == 'L') ? getpwd(cwd) : cwd); return EXIT_SUCCESS; } + +const char * +getpwd(const char *cwd) +{ + const char *pwd; + struct stat cst, pst; + + if(!(pwd = getenv("PWD")) || pwd[0] != '/' || stat(pwd, &pst) != 0) + return cwd; + if(stat(cwd, &cst) != 0) + eprintf("stat %s:", cwd); + if(pst.st_dev == cst.st_dev && pst.st_ino == cst.st_ino) + return pwd; + else + return cwd; +} diff --git a/touch.c b/touch.c @@ -50,7 +50,7 @@ touch(const char *str) eprintf("stat %s:", str); if(cflag) return; - if((fd = creat(str, O_RDONLY|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) + if((fd = creat(str, O_EXCL|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) eprintf("creat %s:", str); close(fd); }