readlink command implementation + manpage

This commit is contained in:
Ben Gras 2006-03-17 09:27:26 +00:00
parent ce64a1d542
commit 96783ed1f7
3 changed files with 41 additions and 2 deletions

View File

@ -154,6 +154,7 @@ ALL = \
rdate \ rdate \
readall \ readall \
rev \ rev \
readlink \
readfs \ readfs \
remsync \ remsync \
rget \ rget \
@ -1044,6 +1045,7 @@ install: \
/usr/bin/rawspeed \ /usr/bin/rawspeed \
/usr/bin/rdate \ /usr/bin/rdate \
/usr/bin/readall \ /usr/bin/readall \
/usr/bin/readlink \
/usr/bin/readfs \ /usr/bin/readfs \
/usr/bin/remsync \ /usr/bin/remsync \
/usr/bin/rget \ /usr/bin/rget \
@ -1501,6 +1503,9 @@ install: \
/usr/bin/readall: readall /usr/bin/readall: readall
install -cs -o bin $? $@ install -cs -o bin $? $@
/usr/bin/readlink: /usr/bin/stat
install -l $? $@
/usr/bin/readfs: readfs /usr/bin/readfs: readfs
install -cs -o bin $? $@ install -cs -o bin $? $@

View File

@ -25,6 +25,7 @@
# include <limits.h> # include <limits.h>
# include <stdio.h> # include <stdio.h>
# include <stdlib.h> # include <stdlib.h>
# include <unistd.h>
# include <string.h> # include <string.h>
# include <time.h> # include <time.h>
# include <sys/stat.h> # include <sys/stat.h>
@ -87,6 +88,8 @@ void printit(struct stat* sb, struct field* f, int n);
void rwx(mode_t mode, char *bit); void rwx(mode_t mode, char *bit);
void usage(void); void usage(void);
int do_readlink=0;
int main(int ac, char** av) int main(int ac, char** av)
{ {
int i, j, nprint = 0, files = 0; int i, j, nprint = 0, files = 0;
@ -98,6 +101,7 @@ int main(int ac, char** av)
if ((arg0 = strrchr(av[0], '/')) == NULL) arg0 = av[0]; else arg0++; if ((arg0 = strrchr(av[0], '/')) == NULL) arg0 = av[0]; else arg0++;
#ifdef S_IFLNK #ifdef S_IFLNK
if (equal(arg0, "lstat")) sym = 1; if (equal(arg0, "lstat")) sym = 1;
if (equal(arg0, "readlink")) do_readlink = 1;
#endif #endif
if (ac > 1 && equal(av[i = 1], "-")) if (ac > 1 && equal(av[i = 1], "-"))
@ -155,6 +159,7 @@ int main(int ac, char** av)
files++; /* We don't know how many files come from stdin. */ files++; /* We don't know how many files come from stdin. */
if (files == 0) { /* Stat all file descriptors. */ if (files == 0) { /* Stat all file descriptors. */
if(do_readlink) return 0;
for (i= 0; i<OPEN_MAX; i++) { for (i= 0; i<OPEN_MAX; i++) {
err= fstat(i, &sbuf); err= fstat(i, &sbuf);
if (err == -1 && errno == EBADF) if (err == -1 && errno == EBADF)
@ -177,6 +182,19 @@ int main(int ac, char** av)
while (fgets(buf, sizeof(buf), stdin)) { while (fgets(buf, sizeof(buf), stdin)) {
char *p= strchr(buf, '\n'); char *p= strchr(buf, '\n');
if (p) *p= 0; if (p) *p= 0;
#ifdef S_IFLNK
if(do_readlink) {
char sbuf[300];
int n;
if((n=readlink(buf, sbuf, sizeof(sbuf)-1)) < 0) {
perror(buf);
continue;
}
sbuf[n] = '\0';
printf("%s: %s\n", buf, sbuf);
continue;
}
#endif
if (!sym) err= stat(av[i], &sbuf); if (!sym) err= stat(av[i], &sbuf);
if (sym || (err != 0 && errno == ENOENT)) { if (sym || (err != 0 && errno == ENOENT)) {
err= lstat(av[i], &sbuf); err= lstat(av[i], &sbuf);
@ -215,6 +233,17 @@ int main(int ac, char** av)
} }
continue; continue;
} }
if(do_readlink) {
char sbuf[300];
int n;
if((n=err=readlink(av[i], sbuf, sizeof(sbuf)-1)) < 0) {
perror(av[i]);
continue;
}
sbuf[n] = '\0';
printf("%s: %s\n", av[i], sbuf);
continue;
}
if (!sym) err= stat(av[i], &sbuf); if (!sym) err= stat(av[i], &sbuf);
if (sym || (err != 0 && errno == ENOENT)) err= lstat(av[i], &sbuf); if (sym || (err != 0 && errno == ENOENT)) err= lstat(av[i], &sbuf);
if (err != -1) { if (err != -1) {

View File

@ -1,6 +1,6 @@
.TH STAT 1 .TH STAT 1
.SH NAME .SH NAME
stat, lstat \- provide a shell interface to the stat(2) system call stat, lstat, readlink \- provide a shell interface to the stat(2) system call
.SH SYNOPSIS .SH SYNOPSIS
.B stat .B stat
.RB [ - ] .RB [ - ]
@ -25,8 +25,13 @@ is called as
.B lstat .B lstat
then the then the
.BR lstat (2) .BR lstat (2)
system call is used, otherwise symbolic links are expanded with system call is used, if called as
.B stat
symbolic links are expanded with
.BR stat (2). .BR stat (2).
If called as
.B readlink
then the output is only the contents of the symbolic link.
.PP .PP
If no fields are named then all fields are printed. If no files are listed If no fields are named then all fields are printed. If no files are listed
then all open filedescriptors are printed. then all open filedescriptors are printed.