Subject: Re: Possible bug in exec with symlink.
From: Chet Ramey <[email-masked]>
To: [email-masked]
Cc: [email-masked]
Date: Wed, 6 Dec 2000 10:57:04 -0500

> I thought that most modern shells had some kind of command to dereference
> symbolic links like 'truename' or 'realname' or something like that.

None do, but one is trivial to write given the presence of realpath(3).
Here's one, minimally tested:

/*
 * realpath -- canonicalize pathnames, resolving symlinks
 *
 * usage: realpath [-csv] pathname [pathname...]
 *
 * options:	-c	check whether or not each resolved path exists
 *		-s	no output, exit status determines whether path is valid
 *		-v	produce verbose output
 *
 *
 * exit status:	0	if all pathnames resolved
 *		1	if any of the pathname arguments could not be resolved
 *
 * Chet Ramey
 * [email-masked]
 */

#include <sys/types.h>
#include <sys/stat.h>

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>

#ifndef PATH_MAX
#  define PATH_MAX 1024
#endif

#ifndef errno
extern int	errno;
#endif

extern int	optind;
extern char	*optarg;

static char	*progname;

static void
usage()
{
	fprintf(stderr, "%s: usage: %s [-csv] pathname [pathname...]\n", progname, progname);
	exit(2);
}

main(c, v)
int	c;
char	**v;
{
	int	opt, cflag, vflag, sflag, es;
	char	*r, realbuf[PATH_MAX];
	struct stat sb;

	if (progname = strrchr(v[0], '/'))
		progname++;
	else
		progname = v[0];

	vflag = cflag = sflag = 0;
	while ((opt = getopt (c, v, "csv")) != EOF) {
		switch (opt) {
		case 'c':
			cflag = 1;
			break;
		case 's':
			sflag = 1;
			break;
		case 'v':
			vflag = 1;
			break;
		default:
			usage();
		}
	}

	c -= optind;
	v += optind;

	if (c == 0)
		usage();

	for (opt = es = 0; opt < c; opt++) {
		r = realpath(v[opt], realbuf);
		if (r == 0) {
			es = 1;
			if (sflag == 0)
				fprintf(stderr, "%s: %s: cannot resolve: %s\n", progname, v[opt], strerror(errno));
			continue;
		}
		if (cflag && (stat(realbuf, &sb) < 0)) {
			es = 1;
			if (sflag == 0)
				fprintf(stderr, "%s: %s: %s\n", progname, v[opt], strerror(errno));
			continue;
		}
		if (sflag == 0) {
			if (vflag)
				printf ("%s -> ", v[opt]);
			printf("%s\n", realbuf);
		}
	}
	exit(es);
}

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
( ``Discere est Dolere'' -- chet)

Chet Ramey, CWRU    [email-masked]    http://cnswww.cns.cwru.edu/~chet/

--
Want to unsubscribe from this list?
Send a message to [email-masked]