Package: libc6 Version: 2.27-8 Severity: normal Tags: upstream Dear Maintainer,
If I use fputs(3), fputc(3), or fwrite(3) to write to a file that can be opened for writing but cannot be written to (e.g /dev/full), the functions return 1 rather than the expected EOF (or 0 in the case of fread()). On the other hand, write(2) returns -1 and sets errno to ENOSPC an expected. Expected results: The functions fputs() and fputc() should return EOF and fwrite() should return 0. All the functions should set errno to ENOSPC (for /dev/full). Actual results: The functions return 1 (an indication of success) and leave errno unchanged. Steps to reproduce: Compile the attached program (the compiler flag `-fno-builtin' does not change anything, nor does -O0): $ gcc -o write write.c Run the program with /dev/full as the output file: $ ./write hello /dev/full fputs() returned 1 and errno is 0 (Success). fputc() returned 104 (h) and errno is 0 (Success). fwrite() returned 5 (the length of "hello" is 5) and errno is 0 (Success). write() returned -1 (the length of "hello" is 5) and errno is 28 (No space left on device). The expected output is: fputs() returned EOF (-1) and errno is 28 (No space left on device). fputc() returned EOF (-1) and errno is 28 (No space left on device). fwrite() returned 0 (the length of "hello" is 5) and errno is 28 (No space left on device). write() returned -1 (the length of "hello" is 5) and errno is 28 (No space left on device). -- System Information: Debian Release: buster/sid APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 4.18.0-2-amd64 (SMP w/2 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages libc6 depends on: ii libgcc1 1:8.2.0-9 libc6 recommends no packages. Versions of packages libc6 suggests: ii debconf [debconf-2.0] 1.5.69 pn glibc-doc <none> ii libc-l10n 2.27-8 ii locales 2.27-8 -- debconf information: * glibc/restart-services: cups cron glibc/kernel-too-old: glibc/kernel-not-supported: glibc/restart-failed: glibc/upgrade: true glibc/disable-screensaver: * libraries/restart-without-asking: false
#include <stdio.h> #include <unistd.h> #include <string.h> #include <errno.h> int main(int argc, char **argv) { int ret; size_t string_len; FILE *output_file; if (argc != 3) { fprintf(stderr, "Usage: %s STRING FILE\nWrite STRING to FILE.\n", argv[0]); return 1; } /* Open the file */ if (!(output_file = fopen(argv[2], "w"))) { fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[2]); return 1; } /* Now try to write to the file using fputs() */ errno = 0; ret = fputs(argv[1], output_file); /* `ret' should be EOF if an error occured (see fputs(3)) */ printf ("fputs() returned "); if (ret == EOF) printf("EOF (%d)", ret); else printf("%d", ret); printf(" and errno is %d (%m).\n", errno); /* This happens with fputc() too */ errno = 0; ret = fputc(argv[1][0], output_file); printf("fputc() returned "); if (ret == EOF) printf("EOF (%d)", ret); else printf("%d (%c)", ret, (char)ret); printf(" and errno is %d (%m).\n", errno); string_len = strlen(argv[1]); /* This happens with fwrite() too */ errno = 0; printf("fwrite() returned %lu (the length of \"%s\" is %lu) ", fwrite(argv[1], 1, string_len, output_file), argv[1], string_len); printf("and errno is %d (%m).\n", errno); /* write() gives us expected results */ errno = 0; printf("write() returned %ld (the length of \"%s\" is %lu) ", write(fileno(output_file), argv[1], string_len), argv[1], string_len); printf("and errno is %d (%m).\n", errno); return 0; }