commit 3172b979dcac67019a264632f8172ca6399a3944
parent 0a3a8c55e4fbaf0d5330a572ef1df8bfd6840ec6
Author: Connor Lane Smith <cls@lubutu.com>
Date: Sat, 28 May 2011 15:37:42 +0100
pwd -LP
Diffstat:
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);
}