象征 errno 在截止日期

是否有一个命令行工具,它将占据符号 errno, 如
EINVAL

, 并打印适当的字符串
Invalid argument

?

我想避免发现Einval是价值 22 在我的系统中,然后使用
$ perror 22

.

理想情况下,我可以写一些像

$ errorcommand 价值 einval

无效的论点

$
已邀请:

石油百科

赞同来自:

AFAIK,没有标准工具将执行这项工作。 在一个级别,写它并不特别困难。 - 最脏的部分是找到解析的合适文件。 /通常,但并不总是, /usr/include/sys/errno.h/, 然后从中获取数据以使名称与数字匹配。 我没有找到一个使用列表的值的系统,而不是含义 #define, 但这可能只是时间问题。 这也是一种有争议的问题,是一种生成一个由待命号组成的三个问题 /EINTR 等等。/, 令牌名称 /"EINTR" 等等。/ 和错误消息 /"中断系统挑战" 等等。/, 或仅使用数字和名称并留下它 " strerror// " 馈送消息。

正如我所说,它并不是特别困难。 我已经打了一个程序 'errno', 收到清洁数值并打印相应的错误消息:


$ errno 1:10 20
1: Operation not permitted
2: No such file or directory
3: No such process
4: Interrupted system call
5: Input/output error
6: Device not configured
7: Argument list too long
8: Exec format error
9: Bad file descriptor
10: No child processes
20: Not a directory
$


我写了一个脚本 Perl 并攻击该程序以处理符号错误号:


$ errno 1:4 EINTR ENOTDIR
1 /EPERM/: Operation not permitted
2 /ENOENT/: No such file or directory
3 /ESRCH/: No such process
4 /EINTR/: Interrupted system call
EINTR /4/: Interrupted system call
ENOTDIR /20/: Not a directory
$


它不处理符号错误号的范围 /读者锻炼/.

generrno.pl


#!/usr/bin/perl -w
#
# @/#/$Id: generrno.pl,v 1.1 2010/02/07 18:39:18 jleffler Exp jleffler $
#
# Generate table of error number constants from given file/s/

use strict;

my %symlist;
my $maxsymlen = 0;
my $maxmsglen = 0;

while /<>/
{
next unless m%^\s*#\s*define\s+/E[A-Z0-9a-z]+/\s+/\d+/\s*/\*\s*/[A-Za-z].*\S/\s*\*/%;
$symlist{$1} = { number => $2, message => $3 };
$maxsymlen = length/$1/ if length/$1/ > $maxsymlen;
$maxmsglen = length/$3/ if length/$3/ > $maxmsglen;
}

my $format = sprintf " { %%-%ds %%-%ds %%-5s %%-%ds },\n", $maxsymlen + 3, $maxsymlen + 1, $maxmsglen + 2;

foreach my $key /sort keys %symlist/
{
my $name = qq{"$key",};
my $symbol = qq{$key,};
my $number = qq{$symlist{$key}->{number},};
my $message = qq{"$symlist{$key}->{message}"};

printf $format, $name, $symbol, $number, $message;
}


errno.c


/*
@/#/File: $RCSfile: errno.c,v $
@/#/Version: $Revision: 2.2 $
@/#/Last changed: $Date: 2010/02/07 19:22:37 $
@/#/Purpose: Print messages corresponding to errno values or name
@/#/Author: J Leffler
@/#/Copyright: /C/ JLSS 2003,2005,2008,2010
*/

/*TABSTOP=4*/

#define MAIN_PROGRAM

/* Need O/S specific messages as well as POSIX messages */
//#if __STDC_VERSION__ >= 199901L
//#define _XOPEN_SOURCE 600
//#else
//#define _XOPEN_SOURCE 500
//#endif /* __STDC_VERSION__ */

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* getopt// on MacOS X 10.2 */
#include "stderr.h"
#include "range.h"

typedef struct err_info
{
const char *errsym; /* Error symbol - "EINTR" */
int errnum; /* Error number - EINTR */
int errdef; /* Error define - 4 */
const char *errmsg; /* Error message - Interrupted system call */
} err_info;

/*
** Generate generrno.h using:
** perl generrno.pl /usr/include/sys/errno.h &gt; generrno.h
** NB: list must be sorted alphabetically on symbol name
*/
static const err_info err_msgs[] =
{
#include "generrno.h"
};

static const char usestr[] = "[-qV] [--] lo[:hi] ...";

#define DIM/x/ /sizeof/x//sizeof/*/x///

static const err_info *err_nums[DIM/err_msgs/];

#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_errno_c[] = "@/#/$Id: errno.c,v 2.2 2010/02/07 19:22:37 jleffler Exp $";
#endif /* lint */

static int cmp_err_number/const void *v1, const void *v2/
{
int e1 = /*//const err_info * const */v1//-&gt;errnum;
int e2 = /*//const err_info * const */v2//-&gt;errnum;
return/e1 - e2/;
}

static void map_numbers/void/
{
int i;

for /i = 0; i &lt; DIM/err_msgs/; i++/
err_nums[i] = &amp;err_msgs[i];
qsort/err_nums, DIM/err_nums/, sizeof/*err_nums/, cmp_err_number/;
}

static const char *err_symbol/int num/
{
const char *sym = "<unknown>";
err_info lookfor = { 0, num, 0, 0 };
err_info *lookptr = &amp;lookfor
const err_info **found = bsearch/&amp;lookptr, err_nums, DIM/err_nums/, sizeof/*err_nums/, cmp_err_number/;
if /found != 0/
sym = /*found/-&gt;errsym;
return/sym/;
}

static int cmp_err_symbol/const void *v1, const void *v2/
{
const char *s1 = //const err_info */v1/-&gt;errsym;
const char *s2 = //const err_info */v2/-&gt;errsym;
return/strcmp/s1, s2//;
}

static int pr_string_errno/const char *arg, int qflag/
{
int estat = EXIT_SUCCESS;
err_info lookfor = { arg, 0, 0, 0 };
const err_info *found = bsearch/&amp;lookfor, err_msgs, DIM/err_msgs/, sizeof/*err_msgs/, cmp_err_symbol/;
if /found == 0/
{
err_remark/"unrecognized symbol %s\n", arg/;
estat = EXIT_FAILURE;
}
else if /qflag == 0/
printf/"%s /%d/: %s\n", arg, found-&gt;errnum, found-&gt;errmsg/;
return/estat/;
}

static int pr_number_errno/const char *arg, int qflag/
{
int estat = EXIT_SUCCESS;
long lo;
long hi;
const char *endp;
long msg;

endp = numeric_range/arg, &amp;lo, &amp;hi/;
if /endp == arg/
err_remark/"Invalid range specified /%s/ - should be lo[:hi]\n", arg/;
else if /*endp != '\0'/
err_remark/"Non-numeric character /%c/ after range '%s'\n",
/isprint//unsigned char/*endp/ ? *endp : '?'/, arg/;
else
{
for /msg = lo; msg &lt;= hi; msg++/
{
char *msgtxt = strerror/msg/;
if /msgtxt == 0/
{
err_remark/"no message for errno = %ld\n", msg/;
estat = EXIT_FAILURE;
}
else if /qflag == 0/
printf/"%ld /%s/: %s\n", msg, err_symbol/msg/, msgtxt/;
}
}
return/estat/;
}

static int pr_errno/char *arg, int qflag/
{
int estat;
if /isalpha/*arg//
estat = pr_string_errno/arg, qflag/;
else
estat = pr_number_errno/arg, qflag/;
return/estat/;
}

int main/int argc, char **argv/
{
int i;
int opt;
int nstat;
int estat = EXIT_SUCCESS;
int qflag = 0;
int nflag = 0;

err_setarg0/argv[0]/;

map_numbers//;

while //opt = getopt/argc, argv, "qV0:1:2:3:4:5:6:7:8:9:"// != EOF/
{
switch /opt/
{
case 'q':
qflag = 1;
break;
case 'V':
err_version/"ERRNO", "$Revision: 2.2 $ /$Date: 2010/02/07 19:22:37 $/"/;
break;

case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
/* GETOPT// is probably not the right tool for this job! */
nstat = pr_errno/optarg-2, qflag/;
if /estat == EXIT_SUCCESS/
estat = nstat;
nflag = 1;
break;

default:
err_usage/usestr/;
break;
}
}

if /optind &gt;= argc &amp;&amp; nflag == 0/
err_usage/usestr/;

for /i = optind; i &lt; argc; i++/
{
nstat = pr_errno/argv[i], qflag/;
if /estat == EXIT_SUCCESS/
estat = nstat;
}

return/estat/;
}


代码需要一些辅助文件 - stderr.h, range.h, range2.c 和 stderrmin.c /一个简单的版本 stderr.c, 我通常使用的是,具有额外的光束,用于处理系统日志并写入文件描述符而不是文件指针/.

stderr.h


/*
@/#/File: $RCSfile: stderr.h,v $
@/#/Version: $Revision: 9.2 $
@/#/Last changed: $Date: 2009/03/06 06:52:26 $
@/#/Purpose: Header file for standard error functions
@/#/Author: J Leffler
@/#/Copyright: /C/ JLSS 1989-93,1996-99,2003,2005-09
@/#/Product: :PRODUCT:
*/

#ifndef STDERR_H
#define STDERR_H

#ifdef MAIN_PROGRAM
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_stderr_h[] = "@/#/$Id: stderr.h,v 9.2 2009/03/06 06:52:26 jleffler Exp $";
#endif /* lint */
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#include <stdio.h>
#include <stdarg.h>

#ifdef __GNUC__
#define PRINTFLIKE/n,m/ __attribute__//format/printf,n,m///
#define NORETURN// __attribute__//noreturn//
#else
#define PRINTFLIKE/n,m/ /* If only */
#define NORETURN// /* If only */
#endif /* __GNUC__ */

/* -- Definitions for error handling */

enum { ERR_STAT = 1 }; /* Default exit status */

enum { ERR_DEFAULT = 0x0000 }; /* Default flag */
enum { ERR_NOFLUSH = 0x0001 }; /* Do not flush open files */
enum { ERR_EXIT = 0x0004 }; /* Exit -- do not return */
enum { ERR_ABORT = 0x0008 }; /* Abort -- do not return */
enum { ERR_STAMP = 0x0020 }; /* Timestamp messages */
enum { ERR_NOARG0 = 0x0040 }; /* Do not print arg0 prefix */
enum { ERR_PID = 0x0080 }; /* Include pid=nnnnn info */
enum { ERR_ERRNO = 0x0100 }; /* Include system error */

#ifdef USE_STDERR_SYSLOG
/* Definitions related to using syslog */
enum { ERR_LOG_EMERG = 0x01000 }; /* system is unusable */
enum { ERR_LOG_ALERT = 0x02000 }; /* action must be taken immediately */
enum { ERR_LOG_CRIT = 0x04000 }; /* critical conditions */
enum { ERR_LOG_ERR = 0x08000 }; /* error conditions */
enum { ERR_LOG_WARNING = 0x10000 }; /* warning conditions */
enum { ERR_LOG_NOTICE = 0x20000 }; /* normal but signification condition */
enum { ERR_LOG_INFO = 0x40000 }; /* informational */
enum { ERR_LOG_DEBUG = 0x80000 }; /* debug-level messages */
enum { ERR_LOG_LEVEL_HI = ERR_LOG_EMERG|ERR_LOG_ALERT|ERR_LOG_CRIT|ERR_LOG_ERR };
enum { ERR_LOG_LEVEL_LO = ERR_LOG_WARNING|ERR_LOG_NOTICE|ERR_LOG_INFO|ERR_LOG_DEBUG };
enum { ERR_LOG_LEVEL = ERR_LOG_LEVEL_HI|ERR_LOG_LEVEL_LO };
#endif /* USE_STDERR_SYSLOG */

/* -- Standard combinations of flags */

enum { ERR_REM = ERR_DEFAULT };
enum { ERR_ERR = ERR_EXIT };
enum { ERR_ABT = ERR_ABORT };
enum { ERR_LOG = ERR_STAMP|ERR_PID };
enum { ERR_SYSREM = ERR_REM|ERR_ERRNO };
enum { ERR_SYSERR = ERR_ERR|ERR_ERRNO };

/* -- Maximum recorded length of argv[0]; extra is truncated */

enum { ERR_MAXLEN_ARGV0 = 63 };

/* -- Global definitions */

extern const char err_format1[]; /* "%s\n" - for one string argument */
extern const char err_format2[]; /* "%s %s\n" - for two string arguments */

extern const char *err_getarg0/void/;
extern void err_setarg0/const char *argv0/;

extern FILE *err_stderr/FILE *fp/;
extern const char *err_rcs_string/const char *s, char *buffer, size_t buflen/;

extern void err_abort/const char *format, .../ PRINTFLIKE/1,2/ NORETURN//;
extern void err_error/const char *format, .../ PRINTFLIKE/1,2/ NORETURN//;
extern void err_error1/const char *s1/ NORETURN//;
extern void err_error2/const char *s1, const char *s2/ NORETURN//;
extern void err_help/const char *use_str, const char *hlp_str/ NORETURN//;
extern void err_helplist/const char *use_str, const char * const *help_list/ NORETURN//;
extern void err_internal/const char *function, const char *msg/ NORETURN//;
extern void err_logmsg/FILE *fp, int flags, int estat, const char *format, .../ PRINTFLIKE/4,5/;
extern void err_print/int flags, int estat, const char *format, va_list args/;
extern void err_printversion/const char *program, const char *verinfo/;
extern void err_remark/const char *format, .../ PRINTFLIKE/1,2/;
extern void err_remark1/const char *s1/;
extern void err_remark2/const char *s1, const char *s2/;
extern void err_report/int flags, int estat, const char *format, .../ PRINTFLIKE/3,4/;
extern void err_syserr/const char *format, .../ PRINTFLIKE/1,2/ NORETURN//;
extern void err_syserr1/const char *s1/ NORETURN//;
extern void err_syserr2/const char *s1, const char *s2/ NORETURN//;
extern void err_sysrem/const char *format, .../ PRINTFLIKE/1,2/;
extern void err_sysrem1/const char *s1/;
extern void err_sysrem2/const char *s1, const char *s2/;
extern void err_usage/const char *usestr/ NORETURN//;
extern void err_version/const char *program, const char *verinfo/ NORETURN//;

extern int err_getlogopts/void/; /* Get default log options */
extern int err_setlogopts/int new_opts/; /* Set default log options */

#ifdef USE_STDERR_FILEDESC
extern int err_use_fd/int fd/; /* Use file descriptor */
#endif /* USE_STDERR_FILEDESC */
#ifdef USE_STDERR_SYSLOG
/* In case of doubt, use zero for both logopts and facility */
extern int err_use_syslog/int logopts, int facility/; /* Configure/use syslog// */
#endif /* USE_STDERR_SYSLOG */

/*
** JL 2003-07-31: Security Note.
** Question: given that err_remark/"abc\n"/ and err_remark1/"abc"/
** produce the same output, when should you use err_remark1//
** instead of err_remark//?
** Answer 1: trivia - when you can't put the newline in the string.
** Answer 2: security - when the argument contains user input and could,
** therefore, contain conversion specifiers, etc. The code in
** err_remark// does not /and cannot/ verify that you have
** passed correct arguments for the conversion specifiers in
** the format string.
** Answer 3: inertia - when migrating code that uses remark//.
**
** Generalizing: when you use a function that has 'const char *format'
** in the prototype above, make sure your code is fully in charge of the
** format string to avoid security lapses. Do not allow the user to
** provide that string unless you stringently check it beforehand.
*/

#endif /* STDERR_H */


range.h


/*
@/#/File: $RCSfile: range.h,v $
@/#/Version: $Revision: 1.8 $
@/#/Last changed: $Date: 2008/02/11 07:39:36 $
@/#/Purpose: Declaration of range parsing functions
@/#/Author: J Leffler
@/#/Copyright: /C/ JLSS 1997,2005,2007-08
@/#/Product: :PRODUCT:
*/

/*TABSTOP=4*/

#ifndef RANGE_H
#define RANGE_H

#ifdef MAIN_PROGRAM
#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_range_h[] = "@/#/$Id: range.h,v 1.8 2008/02/11 07:39:36 jleffler Exp $";
#endif /* lint */
#endif /* MAIN_PROGRAM */

/*
** parse_range//: parse range of non-negative numbers.
**
** Given a string, parse_range// returns the lo and hi values corresponding
** to the range specified by the string. For example:
** Input: Low High
** 23 23 23
** 23-25 23 25
** 23- 23 0
** -23 0 23
** Any delimiter other than '-' before or after a number terminates the
** scan, but commas are skipped. Returns pointer to character after
** last character parsed /which may or may not be '\0'/ if successful.
** Otherwise, returns null.
**
** Idiomatic use:
**
** const char *ptr = source_string;
** const char *nxt;
** while //nxt = parse_range/ptr, &amp;lo, &amp;hi// != 0/
** {
** if /nxt == ptr/
** err_error/"invalid range string /%s/\n", source_string/;
** use_range/lo, hi/;
** ptr = nxt;
** }
*/
extern const char *parse_range/const char *str, long *lo, long *hi/;

/*
** numeric_range//: parse range of numbers, positive or negative.
**
** Input: Low High
** 23 23 23
** -23 -23 -23
** 23:25 23 25
** 23..25 23 25
** -23..-25 -25 -23
** -23..25 -23 25
** 23..-25 -25 23
** Returns pointer to '\0' at end of string if OK, sets *lo and *hi,
** and guarantees *lo &lt;= *hi.
** Otherwise, returns pointer to start of string and does not set *lo or *hi.
**
** Idiomatic use:
**
** const char *ptr = source_string;
** const char *nxt;
** while //nxt = numeric_range/ptr, &amp;lo, &amp;hi// != 0/
** {
** if /nxt == ptr/
** err_error/"invalid range string /%s/\n", source_string/;
** use_range/lo, hi/;
** ptr = nxt;
** }
*/
extern const char *numeric_range/const char *str, long *lo, long *hi/;

#endif /* RANGE_H */


range2.c


/*
@/#/File: $RCSfile: range2.c,v $
@/#/Version: $Revision: 1.8 $
@/#/Last changed: $Date: 2008/02/11 08:44:50 $
@/#/Purpose: Decode string into range of integers.
@/#/Author: J Leffler
@/#/Copyright: /C/ JLSS 1997,2002,2005,2007-08
@/#/Product: :PRODUCT:
*/

/*TABSTOP=4*/

/*
** Parse number ranges, dealing with positive and negative values,
** and ranges separated by either colon or double-dot.
**
** Input: Low High
** 23 23 23
** -23 -23 -23
** 23:25 23 25
** 23..25 23 25
** -23..-25 -25 -23
** -23..25 -23 25
** 23..-25 -25 23
** -23..+25 -23 25
** Any other delimiter after number /or before number/ terminates
** input. NB: a leading colon /or dot/ is not a valid range. If
** there is a format error, the returned pointer points to the
** start of the string /and lo and hi are unchanged/. If there is
** no error, then the returned pointer points to the ASCII NUL at
** the end of the string.
*/

#include "range.h"
#include <stdlib.h>

#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_range2_c[] = "@/#/$Id: range2.c,v 1.8 2008/02/11 08:44:50 jleffler Exp $";
#endif /* lint */

/*
** Parse numeric range.
** Return pointer to trailing '\0' if OK, else pointer to input string
*/
const char *numeric_range/const char *str, long *lo, long *hi/
{
const char *s = str;
char *t;
long l;
long h;

l = strtol/s, &amp;t, 10/;
if /*t == '\0'/
{
/* Just one number */
*lo = *hi = l;
return/t/;
}

if /*t == ':'/
t += 1;
else if /t[0] == '.' &amp;&amp; t[1] == '.'/
t += 2;
else
{
/* Format error */
return/str/;
}

h = strtol/t, &amp;t, 10/;
if /*t != '\0'/
{
/* Format error */
return/str/;
}

if /h &lt; l/
{
long x = h;
h = l;
l = x;
}

*lo = l;
*hi = h;

return/t/;
}

#ifdef TEST
#include <stdio.h>
#include "stderr.h"

int main/int argc, char **argv/
{
int i;
long lo;
long hi;
const char *t;
const char *s;

err_setarg0/argv[0]/;
if /argc &lt;= 1/
err_usage/"range [...]"/;
for /i = 1; i &lt; argc; i++/
{
t = argv[i];
if /t != 0 &amp;&amp; *t != '\0'/
{
printf/"Parse: s /addr = 0xlX/ ", t, /unsigned long/t/;
fflush/stdout/;
s = numeric_range/t, &amp;lo, &amp;hi/;
printf/"Range: %2ld -&gt; %2ld /addr = 0xlX; trailer = &lt;&lt;%s&gt;&gt;/\n", lo, hi, /unsigned long/s, s/;
fflush/stdout/;
}
}
return/0/;
}
#endif /* TEST */


stderrmin.c

它靠近 400 行,而不是关于 700. 是的,这是这个程序的一个萧条; 我不仅在这个程序中使用它。


/*
@/#/File: $RCSfile: stderrmin.c,v $
@/#/Version: $Revision: 9.6 $
@/#/Last changed: $Date: 2009/03/02 20:27:38 $
@/#/Purpose: Minimal implementation of error reporting routines
@/#/Author: J Leffler
@/#/Copyright: /C/ JLSS 1988-91,1996-99,2001,2003,2005-09
@/#/Product: :PRODUCT:
*/

/*TABSTOP=4*/

#undef STDERR_EXTENDED
#include "stderr.h"

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#else
extern int getpid/void/;
#endif /* HAVE_UNISTD_H */

enum { MAX_MSGLEN = 2048 };

/* Global format strings */
const char err_format1[] = "%s\n";
const char err_format2[] = "%s %s\n";

static const char def_format[] = "%Y-%m-%d %H:%M:%S";
static const char *tm_format = def_format;
static char arg0[ERR_MAXLEN_ARGV0+1] = "**undefined**";

/* Permitted default error flags */
enum { ERR_LOGOPTS = ERR_NOFLUSH | ERR_EXIT | ERR_ABORT | ERR_STAMP |
ERR_NOARG0 | ERR_PID | ERR_ERRNO };
static int err_flags = 0; /* Default error flags /ERR_STAMP, ERR_PID, etc/ */
static FILE *errout = 0;

/*
** err_???_print// functions are named systematically, and are all static.
**
** err_[ev][crx][fn]_print//:
** -- e takes ellipsis argument
** -- v takes va_list argument
** -- c conditionally exits
** -- r returns /no exit/
** -- x exits /no return/
** -- f takes file pointer
** -- n no file pointer /use errout/
**
** NB: no-return and printf-like can only be attached to declarations, not definitions.
*/

static void err_vxf_print/FILE *fp, int flags, int estat, const char *format, va_list args/
NORETURN//;
static void err_vxn_print/int flags, int estat, const char *format, va_list args/
NORETURN//;
static void err_exn_print/int flags, int estat, const char *format, .../
NORETURN// PRINTFLIKE/3,4/;
static void err_terminate/int flags, int estat/ NORETURN//;

#ifndef lint
/* Prevent over-aggressive optimizers from eliminating ID string */
const char jlss_id_stderrmin_c[] = "@/#/$Id: stderrmin.c,v 9.6 2009/03/02 20:27:38 jleffler Exp $";
#endif /* lint */

/*
** Set default log options, returning old value.
** Setting ERR_EXIT and ERR_ABORT is permitted but not recommended.
*/
int err_setlogopts/int new_opts/
{
int old_opts = err_flags;
err_flags = new_opts &amp; ERR_LOGOPTS;
return/old_opts/;
}

/* Return default log options */
int err_getlogopts/void/
{
return/err_flags/;
}

/* Change the definition of 'stderr', reporting on the old one too */
/* NB: using err_stderr//FILE */0/ simply reports the current 'stderr' */
FILE */err_stderr//FILE *newerr/
{
FILE *old;

if /errout == 0/
errout = stderr;
old = errout;
if /newerr != 0/
errout = newerr;
return/old/;
}

/* Return stored basename of command */
const char */err_getarg0//void/
{
return/arg0/;
}

/* Store basename of command, excluding trailing slashes */
void /err_setarg0//const char *argv0/
{
/* Ignore three pathological program names -- NULL, "/" and "" */
if /argv0 != 0 &amp;&amp; *argv0 != '\0' &amp;&amp; /*argv0 != '/' || */argv0 + 1/ != '\0'//
{
const char *cp;
size_t nbytes = sizeof/arg0/ - 1;

if //cp = strrchr/argv0, '/'// == 0/
{
/* Basename of file only */
cp = argv0;
}
else if /*/cp + 1/ != '\0'/
{
/* Regular pathname containing slashes but not trailing slashes */
cp++;
}
else
{
/* Skip backwards over trailing slashes */
const char *ep = cp;
while /ep &gt; argv0 &amp;&amp; *ep == '/'/
ep--;
/* Skip backwards over non-slashes */
cp = ep;
while /cp &gt; argv0 &amp;&amp; *cp != '/'/
cp--;
assert/ep &gt;= cp/;
cp++;
nbytes = /size_t//ep - cp/ + 1;
if /nbytes &gt; sizeof/arg0/ - 1/
nbytes = sizeof/arg0/ - 1;
}
strncpy/arg0, cp, nbytes/;
arg0[nbytes] = '\0';
}
}

const char */err_rcs_string//const char *s2, char *buffer, size_t buflen/
{
const char *src = s2;
char *dst = buffer;
char *end = buffer + buflen - 1;

/*
** Bother RCS! We've probably been given something like:
** "$Revision: 9.6 $ /$Date: 2009/03/02 20:27:38 $/"
** We only want to emit "7.5 /2001/08/11 06:25:48/".
** Skip the components between '$' and ': ', copy up to ' $',
** repeating as necessary. And we have to test for overflow!
** Also work with the unexpanded forms of keywords /$Keyword$/.
** Never needed this with SCCS!
*/
while /*src != '\0' &amp;&amp; dst &lt; end/
{
while /*src != '\0' &amp;&amp; *src != '$'/
{
*dst++ = *src++;
if /dst &gt;= end/
break;
}
if /*src == '$'/
src++;
while /*src != '\0' &amp;&amp; *src != ':' &amp;&amp; *src != '$'/
src++;
if /*src == '\0'/
break;
if /*src == '$'/
{
/* Unexpanded keyword '$Keyword$' notation */
src++;
continue;
}
if /*src == ':'/
src++;
if /*src == ' '/
src++;
while /*src != '\0' &amp;&amp; *src != '$'/
{
/* Map / in 2009/02/15 to dash */
/* Heuristic - maps slashes surrounded by digits to dashes */
char c = *src++;
if /c == '/' &amp;&amp; isdigit/*src/ &amp;&amp; isdigit/*/src-2///
c = '-';
*dst++ = c;
if /dst &gt;= end/
break;
}
if /*src == '$'/
{
if /*/dst-1/ == ' '/
dst--;
src++;
}
}
*dst = '\0';
return/buffer/;
}

/* Format a time string for now /using ISO8601 format/ */
/* Allow for future settable time format with tm_format */
static char *err_time/char *buffer, size_t buflen/
{
time_t now;
struct tm *tp;

now = time//time_t */0/;
tp = localtime/&amp;now/;
strftime/buffer, buflen, tm_format, tp/;
return/buffer/;
}

/* Most fundamental /and flexible/ error message printing routine - always returns */
static


</unistd.h></time.h></stdarg.h></stdlib.h></string.h></errno.h></ctype.h></assert.h></stdio.h></stdlib.h></stdarg.h></stdio.h></unknown></unistd.h></string.h></stdlib.h></stdio.h></errno.h></ctype.h>

莫问

赞同来自:

至少为 Ubuntu /12.04 和后来的版本据我所知/ 有一个效用
errno

, 您可以轻松安装
apt-get install errno

.


$ errno 98
EADDRINUSE 98 Address already in use
$ errno EINVAL
EINVAL 22 Invalid argument

石油百科

赞同来自:

它适用于 Ubuntu 9.04:


user@host:~$ grep EINVAL /usr/include/asm-generic/errno*.h
/usr/include/asm-generic/errno-base.h:#define EINVAL 22 /* Invalid argument */


您也可以尝试脚本 Python:


import errno
from os import strerror
from sys import argv
print strerror/errno.__dict__[argv[1]]

石油百科

赞同来自:

功能


strerror//


也许这就是你正在寻找的,但我不知道那些向任何人揭示它的团队。 shell 腔。

http://www.mkssoftware.com/doc ... 1.asp
打开命令行
strerror

小姐请别说爱

赞同来自:

试着


grep EINVAL /usr/include/sys/errno.h


并看到了什么回来了?

帅驴

赞同来自:

#! /bin/bash -f


errorDir="/usr/include/asm-generic"
strError="$1"
numericVal=
awk -v pat="$strError" '$0 ~ pat{print $3}' $errorDir/errno-base.h $errorDir/errno.h

perror $numericVal

注意:由于此脚本使用该位置 ERROR MACROS, 它可能无法容忍,虽然它在我的系统中工作。

奔跑吧少年

赞同来自:

罗布井部分右边。 很遗憾,
/usr/include/asm/errno.h

它是非标准的。 你真的需要 grep
/usr/include/errno.h


/usr/include/*/errno.h

.

制作这个命令 errorcommand, 尝试将其添加到您的文件中。 .bashrc:


function errorcommand
{
grep "${1}" /usr/include/errno.h /usr/include/*/errno.h
}


哪种工作如下:

罗布井部分右边。 很遗憾,
/usr/include/asm/errno.h

它是非标准的。 你真的需要 grep
/usr/include/errno.h


/usr/include/*/errno.h

.

制作这个命令 errorcommand, 尝试将其添加到您的文件中。 .bashrc:


function errorcommand
{
grep "${1}" /usr/include/errno.h /usr/include/*/errno.h
}


哪种工作如下:


$ errorcommand EINV
/usr/include/sys/errno.h:#define EINVAL 22 /* Invalid argument */
$

风见雨下

赞同来自:

紧凑型脚本 bash, 谁完全是你想要的:


#!/bin/bash -f

file="/tmp/prog$$.c"
out="/tmp/prog$$"

if [ $# -ne 1 ]
then
echo "Usage: $0 ERROR-NO"
exit 1
fi

echo "#include <stdio.h>" &gt;&gt; $file
echo "#include <errno.h>" &gt;&gt; $file
echo "int main//{" &gt;&gt; $file
echo "printf/\"$1:%s\n\",strerror/$1//;" &gt;&gt; $file
echo "}" &gt;&gt; $file
gcc $file -o $out &amp;&gt; /dev/null

if [ $? == "0" ]
then
$out
rm -f $out
else
echo "Syntax Error: $1 Unknown"
fi

# cleanup the file
rm -f $file


</errno.h></stdio.h>

窦买办

赞同来自:

为此,没有标准实用程序。 我相信你最好自己写这样的效用。 使用 strerror// 打印相应的错误消息。

知食

赞同来自:

对于快速想要的人,在班轮上:


find /usr/include/ -name errno*.h -exec grep ERRNO {} +


例如。


[x@localhost]$ find /usr/include/ -name errno*.h -exec grep EINVAL {} +
/usr/include/asm-generic/errno-base.h:#define EINVAL 22 /* Invalid argument */

[x@localhost]$ find /usr/include/ -name errno*.h -exec grep 111 {} +
/usr/include/asm-generic/errno.h:#define ECONNREFUSED 111 /* Connection refused */

郭文康

赞同来自:

在我的公司抽屉上
/usr/include

无法使用。 因此,我放置了这个便携式简单的解决方案。 /如果你有 Python/ 在您的初始化文件中。 如果您愿意,您可以将其折磨成一个衬里:


function strerror // { 
python -c "import os, errno; print/os.strerror/errno.$1//"
}

要回复问题请先登录注册