Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ test
compile_commands.json

.quickmarks
.firecmds

.DS_Store
2 changes: 1 addition & 1 deletion include/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <git2/types.h>
#include <stdio.h>

#define LASER_VERSION "1.7.2"
#define LASER_VERSION "1.7.3"

typedef struct laser_opts
{
Expand Down
23 changes: 23 additions & 0 deletions include/laser_pwuid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef LASER_PWUID_H
#define LASER_PWUID_H

#include <pwd.h>

struct laser_uid
{
uid_t uid;
char *name; // we don need the whole passwd struct
};

// i doubt you have more than this many users on your system
#define LASER_UID_CACHE_SIZE 64
struct laser_uid_cache
{
struct laser_uid uid_cache[LASER_UID_CACHE_SIZE];
size_t uid_cache_count;
};

struct laser_uid *laser_getpwuid(uid_t uid);
void laser_pwuid_free_cache(void);

#endif
56 changes: 36 additions & 20 deletions src/laser.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "filetypes/checktypes.h"
#include "git/lgit.h"
#include "init_lua.h"
#include "laser_pwuid.h"
#include "logger.h"
#include "lua_filters.h"
#include "utils.h"
Expand All @@ -14,6 +15,9 @@
#define BLOCK_SIZE 512
#define BRANCH_SIZE 8

#define INITIAL_ENTRIES_CAPACITY 16
#define ENTRIES_GROWTH_FACTOR 2

static ssize_t longest_ownername = 0;
static size_t current_dir_total_size = 0;

Expand Down Expand Up @@ -92,7 +96,7 @@ void laser_process_single_file(laser_opts opts)
if (opts.show_git->show_git_status)
lgit_getGitStatus(opts, &entry, opts.dir);

char *ownername = getpwuid(entry.s.st_uid)->pw_name;
char *ownername = laser_getpwuid(entry.s.st_uid)->name;
longest_ownername = strlen(ownername); // this has to be the longest name
// cus it be the ownly name

Expand Down Expand Up @@ -123,7 +127,6 @@ static void laser_list_directory(laser_opts opts, int depth)
}

static void laser_process_entries(laser_opts opts, int depth, char *indent)

{
DIR *dir = opendir(opts.dir);
if (dir == NULL)
Expand All @@ -138,9 +141,11 @@ static void laser_process_entries(laser_opts opts, int depth, char *indent)
strerror(errno));

struct laser_dirent **entries = NULL;
size_t entries_capacity = 0;
if (opts.sort)
{
entries = malloc(sizeof(struct laser_dirent *));
entries_capacity = INITIAL_ENTRIES_CAPACITY;
entries = malloc(sizeof(*entries) * entries_capacity);
if (entries == NULL)
laser_logger_fatal(1, "Failed to allocate entries struct: %s",
strerror(errno));
Expand All @@ -155,7 +160,7 @@ static void laser_process_entries(laser_opts opts, int depth, char *indent)
exit(1);
}

int entry_count = 0;
size_t entry_count = 0;
int entry_ignored = 0;
char full_path[LASER_PATH_MAX];
while ((entry->d = readdir(dir)) != NULL)
Expand Down Expand Up @@ -222,23 +227,25 @@ static void laser_process_entries(laser_opts opts, int depth, char *indent)
current_dir_total_size += entry->s.st_size;
}

char *ownername = getpwuid(entry->s.st_uid)->pw_name;
char *ownername = laser_getpwuid(entry->s.st_uid)->name;
ssize_t ownername_len = strlen(ownername);
if (ownername_len > longest_ownername)
longest_ownername = ownername_len;

if (!opts.sort)
{
// we dunno what dir is gon be last
laser_handle_entry(entry, full_path, indent, depth, opts, 0);
continue;
}

entries = realloc(entries, (entry_count + 1) *
sizeof(struct laser_dirent *));
if (entries == NULL)
laser_logger_fatal(1, "Failed to realloc entries: %s",
strerror(errno));
if (entry_count >= entries_capacity)
{
entries_capacity += ENTRIES_GROWTH_FACTOR;
entries = realloc(entries, sizeof(*entries) * entries_capacity);
if (entries == NULL)
laser_logger_fatal(1, "Failed to realloc entries: %s",
strerror(errno));
}

size_t entry_size = sizeof(struct laser_dirent) +
offsetof(struct dirent, d_name) +
Expand Down Expand Up @@ -276,9 +283,9 @@ static void laser_process_entries(laser_opts opts, int depth, char *indent)
laser_sort(entries, entry_count, sizeof(struct laser_dirent *),
laser_cmp_dirent, NULL);

for (int i = 0; i < entry_count; i++)
for (size_t i = 0; i < entry_count; i++)
{
int is_last = (i == entry_count - 1);
size_t is_last = (i == entry_count - 1);

snprintf(full_path, sizeof(full_path), "%s/%s", opts.dir,
entries[i]->d->d_name);
Expand Down Expand Up @@ -420,7 +427,7 @@ static void laser_print_long_entry(struct laser_dirent *entry,
lua_pushinteger(L, entry->s.st_mtime);
lua_setfield(L, -2, "mtime");

lua_pushstring(L, getpwuid(entry->s.st_uid)->pw_name);
lua_pushstring(L, laser_getpwuid(entry->s.st_uid)->name);
lua_setfield(L, -2, "owner");
lua_pushstring(L, S_ISDIR(entry->s.st_mode) ? "d"
: S_ISLNK(entry->s.st_mode) ? "l"
Expand Down Expand Up @@ -494,11 +501,6 @@ static off_t laser_git_dir_size(struct laser_dirent *ent, char *fp)
if (!S_ISDIR(ent->s.st_mode))
return -1;

off_t s = 0;

struct laser_dirent e;
char full_path[LASER_PATH_MAX];

DIR *dir = opendir(fp);
if (dir == NULL)
{
Expand All @@ -507,14 +509,28 @@ static off_t laser_git_dir_size(struct laser_dirent *ent, char *fp)
return -1;
}

off_t s = 0;

struct laser_dirent e;
size_t fp_len = strlen(fp);

char full_path[LASER_PATH_MAX];
memcpy(full_path, fp, fp_len);
full_path[fp_len] = '/';

while ((e.d = readdir(dir)) != NULL)
{
if (strcmp(e.d->d_name, ".") == 0 || strcmp(e.d->d_name, "..") == 0)
continue;

snprintf(full_path, sizeof(full_path), "%s/%s", fp, e.d->d_name);
// first +1 is to ensure that / is added
memcpy(full_path + fp_len + 1, e.d->d_name, strlen(e.d->d_name) + 1);
if (stat(full_path, &e.s) == -1)
{
// just ignore Eror NO ENTry
if (errno == ENOENT)
continue;

laser_logger_error("couldn't stat %s, %s\n", full_path,
strerror(errno));
continue;
Expand Down
50 changes: 50 additions & 0 deletions src/laser_pwuid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "laser_pwuid.h"
#include "logger.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>

static struct laser_uid_cache uid_cache = {.uid_cache_count = 0};

// to free the allocated memory by the cache you have to call the
// `laser_pwuid_free_cache` function at the end of the program run, you
// SHOULDN'T be manually freeing this memory!!
struct laser_uid *laser_getpwuid(uid_t uid)
{
for (size_t i = 0; i < uid_cache.uid_cache_count; i++)
{
if (uid_cache.uid_cache[i].uid == uid)
return &uid_cache.uid_cache[i];
}

struct passwd *pw = getpwuid(uid);
if (!pw)
laser_logger_fatal(1, "getpwuid failed: %s", strerror(errno));

// if there is not space (which shouldn't happen cuz if it does then that's
// impressive, how many users have you got???) then just return NULL
if (uid_cache.uid_cache_count >= LASER_UID_CACHE_SIZE)
return NULL;

struct laser_uid *entry = &uid_cache.uid_cache[uid_cache.uid_cache_count];
uid_cache.uid_cache_count++;

entry->uid = uid;
entry->name = strdup(pw->pw_name);
if (!entry->name)
laser_logger_fatal(1, "failed to allocate memory for uid name: %s",
strerror(errno));

return entry;
}

void laser_pwuid_free_cache(void)
{
for (size_t i = 0; i < uid_cache.uid_cache_count; i++)
{
if (uid_cache.uid_cache[i].name)
free(uid_cache.uid_cache[i].name);
}

uid_cache.uid_cache_count = 0;
}
3 changes: 2 additions & 1 deletion src/lua_filters.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "lua_filters.h"
#include "laser_pwuid.h"
#include "logger.h"

int lua_filters_apply(laser_opts opts, struct laser_dirent *entry)
Expand All @@ -20,7 +21,7 @@ int lua_filters_apply(laser_opts opts, struct laser_dirent *entry)
lua_pushinteger(L, entry->s.st_mtime);
lua_setfield(L, -2, "mtime");

lua_pushstring(L, getpwuid(entry->s.st_uid)->pw_name);
lua_pushstring(L, laser_getpwuid(entry->s.st_uid)->name);
lua_setfield(L, -2, "owner");

lua_pushstring(L, S_ISDIR(entry->s.st_mode) ? "d"
Expand Down
2 changes: 2 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "colors.h"
#include "init_lua.h"
#include "laser.h"
#include "laser_pwuid.h"
#include "logger.h"
#include <git2.h>
#include <git2/global.h>
Expand Down Expand Up @@ -77,6 +78,7 @@ int main(int argc, char **argv)
clean:
laser_cli_destroy_opts(opts);
laser_lua_destroy();
laser_pwuid_free_cache();
git_libgit2_shutdown();

return 0;
Expand Down