}
struct file *make_bdev(const struct file_class *class,
- struct stat *sb, const char *name, int fd)
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd)
{
return make_file(class? class: &bdev_class,
- sb, name, fd);
+ sb, name, map_file_data, fd);
}
static struct partition *make_partition(dev_t dev, const char *name)
}
struct file *make_cdev(const struct file_class *class,
- struct stat *sb, const char *name, int fd)
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd)
{
return make_file(class? class: &cdev_class,
- sb, name, fd);
+ sb, name, map_file_data, fd);
}
static struct chrdrv *make_chrdrv(unsigned long major, const char *name)
}
struct file *make_fifo(const struct file_class *class,
- struct stat *sb, const char *name, int fd)
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd)
{
return make_file(class? class: &fifo_class,
- sb, name, fd);
+ sb, name, map_file_data, fd);
}
const struct file_class fifo_class = {
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <unistd.h>
+
#include "xalloc.h"
#include "nls.h"
#include "buffer.h"
#include "lsfd.h"
static struct idcache *username_cache;
+static size_t pagesize;
static const char *assocstr[N_ASSOCS] = {
[ASSOC_CWD] = "cwd",
str = ul_buffer_get_data(&buf, NULL, NULL);
break;
}
+ case COL_MAPLEN:
+ if (file->association != -ASSOC_SHM
+ && file->association != -ASSOC_MEM)
+ return true;
+ xasprintf(&str, "%lu", file->assoc_data.map_length);
+ break;
default:
return false;
};
}
struct file *make_file(const struct file_class *class,
- struct stat *sb, const char *name, int association)
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int association)
{
struct file *file;
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;
}
username_cache = new_idcache();
if (!username_cache)
err(EXIT_FAILURE, _("failed to allocate UID cache"));
+
+ pagesize = getpagesize();
}
static void file_class_finalize(void)
}
struct file *make_sock(const struct file_class *class,
- struct stat *sb, const char *name, int fd,
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd,
struct proc *proc)
{
struct file *file = make_file(class? class: &sock_class,
- sb, name, fd);
+ sb, name, map_file_data, fd);
if (fd >= 0) {
struct sock *sock = (struct sock *)file;
}
struct file *make_unkn(const struct file_class *class,
- struct stat *sb, const char *name, int fd)
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd)
{
return make_file(class? class: &unkn_class,
- sb, name, fd);
+ sb, name, map_file_data, fd);
}
const struct file_class unkn_class = {
N_("file descriptor for the file") },
[COL_INODE] = { "INODE", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER,
N_("inode number") },
+ [COL_MAPLEN] = { "MAPLEN", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER,
+ N_("length of file mapping (in page)") },
[COL_MISCDEV] = { "MISCDEV", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING,
N_("misc character device name resolved by /procmisc") },
[COL_MNT_ID] = { "MNTID", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER,
}
static struct file *collect_file(struct proc *proc,
- struct stat *sb, char *name, int assoc)
+ struct stat *sb, char *name,
+ struct map_file_data *map_file_data,
+ int assoc)
{
switch (sb->st_mode & S_IFMT) {
case S_IFCHR:
- return make_cdev(NULL, sb, name, assoc);
+ return make_cdev(NULL, sb, name, map_file_data, assoc);
case S_IFBLK:
- return make_bdev(NULL, sb, name, assoc);
+ return make_bdev(NULL, sb, name, map_file_data, assoc);
case S_IFSOCK:
- return make_sock(NULL, sb, name, assoc, proc);
+ return make_sock(NULL, sb, name, map_file_data, assoc, proc);
case S_IFIFO:
- return make_fifo(NULL, sb, name, assoc);
+ return make_fifo(NULL, sb, name, map_file_data, assoc);
case S_IFLNK:
case S_IFREG:
case S_IFDIR:
- return make_file(NULL, sb, name, assoc);
+ return make_file(NULL, sb, name, map_file_data, assoc);
default:
- return make_unkn(NULL, sb, name, assoc);
+ return make_unkn(NULL, sb, name, map_file_data, assoc);
}
}
if ((len = readlinkat(dd, dp->d_name, sym, sizeof(sym) - 1)) < 0)
return NULL;
- f = collect_file(proc, &sb, sym, (int)num);
+ f = collect_file(proc, &sb, sym, NULL, (int)num);
if (!f)
return NULL;
ssize_t len;
char sym[PATH_MAX];
struct file *f;
- unsigned long start, end;
+ struct map_file_data map_file_data;
struct map *map;
enum association assoc;
map = NULL;
- if (sscanf(dp->d_name, "%lx-%lx", &start, &end) == 2)
- map = find_map(maps, start);
+ if (sscanf(dp->d_name, "%lx-%lx", &map_file_data.start, &map_file_data.end) == 2)
+ map = find_map(maps, map_file_data.start);
assoc = (map && map->shared)? ASSOC_SHM: ASSOC_MEM;
- f = collect_file(proc, &sb, sym, -assoc);
+ f = collect_file(proc, &sb, sym, &map_file_data, -assoc);
if (!f)
return NULL;
if ((len = readlinkat(dd, name, sym, sizeof(sym) - 1)) < 0)
return NULL;
- return collect_file(proc, &sb, sym, association);
+ return collect_file(proc, &sb, sym, NULL, association);
}
static void collect_proc_uid(struct proc *proc, int dd)
COL_FD,
COL_FLAGS,
COL_INODE,
+ COL_MAPLEN,
COL_MISCDEV,
COL_MNT_ID,
COL_MODE,
int mnt_id;
};
+struct map_file_data {
+ unsigned long start, end;
+};
+
struct file {
struct list_head files;
const struct file_class *class;
unsigned long long pos;
union assoc_data {
struct fdinfo_data fdinfo;
+ unsigned long map_length;
} assoc_data;
};
extern const struct file_class file_class, cdev_class, bdev_class, sock_class, unkn_class, fifo_class;
struct file *make_file(const struct file_class *class,
- struct stat *sb, const char *name, int association);
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int association);
struct file *make_cdev(const struct file_class *class,
- struct stat *sb, const char *name, int fd);
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd);
struct file *make_bdev(const struct file_class *class,
- struct stat *sb, const char *name, int fd);
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd);
struct file *make_sock(const struct file_class *class,
- struct stat *sb, const char *name, int fd,
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd,
struct proc *proc);
struct file *make_unkn(const struct file_class *class,
- struct stat *sb, const char *name, int fd);
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd);
struct file *make_fifo(const struct file_class *class,
- struct stat *sb, const char *name, int fd);
+ struct stat *sb, const char *name,
+ struct map_file_data *map_file_data,
+ int fd);
/*
* Name managing