/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */12/*3* Copyright (c) 1997, 2004 Todd C. Miller <[email protected]>4*5* Permission to use, copy, modify, and distribute this software for any6* purpose with or without fee is hereby granted, provided that the above7* copyright notice and this permission notice appear in all copies.8*9* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16*/1718#include <errno.h>19#include <libgen.h>20#include <stdlib.h>21#include <string.h>22#include <sys/param.h>2324char * __freebsd11_dirname(char *path);2526char *27__freebsd11_dirname(char *path)28{29static char *dname = NULL;30size_t len;31const char *endp;3233if (dname == NULL) {34dname = (char *)malloc(MAXPATHLEN);35if (dname == NULL)36return(NULL);37}3839/* Empty or NULL string gets treated as "." */40if (path == NULL || *path == '\0') {41dname[0] = '.';42dname[1] = '\0';43return (dname);44}4546/* Strip any trailing slashes */47endp = path + strlen(path) - 1;48while (endp > path && *endp == '/')49endp--;5051/* Find the start of the dir */52while (endp > path && *endp != '/')53endp--;5455/* Either the dir is "/" or there are no slashes */56if (endp == path) {57dname[0] = *endp == '/' ? '/' : '.';58dname[1] = '\0';59return (dname);60} else {61/* Move forward past the separating slashes */62do {63endp--;64} while (endp > path && *endp == '/');65}6667len = endp - path + 1;68if (len >= MAXPATHLEN) {69errno = ENAMETOOLONG;70return (NULL);71}72memcpy(dname, path, len);73dname[len] = '\0';74return (dname);75}7677__sym_compat(dirname, __freebsd11_dirname, FBSD_1.0);787980