From owner-freebsd-hackers Tue Jan 16 4:52: 7 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from ringworld.nanolink.com (ringworld.nanolink.com [195.24.48.189]) by hub.freebsd.org (Postfix) with SMTP id 3132037B69C for ; Tue, 16 Jan 2001 04:51:44 -0800 (PST) Received: (qmail 6881 invoked by uid 1000); 16 Jan 2001 12:50:20 -0000 Date: Tue, 16 Jan 2001 14:50:20 +0200 From: Peter Pentchev To: mouss Cc: "W.H.Scholten" , Alfred Perlstein , freebsd-hackers@FreeBSD.ORG Subject: Re: pppd & mkdir diff Message-ID: <20010116145020.E364@ringworld.oblivion.bg> Mail-Followup-To: mouss , "W.H.Scholten" , Alfred Perlstein , freebsd-hackers@FreeBSD.ORG References: <3A5C843C.794BDF32@xs4all.nl> <20010111132509.J7240@fw.wintelcom.net> <3A5EE6B1.41C67EA6@xs4all.nl> <20010112081422.U7240@fw.wintelcom.net> <3A6025F1.794BDF32@xs4all.nl> <4.3.0.20010116131322.03f23a80@pop.free.fr> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <4.3.0.20010116131322.03f23a80@pop.free.fr>; from usebsd@free.fr on Tue, Jan 16, 2001 at 01:32:13PM +0100 Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Tue, Jan 16, 2001 at 01:32:13PM +0100, mouss wrote: > These are probably cosmetic comments, but here they are anyway... > > > At 09:54 13/01/01 +0000, W.H.Scholten wrote: > > >+char *dirname(char *path) { > >+ char *slash; > >+ > >+ while (path[ strlen(path)-1 ] == '/') path[ strlen(path)-1 ] = 0; > > if path is an empty string, you are accessing path[-1], which is dangerous. > > Also, you're computing strlen too many times, and strlen is a loop > (while (*ptr) ptr++). so I suggest using a pointer to the string as in > /usr/bin/dirname/dirname.c. mainly: > if (*path == '\0') return "/"; /* if const is not ok, strdup("/") */ > ptr = path; > while (*ptr) ptr++; > while ((*ptr == '/') && (ptr > path)) ptr--; > ... > > > >+ > >+ slash = strrchr(path, '/'); > >+ if (slash) { > >+ *slash = 0; > >+ while (path[ strlen(path)-1 ] == '/') path[ strlen(path)-1 > >] = 0; > > you already did that (I mean trimming the trailing slashes). > > Finally, I'd propose adding such a function (dirname) in a library (either libc > or say libfile) to allow code reuse. such a lib would contain functions > such as basename, dir_create (mkdir -p), .... so that the commands > mkdir, rmdir, cp, mv, ... etc call the lib functions instead of rewriting code. As somebody already pointed out, there *is* a dirname(3) function, and even a dirname(1) cmdline utility to invoke it. In a followup to Alfred's mkdir(1) commit, I sent a sample implementation of a direxname() function, which calls dirname(3) in a loop, and returns the longest existing path component. I'll get back to him shortly with a patch to mkdir(1) using direxname() to report a meaningful error message, something like "Cannot create /exists/nonex/foo/bar, nonexistent path components after /exists". In the meantime, attached is my first shot at direxname() implementation, using dirname(3)'s static buffer. G'luck, Peter -- "yields falsehood, when appended to its quotation." yields falsehood, when appended to its quotation. #include #include #include #include #include #include #include #include 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 freebsd-hackers" in the body of the message