Fix build (and more) on SmartOS (#363)

* Define _XOPEN_SOURCE_EXTENDED on SmartOS

Enables wide ncurses.

* SmartOS has alloca() in alloca.h

* SmartOS does not have sig_t

* dprintf() is not available on SmartOS

So replace its usage with fprintf.

* SmartOS has no d_type

* SmartOS has no CLOCK_MONOTONIC_RAW

* SmartOS has no O_DIRECTORY

* Work around SmartOS not having mime detection

* Missing comma
This commit is contained in:
Sijmen J. Mulder 2019-10-16 03:37:45 +02:00 committed by Mischievous Meerkat
parent 98042ad7d0
commit 3953639c5d

121
src/nnn.c
View file

@ -58,7 +58,7 @@
#ifndef NCURSES_WIDECHAR #ifndef NCURSES_WIDECHAR
#define NCURSES_WIDECHAR 1 #define NCURSES_WIDECHAR 1
#endif #endif
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(__sun)
#ifndef _XOPEN_SOURCE_EXTENDED #ifndef _XOPEN_SOURCE_EXTENDED
#define _XOPEN_SOURCE_EXTENDED #define _XOPEN_SOURCE_EXTENDED
#endif #endif
@ -86,6 +86,9 @@
#include <signal.h> #include <signal.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef __sun
#include <alloca.h>
#endif
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <time.h> #include <time.h>
@ -318,8 +321,9 @@ static bool interrupted = FALSE;
static sighandler_t oldsighup; /* old value of hangup signal */ static sighandler_t oldsighup; /* old value of hangup signal */
static sighandler_t oldsigtstp; /* old value of SIGTSTP */ static sighandler_t oldsigtstp; /* old value of SIGTSTP */
#else #else
static sig_t oldsighup; /* note: no sig_t on Solaris-derivs */
static sig_t oldsigtstp; static void (*oldsighup)(int);
static void (*oldsigtstp)(int);
#endif #endif
/* For use in functions which are isolated and don't return the buffer */ /* For use in functions which are isolated and don't return the buffer */
@ -338,10 +342,10 @@ static char g_tmpfpath[TMP_LEN_MAX] __attribute__ ((aligned));
#endif #endif
/* Options to identify file mime */ /* Options to identify file mime */
#ifdef __APPLE__ #if defined(__APPLE__)
#define FILE_OPTS "-bIL" #define FILE_MIME_OPTS "-bIL"
#else #elif !defined(__sun) /* no mime option for 'file' */
#define FILE_OPTS "-biL" #define FILE_MIME_OPTS "-biL"
#endif #endif
/* Macros for utilities */ /* Macros for utilities */
@ -2705,14 +2709,14 @@ static inline bool getutil(char *util)
return spawn("which", util, NULL, NULL, F_NORMAL | F_NOTRACE) == 0; return spawn("which", util, NULL, NULL, F_NORMAL | F_NOTRACE) == 0;
} }
static void pipetofd(char *cmd, int fd) static void pipetof(char *cmd, FILE *fout)
{ {
FILE *fp = popen(cmd, "r"); FILE *fin = popen(cmd, "r");
if (fp) { if (fin) {
while (fgets(g_buf, CMD_LEN_MAX - 1, fp)) while (fgets(g_buf, CMD_LEN_MAX - 1, fin))
dprintf(fd, "%s", g_buf); fprintf(fout, "%s", g_buf);
pclose(fp); pclose(fin);
} }
} }
@ -2722,6 +2726,7 @@ static void pipetofd(char *cmd, int fd)
static bool show_stats(const char *fpath, const struct stat *sb) static bool show_stats(const char *fpath, const struct stat *sb)
{ {
int fd; int fd;
FILE *fp;
char *p, *begin = g_buf; char *p, *begin = g_buf;
size_t r; size_t r;
@ -2735,27 +2740,33 @@ static bool show_stats(const char *fpath, const struct stat *sb)
g_buf[r - 1] = '\0'; g_buf[r - 1] = '\0';
DPRINTF_S(g_buf); DPRINTF_S(g_buf);
pipetofd(g_buf, fd); if (!(fp = fdopen(fd, "w"))) {
close(fd);
return FALSE;
}
pipetof(g_buf, fp);
if (S_ISREG(sb->st_mode)) { if (S_ISREG(sb->st_mode)) {
/* Show file(1) output */ /* Show file(1) output */
p = get_output(g_buf, CMD_LEN_MAX, "file", "-b", fpath, FALSE); p = get_output(g_buf, CMD_LEN_MAX, "file", "-b", fpath, FALSE);
if (p) { if (p) {
dprintf(fd, "\n\n "); fprintf(fp, "\n\n ");
while (*p) { while (*p) {
if (*p == ',') { if (*p == ',') {
*p = '\0'; *p = '\0';
dprintf(fd, " %s\n", begin); fprintf(fp, " %s\n", begin);
begin = p + 1; begin = p + 1;
} }
++p; ++p;
} }
dprintf(fd, " %s", begin); fprintf(fp, " %s", begin);
} }
} }
dprintf(fd, "\n\n"); fprintf(fp, "\n\n");
fclose(fp);
close(fd); close(fd);
spawn(pager, g_tmpfpath, NULL, NULL, F_CLI); spawn(pager, g_tmpfpath, NULL, NULL, F_CLI);
@ -3015,12 +3026,12 @@ static void lock_terminal(void)
spawn(tmp, NULL, NULL, NULL, F_NORMAL); spawn(tmp, NULL, NULL, NULL, F_NORMAL);
} }
static void printkv(kv *kvarr, int fd, uchar max) static void printkv(kv *kvarr, FILE *fp, uchar max)
{ {
uchar i = 0; uchar i = 0;
for (; i < max && kvarr[i].key; ++i) for (; i < max && kvarr[i].key; ++i)
dprintf(fd, " %c: %s\n", (char)kvarr[i].key, kvarr[i].val); fprintf(fp, " %c: %s\n", (char)kvarr[i].key, kvarr[i].val);
} }
/* /*
@ -3034,6 +3045,7 @@ static void printkv(kv *kvarr, int fd, uchar max)
static void show_help(const char *path) static void show_help(const char *path)
{ {
int i, fd; int i, fd;
FILE *fp;
const char *start, *end; const char *start, *end;
const char helpstr[] = { const char helpstr[] = {
"0\n" "0\n"
@ -3074,14 +3086,18 @@ static void show_help(const char *path)
fd = create_tmp_file(); fd = create_tmp_file();
if (fd == -1) if (fd == -1)
return; return;
if (!(fp = fdopen(fd, "w"))) {
close(fd);
return;
}
if (getutil("fortune")) if (getutil("fortune"))
pipetofd("fortune -s", fd); pipetof("fortune -s", fp);
start = end = helpstr; start = end = helpstr;
while (*end) { while (*end) {
if (*end == '\n') { if (*end == '\n') {
dprintf(fd, "%*c%.*s", fprintf(fp, "%*c%.*s",
xchartohex(*start), ' ', (int)(end - start), start + 1); xchartohex(*start), ' ', (int)(end - start), start + 1);
start = end + 1; start = end + 1;
} }
@ -3089,31 +3105,32 @@ static void show_help(const char *path)
++end; ++end;
} }
dprintf(fd, "\nVOLUME: %s of ", coolsize(get_fs_info(path, FREE))); fprintf(fp, "\nVOLUME: %s of ", coolsize(get_fs_info(path, FREE)));
dprintf(fd, "%s free\n\n", coolsize(get_fs_info(path, CAPACITY))); fprintf(fp, "%s free\n\n", coolsize(get_fs_info(path, CAPACITY)));
if (bookmark[0].val) { if (bookmark[0].val) {
dprintf(fd, "BOOKMARKS\n"); fprintf(fp, "BOOKMARKS\n");
printkv(bookmark, fd, BM_MAX); printkv(bookmark, fp, BM_MAX);
dprintf(fd, "\n"); fprintf(fp, "\n");
} }
if (plug[0].val) { if (plug[0].val) {
dprintf(fd, "PLUGIN KEYS\n"); fprintf(fp, "PLUGIN KEYS\n");
printkv(plug, fd, PLUGIN_MAX); printkv(plug, fp, PLUGIN_MAX);
dprintf(fd, "\n"); fprintf(fp, "\n");
} }
for (i = NNN_OPENER; i <= NNN_TRASH; ++i) { for (i = NNN_OPENER; i <= NNN_TRASH; ++i) {
start = getenv(env_cfg[i]); start = getenv(env_cfg[i]);
if (start) if (start)
dprintf(fd, "%s: %s\n", env_cfg[i], start); fprintf(fp, "%s: %s\n", env_cfg[i], start);
} }
if (g_selpath) if (g_selpath)
dprintf(fd, "SELECTION FILE: %s\n", g_selpath); fprintf(fp, "SELECTION FILE: %s\n", g_selpath);
dprintf(fd, "\nv%s\n%s\n", VERSION, GENERAL_INFO); fprintf(fp, "\nv%s\n%s\n", VERSION, GENERAL_INFO);
fclose(fp);
close(fd); close(fd);
spawn(pager, g_tmpfpath, NULL, NULL, F_CLI); spawn(pager, g_tmpfpath, NULL, NULL, F_CLI);
@ -3187,7 +3204,11 @@ static int dentfill(char *path, struct entry **dents)
if (!dp) if (!dp)
goto exit; goto exit;
#ifdef __sun
if (cfg.blkorder) { /* no d_type */
#else
if (cfg.blkorder || dp->d_type == DT_UNKNOWN) { if (cfg.blkorder || dp->d_type == DT_UNKNOWN) {
#endif
/* /*
* Optimization added for filesystems which support dirent.d_type * Optimization added for filesystems which support dirent.d_type
* see readdir(3) * see readdir(3)
@ -3302,7 +3323,12 @@ static int dentfill(char *path, struct entry **dents)
/* Copy other fields */ /* Copy other fields */
dentp->t = cfg.mtime ? sb.st_mtime : sb.st_atime; dentp->t = cfg.mtime ? sb.st_mtime : sb.st_atime;
if (dp->d_type == DT_LNK && !flags) { /* Do not add sizes for links */ #ifdef __sun
if (0) { /* no d_type */
#else
if (!flags && dp->d_type == DT_LNK) { /* Do not add sizes for links */
#endif
/* Do not add sizes for links */
dentp->mode = (sb.st_mode & ~S_IFMT) | S_IFLNK; dentp->mode = (sb.st_mode & ~S_IFMT) | S_IFLNK;
dentp->size = 0; dentp->size = 0;
} else { } else {
@ -3350,8 +3376,11 @@ static int dentfill(char *path, struct entry **dents)
if (S_ISDIR(sb.st_mode)) if (S_ISDIR(sb.st_mode))
dentp->flags |= DIR_OR_LINK_TO_DIR; dentp->flags |= DIR_OR_LINK_TO_DIR;
} else if (dp->d_type == DT_DIR || (dp->d_type == DT_LNK && S_ISDIR(sb.st_mode))) #ifndef __sun /* no d_type */
} else if (dp->d_type == DT_DIR || (dp->d_type == DT_LNK && S_ISDIR(sb.st_mode))) {
dentp->flags |= DIR_OR_LINK_TO_DIR; dentp->flags |= DIR_OR_LINK_TO_DIR;
#endif
}
++n; ++n;
} while ((dp = readdir(dirp))); } while ((dp = readdir(dirp)));
@ -3800,7 +3829,15 @@ nochange:
r = curscroll + (event.y - 2); r = curscroll + (event.y - 2);
move_cursor(r, 1); move_cursor(r, 1);
currentmouse ^= 1; currentmouse ^= 1;
clock_gettime(CLOCK_MONOTONIC_RAW, &mousetimings[currentmouse]); clock_gettime(
#if defined(CLOCK_MONOTONIC_RAW)
CLOCK_MONOTONIC_RAW,
#elif defined(CLOCK_MONOTONIC)
CLOCK_MONOTONIC,
#else
CLOCK_REALTIME,
#endif
&mousetimings[currentmouse]);
/*Single click just selects, double click also opens */ /*Single click just selects, double click also opens */
if (((_ABSSUB(mousetimings[0].tv_sec, mousetimings[1].tv_sec) << 30) if (((_ABSSUB(mousetimings[0].tv_sec, mousetimings[1].tv_sec) << 30)
@ -3881,8 +3918,14 @@ nochange:
/* If NNN_USE_EDITOR is set, open text in EDITOR */ /* If NNN_USE_EDITOR is set, open text in EDITOR */
if (cfg.useeditor && if (cfg.useeditor &&
get_output(g_buf, CMD_LEN_MAX, "file", FILE_OPTS, newpath, FALSE) #ifdef FILE_MIME_OPTS
get_output(g_buf, CMD_LEN_MAX, "file", FILE_MIME_OPTS, newpath, FALSE)
&& !strncmp(g_buf, "text/", 5)) { && !strncmp(g_buf, "text/", 5)) {
#else
/* no mime option; guess from description instead */
get_output(g_buf, CMD_LEN_MAX, "file", "-b", newpath, FALSE)
&& strstr(g_buf, "text")) {
#endif
spawn(editor, newpath, NULL, path, F_CLI); spawn(editor, newpath, NULL, path, F_CLI);
continue; continue;
} }
@ -4561,7 +4604,11 @@ nochange:
} }
/* Open the descriptor to currently open directory */ /* Open the descriptor to currently open directory */
#ifdef O_DIRECTORY
fd = open(path, O_RDONLY | O_DIRECTORY); fd = open(path, O_RDONLY | O_DIRECTORY);
#else
fd = open(path, O_RDONLY);
#endif
if (fd == -1) { if (fd == -1) {
printwarn(&presel); printwarn(&presel);
goto nochange; goto nochange;