Introduction
Introduction Statistics Contact Development Disclaimer Help
Implement nopen(1) - noice - small file browser (mirror / fork from 2f30.org)
git clone git://git.codemadness.org/noice
Log
Files
Refs
README
LICENSE
---
commit 50592339bf450037972b85777d1c524e35545aa8
parent 47d659c5fc930f0815c2bf5a24b3c2228b13695e
Author: sin <[email protected]>
Date: Fri, 2 Aug 2019 15:43:07 +0100
Implement nopen(1)
Diffstat:
M Makefile | 48 ++++++++++++++++++-----------…
D config.def.h | 102 -----------------------------…
M noice.1 | 24 ++++++++----------------
M noice.c | 113 ++---------------------------…
A noiceconf.def.h | 93 +++++++++++++++++++++++++++++…
A nopen.1 | 31 +++++++++++++++++++++++++++++…
A nopen.c | 95 ++++++++++++++++++++++++++++++
A nopenconf.def.h | 9 +++++++++
A spawn.c | 43 ++++++++++++++++++++++++++++++
M strverscmp.c | 2 ++
M util.h | 21 +++++++++++++--------
11 files changed, 327 insertions(+), 254 deletions(-)
---
diff --git a/Makefile b/Makefile
@@ -1,45 +1,53 @@
VERSION = 0.8
-
PREFIX = /usr/local
MANPREFIX = $(PREFIX)/man
#CPPFLAGS = -DDEBUG
#CFLAGS = -g
-LDLIBS = -lcurses
-DISTFILES = noice.c strlcat.c strlcpy.c strverscmp.c util.h config.def.h\
- noice.1 Makefile README LICENSE
-OBJ = noice.o strlcat.o strlcpy.o strverscmp.o
-BIN = noice
+NOICELDLIBS = -lcurses
+NOPENLDLIBS =
+NOICEOBJ = noice.o spawn.o strlcat.o strlcpy.o strverscmp.o
+NOPENOBJ = nopen.o spawn.o
+BIN = noice nopen
+MAN = noice.1 nopen.1
all: $(BIN)
-$(BIN): $(OBJ)
- $(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(LDLIBS)
+noice: $(NOICEOBJ)
+ $(CC) $(CFLAGS) -o $@ $(NOICEOBJ) $(LDFLAGS) $(NOICELDLIBS)
+
+nopen: $(NOPENOBJ)
+ $(CC) $(CFLAGS) -o $@ $(NOPENOBJ) $(LDFLAGS) $(NOPENLDLIBS)
-noice.o: util.h config.h
+noice.o: noiceconf.h util.h
+nopen.o: nopenconf.h util.h
+spawn.o: util.h
strlcat.o: util.h
strlcpy.o: util.h
+strverscmp.o: util.h
+
+noiceconf.h:
+ cp noiceconf.def.h $@
-config.h:
- cp config.def.h $@
+nopenconf.h:
+ cp nopenconf.def.h $@
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
- cp -f $(BIN).1 $(DESTDIR)$(MANPREFIX)/man1
+ cp -f $(MAN) $(DESTDIR)$(MANPREFIX)/man1
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/$(BIN)
- rm -f $(DESTDIR)$(MANPREFIX)/man1/$(BIN).1
+ cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN)
+ cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN)
-dist:
+dist: clean
mkdir -p noice-$(VERSION)
- cp $(DISTFILES) noice-$(VERSION)
- tar -cf noice-$(VERSION).tar noice-$(VERSION)
- gzip noice-$(VERSION).tar
- rm -rf noice-$(VERSION)
+ cp `find . -maxdepth 1 -type f` noice-$(VERSION)
+ tar -c noice-$(VERSION) | gzip > noice-$(VERSION).tar.gz
clean:
- rm -f $(BIN) $(OBJ) noice-$(VERSION).tar.gz
+ rm -f $(BIN) $(NOICEOBJ) $(NOPENOBJ) noice-$(VERSION).tar.gz
+ rm -rf noice-$(VERSION)
diff --git a/config.def.h b/config.def.h
@@ -1,102 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#define CWD "cwd: "
-#define CURSR " > "
-#define EMPTY " "
-
-int dirorder = 0; /* Set to 1 to sort by directory first */
-int mtimeorder = 0; /* Set to 1 to sort by time modified */
-int icaseorder = 0; /* Set to 1 to sort by ignoring case */
-int versorder = 0; /* Set to 1 to sort by version number */
-int idletimeout = 0; /* Screensaver timeout in seconds, 0 to disable */
-int showhidden = 0; /* Set to 1 to show hidden files by default */
-int usecolor = 0; /* Set to 1 to enable color attributes */
-char *idlecmd = "rain"; /* The screensaver program */
-
-/* See curs_attr(3) for valid video attributes */
-#define CURSR_ATTR A_NORMAL
-#define DIR_ATTR A_NORMAL | COLOR_PAIR(4)
-#define LINK_ATTR A_NORMAL | COLOR_PAIR(6)
-#define SOCK_ATTR A_NORMAL | COLOR_PAIR(1)
-#define FIFO_ATTR A_NORMAL | COLOR_PAIR(5)
-#define EXEC_ATTR A_NORMAL | COLOR_PAIR(2)
-
-/* Colors to use with COLOR_PAIR(n) as attributes */
-struct cpair pairs[] = {
- { .fg = 0, .bg = 0 },
- /* pairs start at 1 */
- { COLOR_RED, -1 },
- { COLOR_GREEN, -1 },
- { COLOR_YELLOW, -1 },
- { COLOR_BLUE, -1 },
- { COLOR_MAGENTA, -1 },
- { COLOR_CYAN, -1 },
-};
-
-struct assoc assocs[] = {
- { .regex = "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", .file = "mpv", .argv …
- { .regex = "\\.(png|jpg|gif)$", .file = "sxiv", .argv = { "sxiv", "{}"…
- { .regex = "\\.(html|svg)$", .file = "firefox", .argv = { "firefox", "…
- { .regex = "\\.pdf$", .file = "mupdf", .argv = { "mupdf", "{}", NULL} …
- { .regex = "\\.sh$", .file = "sh", .argv = { "sh", "{}", NULL} },
- { .regex = ".", .file = "less", .argv = { "less", "{}", NULL } },
-};
-
-struct key bindings[] = {
- /* Quit */
- { 'q', SEL_QUIT },
- /* Back */
- { KEY_BACKSPACE, SEL_BACK },
- { KEY_LEFT, SEL_BACK },
- { 'h', SEL_BACK },
- { CONTROL('H'), SEL_BACK },
- /* Inside */
- { KEY_ENTER, SEL_GOIN },
- { '\r', SEL_GOIN },
- { KEY_RIGHT, SEL_GOIN },
- { 'l', SEL_GOIN },
- /* Filter */
- { '/', SEL_FLTR },
- { '&', SEL_FLTR },
- /* Next */
- { 'j', SEL_NEXT },
- { KEY_DOWN, SEL_NEXT },
- { CONTROL('N'), SEL_NEXT },
- /* Previous */
- { 'k', SEL_PREV },
- { KEY_UP, SEL_PREV },
- { CONTROL('P'), SEL_PREV },
- /* Page down */
- { KEY_NPAGE, SEL_PGDN },
- { CONTROL('D'), SEL_PGDN },
- /* Page up */
- { KEY_PPAGE, SEL_PGUP },
- { CONTROL('U'), SEL_PGUP },
- /* Home */
- { KEY_HOME, SEL_HOME },
- { META('<'), SEL_HOME },
- { '^', SEL_HOME },
- /* End */
- { KEY_END, SEL_END },
- { META('>'), SEL_END },
- { '$', SEL_END },
- /* Change dir */
- { 'c', SEL_CD },
- { '~', SEL_CDHOME },
- /* Toggle hide .dot files */
- { '.', SEL_TOGGLEDOT },
- /* Toggle sort by directory first */
- { 'd', SEL_DSORT },
- /* Toggle sort by time */
- { 't', SEL_MTIME },
- /* Toggle case sensitivity */
- { 'i', SEL_ICASE },
- /* Toggle sort by version number */
- { 'v', SEL_VERS },
- { CONTROL('L'), SEL_REDRAW },
- /* Run command */
- { 'z', SEL_RUN, "top" },
- { '!', SEL_RUN, "sh", "SHELL" },
- /* Run command with argument */
- { 'e', SEL_RUNARG, "vi", "EDITOR" },
- { 'p', SEL_RUNARG, "less", "PAGER" },
-};
diff --git a/noice.1 b/noice.1
@@ -1,4 +1,4 @@
-.Dd March 31, 2019
+.Dd August 2, 2019
.Dt NOICE 1
.Os
.Sh NAME
@@ -84,23 +84,13 @@ directory you came out of.
.Sh CONFIGURATION
.Nm
is configured by modifying
-.Pa config.h
+.Pa noiceconf.h
and recompiling the code.
.Pp
-The file associations are specified by regexes
-matching on the currently selected filename.
-If a match is found the associated program is executed
-with the filename passed in as the argument.
-If no match is found the program
-.Xr less 1
-is invoked.
-This is useful for editing text files as one can use the
-.Ic v
-command in
-.Xr less 1
-to edit the file using the
-.Ev EDITOR
-environment variable.
+.Nm
+invokes
+.Xr nopen 1
+to open a file in the user's preferred application.
.Sh FILTERS
Filters allow you to use regexes to display only the matched
entries in the current directory view.
@@ -131,6 +121,8 @@ commands respectively.
If you are using
.Xr urxvt 1
you might have to set backspace key to DEC.
+.Sh SEE ALSO
+.Xr nopen 1
.Sh AUTHORS
.An Lazaros Koromilas Aq Mt [email protected] ,
.An Dimitris Papastamos Aq Mt [email protected] .
diff --git a/noice.c b/noice.c
@@ -1,7 +1,6 @@
/* See LICENSE file for copyright and license details. */
#include <sys/stat.h>
#include <sys/types.h>
-#include <sys/wait.h>
#include <curses.h>
#include <dirent.h>
@@ -20,21 +19,12 @@
#include "util.h"
-#define NR_ARGS 32
-#define LEN(x) (sizeof(x) / sizeof(*(x)))
#undef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define ISODD(x) ((x) & 1)
#define CONTROL(c) ((c) ^ 0x40)
#define META(c) ((c) ^ 0x80)
-struct assoc {
- char *regex; /* Regex to match on filename */
- char *file;
- char *argv[NR_ARGS];
- regex_t regcomp;
-};
-
struct cpair {
int fg;
int bg;
@@ -71,7 +61,7 @@ struct key {
char *env; /* Environment variable to run */
};
-#include "config.h"
+#include "noiceconf.h"
struct entry {
char name[PATH_MAX];
@@ -167,59 +157,6 @@ xdirname(const char *path)
return out;
}
-void
-spawnvp(char *dir, char *file, char *argv[])
-{
- pid_t pid;
- int status;
-
- pid = fork();
- if (pid == 0) {
- if (dir != NULL)
- chdir(dir);
- execvp(file, argv);
- _exit(1);
- } else {
- /* Ignore interruptions */
- while (waitpid(pid, &status, 0) == -1)
- DPRINTF_D(status);
- DPRINTF_D(pid);
- }
-}
-
-void
-spawnlp(char *dir, char *file, char *argv0, ...)
-{
- char *argv[NR_ARGS];
- va_list ap;
- int argc;
-
- va_start(ap, argv0);
- argv[0] = argv0;
- for (argc = 1; argv[argc] = va_arg(ap, char *); argc++)
- ;
- argv[argc] = NULL;
- va_end(ap);
- spawnvp(dir, file, argv);
-}
-
-void
-spawnassoc(struct assoc *assoc, char *arg)
-{
- char *argv[NR_ARGS];
- int i;
-
- for (i = 0; assoc->argv[i]; i++) {
- if (strcmp(assoc->argv[i], "{}") == 0) {
- argv[i] = arg;
- continue;
- }
- argv[i] = assoc->argv[i];
- }
- argv[i] = NULL;
- spawnvp(NULL, assoc->file, argv);
-}
-
char *
xgetenv(char *name, char *fallback)
{
@@ -231,21 +168,6 @@ xgetenv(char *name, char *fallback)
return value && value[0] ? value : fallback;
}
-struct assoc *
-openwith(char *file)
-{
- int i;
-
- for (i = 0; i < LEN(assocs); i++) {
- if (regexec(&assocs[i].regcomp, file, 0, NULL, 0) == 0) {
- DPRINTF_S(assocs[i].argv[0]);
- return &assocs[i];
- }
- }
-
- return NULL;
-}
-
int
setfilter(regex_t *regex, char *filter)
{
@@ -671,7 +593,6 @@ browse(char *ipath, char *ifilter)
char path[PATH_MAX], oldpath[PATH_MAX], newpath[PATH_MAX];
char fltr[LINE_MAX];
char *dir, *tmp, *run, *env;
- struct assoc *assoc;
struct stat sb;
regex_t re;
int r, fd;
@@ -744,13 +665,8 @@ nochange:
strlcpy(fltr, ifilter, sizeof(fltr));
goto begin;
case S_IFREG:
- assoc = openwith(newpath);
- if (assoc == NULL) {
- printmsg("No association");
- goto nochange;
- }
exitcurses();
- spawnassoc(assoc, newpath);
+ spawnlp(path, "nopen", "nopen", newpath, (void…
initcurses();
continue;
default:
@@ -869,7 +785,7 @@ nochange:
mkpath(path, dents[cur].name, oldpath, sizeof(…
run = xgetenv(env, run);
exitcurses();
- spawnlp(path, run, run, NULL);
+ spawnlp(path, run, run, (void *)0);
initcurses();
goto begin;
case SEL_RUNARG:
@@ -878,7 +794,7 @@ nochange:
mkpath(path, dents[cur].name, oldpath, sizeof(…
run = xgetenv(env, run);
exitcurses();
- spawnlp(path, run, run, dents[cur].name, NULL);
+ spawnlp(path, run, run, dents[cur].name, (void *)0);
initcurses();
goto begin;
}
@@ -886,31 +802,13 @@ nochange:
if (idletimeout != 0 && idle == idletimeout) {
idle = 0;
exitcurses();
- spawnlp(NULL, idlecmd, idlecmd, NULL);
+ spawnlp(NULL, idlecmd, idlecmd, (void *)0);
initcurses();
}
}
}
void
-initassocs(void)
-{
- char errbuf[256];
- int i, r;
-
- for (i = 0; i < LEN(assocs); i++) {
- r = regcomp(&assocs[i].regcomp, assocs[i].regex,
- REG_NOSUB | REG_EXTENDED | REG_ICASE);
- if (r != 0) {
- regerror(r, &assocs[i].regcomp, errbuf, sizeof(errbuf)…
- fprintf(stderr, "invalid regex assocs[%d]: %s: %s\n",
- i, assocs[i].regex, errbuf);
- exit(1);
- }
- }
-}
-
-void
usage(char *argv0)
{
fprintf(stderr, "usage: %s [dir]\n", argv0);
@@ -954,7 +852,6 @@ main(int argc, char *argv[])
/* Set locale before curses setup */
setlocale(LC_ALL, "");
- initassocs();
initcurses();
browse(ipath, ifilter);
exitcurses();
diff --git a/noiceconf.def.h b/noiceconf.def.h
@@ -0,0 +1,93 @@
+/* See LICENSE file for copyright and license details. */
+#define CWD "cwd: "
+#define CURSR " > "
+#define EMPTY " "
+
+int dirorder = 0; /* Set to 1 to sort by directory first */
+int mtimeorder = 0; /* Set to 1 to sort by time modified */
+int icaseorder = 0; /* Set to 1 to sort by ignoring case */
+int versorder = 0; /* Set to 1 to sort by version number */
+int idletimeout = 0; /* Screensaver timeout in seconds, 0 to disable */
+int showhidden = 0; /* Set to 1 to show hidden files by default */
+int usecolor = 0; /* Set to 1 to enable color attributes */
+char *idlecmd = "rain"; /* The screensaver program */
+
+/* See curs_attr(3) for valid video attributes */
+#define CURSR_ATTR A_NORMAL
+#define DIR_ATTR A_NORMAL | COLOR_PAIR(4)
+#define LINK_ATTR A_NORMAL | COLOR_PAIR(6)
+#define SOCK_ATTR A_NORMAL | COLOR_PAIR(1)
+#define FIFO_ATTR A_NORMAL | COLOR_PAIR(5)
+#define EXEC_ATTR A_NORMAL | COLOR_PAIR(2)
+
+/* Colors to use with COLOR_PAIR(n) as attributes */
+struct cpair pairs[] = {
+ { .fg = 0, .bg = 0 },
+ /* pairs start at 1 */
+ { COLOR_RED, -1 },
+ { COLOR_GREEN, -1 },
+ { COLOR_YELLOW, -1 },
+ { COLOR_BLUE, -1 },
+ { COLOR_MAGENTA, -1 },
+ { COLOR_CYAN, -1 },
+};
+
+struct key bindings[] = {
+ /* Quit */
+ { 'q', SEL_QUIT },
+ /* Back */
+ { KEY_BACKSPACE, SEL_BACK },
+ { KEY_LEFT, SEL_BACK },
+ { 'h', SEL_BACK },
+ { CONTROL('H'), SEL_BACK },
+ /* Inside */
+ { KEY_ENTER, SEL_GOIN },
+ { '\r', SEL_GOIN },
+ { KEY_RIGHT, SEL_GOIN },
+ { 'l', SEL_GOIN },
+ /* Filter */
+ { '/', SEL_FLTR },
+ { '&', SEL_FLTR },
+ /* Next */
+ { 'j', SEL_NEXT },
+ { KEY_DOWN, SEL_NEXT },
+ { CONTROL('N'), SEL_NEXT },
+ /* Previous */
+ { 'k', SEL_PREV },
+ { KEY_UP, SEL_PREV },
+ { CONTROL('P'), SEL_PREV },
+ /* Page down */
+ { KEY_NPAGE, SEL_PGDN },
+ { CONTROL('D'), SEL_PGDN },
+ /* Page up */
+ { KEY_PPAGE, SEL_PGUP },
+ { CONTROL('U'), SEL_PGUP },
+ /* Home */
+ { KEY_HOME, SEL_HOME },
+ { META('<'), SEL_HOME },
+ { '^', SEL_HOME },
+ /* End */
+ { KEY_END, SEL_END },
+ { META('>'), SEL_END },
+ { '$', SEL_END },
+ /* Change dir */
+ { 'c', SEL_CD },
+ { '~', SEL_CDHOME },
+ /* Toggle hide .dot files */
+ { '.', SEL_TOGGLEDOT },
+ /* Toggle sort by directory first */
+ { 'd', SEL_DSORT },
+ /* Toggle sort by time */
+ { 't', SEL_MTIME },
+ /* Toggle case sensitivity */
+ { 'i', SEL_ICASE },
+ /* Toggle sort by version number */
+ { 'v', SEL_VERS },
+ { CONTROL('L'), SEL_REDRAW },
+ /* Run command */
+ { 'z', SEL_RUN, "top" },
+ { '!', SEL_RUN, "sh", "SHELL" },
+ /* Run command with argument */
+ { 'e', SEL_RUNARG, "vi", "EDITOR" },
+ { 'p', SEL_RUNARG, "less", "PAGER" },
+};
diff --git a/nopen.1 b/nopen.1
@@ -0,0 +1,31 @@
+.Dd August 2, 2019
+.Dt NOPEN 1
+.Os
+.Sh NAME
+.Nm nopen
+.Nd opens a file in the user's preferred application
+.Sh SYNOPSIS
+.Nm
+.Ar file...
+.Sh DESCRIPTION
+.Nm
+opens the files provided as arguments with the user's proferred
+application.
+.Pp
+The file associations are specified by regexes
+matching on the currently selected filename.
+If a match is found the associated program is executed
+with the filename passed in as the argument.
+If no match is found the program
+.Xr less 1
+is invoked.
+.Sh CONFIGURATION
+.Nm
+is configured by modifying
+.Pa nopenconf.h
+and recompiling the code.
+.Sh SEE ALSO
+.Xr noice 1
+.Sh AUTHORS
+.An Lazaros Koromilas Aq Mt [email protected] ,
+.An Dimitris Papastamos Aq Mt [email protected] .
diff --git a/nopen.c b/nopen.c
@@ -0,0 +1,95 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "util.h"
+
+struct assoc {
+ char *regex; /* Regex to match on filename */
+ char *file;
+ char *argv[NR_ARGS];
+ regex_t regcomp;
+};
+
+#include "nopenconf.h"
+
+void
+spawnassoc(struct assoc *assoc, char *arg)
+{
+ char *argv[NR_ARGS];
+ int i;
+
+ for (i = 0; assoc->argv[i]; i++) {
+ if (strcmp(assoc->argv[i], "{}") == 0) {
+ argv[i] = arg;
+ continue;
+ }
+ argv[i] = assoc->argv[i];
+ }
+ argv[i] = NULL;
+ spawnvp(NULL, assoc->file, argv);
+}
+
+struct assoc *
+openwith(char *file)
+{
+ int i;
+
+ for (i = 0; i < LEN(assocs); i++) {
+ if (regexec(&assocs[i].regcomp, file, 0, NULL, 0) == 0)
+ return &assocs[i];
+ }
+
+ return NULL;
+}
+
+void
+initassocs(void)
+{
+ char errbuf[256];
+ int i, r;
+
+ for (i = 0; i < LEN(assocs); i++) {
+ r = regcomp(&assocs[i].regcomp, assocs[i].regex,
+ REG_NOSUB | REG_EXTENDED | REG_ICASE);
+ if (r != 0) {
+ regerror(r, &assocs[i].regcomp, errbuf, sizeof(errbuf)…
+ fprintf(stderr, "invalid regex assocs[%d]: %s: %s\n",
+ i, assocs[i].regex, errbuf);
+ exit(1);
+ }
+ }
+}
+
+void
+usage(char *argv0)
+{
+ fprintf(stderr, "usage: %s file...\n", argv0);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ if (argc == 1)
+ usage(argv[0]);
+ argc--;
+ argv++;
+ initassocs();
+ for (; *argv != NULL; argv++) {
+ struct assoc *assoc;
+
+ assoc = openwith(argv[0]);
+ if (assoc == NULL)
+ continue;
+ spawnassoc(assoc, argv[0]);
+ }
+ return 0;
+}
diff --git a/nopenconf.def.h b/nopenconf.def.h
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+struct assoc assocs[] = {
+ { .regex = "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", .file = "mpv", .argv …
+ { .regex = "\\.(png|jpg|gif)$", .file = "sxiv", .argv = { "sxiv", "{}"…
+ { .regex = "\\.(html|svg)$", .file = "firefox", .argv = { "firefox", "…
+ { .regex = "\\.pdf$", .file = "mupdf", .argv = { "mupdf", "{}", NULL} …
+ { .regex = "\\.sh$", .file = "sh", .argv = { "sh", "{}", NULL} },
+ { .regex = ".", .file = "less", .argv = { "less", "{}", NULL } },
+};
diff --git a/spawn.c b/spawn.c
@@ -0,0 +1,43 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "util.h"
+
+void
+spawnvp(char *dir, char *file, char *argv[])
+{
+ pid_t pid;
+ int status;
+
+ pid = fork();
+ if (pid == 0) {
+ if (dir != NULL)
+ chdir(dir);
+ execvp(file, argv);
+ _exit(1);
+ } else {
+ /* Ignore interruptions */
+ while (waitpid(pid, &status, 0) == -1)
+ ;
+ }
+}
+
+void
+spawnlp(char *dir, char *file, char *argv0, ...)
+{
+ char *argv[NR_ARGS];
+ va_list ap;
+ int argc;
+
+ va_start(ap, argv0);
+ argv[0] = argv0;
+ for (argc = 1; argv[argc] = va_arg(ap, char *); argc++)
+ ;
+ argv[argc] = NULL;
+ va_end(ap);
+ spawnvp(dir, file, argv);
+}
diff --git a/strverscmp.c b/strverscmp.c
@@ -1,6 +1,8 @@
+/* See LICENSE file for copyright and license details. */
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+
#include "util.h"
int
diff --git a/util.h b/util.h
@@ -1,12 +1,6 @@
/* See LICENSE file for copyright and license details. */
-#undef strlcat
-size_t strlcat(char *, const char *, size_t);
-#undef strlcpy
-size_t strlcpy(char *, const char *, size_t);
-#undef dprintf
-int dprintf(int, const char *, ...);
-#undef strverscmp
-int strverscmp(const char *, const char *);
+#define LEN(x) (sizeof(x) / sizeof(*(x)))
+#define NR_ARGS 32
#ifdef DEBUG
#define DEBUG_FD 8
@@ -22,3 +16,14 @@ int strverscmp(const char *, const char *);
#define DPRINTF_P(x)
#define DPRINTF_LLU(x)
#endif /* DEBUG */
+
+#undef strlcat
+size_t strlcat(char *, const char *, size_t);
+#undef strlcpy
+size_t strlcpy(char *, const char *, size_t);
+#undef dprintf
+int dprintf(int, const char *, ...);
+
+int strverscmp(const char *, const char *);
+void spawnvp(char *, char *, char *[]);
+void spawnlp(char *, char *, char *, ...);
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.