/*
 * _file_sync — нейтрализовать буфер потока (см. _file.h и
 * docs/file-buffering-design.md, «семантика инвалидации»).
 *
 * Направление «запись»: сбросить несброшенный хвост одним write();
 * короткая запись = ошибка потока.  Направление «чтение»: откатить
 * позицию fd назад на непрочитанный readahead (+1 за hold-байт
 * ungetc) — после этого реальная позиция fd совпадает с логической
 * позицией потока, буфер объявляется пустым.
 */

#include <unistd.h>
#include "_file.h"

int _file_sync(FILE *fp)
{
    if (fp->flags & _F_DIROUT) {
        uint16_t n = fp->level;
        fp->flags &= (uint8_t)~_F_DIROUT;
        fp->level = 0;
        fp->curp  = fp->buf;
        if (n) {
            int w = write(fp->fd, fp->buf, n);
            if (w < 0 || (uint16_t)w != n) {
                fp->flags |= _F_ERROR;
                return EOF;
            }
        }
    } else {
        long back = fp->level;
        if (fp->hold != EOF) { back++; fp->hold = EOF; }
        fp->level = 0;
        fp->curp  = fp->buf;
        if (back) {
            if (lseek(fp->fd, -back, SEEK_CUR) < 0) {
                fp->flags |= _F_ERROR;
                return EOF;
            }
        }
    }
    return 0;
}
