Usefulness of access(2) -- source available

Mike Braca mjb at brunix.UUCP
Wed Sep 28 05:57:58 AEST 1983


Here is eaccess for 4.1c BSD:

#include <sys/param.h>
#include <sys/stat.h>
#include <sys/errno.h>

/*
 * Like access(2) except uses effective uid/gid.
 * 4.1c BSD version.
 */

eaccess(filename, mode)
char *filename;
register int mode;
{
	extern int errno;
	struct stat statbuf;
	int euid = geteuid();
	mode &= 7;	/* Clear cruft */

	/*
	 * If we're trying to write, check for
	 * read-only file system or text file busy.
	 */
	if ((mode & 2) &&
	    (access(filename, 2) < 0) &&
	    (errno == EROFS || errno == ETXTBSY))
		return -1;

	/*
	 * Otherwise, superuser always passes.
	 */
	if (euid == 0)
		return 0;

	/*
	 * Stat will fail with correct error number
	 * if we don't have access.
	 */
	if (stat(filename, &statbuf) < 0)
		return -1;

	/*
	 * If we own the file, check owner bits.
	 */
	if (statbuf.st_uid == euid)
		mode <<= 6;

	/*
	 * If we're the same group as the file,
	 * check group bits.
	 */
	else if (statbuf.st_gid == getegid())
		mode <<= 3;

	/*
	 * This is the 4.1c BSD way to check group
	 * membership. 4.2 should be the same.
	 */
	else {
		int ngroups = NGROUPS;	/* from <sys/param.h> */
		int groups[NGROUPS];
		getgroups(&ngroups, groups);
		while (--ngroups >= 0)
			if (groups[ngroups] == statbuf.st_gid) {
				mode <<= 3;
				break;
			}
	}

	/*
	 * Otherwise we are checking "world" bits.
	 * See if the requested access matches the
	 * file permissions.
	 */
	if ((mode & statbuf.st_mode) != mode) {
		errno = EACCES;	/* sic */
		return -1;
	}
	return 0;
}

Mike Braca, Brown U. Institute for Research in Information and Scholarship
{ihnp4,allegra,decvax}!brunix!mjb, mjb.Brown at UDel-Relay, MJB at BROWNCS.BITNET



More information about the Comp.unix.wizards mailing list