Skip to content

Commit 924d629

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 a603970 commit 924d629

File tree

6 files changed

+39
-8
lines changed

6 files changed

+39
-8
lines changed

lib/c.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -496,10 +496,9 @@ char *fgets(char *str, int n, FILE *stream)
496496

497497
int fputc(int c, FILE *stream)
498498
{
499-
char buf[1];
500-
buf[0] = c;
501-
__syscall(__syscall_write, stream, buf, 1);
502-
return 0;
499+
if (__syscall(__syscall_write, stream, &c, 1) < 0)
500+
return -1;
501+
return c;
503502
}
504503

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

tests/driver.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,4 +1611,36 @@ int main()
16111611
}
16121612
EOF
16131613

1614+
# test the return value when calling fputc().
1615+
#
1616+
# Since the FILE data type is defined as an int in
1617+
# the built-in C library, and most of the functions
1618+
# such as fputc(), fgetc(), fclose() and fgets() directly
1619+
# treat the "stream" parameter (of type FILE *) as a file
1620+
# descriptor for performing input/output operations, the
1621+
# following test cases define "stdout" as 1, which is the
1622+
# file descriptor for the standard output.
1623+
#
1624+
try_output 0 "awritten = a" << EOF
1625+
#define stdout 1
1626+
1627+
int main()
1628+
{
1629+
int c = fputc('a', stdout);
1630+
printf("written = %c", c);
1631+
return 0;
1632+
}
1633+
EOF
1634+
1635+
try_output 1 "" << EOF
1636+
#define stdout 1
1637+
1638+
int main()
1639+
{
1640+
__syscall(__syscall_close, 1);
1641+
int c = fputc('a', stdout);
1642+
return c == -1;
1643+
}
1644+
EOF
1645+
16141646
echo OK

tests/snapshots/fib-arm.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

tests/snapshots/fib-riscv.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

tests/snapshots/hello-arm.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

tests/snapshots/hello-riscv.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)