return true;
}
-struct file *new_bdev(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd)
-{
- return new_file(class? class: &bdev_class,
- sb, name, map_file_data, fd);
-}
-
static struct partition *new_partition(dev_t dev, const char *name)
{
struct partition *partition = xcalloc(1, sizeof(*partition));
return true;
}
-struct file *new_cdev(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd)
-{
- return new_file(class? class: &cdev_class,
- sb, name, map_file_data, fd);
-}
-
static struct chrdrv *new_chrdrv(unsigned long major, const char *name)
{
struct chrdrv *chrdrv = xcalloc(1, sizeof(*chrdrv));
return true;
}
-struct file *new_fifo(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd)
-{
- return new_file(class? class: &fifo_class,
- sb, name, map_file_data, fd);
-}
-
const struct file_class fifo_class = {
.super = &file_class,
.size = sizeof(struct file),
#include "lsfd.h"
static struct idcache *username_cache;
-static size_t pagesize;
static const char *assocstr[N_ASSOCS] = {
[ASSOC_CWD] = "cwd",
free(file->name);
}
-struct file *new_file(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int association)
-{
- struct file *file;
-
- class = class? class: &file_class;
- file = xcalloc(1, class->size);
-
- file->class = class;
- file->association = association;
- file->name = xstrdup(name);
- file->stat = *sb;
-
- if (file->association == -ASSOC_SHM
- || file->association == -ASSOC_MEM)
- file->assoc_data.map_length = (map_file_data->end - map_file_data->start) / pagesize;
-
- return file;
-}
-
static void file_class_initialize(void)
{
username_cache = new_idcache();
if (!username_cache)
err(EXIT_FAILURE, _("failed to allocate UID cache"));
-
- pagesize = getpagesize();
}
static void file_class_finalize(void)
return true;
}
-struct file *new_sock(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd,
- struct proc *proc)
+static void init_sock_content(struct file *file,
+ struct proc *proc,
+ struct map_file_data *map_file_data)
{
- struct file *file = new_file(class? class: &sock_class,
- sb, name, map_file_data, fd);
+ int fd;
+
+ assert(file);
+ assert(proc);
+
+ fd = file->association;
+
if (fd >= 0 || fd == -ASSOC_MEM || fd == -ASSOC_SHM) {
struct sock *sock = (struct sock *)file;
-
char path[PATH_MAX];
char buf[256];
ssize_t len;
+
memset(path, 0, sizeof(path));
if (fd >= 0)
sprintf(path, "/proc/%d/fd/%d", proc->pid, fd);
- else
+ else {
+ assert(map_file_data);
sprintf(path, "/proc/%d/map_files/%lx-%lx", proc->pid,
map_file_data->start, map_file_data->end);
+ }
len = getxattr(path, "system.sockprotoname", buf, sizeof(buf) - 1);
if (len > 0) {
buf[len] = '\0';
sock->protoname = xstrdup(buf);
}
}
-
- return file;
}
static void free_sock_content(struct file *file)
.super = &file_class,
.size = sizeof(struct sock),
.fill_column = sock_fill_column,
+ .initialize_content = init_sock_content,
.free_content = free_sock_content,
};
return true;
}
-struct file *new_unkn(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd)
-{
- return new_file(class? class: &unkn_class,
- sb, name, map_file_data, fd);
-}
-
const struct file_class unkn_class = {
.super = &file_class,
.size = sizeof(struct file),
.fill_column = unkn_fill_column,
- .free_content = NULL,
};
#include "lsfd.h"
+
static void fill_proc(struct proc *proc);
static void add_nodev(unsigned long minor, const char *filesystem);
}
+static struct file *new_file(const struct file_class *class,
+ struct proc *proc,
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int association)
+{
+ struct file *file;
+
+ assert(class);
+
+ file = xcalloc(1, class->size);
+ file->class = class;
+ file->association = association;
+ file->name = xstrdup(name);
+ file->stat = *sb;
+
+ if (file->association == -ASSOC_SHM || file->association == -ASSOC_MEM) {
+ static size_t pagesize = 0;
+
+ assert(map_file_data);
+ if (!pagesize)
+ pagesize = getpagesize();
+
+ file->assoc_data.map_length =
+ (map_file_data->end - map_file_data->start) / pagesize;
+ }
+
+ if (file->class->initialize_content)
+ file->class->initialize_content(file, proc, map_file_data);
+
+ return file;
+}
+
+
static struct proc *new_prococess(pid_t pid, struct proc * leader)
{
struct proc *proc = xcalloc(1, sizeof(*proc));
}
}
-static struct file *collect_file(struct proc *proc,
- struct stat *sb, char *name,
- struct map_file_data *map_file_data,
- int assoc)
+static const struct file_class *stat2class(struct stat *sb)
{
+ assert(sb);
+
switch (sb->st_mode & S_IFMT) {
case S_IFCHR:
- return new_cdev(NULL, sb, name, map_file_data, assoc);
+ return &cdev_class;
case S_IFBLK:
- return new_bdev(NULL, sb, name, map_file_data, assoc);
+ return &bdev_class;
case S_IFSOCK:
- return new_sock(NULL, sb, name, map_file_data, assoc, proc);
+ return &sock_class;
case S_IFIFO:
- return new_fifo(NULL, sb, name, map_file_data, assoc);
+ return &fifo_class;
case S_IFLNK:
case S_IFREG:
case S_IFDIR:
- return new_file(NULL, sb, name, map_file_data, assoc);
+ return &file_class;
default:
- return new_unkn(NULL, sb, name, map_file_data, assoc);
+ break;
}
+
+ return &unkn_class;
+}
+
+static struct file *collect_file(struct proc *proc,
+ struct stat *sb, char *name,
+ struct map_file_data *map_file_data,
+ int assoc)
+{
+ return new_file(stat2class(sb), proc, sb, name, map_file_data, assoc);
}
static void read_fdinfo(struct file *file, FILE *fdinfo)
int column_id,
size_t column_index);
int (*handle_fdinfo)(struct file *file, const char *key, const char* value);
+ void (*initialize_content)(struct file *file,
+ struct proc *proc,
+ struct map_file_data *map_file_data);
void (*free_content)(struct file *file);
};
extern const struct file_class file_class, cdev_class, bdev_class, sock_class, unkn_class, fifo_class;
-struct file *new_file(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int association);
-struct file *new_cdev(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd);
-struct file *new_bdev(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd);
-struct file *new_sock(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd,
- struct proc *proc);
-struct file *new_unkn(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd);
-struct file *new_fifo(const struct file_class *class,
- struct stat *sb, const char *name,
- struct map_file_data *map_file_data,
- int fd);
-
/*
* Name managing
*/