/* Copyright (c) 2016, 2018, 2019, 2022 Dennis Wölfing
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/* libc/src/stdio/fflush.c
 * Flush a file stream. (C89)
 */

#define fflush_unlocked __fflush_unlocked
#define flockfile __flockfile
#define funlockfile __funlockfile
#define pthread_mutex_lock __mutex_lock
#define pthread_mutex_unlock __mutex_unlock
#include "FILE.h"

FILE* __firstFile;
__mutex_t __fileListMutex = _MUTEX_INIT(_MUTEX_NORMAL);

int fflush(FILE* file) {
    if (!file) {
        int result = 0;
        result |= fflush(stdin);
        result |= fflush(stdout);
        result |= fflush(stderr);

        pthread_mutex_lock(&__fileListMutex);
        file = __firstFile;
        while (file) {
            result |= fflush(file);
            file = file->next;
        }
        pthread_mutex_unlock(&__fileListMutex);

        return result;
    }

    flockfile(file);
    int result = fflush_unlocked(file);
    funlockfile(file);
    return result;
}
