HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Implementing dirpath(3p) and fdirpath(3p) functions

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
fdirpathdirpathandfunctionsimplementing

Problem

I'm implementing a dirpath and fdirpath functions, which allow to retrieve path from the directory handle (or its descriptor). This can be useful e.g. if one needs to implement some functions like openat(3) on systems which lack similar functions, but have fork(3), mmap(3) and pthreads. I'd like to know your opinions, suggestions on how to improve these functions, proposals, advice and even remarks. The function shall remain as portable as possible (by portability I mean POSIX).

Source code

```
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

size_t fdirpath(int fd, char *buffer, size_t size)
{
int mfd = -1;
pid_t pid = 0;
int status = 0;
size_t msize = 0;
char *mdata = NULL;
char mpath[] = "/tmp/dirpath/XXXXXX";
int const mflags = MAP_SHARED;
int const mprot = (PROT_READ | PROT_WRITE);
size_t *total = NULL;

if ((fd == -1)
|| ((buffer == NULL) && (size != 0))
|| ((buffer != NULL) && (size == 0))) {
errno = EINVAL;
return (size_t)-1;
}
pthread_mutex_lock(&mutex);
if (mkdir("/tmp/dirpath", 0755) == -1) {
if (errno != EEXIST) {
return (size_t)-1;
}
}
if ((mfd = mkstemp(mpath)) == -1) {
return (size_t)-1;
}
pthread_mutex_unlock(&mutex);

/ Create a temporary shared file /
msize += sizeof(size_t);
msize += size;
if (ftruncate(mfd, (off_t)msize)) {
status = errno;
close(mfd);
unlink(mpath);
errno = status;
return (size_t)-1;
}
if ((mdata = mmap(NULL, msize, mprot, mflags, mfd, 0)) == MAP_FAILED) {
status = errno;
close(mfd);
unlink(mpath);
errno = status;
return (size_t)-1;
}
total = (size_t*)mdata;
mdata += sizeof(size_t);
if (buffer != NULL) {
memcpy(mdata, buffer, size);
}
mdata -= si

Solution

I've used fork(3) to let functions work in the multithreaded environment: getcwd(3) may yield inappropriate results when chdir(3) is called in the different threads.

This problem is solved by introducing more problems. It is very unsafe to fork multithreaded program in the first place (see this blog post for details). I don't know how to solve the path resolution problem in absence of *at() calls in a sane way. Maybe, I'd resort to running a path resolution daemon with a unix domain sockets to communicate open descriptors.

In any case, mmap backed up by the actual file doesn't sound right.

Context

StackExchange Code Review Q#81982, answer score: 2

Revisions (0)

No revisions yet.