Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Jan 2001 14:16:33 +0200
From:      Peter Pentchev <roam@orbitel.bg>
To:        Alfred Perlstein <alfred@FreeBSD.org>
Cc:        cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/bin/mkdir mkdir.c
Message-ID:  <20010114141633.D1598@ringworld.oblivion.bg>
In-Reply-To: <200101141208.f0EC8pk52510@freefall.freebsd.org>; from alfred@FreeBSD.org on Sun, Jan 14, 2001 at 04:08:51AM -0800
References:  <200101141208.f0EC8pk52510@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Jan 14, 2001 at 04:08:51AM -0800, Alfred Perlstein wrote:
> alfred      2001/01/14 04:08:51 PST
> 
>   Modified files:
>     bin/mkdir            mkdir.c 
>   Log:
>   Special case the error reporting when errno is ENOTDIR or ENOENT.
>   
>   This makes "mkdir /nonexistant/foo" complain that /nonexistant
>   doesn't exist rather than /nonexistant/foo which doesn't make much
>   sense.
>   
>   Submitted (in a different form) by: W.H.Scholten <whs@xs4all.nl>
>   
>   Revision  Changes    Path
>   1.20      +6 -2      src/bin/mkdir/mkdir.c

How about the attached program implementing and demonstrating a new
direxname() function, which uses dirname()'s static buffer to extract
the longest existing path component of the specified dirname?
mkdir(1) could report this in case of error (something like
"cannot create /path/exists/nonex/foo/bar, nonexisting path components
 after /path/exists"

G'luck,
Peter

PS. The attached code is a bit modified dirname(1) with the direxname()
function introduced.

-- 
No language can express every thought unambiguously, least of all this one.

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

#include <err.h>
#include <errno.h>
#include <libgen.h>
#include <stdio.h>
#include <sysexits.h>
#include <unistd.h>

char *direxname(const char *path);
void usage(void);

int
main(int argc, char **argv) {
	char ch, *p;

	while (ch = getopt(argc, argv, ""), ch != -1)
		switch (ch) {
			case '?':
			default:
				usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 1)
		usage();

	if (p = direxname(argv[0]), p == NULL)
		err(1, "%s", argv[0]);
	printf("%s\n", p);
	return (EX_OK);
}

void
usage(void) {
	errx(EX_USAGE, "usage: direxname path");
}

char *
direxname(const char *path) {
	char *d;
	struct stat sb;

	for (d = dirname(path); d != NULL; d = dirname(d)) {
		if (stat(d, &sb) == 0)
			return (d);
		if ((errno != ENOTDIR) && (errno != ENOENT))
			return (NULL);
	}

	/* dirname() returned NULL, errno is set */
	return (NULL);
}


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010114141633.D1598>