Skip to content

Commit defeb1b

Browse files
committed
Correct the return value of fputc function
According to the man page, the return value of fputc() should be either the character written as an "unsigned char" cast to an "int" or EOF on error, but the current implementation doesn't follow the specification. Therefore, these changes correct the implementation to return the ASCII code of the written character or -1 if the output fails, thereby matching the description in the man page. Additionally, the necessary test cases are also added to validate the correctness.
1 parent f5e57e6 commit defeb1b

File tree

6 files changed

+36
-8
lines changed

6 files changed

+36
-8
lines changed

lib/c.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -460,10 +460,9 @@ char *fgets(char *str, int n, FILE *stream)
460460

461461
int fputc(int c, FILE *stream)
462462
{
463-
char buf[1];
464-
buf[0] = c;
465-
__syscall(__syscall_write, stream, buf, 1);
466-
return 0;
463+
if (__syscall(__syscall_write, stream, &c, 1) < 0)
464+
return -1;
465+
return c;
467466
}
468467

469468
/* Non-portable: Assume page size is 4KiB */

tests/driver.sh

+29
Original file line numberDiff line numberDiff line change
@@ -1674,4 +1674,33 @@ int main() {
16741674
}
16751675
EOF
16761676

1677+
# test the return value when calling fputc().
1678+
#
1679+
# Since the FILE data type is defined as an int in
1680+
# the built-in C library, and most of the functions
1681+
# such as fputc(), fgetc(), fclose() and fgets() directly
1682+
# treat the "stream" parameter (of type FILE *) as a file
1683+
# descriptor for performing input/output operations, the
1684+
# following test cases define "stdout" as 1, which is the
1685+
# file descriptor for the standard output.
1686+
try_output 0 "awritten = a" << EOF
1687+
#define stdout 1
1688+
int main()
1689+
{
1690+
int c = fputc('a', stdout);
1691+
printf("written = %c", c);
1692+
return 0;
1693+
}
1694+
EOF
1695+
1696+
try_output 1 "" << EOF
1697+
#define stdout 1
1698+
int main()
1699+
{
1700+
__syscall(__syscall_close, 1);
1701+
int c = fputc('a', stdout);
1702+
return c == -1;
1703+
}
1704+
EOF
1705+
16771706
echo OK

tests/snapshots/fib-arm.json

+1-1
Large diffs are not rendered by default.

tests/snapshots/fib-riscv.json

+1-1
Large diffs are not rendered by default.

tests/snapshots/hello-arm.json

+1-1
Large diffs are not rendered by default.

tests/snapshots/hello-riscv.json

+1-1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)