diff --git a/Build.sh b/Build.sh index 2c1400e..5382a6b 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.601 2012/12/17 22:57:49 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.602 2012/12/17 23:18:01 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012 @@ -1527,7 +1527,7 @@ else #define EXTERN #define MKSH_INCLUDES_ONLY #include "sh.h" - __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.601 2012/12/17 22:57:49 tg Exp $"); + __RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.602 2012/12/17 23:18:01 tg Exp $"); int main(void) { printf("Hello, World!\n"); return (0); } EOF case $cm in @@ -1779,6 +1779,12 @@ ac_test strerror <<-'EOF' int main(int ac, char *av[]) { return (*strerror(*av[ac])); } EOF +ac_test sys_errlist '!' strerror 0 "the sys_signame[] array and sys_nerr" <<-'EOF' + extern int sys_nerr; + extern char *sys_errlist[]; + int main(void) { return (*sys_errlist[sys_nerr - 1]); } +EOF + ac_test strlcpy <<-'EOF' #include int main(int ac, char *av[]) { return (strlcpy(*av, av[1], @@ -1805,11 +1811,15 @@ ac_test '!' revoke_decl revoke 1 'if revoke() does not need to be declared' <<-' long revoke(void); /* this clashes if defined before */ int main(void) { return ((int)revoke()); } EOF -ac_test '!' sys_siglist_decl sys_siglist 1 'if sys_siglist[] does not need to be declared' <<-'EOF' +ac_test sys_errlist_decl sys_errlist 0 "for declaration of sys_errlist[] and sys_nerr" <<-'EOF' #define MKSH_INCLUDES_ONLY #include "sh.h" - extern int sys_siglist[5][5][5][5][5]; /* this clashes happily */ - int main(void) { return (sys_siglist[0][0][0][0][0]); } + int main(void) { return (*sys_errlist[sys_nerr - 1]); } +EOF +ac_test sys_siglist_decl sys_siglist 1 'for declaration of sys_siglist[]' <<-'EOF' + #define MKSH_INCLUDES_ONLY + #include "sh.h" + int main(void) { return (sys_siglist[0][0]); } EOF CC=$save_CC; LDFLAGS=$save_LDFLAGS; LIBS=$save_LIBS diff --git a/eval.c b/eval.c index 44f43ba..6fdf4a3 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.131 2012/12/08 18:30:29 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.132 2012/12/17 23:18:03 tg Exp $"); /* * string expansion @@ -1325,7 +1325,7 @@ comsub(Expand *xp, const char *cp, int fn MKSH_A_UNUSED) maketemp(ATEMP, TT_FUNSUB, &tf); if (!tf->shf) { errorf("can't %s temporary file %s: %s", - "create", tf->tffn, strerror(errno)); + "create", tf->tffn, cstrerror(errno)); } /* save stdout and make the temporary file it */ ofd1 = savefd(1); diff --git a/exec.c b/exec.c index 281417e..d047ca4 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.108 2012/12/04 01:18:27 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.109 2012/12/17 23:18:03 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL "/bin/sh" @@ -461,7 +461,7 @@ execute(struct op * volatile t, if (rv == ENOEXEC) scriptexec(t, (const char **)up); else - errorf("%s: %s", s, strerror(rv)); + errorf("%s: %s", s, cstrerror(rv)); } Break: exstat = rv & 0xFF; @@ -688,14 +688,14 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, rv = (tp->u2.errnov == ENOENT) ? 127 : 126; warningf(true, "%s: %s %s: %s", cp, "can't find", "function definition file", - strerror(tp->u2.errnov)); + cstrerror(tp->u2.errnov)); break; } if (include(tp->u.fpath, 0, NULL, false) < 0) { rv = errno; warningf(true, "%s: %s %s %s: %s", cp, "can't open", "function definition file", - tp->u.fpath, strerror(rv)); + tp->u.fpath, cstrerror(rv)); rv = 127; break; } @@ -789,7 +789,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, } else { rv = 126; warningf(true, "%s: %s: %s", cp, "can't execute", - strerror(tp->u2.errnov)); + cstrerror(tp->u2.errnov)); } break; } @@ -924,7 +924,7 @@ scriptexec(struct op *tp, const char **ap) execve(args.rw[0], args.rw, cap.rw); /* report both the programme that was run and the bogus interpreter */ - errorf("%s: %s: %s", tp->str, sh, strerror(errno)); + errorf("%s: %s: %s", tp->str, sh, cstrerror(errno)); } int @@ -1363,7 +1363,7 @@ iosetup(struct ioword *iop, struct tbl *tp) warningf(true, "can't %s %s: %s", iotype == IODUP ? "dup" : (iotype == IOREAD || iotype == IOHERE) ? - "open" : "create", cp, strerror(u)); + "open" : "create", cp, cstrerror(u)); } return (-1); } @@ -1393,7 +1393,7 @@ iosetup(struct ioword *iop, struct tbl *tp) warningf(true, "%s %s %s", "can't finish (dup) redirection", snptreef(NULL, 32, "%R", &iotmp), - strerror(eno)); + cstrerror(eno)); if (iotype != IODUP) close(u); return (-1); @@ -1486,7 +1486,7 @@ herein(const char *content, int sub, char **resbuf) if (!(shf = h->shf) || (fd = open(h->tffn, O_RDONLY, 0)) < 0) { i = errno; warningf(true, "can't %s temporary file %s: %s", - !shf ? "create" : "open", h->tffn, strerror(i)); + !shf ? "create" : "open", h->tffn, cstrerror(i)); if (shf) shf_close(shf); /* special to iosetup(): don't print error */ @@ -1503,7 +1503,7 @@ herein(const char *content, int sub, char **resbuf) i = errno; close(fd); warningf(true, "can't %s temporary file %s: %s", - "write", h->tffn, strerror(i)); + "write", h->tffn, cstrerror(i)); /* special to iosetup(): don't print error */ return (-2); } diff --git a/funcs.c b/funcs.c index 8a341d6..8bc740c 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.234 2012/12/17 23:09:15 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.235 2012/12/17 23:18:04 tg Exp $"); #if HAVE_KILLPG /* @@ -253,7 +253,7 @@ c_pwd(const char **wp) p = NULL; if (!p && !(p = allocd = ksh_get_wd())) { bi_errorf("%s: %s", "can't determine current directory", - strerror(errno)); + cstrerror(errno)); return (1); } shprintf("%s\n", p); @@ -1379,7 +1379,7 @@ c_kill(const char **wp) rv = 1; } else { if (mksh_kill(n, sig) < 0) { - bi_errorf("%s: %s", p, strerror(errno)); + bi_errorf("%s: %s", p, cstrerror(errno)); rv = 1; } } @@ -1726,7 +1726,7 @@ c_dot(const char **wp) return (1); } if ((file = search_path(cp, path, R_OK, &errcode)) == NULL) { - bi_errorf("%s: %s", cp, strerror(errcode)); + bi_errorf("%s: %s", cp, cstrerror(errcode)); return (1); } @@ -1743,7 +1743,7 @@ c_dot(const char **wp) } if ((i = include(file, argc, argv, false)) < 0) { /* should not happen */ - bi_errorf("%s: %s", cp, strerror(errno)); + bi_errorf("%s: %s", cp, cstrerror(errno)); return (1); } return (i); @@ -1834,7 +1834,7 @@ c_read(const char **wp) #if HAVE_SELECT case 't': if (parse_usec(builtin_opt.optarg, &tv)) { - bi_errorf("%s: %s '%s'", Tsynerr, strerror(errno), + bi_errorf("%s: %s '%s'", Tsynerr, cstrerror(errno), builtin_opt.optarg); return (2); } @@ -1916,7 +1916,7 @@ c_read(const char **wp) rv = 1; goto c_read_out; default: - bi_errorf("%s: %s", Tselect, strerror(errno)); + bi_errorf("%s: %s", Tselect, cstrerror(errno)); rv = 2; goto c_read_out; } @@ -2710,7 +2710,7 @@ c_mknod(const char **wp) goto c_mknod_failed; } else if (mkfifo(argv[0], mode)) { c_mknod_failed: - bi_errorf("%s: %s", argv[0], strerror(errno)); + bi_errorf("%s: %s", argv[0], cstrerror(errno)); c_mknod_err: rv = 1; } @@ -3610,7 +3610,7 @@ set_ulimit(const struct limits *l, const char *v, int how) if (errno == EPERM) bi_errorf("%s exceeds allowable %s limit", v, l->name); else - bi_errorf("bad %s limit: %s", l->name, strerror(errno)); + bi_errorf("bad %s limit: %s", l->name, cstrerror(errno)); return (1); } @@ -3653,7 +3653,7 @@ c_rename(const char **wp) bi_errorf(Tsynerr); else if ((rv = rename(wp[0], wp[1])) != 0) { rv = errno; - bi_errorf("%s: %s", "failed", strerror(rv)); + bi_errorf("%s: %s", "failed", cstrerror(rv)); } return (rv); @@ -3676,7 +3676,7 @@ c_realpath(const char **wp) bi_errorf(Tsynerr); else if ((buf = do_realpath(wp[0])) == NULL) { rv = errno; - bi_errorf("%s: %s", wp[0], strerror(rv)); + bi_errorf("%s: %s", wp[0], cstrerror(rv)); if ((unsigned int)rv > 255) rv = 255; } else { @@ -3723,7 +3723,7 @@ c_cat(const char **wp) fd = STDIN_FILENO; else if ((fd = open(fn, O_RDONLY)) < 0) { eno = errno; - bi_errorf("%s: %s", fn, strerror(eno)); + bi_errorf("%s: %s", fn, cstrerror(eno)); rv = 1; continue; } @@ -3739,7 +3739,7 @@ c_cat(const char **wp) continue; } /* an error occured during reading */ - bi_errorf("%s: %s", fn, strerror(eno)); + bi_errorf("%s: %s", fn, cstrerror(eno)); rv = 1; break; } else if (n == 0) @@ -3754,7 +3754,7 @@ c_cat(const char **wp) /* an error occured during writing */ eno = errno; bi_errorf("%s: %s", "", - strerror(eno)); + cstrerror(eno)); rv = 1; if (fd != STDIN_FILENO) close(fd); @@ -3789,7 +3789,7 @@ c_sleep(const char **wp) if (!wp[0] || wp[1]) bi_errorf(Tsynerr); else if (parse_usec(wp[0], &tv)) - bi_errorf("%s: %s '%s'", Tsynerr, strerror(errno), wp[0]); + bi_errorf("%s: %s '%s'", Tsynerr, cstrerror(errno), wp[0]); else { #ifndef MKSH_NOPROSPECTOFWORK sigset_t omask, bmask; @@ -3819,7 +3819,7 @@ c_sleep(const char **wp) */ rv = 0; else - bi_errorf("%s: %s", Tselect, strerror(errno)); + bi_errorf("%s: %s", Tselect, cstrerror(errno)); #ifndef MKSH_NOPROSPECTOFWORK /* this will re-schedule signal delivery */ sigprocmask(SIG_SETMASK, &omask, NULL); diff --git a/histrap.c b/histrap.c index 74d3fa5..13fee35 100644 --- a/histrap.c +++ b/histrap.c @@ -27,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.129 2012/12/04 01:18:30 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.130 2012/12/17 23:18:05 tg Exp $"); Trap sigtraps[NSIG + 1]; static struct sigaction Sigact_ign; @@ -297,7 +297,7 @@ c_fc(const char **wp) tf = maketemp(ATEMP, TT_HIST_EDIT, &e->temps); if (!(shf = tf->shf)) { bi_errorf("can't %s temporary file %s: %s", - "create", tf->tffn, strerror(errno)); + "create", tf->tffn, cstrerror(errno)); return (1); } for (hp = rflag ? hlast : hfirst; @@ -305,7 +305,7 @@ c_fc(const char **wp) shf_fprintf(shf, "%s\n", *hp); if (shf_close(shf) == EOF) { bi_errorf("can't %s temporary file %s: %s", - "write", tf->tffn, strerror(errno)); + "write", tf->tffn, cstrerror(errno)); return (1); } @@ -331,7 +331,7 @@ c_fc(const char **wp) if (!(shf = shf_open(tf->tffn, O_RDONLY, 0, 0))) { bi_errorf("can't %s temporary file %s: %s", - "open", tf->tffn, strerror(errno)); + "open", tf->tffn, cstrerror(errno)); return (1); } @@ -351,7 +351,7 @@ c_fc(const char **wp) } if (n < 0) { bi_errorf("can't %s temporary file %s: %s", - "read", tf->tffn, strerror(shf_errno(shf))); + "read", tf->tffn, cstrerror(shf_errno(shf))); errout: shf_close(shf); return (1); @@ -807,7 +807,7 @@ hist_init(Source *s) } if (hs != hist_init_retry) bi_errorf("can't %s %s: %s", - "unlink HISTFILE", hname, strerror(errno)); + "unlink HISTFILE", hname, cstrerror(errno)); histfsize = 0; return; } else { diff --git a/jobs.c b/jobs.c index 1fec03c..0338a83 100644 --- a/jobs.c +++ b/jobs.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.92 2012/12/04 01:18:31 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.93 2012/12/17 23:18:06 tg Exp $"); #if HAVE_KILLPG #define mksh_killpg killpg @@ -306,7 +306,7 @@ j_change(void) if ((ttypgrp = tcgetpgrp(tty_fd)) < 0) { warningf(false, "%s: %s %s: %s", "j_init", "tcgetpgrp", "failed", - strerror(errno)); + cstrerror(errno)); ttypgrp_ok = false; break; } @@ -321,13 +321,13 @@ j_change(void) if (ttypgrp_ok && kshpgrp != kshpid) { if (setpgid(0, kshpid) < 0) { warningf(false, "%s: %s %s: %s", "j_init", - "setpgid", "failed", strerror(errno)); + "setpgid", "failed", cstrerror(errno)); ttypgrp_ok = false; } else { if (tcsetpgrp(tty_fd, kshpid) < 0) { warningf(false, "%s: %s %s: %s", "j_init", "tcsetpgrp", "failed", - strerror(errno)); + cstrerror(errno)); ttypgrp_ok = false; } else restore_ttypgrp = kshpgrp; @@ -370,7 +370,7 @@ ksh_nice(int ness) errno = 0; /* this is gonna annoy users; complain to your distro, people! */ if (nice(ness) == -1 && (eno = errno) != 0) - warningf(false, "%s: %s", "bgnice", strerror(eno)); + warningf(false, "%s: %s", "bgnice", cstrerror(eno)); #else (void)nice(ness); #endif @@ -735,7 +735,7 @@ j_kill(const char *cp, int sig) if (j->pgrp == 0) { /* started when !Flag(FMONITOR) */ if (kill_job(j, sig) < 0) { - bi_errorf("%s: %s", cp, strerror(errno)); + bi_errorf("%s: %s", cp, cstrerror(errno)); rv = 1; } } else { @@ -744,7 +744,7 @@ j_kill(const char *cp, int sig) mksh_killpg(j->pgrp, SIGCONT); #endif if (mksh_killpg(j->pgrp, sig) < 0) { - bi_errorf("%s: %s", cp, strerror(errno)); + bi_errorf("%s: %s", cp, cstrerror(errno)); rv = 1; } } @@ -820,7 +820,7 @@ j_resume(const char *cp, int bg) "1st", "tcsetpgrp", tty_fd, (long)((j->flags & JF_SAVEDTTYPGRP) ? j->saved_ttypgrp : j->pgrp), "failed", - strerror(rv)); + cstrerror(rv)); return (1); } } @@ -840,11 +840,11 @@ j_resume(const char *cp, int bg) if (ttypgrp_ok && tcsetpgrp(tty_fd, kshpgrp) < 0) warningf(true, "%s %s(%d, %ld) %s: %s", "fg: 2nd", "tcsetpgrp", tty_fd, - (long)kshpgrp, "failed", strerror(errno)); + (long)kshpgrp, "failed", cstrerror(errno)); } sigprocmask(SIG_SETMASK, &omask, NULL); bi_errorf("%s %s %s", "can't continue job", - cp, strerror(eno)); + cp, cstrerror(eno)); return (1); } if (!bg) { @@ -1131,7 +1131,7 @@ j_waitj(Job *j, if (tcsetpgrp(tty_fd, kshpgrp) < 0) warningf(true, "%s %s(%d, %ld) %s: %s", "j_waitj:", "tcsetpgrp", tty_fd, - (long)kshpgrp, "failed", strerror(errno)); + (long)kshpgrp, "failed", cstrerror(errno)); if (j->state == PSTOPPED) { j->flags |= JF_SAVEDTTY; mksh_tcget(tty_fd, &j->ttystat); @@ -1822,21 +1822,21 @@ tty_init_talking(void) #ifndef MKSH_DISABLE_TTY_WARNING warningf(false, "%s: %s %s: %s", "No controlling tty", "open", "/dev/tty", - strerror(errno)); + cstrerror(errno)); #endif break; case 2: #ifndef MKSH_DISABLE_TTY_WARNING - warningf(false, "%s: %s", "can't find tty fd", strerror(errno)); + warningf(false, "%s: %s", "can't find tty fd", cstrerror(errno)); #endif break; case 3: warningf(false, "%s: %s %s: %s", "j_ttyinit", - "dup of tty fd", "failed", strerror(errno)); + "dup of tty fd", "failed", cstrerror(errno)); break; case 4: warningf(false, "%s: %s: %s", "j_ttyinit", - "can't set close-on-exec flag", strerror(errno)); + "can't set close-on-exec flag", cstrerror(errno)); break; } } diff --git a/main.c b/main.c index 5d1769b..eaebab9 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.248 2012/12/07 23:46:36 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.249 2012/12/17 23:18:07 tg Exp $"); extern char **environ; @@ -484,7 +484,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp) SHF_MAPHI | SHF_CLEXEC); if (s->u.shf == NULL) { shl_stdout_ok = false; - warningf(true, "%s: %s", s->file, strerror(errno)); + warningf(true, "%s: %s", s->file, cstrerror(errno)); /* mandated by SUSv4 */ exstat = 127; unwind(LERROR); diff --git a/misc.c b/misc.c index cdbcff4..988f98c 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.204 2012/12/05 19:38:22 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.205 2012/12/17 23:18:08 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -1853,7 +1853,7 @@ c_cd(const char **wp) if (cdnode) bi_errorf("%s: %s", dir, "bad directory"); else - bi_errorf("%s: %s", tryp, strerror(errno)); + bi_errorf("%s: %s", tryp, cstrerror(errno)); afree(allocd, ATEMP); Xfree(xs, xp); return (2); diff --git a/sh.h b/sh.h index 0bd65c3..1c3609b 100644 --- a/sh.h +++ b/sh.h @@ -94,6 +94,10 @@ /* shudder… */ #include #endif +#ifdef _ISC_UNIX +/* XXX imake style */ +#include +#endif #if HAVE_ULIMIT_H #include #endif @@ -160,7 +164,7 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.617 2012/12/17 22:14:26 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.618 2012/12/17 23:18:09 tg Exp $"); #endif #define MKSH_VERSION "R41 2012/12/07" @@ -363,8 +367,11 @@ extern int getrusage(int, struct rusage *); extern int revoke(const char *); #endif -#if !HAVE_STRERROR -extern char *strerror(int); +#if defined(DEBUG) || !HAVE_STRERROR +#define strerror dontuse_strerror /* poisoned */ +extern const char *cstrerror(int); +#else +#define cstrerror(errnum) ((const char *)strerror(errnum)) #endif #if !HAVE_STRLCPY diff --git a/shf.c b/shf.c index b46bea1..5baf91d 100644 --- a/shf.c +++ b/shf.c @@ -24,7 +24,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.52 2012/12/17 22:57:50 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.53 2012/12/17 23:18:11 tg Exp $"); /* flags to shf_emptybuf() */ #define EB_READSW 0x01 /* about to switch to reading */ @@ -1078,21 +1078,79 @@ shf_putc(int c, struct shf *shf) } #endif -#if !HAVE_STRERROR -/* - * This is absolutely minimalistic. We could catch a number of well- - * known errors (like ENOENT) and provide real error strings for them, - * but to do that, I'd like a survey of which errors usually occur on - * what systems, to be worth it. Modern systems do have strerror; this - * is a porting aid only right now. - */ -char * -strerror(int errnum) +#ifdef DEBUG +const char * +cstrerror(int errnum) { - /* "Errno. " + sign + rounded(octal) bits + NUL */ - static char errbuf[7 + 1 + (8 * sizeof(int) + 2) / 3 + 1]; +#undef strerror + return (strerror(errnum)); +#define strerror dontuse_strerror /* poisoned */ +} +#elif !HAVE_STRERROR +#if HAVE_SYS_ERRLIST +#if !HAVE_SYS_ERRLIST_DECL +extern int sys_nerr; +extern char *sys_errlist[]; +#endif +#endif +const char * +cstrerror(int errnum) +{ + /* "Unknown error: " + sign + rough estimate + NUL */ + static char errbuf[15 + 1 + (8 * sizeof(int) + 2) / 3 + 1]; - shf_snprintf(errbuf, sizeof(errbuf), "Errno. %d", errnum); - return (errbuf); +#if HAVE_SYS_ERRLIST + if (errnum > 0 && errnum < sys_nerr) + return (sys_errlist[errnum]); +#endif + + switch (errnum) { + case 0: + return ("Undefined error: 0"); +#ifdef EPERM + case EPERM: + return ("Operation not permitted"); +#endif +#ifdef ENOENT + case ENOENT: + return ("No such file or directory"); +#endif +#ifdef ESRCH + case ESRCH: + return ("No such process"); +#endif +#ifdef E2BIG + case E2BIG: + return ("Argument list too long"); +#endif +#ifdef ENOEXEC + case ENOEXEC: + return ("Exec format error"); +#endif +#ifdef ENOMEM + case ENOMEM: + return ("Cannot allocate memory"); +#endif +#ifdef EACCES + case EACCES: + return ("Permission denied"); +#endif +#ifdef ENOTDIR + case ENOTDIR: + return ("Not a directory"); +#endif +#ifdef EINVAL + case EINVAL: + return ("Invalid argument"); +#endif +#ifdef ELOOP + case ELOOP: + return ("Too many levels of symbolic links"); +#endif + default: + shf_snprintf(errbuf, sizeof(errbuf), + "Unknown error: %d", errnum); + return (errbuf); + } } #endif