diff --git a/include/err.h b/include/err.h new file mode 100644 index 0000000000..e5010f6a50 --- /dev/null +++ b/include/err.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * include/err.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_ERR_H +#define __INCLUDE_ERR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_LIBC_ERR + +/* Print "pid: ", FORMAT, ": ", the standard error string for errno, + * and a newline, on stderr. + */ + +void warn(FAR const char *fmt, ...); +void vwarn(FAR const char *fmt, va_list ap); + +/* Likewise, but without ": " and the standard error string. */ + +void warnx(FAR const char *fmt, ...); +void vwarnx(FAR const char *fmt, va_list ap); + +/* Likewise, and then exit with STATUS. */ + +void err(int status, FAR const char *fmt, ...); +void verr(int status, FAR const char *fmt, va_list ap); +void errx(int status, FAR const char *fmt, ...); +void verrx(int status, FAR const char *, va_list ap); + +#endif /* CONFIG_LIBC_ERR */ +#endif /* __INCLUDE_ERR_H */ diff --git a/libs/libc/misc/Kconfig b/libs/libc/misc/Kconfig index 183108c760..8bc4e543e2 100644 --- a/libs/libc/misc/Kconfig +++ b/libs/libc/misc/Kconfig @@ -61,3 +61,9 @@ config LIBC_ENVPATH ---help--- Use the contents of the common environment variable to locate executable or library files. Default: n + +config LIBC_ERR + bool "Support err() verr() verrx() warn() vwarn() vwarnx()" + default y + ---help--- + Support err() verr() verrx() warn() vwarn() vwarnx(). Default: y diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs index e6c3e6f786..74aea90eed 100644 --- a/libs/libc/misc/Make.defs +++ b/libs/libc/misc/Make.defs @@ -56,6 +56,10 @@ ifeq ($(CONFIG_LIBC_ENVPATH),y) CSRCS += lib_envpath.c endif +ifeq ($(CONFIG_LIBC_ERR),y) +CSRCS += lib_err.c +endif + # To ensure uname information is newest, # add lib_utsname.o to phony target for force rebuild diff --git a/libs/libc/misc/lib_err.c b/libs/libc/misc/lib_err.c new file mode 100644 index 0000000000..11c1cda138 --- /dev/null +++ b/libs/libc/misc/lib_err.c @@ -0,0 +1,156 @@ +/**************************************************************************** + * libs/libc/misc/lib_err.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define VA(call) \ +do \ +{ \ + va_list ap; \ + va_start(ap, fmt); \ + call; \ + va_end(ap); \ +} while(0) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vwarn + ****************************************************************************/ + +void vwarn(FAR const char *fmt, va_list ap) +{ + int error = errno; + struct va_format vaf; + +#ifdef va_copy + va_list copy; + + va_copy(copy, ap); + + vaf.fmt = fmt; + vaf.va = © +#else + vaf.fmt = fmt; + vaf.va = ≈ +#endif + +#ifdef CONFIG_FILE_STREAM + fprintf(stderr, "%d: %pV: %s\n", getpid(), &vaf, strerror(error)); +#else + dprintf(STDERR_FILENO, "%d: %pV: %s\n", getpid(), &vaf, strerror(error)); +#endif +} + +/**************************************************************************** + * Name: vwarnx + ****************************************************************************/ + +void vwarnx(FAR const char *fmt, va_list ap) +{ + struct va_format vaf; + +#ifdef va_copy + va_list copy; + + va_copy(copy, ap); + + vaf.fmt = fmt; + vaf.va = © +#else + vaf.fmt = fmt; + vaf.va = ≈ +#endif + +#ifdef CONFIG_FILE_STREAM + fprintf(stderr, "%d: %pV\n", getpid(), &vaf); +#else + dprintf(STDERR_FILENO, "%d: %pV\n", getpid(), &vaf); +#endif +} + +/**************************************************************************** + * Name: warn + ****************************************************************************/ + +void warn(FAR const char *fmt, ...) +{ + VA(vwarn(fmt, ap)); +} + +/**************************************************************************** + * Name: warnx + ****************************************************************************/ + +void warnx(FAR const char *fmt, ...) +{ + VA(vwarnx(fmt, ap)); +} + +/**************************************************************************** + * Name: verr + ****************************************************************************/ + +void verr(int status, FAR const char *fmt, va_list ap) +{ + vwarn(fmt, ap); + exit(status); +} + +/**************************************************************************** + * Name: verrx + ****************************************************************************/ + +void verrx(int status, FAR const char *fmt, va_list ap) +{ + vwarnx(fmt, ap); + exit(status); +} + +/**************************************************************************** + * Name: err + ****************************************************************************/ + +void err(int status, FAR const char *fmt, ...) +{ + VA(verr(status, fmt, ap)); +} + +/**************************************************************************** + * Name: errx + ****************************************************************************/ + +void errx(int status, FAR const char *fmt, ...) +{ + VA(verrx(status, fmt, ap)); +}