mirror of
https://github.com/sheumann/hush.git
synced 2025-01-10 16:29:44 +00:00
Fix the implementation of vasprintf to work with ORCA/C's varargs implementation. Also, shrink the stack-allocated buffer in it.
This code could theoretically break if the ORCA/C varargs implementation changed, but it should be OK in practice. Also removed some unused code in libbb/xfuncs.printf.c that includes potentially problematic varargs use (defining varargs functions but not necessarily calling va_start/va_end in them).
This commit is contained in:
parent
bdafda3f97
commit
32e9dccc33
@ -36,27 +36,42 @@ int FAST_FUNC usleep(unsigned usec)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_VASPRINTF
|
||||
#ifndef __ORCAC__
|
||||
# define VASPRINTF_BUF_SIZE 128
|
||||
#else
|
||||
# define VASPRINTF_BUF_SIZE 8
|
||||
#endif
|
||||
|
||||
int FAST_FUNC vasprintf(char **string_ptr, const char *format, va_list p)
|
||||
{
|
||||
int r;
|
||||
va_list p2;
|
||||
char buf[128];
|
||||
char buf[VASPRINTF_BUF_SIZE];
|
||||
|
||||
#ifndef __ORCAC__
|
||||
va_copy(p2, p);
|
||||
r = vsnprintf(buf, 128, format, p);
|
||||
va_end(p);
|
||||
#else
|
||||
// ORCA/C doesn't have va_copy, so copy it manually instead.
|
||||
// Don't call va_end on the copy, because that would mess up the stack.
|
||||
memcpy(p2, p, sizeof(va_list));
|
||||
#endif
|
||||
r = vsnprintf(buf, VASPRINTF_BUF_SIZE, format, p);
|
||||
|
||||
/* Note: can't use xstrdup/xmalloc, they call vasprintf (us) on failure! */
|
||||
|
||||
if (r < 128) {
|
||||
if (r < VASPRINTF_BUF_SIZE) {
|
||||
#ifndef __ORCAC__
|
||||
va_end(p2);
|
||||
#endif
|
||||
*string_ptr = strdup(buf);
|
||||
return (*string_ptr ? r : -1);
|
||||
}
|
||||
|
||||
*string_ptr = malloc(r+1);
|
||||
r = (*string_ptr ? vsnprintf(*string_ptr, r+1, format, p2) : -1);
|
||||
#ifndef __ORCAC__
|
||||
va_end(p2);
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -477,75 +477,6 @@ void FAST_FUNC selinux_or_die(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int FAST_FUNC ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...)
|
||||
{
|
||||
int ret;
|
||||
va_list p;
|
||||
|
||||
ret = ioctl(fd, request, argp);
|
||||
if (ret < 0) {
|
||||
va_start(p, fmt);
|
||||
bb_verror_msg(fmt, p, strerror(errno));
|
||||
/* xfunc_die can actually longjmp, so be nice */
|
||||
va_end(p);
|
||||
xfunc_die();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FAST_FUNC ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...)
|
||||
{
|
||||
va_list p;
|
||||
int ret = ioctl(fd, request, argp);
|
||||
|
||||
if (ret < 0) {
|
||||
va_start(p, fmt);
|
||||
bb_verror_msg(fmt, p, strerror(errno));
|
||||
va_end(p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if ENABLE_IOCTL_HEX2STR_ERROR
|
||||
int FAST_FUNC bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ioctl(fd, request, argp);
|
||||
if (ret < 0)
|
||||
bb_simple_perror_msg(ioctl_name);
|
||||
return ret;
|
||||
}
|
||||
int FAST_FUNC bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ioctl(fd, request, argp);
|
||||
if (ret < 0)
|
||||
bb_simple_perror_msg_and_die(ioctl_name);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int FAST_FUNC bb_ioctl_or_warn(int fd, unsigned request, void *argp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ioctl(fd, request, argp);
|
||||
if (ret < 0)
|
||||
bb_perror_msg("ioctl %#x failed", request);
|
||||
return ret;
|
||||
}
|
||||
int FAST_FUNC bb_xioctl(int fd, unsigned request, void *argp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ioctl(fd, request, argp);
|
||||
if (ret < 0)
|
||||
bb_perror_msg_and_die("ioctl %#x failed", request);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BB_MMU
|
||||
pid_t FAST_FUNC xfork(void)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user