New AT_ flags for restricting pathname lookup
New AT_ flags for restricting pathname lookup
Posted Oct 7, 2018 17:22 UTC (Sun) by rweikusat2 (subscriber, #117920)In reply to: New AT_ flags for restricting pathname lookup by eru
Parent article: New AT_ flags for restricting pathname lookup
Manipulating pathnames means "doing string operations", something that's fairly cumbersome in C. For an example, consider the following toy-program:
#define _GNU_SOURCE
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
static char *cwd[] = {
".",
NULL
};
int main(int argc, char **argv)
{
DIR *dir;
struct dirent *d_ent;
struct stat st;
int dirfd, rc;
++argv;
if (!*argv) argv = cwd;
do {
dirfd = open(*argv, O_RDONLY, 0);
if (dirfd == -1) {
perror("open");
continue;
}
dir = fdopendir(dirfd);
if (!dir) {
perror("fdopendir");
continue;
}
printf("-----\nfiles in %s\n-----\n", *argv);
while ((d_ent = readdir(dir))) {
rc = fstatat(dirfd, d_ent->d_name, &, 0);
if (rc == -1) {
if (errno != ENOENT) perror("fstatat");
continue;
}
if (S_ISREG(st.st_mode))
printf("%s\t\t%zu bytes\n", d_ent->d_name, (size_t)st.st_size);
}
closedir(dir);
} while (*++argv);
return 0;
}
This takes a list of directory pathnames as arguments and prints the names and sizes of all files in any of the directories. It uses fstatat because the names returned by readdir are filenames relative to the directory being read. Thanks to the *at-call, they can be accessed without doing dynamic string manipulation and buffer management and also without changing the cwd of the process forward and backward for each directory.
Also, chdir is basically unusable in multi-threaded processes as it changes the working directory of the process, ie, it affects all threads, not just the one executing it and, as seen by another thread, the cwd change is an unpredictable, asynchronously occuring event. Eg, a thread desiring to create two files in the same directory might end up creating them in different directories.
Lastly, the directory a process was started in might have been picked intentionally, eg, as location where core dumps should go to, and the process shouldn't change it except if there's a very good reason for that (and this should be documented).
