mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
[ncls] implement -L option / symlink handling #2006
This commit is contained in:
parent
70936ada74
commit
b429da0457
@ -21,7 +21,7 @@ ncls - List paths with rendering of multimedia
|
||||
|
||||
**-l**: use a long listing format.
|
||||
|
||||
**-L**: when showing file information for a symbolic link, show information for the file the link references rather than for the link itself.
|
||||
**-L**: dereference symbolic links
|
||||
|
||||
**-R**: list subdirectories recursively.
|
||||
|
||||
|
@ -166,7 +166,7 @@ usage(const char* exe, int status){
|
||||
ncplane_set_fg_rgb8(n, 0xff, 0xff, 0x80);
|
||||
ncplane_printf(n, " -p:");
|
||||
ncplane_set_fg_rgb8(n, 0xff, 0xff, 0xff);
|
||||
ncplane_printf(n, " data file path (default: %s)\n", NOTCURSES_SHARE);
|
||||
ncplane_printf(n, " data file path (default: %s)\n", notcurses_data_dir());
|
||||
ncplane_printf(n, "\nspecify demos via their first letter. repetitions are allowed.\n");
|
||||
ncplane_set_fg_rgb8(n, 0x80, 0xff, 0x80);
|
||||
ncplane_printf(n, " default spec: %s\n\n", DEFAULT_DEMO);
|
||||
|
@ -71,9 +71,7 @@ struct lsContext {
|
||||
int handle_path(int dirfd, const std::string& dir, const char* p, const lsContext& ctx, bool toplevel);
|
||||
|
||||
// handle a single inode of arbitrary type
|
||||
int handle_inode(const std::string& dir, const char* p, const struct stat* st, const lsContext& ctx){
|
||||
(void)st; // FIXME handle symlink (dereflinks)
|
||||
(void)ctx; // FIXME handle symlink (dereflinks)
|
||||
int handle_inode(const std::string& dir, const char* p){
|
||||
pthread_mutex_lock(&mtx);
|
||||
work.emplace(job{dir, p});
|
||||
pthread_mutex_unlock(&mtx);
|
||||
@ -85,12 +83,12 @@ int handle_inode(const std::string& dir, const char* p, const struct stat* st, c
|
||||
// otherwise, if |ctx->recursedirs| or |toplevel| is set, we will recurse,
|
||||
// passing false for toplevel (but preserving |ctx|).
|
||||
int handle_dir(int dirfd, const std::string& pdir, const char* p,
|
||||
const struct stat* st, const lsContext& ctx, bool toplevel){
|
||||
const lsContext& ctx, bool toplevel){
|
||||
if(ctx.directories){
|
||||
return handle_inode(pdir, p, st, ctx);
|
||||
return handle_inode(pdir, p);
|
||||
}
|
||||
if(!ctx.recursedirs && !toplevel){
|
||||
return handle_inode(pdir, p, st, ctx);
|
||||
return handle_inode(pdir, p);
|
||||
}
|
||||
if((strcmp(p, ".") == 0 || strcmp(p, "..") == 0) && !toplevel){
|
||||
return 0;
|
||||
@ -130,36 +128,42 @@ int handle_dir(int dirfd, const std::string& pdir, const char* p,
|
||||
return r;
|
||||
}
|
||||
|
||||
int handle_deref(const char* p, const struct stat* st, const lsContext& ctx){
|
||||
(void)p;
|
||||
(void)st;
|
||||
(void)ctx; // FIXME dereference and rerun on target
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handle some path |p|, either absolute or relative to |dirfd|. |toplevel| is
|
||||
// true iff the path was directly listed on the command line.
|
||||
// true iff the path was directly listed on the command line. we rely on lstat()
|
||||
// and fstatat() to resolve symbolic links for us.
|
||||
int handle_path(int dirfd, const std::string& pdir, const char* p, const lsContext& ctx, bool toplevel){
|
||||
struct stat st;
|
||||
#ifndef __MINGW32__
|
||||
if(fstatat(dirfd, p, &st, AT_NO_AUTOMOUNT)){
|
||||
int flags = AT_NO_AUTOMOUNT;
|
||||
if(!ctx.dereflinks){
|
||||
flags |= AT_SYMLINK_NOFOLLOW;
|
||||
}
|
||||
if(fstatat(dirfd, p, &st, flags)){
|
||||
std::cerr << "Error running fstatat(" << p << "): " << strerror(errno) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(stat(path_join(pdir, p).c_str(), &st)){
|
||||
std::cerr << "Error running stat(" << p << "): " << strerror(errno) << std::endl;
|
||||
return -1;
|
||||
if(ctx.dereflinks){
|
||||
if(lstat(path_join(pdir, p).c_str(), &st)){
|
||||
std::cerr << "Error running stat(" << p << "): " << strerror(errno) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
if(stat(path_join(pdir, p).c_str(), &st)){
|
||||
std::cerr << "Error running stat(" << p << "): " << strerror(errno) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if((st.st_mode & S_IFMT) == S_IFDIR){
|
||||
return handle_dir(dirfd, pdir, p, &st, ctx, toplevel);
|
||||
return handle_dir(dirfd, pdir, p, ctx, toplevel);
|
||||
}else if((st.st_mode & S_IFMT) == S_IFLNK){
|
||||
if(toplevel && ctx.dereflinks){
|
||||
return handle_deref(p, &st, ctx);
|
||||
}
|
||||
pthread_mutex_lock(&outmtx);
|
||||
std::cout << path_join(pdir, p) << '\n';
|
||||
pthread_mutex_unlock(&outmtx);
|
||||
return 0;
|
||||
}
|
||||
return handle_inode(pdir, p, &st, ctx);
|
||||
return handle_inode(pdir, p);
|
||||
}
|
||||
|
||||
// return long-term return code
|
||||
|
Loading…
x
Reference in New Issue
Block a user