Fix bugs and make code tinier

- Fixed bug where stdio eof wasn't being sticky
- Fixed bug where fseeko() wasn't clearing eof state
- Removed assert() usage from libc favoring _unassert() / _npassert()
This commit is contained in:
Justine Tunney 2022-10-09 22:38:28 -07:00
parent 9b7c8db846
commit d5910e2673
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
115 changed files with 510 additions and 290 deletions

View file

@ -53,7 +53,7 @@ ssize_t appendd(char **b, const void *s, size_t l) {
z.n = ROUNDUP(z.n, W);
if ((p = realloc(p, z.n))) {
z.n = malloc_usable_size(p);
assert(!(z.n & (W - 1)));
_unassert(!(z.n & (W - 1)));
*b = p;
} else {
return -1;

View file

@ -51,14 +51,14 @@ ssize_t appendr(char **b, size_t i) {
char *p;
size_t n;
struct appendz z;
assert(b);
_unassert(b);
z = appendz((p = *b));
if (i != z.i || !p) {
n = ROUNDUP(i + 1, 8) + W;
if (n > z.n || _bsrl(n) < _bsrl(z.n)) {
if ((p = realloc(p, n))) {
z.n = malloc_usable_size(p);
assert(!(z.n & (W - 1)));
_unassert(!(z.n & (W - 1)));
*b = p;
} else {
return -1;

View file

@ -67,7 +67,7 @@ ssize_t appendw(char **b, uint64_t w) {
z.n = ROUNDUP(z.n, W);
if ((p = realloc(p, z.n))) {
z.n = malloc_usable_size(p);
assert(!(z.n & (W - 1)));
_unassert(!(z.n & (W - 1)));
*b = p;
} else {
return -1;

View file

@ -34,7 +34,7 @@ struct appendz appendz(char *p) {
struct appendz z;
if (p) {
z.n = malloc_usable_size(p);
assert(z.n >= W * 2 && !(z.n & (W - 1)));
_unassert(z.n >= W * 2 && !(z.n & (W - 1)));
z.i = *(size_t *)(p + z.n - W);
if (!IsTiny() && W == 8) {
/*
@ -43,10 +43,10 @@ struct appendz appendz(char *p) {
* can be free()'d safely, but they need to be allocated by the
* append library, because we write a special value to the end.
*/
assert((z.i >> 48) == APPEND_COOKIE);
_unassert((z.i >> 48) == APPEND_COOKIE);
z.i &= 0x0000ffffffffffff;
}
assert(z.n >= z.i);
_unassert(z.n >= z.i);
} else {
z.i = 0;
z.n = 0;

View file

@ -20,7 +20,7 @@
#include "libc/stdio/stdio.h"
/**
* Clears error state on stream.
* Clears eof and error state indicators on stream.
*
* @param f is file object stream pointer
* @see clearerr_unlocked()

View file

@ -18,6 +18,13 @@
*/
#include "libc/stdio/stdio.h"
/**
* Clears eof and error state indicators on stream.
*
* @param f is file object stream pointer
* @see clearerr()
* @threadsafe
*/
void clearerr_unlocked(FILE *f) {
f->state = 0;
}

View file

@ -336,7 +336,8 @@ static struct dirent *readdir_impl(DIR *dir) {
ent = 0;
zip = _weaken(__zipos_get)();
while (!ent && dir->tell < dir->zip.records) {
assert(ZIP_CFILE_MAGIC(zip->map + dir->zip.offset) == kZipCfileHdrMagic);
_npassert(ZIP_CFILE_MAGIC(zip->map + dir->zip.offset) ==
kZipCfileHdrMagic);
s = ZIP_CFILE_NAME(zip->map + dir->zip.offset);
n = ZIP_CFILE_NAMESIZE(zip->map + dir->zip.offset);
if (dir->zip.prefixlen < n &&

View file

@ -16,6 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/stdio/lock.internal.h"
#include "libc/stdio/stdio.h"
@ -31,6 +33,8 @@ size_t fread(void *buf, size_t stride, size_t count, FILE *f) {
size_t rc;
flockfile(f);
rc = fread_unlocked(buf, stride, count, f);
STDIOTRACE("fread(%p, %'zu, %'zu, %p) → %'zu %s", buf, stride, count, f, rc,
DescribeStdioState(f->state));
funlockfile(f);
return rc;
}

View file

@ -42,6 +42,9 @@ size_t fread_unlocked(void *buf, size_t stride, size_t count, FILE *f) {
ssize_t rc;
size_t n, m;
struct iovec iov[2];
if (f->state) {
return 0;
}
if ((f->iomode & O_ACCMODE) == O_WRONLY) {
f->state = errno = EBADF;
return 0;

View file

@ -16,6 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/stdio/lock.internal.h"
#include "libc/stdio/stdio.h"
@ -37,6 +39,8 @@ int fseeko(FILE *f, int64_t offset, int whence) {
int rc;
flockfile(f);
rc = fseeko_unlocked(f, offset, whence);
STDIOTRACE("fseeko(%p, %'ld, %s) → %d %s", f, offset, DescribeWhence(whence),
rc, DescribeStdioState(f->state));
funlockfile(f);
return rc;
}

View file

@ -47,6 +47,7 @@ int fseeko_unlocked(FILE *f, int64_t offset, int whence) {
if (lseek(f->fd, offset, whence) != -1) {
f->beg = 0;
f->end = 0;
f->state = 0;
res = 0;
} else {
f->state = errno == ESPIPE ? EBADF : errno;
@ -69,6 +70,7 @@ int fseeko_unlocked(FILE *f, int64_t offset, int whence) {
}
if (0 <= pos && pos <= f->end) {
f->beg = pos;
f->state = 0;
res = 0;
} else {
f->state = errno = EINVAL;

View file

@ -16,6 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/stdio/lock.internal.h"
#include "libc/stdio/stdio.h"
@ -31,6 +33,8 @@ size_t fwrite(const void *data, size_t stride, size_t count, FILE *f) {
size_t rc;
flockfile(f);
rc = fwrite_unlocked(data, stride, count, f);
STDIOTRACE("fwrite(%p, %'zu, %'zu, %p) → %'zu %s", data, stride, count, f, rc,
DescribeStdioState(f->state));
funlockfile(f);
return rc;
}

View file

@ -44,6 +44,9 @@ size_t fwrite_unlocked(const void *data, size_t stride, size_t count, FILE *f) {
size_t n, m;
const char *p;
struct iovec iov[2];
if (f->state) {
return 0;
}
if ((f->iomode & O_ACCMODE) == O_RDONLY) {
f->state = errno = EBADF;
return 0;

View file

@ -51,9 +51,9 @@ ssize_t kvappendf(char **b, const char *f, va_list v) {
z.n = ROUNDUP(z.n, W);
if ((p = realloc(p, z.n))) {
z.n = malloc_usable_size(p);
assert(!(z.n & (W - 1)));
_unassert(!(z.n & (W - 1)));
s = kvsnprintf(p + z.i, z.n - W - z.i, f, w);
assert(s == r);
_unassert(s == r);
*b = p;
} else {
va_end(w);

View file

@ -18,11 +18,11 @@
*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/errno.h"
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/lcg.internal.h"
#include "libc/stdio/rand.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/temp.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/o.h"
@ -38,7 +38,7 @@ int mkostempsmi(char *tpl, int slen, unsigned flags, uint64_t *rando, int mode,
size_t wildlen = strlen(WILDCARD);
if (len < wildlen || slen > len - wildlen) return einval();
char *ss = tpl + len - wildlen - slen;
assert(memcmp(ss, WILDCARD, wildlen) == 0);
_npassert(memcmp(ss, WILDCARD, wildlen) == 0);
flags = (flags & ~(flags & O_ACCMODE)) | O_RDWR | O_CREAT | O_EXCL;
unsigned attempts = ATTEMPTS;
do {

View file

@ -31,7 +31,6 @@ int pclose(FILE *f) {
int ws, pid;
pid = f->pid;
fclose(f);
assert(pid);
if (!pid) return 0;
TryAgain:
if (wait4(pid, &ws, 0, 0) != -1) {

View file

@ -44,9 +44,9 @@ ssize_t(vappendf)(char **b, const char *f, va_list v) {
z.n = ROUNDUP(z.n, W);
if ((p = realloc(p, z.n))) {
z.n = malloc_usable_size(p);
assert(!(z.n & (W - 1)));
_unassert(!(z.n & (W - 1)));
s = (vsnprintf)(p + z.i, z.n - W - z.i, f, w);
assert(s == r);
_unassert(s == r);
*b = p;
} else {
va_end(w);