libfdisk: do not use va_list in the Ask API
# fdisk /dev/sda Welcome to fdisk (util-linux 2.23). [...] Command (m for help): a Segmentation fault (core dumped) It's too fragile, the va_list implementation is architecture specific and it seems we need such thing in libfdisk at all. Reported-by: "Gabor Z. Papp" <gzp@papp.hu> Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
a21aa92fd4
commit
4fb18cde32
|
@ -167,7 +167,6 @@ static int ask_offset(struct fdisk_context *cxt,
|
|||
int ask_callback(struct fdisk_context *cxt, struct fdisk_ask *ask,
|
||||
void *data __attribute__((__unused__)))
|
||||
{
|
||||
va_list ap;
|
||||
int rc = 0;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
|
@ -180,23 +179,17 @@ int ask_callback(struct fdisk_context *cxt, struct fdisk_ask *ask,
|
|||
case FDISK_ASKTYPE_OFFSET:
|
||||
return ask_offset(cxt, ask, buf, sizeof(buf));
|
||||
case FDISK_ASKTYPE_INFO:
|
||||
fdisk_ask_print_get_va(ask, ap);
|
||||
vfprintf(stdout, fdisk_ask_print_get_mesg(ask), ap);
|
||||
fputs(fdisk_ask_print_get_mesg(ask), stdout);
|
||||
fputc('\n', stdout);
|
||||
va_end(ap);
|
||||
break;
|
||||
case FDISK_ASKTYPE_WARNX:
|
||||
fdisk_ask_print_get_va(ask, ap);
|
||||
vfprintf(stderr, fdisk_ask_print_get_mesg(ask), ap);
|
||||
fputs(fdisk_ask_print_get_mesg(ask), stderr);
|
||||
fputc('\n', stderr);
|
||||
va_end(ap);
|
||||
break;
|
||||
case FDISK_ASKTYPE_WARN:
|
||||
fdisk_ask_print_get_va(ask, ap);
|
||||
vfprintf(stderr, fdisk_ask_print_get_mesg(ask), ap);
|
||||
fputs(fdisk_ask_print_get_mesg(ask), stderr);
|
||||
errno = fdisk_ask_print_get_errno(ask);
|
||||
fprintf(stderr, ": %m\n");
|
||||
va_end(ap);
|
||||
break;
|
||||
case FDISK_ASKTYPE_YESNO:
|
||||
fputc('\n', stdout);
|
||||
|
|
|
@ -18,11 +18,6 @@ void fdisk_reset_ask(struct fdisk_ask *ask)
|
|||
case FDISK_ASKTYPE_NUMBER:
|
||||
free(ask->data.num.range);
|
||||
break;
|
||||
case FDISK_ASKTYPE_WARNX:
|
||||
case FDISK_ASKTYPE_WARN:
|
||||
if (ask->data.print.has_va)
|
||||
va_end(ask->data.print.va);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -452,44 +447,32 @@ int fdisk_ask_print_set_mesg(struct fdisk_ask *ask, const char *mesg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* caller has to call va_end(ap) */
|
||||
int fdisk_ask_print_get_va(struct fdisk_ask *ask, va_list ap)
|
||||
{
|
||||
assert(ask);
|
||||
assert(is_print_ask(ask));
|
||||
va_copy(ap, ask->data.print.va);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* note that fdisk_free_ask() calls va_end() to free the private va list. */
|
||||
int fdisk_ask_print_set_va(struct fdisk_ask *ask, va_list ap)
|
||||
{
|
||||
assert(ask);
|
||||
va_copy(ask->data.print.va, ap);
|
||||
ask->data.print.has_va = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_vprint(struct fdisk_context *cxt, int errnum, int type,
|
||||
const char *fmt, va_list va)
|
||||
{
|
||||
struct fdisk_ask *ask;
|
||||
int rc;
|
||||
char *mesg;
|
||||
|
||||
assert(cxt);
|
||||
|
||||
ask = fdisk_new_ask();
|
||||
if (!ask)
|
||||
if (vasprintf(&mesg, fmt, va) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
ask = fdisk_new_ask();
|
||||
if (!ask) {
|
||||
free(mesg);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fdisk_ask_set_type(ask, type);
|
||||
fdisk_ask_print_set_mesg(ask, fmt);
|
||||
fdisk_ask_print_set_va(ask, va);
|
||||
fdisk_ask_print_set_mesg(ask, mesg);
|
||||
if (errnum >= 0)
|
||||
fdisk_ask_print_set_errno(ask, errnum);
|
||||
rc = fdisk_do_ask(cxt, ask);
|
||||
|
||||
fdisk_free_ask(ask);
|
||||
free(mesg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -231,8 +231,6 @@ struct fdisk_ask {
|
|||
/* FDISK_ASKTYPE_{WARN,WARNX,..} */
|
||||
struct ask_print {
|
||||
const char *mesg;
|
||||
va_list va;
|
||||
unsigned int has_va:1;
|
||||
int errnum; /* errno */
|
||||
} print;
|
||||
/* FDISK_ASKTYPE_YESNO */
|
||||
|
|
|
@ -182,8 +182,6 @@ extern int fdisk_ask_print_get_errno(struct fdisk_ask *ask);
|
|||
extern int fdisk_ask_print_set_errno(struct fdisk_ask *ask, int errnum);
|
||||
extern const char *fdisk_ask_print_get_mesg(struct fdisk_ask *ask);
|
||||
extern int fdisk_ask_print_set_mesg(struct fdisk_ask *ask, const char *mesg);
|
||||
extern int fdisk_ask_print_get_va(struct fdisk_ask *ask, va_list ap);
|
||||
extern int fdisk_ask_print_set_va(struct fdisk_ask *ask, va_list ap);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue