From: Radu Nichita Date: Wed, 12 Jul 2023 22:47:09 +0000 (+0300) Subject: lib/nolibc: scanf and fscanf functions X-Git-Tag: RELEASE-0.14.0~221 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=e622c0043f505b83d81e88c70d42ba6ae7514dac;p=unikraft%2Funikraft.git lib/nolibc: scanf and fscanf functions Adding scanf and fscanf function to nolibc, since their symbols were exported, but no implementation was provided. Signed-off-by: Radu Nichita Reviewed-by: Adina-Maria Vaman Approved-by: Razvan Deaconescu Tested-by: Unikraft CI GitHub-Closes: #977 --- diff --git a/lib/nolibc/Makefile.uk b/lib/nolibc/Makefile.uk index 3efeba4bf..82a22f716 100644 --- a/lib/nolibc/Makefile.uk +++ b/lib/nolibc/Makefile.uk @@ -44,6 +44,7 @@ LIBNOLIBC_SRCS-y += $(LIBNOLIBC_BASE)/musl-imported/src/network/ntohs.c LIBNOLIBC_SRCS-y += $(LIBNOLIBC_BASE)/h_errno.c LIBNOLIBC_SRCS-y += $(LIBNOLIBC_BASE)/getopt.c LIBNOLIBC_SRCS-y += $(LIBNOLIBC_BASE)/sscanf.c +LIBNOLIBC_SRCS-y += $(LIBNOLIBC_BASE)/scanf.c LIBNOLIBC_SRCS-y += $(LIBNOLIBC_BASE)/asprintf.c LIBNOLIBC_SRCS-y += $(LIBNOLIBC_BASE)/random.c diff --git a/lib/nolibc/exportsyms.uk b/lib/nolibc/exportsyms.uk index c90f452e8..1307f77cd 100644 --- a/lib/nolibc/exportsyms.uk +++ b/lib/nolibc/exportsyms.uk @@ -22,8 +22,9 @@ free # sscanf vsscanf -scanf sscanf +scanf +fscanf # stdio stdin diff --git a/lib/nolibc/include/stdio.h b/lib/nolibc/include/stdio.h index 1e5f9f2aa..e84a38221 100644 --- a/lib/nolibc/include/stdio.h +++ b/lib/nolibc/include/stdio.h @@ -78,6 +78,9 @@ int printf(const char *fmt, ...) __printf(1, 2); int vsscanf(const char *str, const char *fmt, va_list ap); int sscanf(const char *str, const char *fmt, ...) __scanf(2, 3); +int scanf(const char *fmt, ...); __scanf(1, 2); +int fscanf(FILE *fp, const char *fmt, ...); __scanf(2, 3); + int vasprintf(char **str, const char *fmt, va_list ap); int asprintf(char **str, const char *fmt, ...) __printf(2, 3); diff --git a/lib/nolibc/scanf.c b/lib/nolibc/scanf.c new file mode 100644 index 000000000..b07df6420 --- /dev/null +++ b/lib/nolibc/scanf.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#include +#include + +#include + +static int +uk_scanf(void *buffer, size_t *cnt) +{ + int bytes_read; + size_t bytes_total = 0, count; + char *buf = buffer; + + count = *cnt; + + do { + while ((bytes_read = ukplat_cink(buf, + count - bytes_total)) <= 0) + ; + + buf = buf + bytes_read; + *(buf - 1) = *(buf - 1) == '\r' ? + '\n' : *(buf - 1); + + /* Echo the input */ + if (*(buf - 1) == '\177') { + /* DELETE control character */ + if (buf - 1 != buffer) { + /* If this is not the first byte */ + ukplat_coutk("\b \b", 3); + buf -= 1; + if (bytes_total > 0) + bytes_total--; + } + buf -= 1; + } else { + ukplat_coutk(buf - bytes_read, bytes_read); + bytes_total += bytes_read; + } + + } while (bytes_total < count && + ((bytes_total == 0) || (*(buf - 1) != '\n' && *(buf - 1) != '\0'))); + + *cnt = bytes_total; + + return 0; +} + +int +vfscanf(FILE *fp, const char *fmt, va_list ap) +{ + int ret = 0; + char buf[1024]; + size_t size = sizeof(buf); + + if (fp == stdin) + ret = uk_scanf(buf, &size); + else + return 0; + + if (ret < 0) + return ret; + + ret = vsscanf(buf, fmt, ap); + return ret; +} + +int +vscanf(const char *fmt, va_list ap) +{ + return vfscanf(stdin, fmt, ap); +} + +int +fscanf(FILE *fp, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfscanf(fp, fmt, ap); + va_end(ap); + + return ret; +} + +int +scanf(const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vscanf(fmt, ap); + va_end(ap); + return ret; +}