mirror of
https://github.com/fluencelabs/musl
synced 2025-05-28 23:21:34 +00:00
previously, fgets, fputs, fread, and fwrite completely omitted locking and access to the FILE object when their arguments yielded a zero length read or write operation independent of the FILE state. this optimization was invalid; it wrongly skipped marking the stream as byte-oriented (a C conformance bug) and exposed observably missing synchronization (a POSIX conformance bug) where one of these functions could wrongly complete despite another thread provably holding the lock.
38 lines
696 B
C
38 lines
696 B
C
#include "stdio_impl.h"
|
|
#include <string.h>
|
|
|
|
size_t __fwritex(const unsigned char *restrict s, size_t l, FILE *restrict f)
|
|
{
|
|
size_t i=0;
|
|
|
|
if (!f->wend && __towrite(f)) return 0;
|
|
|
|
if (l > f->wend - f->wpos) return f->write(f, s, l);
|
|
|
|
if (f->lbf >= 0) {
|
|
/* Match /^(.*\n|)/ */
|
|
for (i=l; i && s[i-1] != '\n'; i--);
|
|
if (i) {
|
|
if (f->write(f, s, i) < i)
|
|
return i;
|
|
s += i;
|
|
l -= i;
|
|
}
|
|
}
|
|
|
|
memcpy(f->wpos, s, l);
|
|
f->wpos += l;
|
|
return l+i;
|
|
}
|
|
|
|
size_t fwrite(const void *restrict src, size_t size, size_t nmemb, FILE *restrict f)
|
|
{
|
|
size_t k, l = size*nmemb;
|
|
FLOCK(f);
|
|
k = __fwritex(src, l, f);
|
|
FUNLOCK(f);
|
|
return k==l ? nmemb : k/size;
|
|
}
|
|
|
|
weak_alias(fwrite, fwrite_unlocked);
|