/* We assume here that we are the only remaining thread. */ void attribute_hidden _stdio_term(void) { #if defined(__STDIO_BUFFERS) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__) register FILE *ptr; #ifdef __UCLIBC_HAS_THREADS__ /* First, make sure the open file list is unlocked. If it was * locked, then I suppose there is a chance that a pointer in the * chain might be corrupt due to a partial store. */ __stdio_init_mutex(&_stdio_openlist_add_lock); #warning check #ifdef __STDIO_BUFFERS __stdio_init_mutex(&_stdio_openlist_del_lock); #endif /* Next we need to worry about the streams themselves. If a stream * is currently locked, then it may be in an invalid state. So we * 'disable' it in case a custom stream is stacked on top of it. * Then we reinitialize the locks. */ for (ptr = _stdio_openlist ; ptr ; ptr = ptr->__nextopen ) { if (__STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(ptr)) { /* The stream is already locked, so we don't want to touch it. * However, if we have custom streams, we can't just close it * or leave it locked since a custom stream may be stacked * on top of it. So we do unlock it, while also disabling it. */ ptr->__modeflags = (__FLAG_READONLY|__FLAG_WRITEONLY); __STDIO_STREAM_DISABLE_GETC(ptr); __STDIO_STREAM_DISABLE_PUTC(ptr); __STDIO_STREAM_INIT_BUFREAD_BUFPOS(ptr); } ptr->__user_locking = 1; /* Set locking mode to "by caller". */ __stdio_init_mutex(&ptr->__lock); /* Shouldn't be necessary, but... */ } #endif /* Finally, flush all writing streams and shut down all custom streams. * NOTE: We assume that any stacking by custom streams is done on top * of streams previously allocated, and hence further down the * list. Otherwise we have no way of knowing the order in which * to shut them down. * Remember that freopen() counts as a new allocation here, even * though the stream is reused. That's because it moves the * stream to the head of the list. */ for (ptr = _stdio_openlist ; ptr ; ptr = ptr->__nextopen ) { #ifdef __STDIO_BUFFERS /* Write any pending buffered chars. */ if (__STDIO_STREAM_IS_WRITING(ptr)) { __STDIO_COMMIT_WRITE_BUFFER(ptr); } #endif #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ /* Actually close all custom streams to perform any special cleanup. */ if (ptr->__cookie != &ptr->__filedes) { __CLOSE(ptr); } #endif } #endif }
int ftrylockfile(FILE *stream) { __STDIO_STREAM_VALIDATE(stream); return __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(stream); }