readlink command implementation + manpage
This commit is contained in:
		
							parent
							
								
									ce64a1d542
								
							
						
					
					
						commit
						96783ed1f7
					
				| @ -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 $? $@ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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) { | ||||||
|  | |||||||
| @ -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. | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ben Gras
						Ben Gras