utils: Add thread-safe variants of dirname(3) and basename(3)

This commit is contained in:
Tobias Brunner
2014-02-24 12:04:11 +01:00
parent ba10cd3c7f
commit 766141bc77
3 changed files with 144 additions and 4 deletions
+61 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2013 Tobias Brunner
* Copyright (C) 2008-2014 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -14,8 +14,7 @@
* for more details.
*/
#include "utils.h"
#define _GNU_SOURCE /* for memrchr */
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
@@ -27,6 +26,8 @@
#include <time.h>
#include <pthread.h>
#include "utils.h"
#include "collections/enumerator.h"
#include "utils/debug.h"
#include "utils/chunk.h"
@@ -193,6 +194,63 @@ char* strreplace(const char *str, const char *search, const char *replace)
return res;
}
/**
* Described in header.
*/
char* path_dirname(const char *path)
{
char *pos;
pos = path ? strrchr(path, '/') : NULL;
if (pos && !pos[1])
{ /* if path ends with slashes we have to look beyond them */
while (pos > path && *pos == '/')
{ /* skip trailing slashes */
pos--;
}
pos = memrchr(path, '/', pos - path + 1);
}
if (!pos)
{
return strdup(".");
}
while (pos > path && *pos == '/')
{ /* skip superfluous slashes */
pos--;
}
return strndup(path, pos - path + 1);
}
/**
* Described in header.
*/
char* path_basename(const char *path)
{
char *pos, *trail = NULL;
if (!path || !*path)
{
return strdup(".");
}
pos = strrchr(path, '/');
if (pos && !pos[1])
{ /* if path ends with slashes we have to look beyond them */
while (pos > path && *pos == '/')
{ /* skip trailing slashes */
pos--;
}
if (pos == path && *pos == '/')
{ /* contains only slashes */
return strdup("/");
}
trail = pos + 1;
pos = memrchr(path, '/', trail - path);
}
pos = pos ? pos + 1 : (char*)path;
return trail ? strndup(pos, trail - pos) : strdup(pos);
}
/**
* Described in header.
*/