fe

terminal file explorer and picker

git clone https://9o.is/git/fe.git

commit e56ba05aa681cac65ebcdea81c487729b2bb36f3
parent 8dd5db74d17d9a44c73aa38608ac157ae638cce6
Author: Jul <jul@9o.is>
Date:   Sun, 18 Jan 2026 08:57:49 -0500

improve posix compliance

Diffstat:
MMakefile | 51+++++++++++++++++++++++++++------------------------
Acompats.c | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acompats.h | 8++++++++
Mconfig.def.h | 9---------
Aconfigure | 25+++++++++++++++++++++++++
Mentries.c | 3+--
Mfe.c | 3---
Moptions.c | 2--
Mtty.c | 2--
Mtty_interface.c | 3+--
10 files changed, 168 insertions(+), 44 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,40 +1,43 @@ +.POSIX= VERSION=0.1 -CPPFLAGS=-DVERSION=\"${VERSION}\" -D_GNU_SOURCE -CFLAGS+=-MD -Wall -Wextra -g -std=c99 -O3 -pedantic -Werror=vla -PREFIX?=/usr/local -MANDIR?=$(PREFIX)/share/man -BINDIR?=$(PREFIX)/bin -DEBUGGER?= +PREFIX = /usr/local +MANDIR = $(PREFIX)/share/man +BINDIR = $(PREFIX)/bin -INSTALL=install -INSTALL_PROGRAM=$(INSTALL) -INSTALL_DATA=${INSTALL} -m 644 +INSTALL = install +INSTALL_PROGRAM = $(INSTALL) -m 0755 -OBJECTS=fe.o entries.o options.o spawn.o tty_interface.o tty.o +CFLAGS = -MD -Wall -Wextra -g -std=c99 -O3 -pedantic -Werror=vla +CPPFLAGS = -include config.h \ + -include compats.h \ + -DVERSION=\"${VERSION}\" \ + -D_POSIX_C_SOURCE=200809L -all: fe - -fe: $(OBJECTS) - $(CC) $(CFLAGS) $(CCFLAGS) -o $@ $(OBJECTS) +OBJS = fe.o \ + options.o \ + entries.o \ + tty_interface.o \ + tty.o \ + spawn.o \ + compats.o -%.o: %.c config.h - $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< +all: fe -config.h: config.def.h - cp config.def.h config.h +fe: $(OBJS) + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(OBJS) install: fe mkdir -p $(DESTDIR)$(BINDIR) - cp fe $(DESTDIR)$(BINDIR)/ - chmod 755 ${DESTDIR}${BINDIR}/fe + $(INSTALL_PROGRAM) fe $(DESTDIR)$(BINDIR) + +uninstall: + rm -f $(DESTDIR)$(BINDIR)/fe clean: rm -f fe *.o *.d veryclean: clean - rm -f config.h - -.PHONY: test check all clean veryclean install fmt acceptance + rm -f config.h compats.h --include $(OBJECTS:.o=.d) +.PHONY: all clean veryclean install uninstall diff --git a/compats.c b/compats.c @@ -0,0 +1,106 @@ +#if !HAVE_STRLCAT +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <string.h> + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} +#endif /* !HAVE_STRLCAT */ +#if !HAVE_STRLCPY +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <string.h> + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} +#endif /* !HAVE_STRLCPY */ diff --git a/compats.h b/compats.h @@ -0,0 +1,8 @@ +/* Generated by configure */ + +#define HAVE_STRLCPY 0 +extern size_t strlcpy(char *, const char *, size_t); + +#define HAVE_STRLCAT 0 +extern size_t strlcat(char *, const char *, size_t); + diff --git a/config.def.h b/config.def.h @@ -1,7 +1,3 @@ -#ifdef __cplusplus -extern "C" { -#endif - #include "tty.h" #define COLOR_DIRECTORY TTY_COLOR_BLUE @@ -19,8 +15,3 @@ extern "C" { #define SORT_ICASE 0; #define SORT_MTIME 0; #define SHOW_HIDDEN 0; - -#ifdef __cplusplus -} -#endif - diff --git a/configure b/configure @@ -0,0 +1,25 @@ +#!/usr/bin/env sh + +if [ ! -e config.h ]; then + cp config.def.h config.h +fi + +printf "/* Generated by configure */\n\n" > compats.h + +probe_func() { + def=$1 + ret=$2 + fun=$3 + arg="$4" + + if printf "int main() { void *p = (void *)%s; return 0; }" "$fun" | \ + cc -x c -o /dev/null - >/dev/null 2>&1; then + printf "#define %s 1\n" "$def" >> compats.h + else + printf "#define %s 0\n" "$def" >> compats.h + printf "extern %s %s%s\n\n" "$ret" "$fun" "$arg" >> compats.h + fi +} + +probe_func HAVE_STRLCPY size_t strlcpy '(char *, const char *, size_t);' +probe_func HAVE_STRLCAT size_t strlcat '(char *, const char *, size_t);' diff --git a/entries.c b/entries.c @@ -13,10 +13,9 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <strings.h> #include <unistd.h> - #include "entries.h" -#include "config.h" static int sort_dir; static int sort_icase; diff --git a/fe.c b/fe.c @@ -4,14 +4,11 @@ #include <ctype.h> #include <limits.h> #include <unistd.h> - #include "tty.h" #include "entries.h" #include "options.h" #include "tty_interface.h" -#include "config.h" - int main(int argc, char *argv[]) { options_t options; options_parse(&options, argc, argv); diff --git a/options.c b/options.c @@ -3,9 +3,7 @@ #include <stdlib.h> #include <string.h> #include <limits.h> - #include "options.h" -#include "config.h" static const char *usage_str = "" diff --git a/tty.c b/tty.c @@ -7,9 +7,7 @@ #include <sys/select.h> #include <signal.h> #include <errno.h> - #include "tty.h" -#include "config.h" void tty_reset(tty_t *tty) { tcsetattr(tty->fdin, TCSANOW, &tty->original_termios); diff --git a/tty_interface.c b/tty_interface.c @@ -6,7 +6,6 @@ #include "tty_interface.h" #include "spawn.h" -#include "config.h" static void clear(tty_interface_t *state) { tty_t *tty = state->tty; @@ -275,7 +274,7 @@ static const keybinding_t keybindings[] = { {KEY('.'), action_togglehidden,NULL}, /* . */ {KEY('p'), action_run, "less %s/%s"}, /* p (preview) */ {KEY('t'), action_run, "echo \"create 'vis %s/%s'\" > $DVTM_CMD_FIFO"}, /* edit new tab */ - {KEY('f'), action_setpath, "find %s | fzy -l 999"}, /* s (search) */ + {KEY('f'), action_setpath, "find %s | fzf"}, /* s (search) */ {KEY('-'), action_parent,NULL}, /* - */ {"\x1bOD", action_parent,NULL}, /* LEFT */ {"\x1b[D", action_parent,NULL}, /* LEFT */