nuttx/libs/libc/misc/lib_err.c
chao.an 316797a7f6 libc/err: fix unpaired va_end()
each invocation of va_start() must be matched by a corresponding
invocation of va_end() in the same function

Signed-off-by: chao.an <anchao@xiaomi.com>
2022-03-19 10:13:23 +02:00

161 lines
4.4 KiB
C

/****************************************************************************
* 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 <err.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
/****************************************************************************
* 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 = &copy;
#else
vaf.fmt = fmt;
vaf.va = &ap;
#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 = &copy;
#else
vaf.fmt = fmt;
vaf.va = &ap;
#endif
#ifdef CONFIG_FILE_STREAM
fprintf(stderr, "%d: %pV\n", getpid(), &vaf);
#else
dprintf(STDERR_FILENO, "%d: %pV\n", getpid(), &vaf);
#endif
#ifdef va_copy
va_end(copy);
#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));
}