/*
 * ftell — логическая позиция потока.  Без побочных эффектов: позиция
 * fd корректируется на состояние буфера арифметикой —
 *   режим записи:  fd_pos + level (несброшенный хвост впереди fd);
 *   режим чтения:  fd_pos − level − (1, если hold от ungetc).
 * Для консольных псевдопотоков — EBADF/-1.
 */

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

long ftell(FILE *fp)
{
#ifndef LIBC_NOCHECK
    if (!fp) { errno = EBADF; return -1L; }
#endif
    if (fp->flags & (_F_CONIN | _F_CONOUT)) {
        errno = EBADF;
        return -1L;
    }
    long pos = lseek(fp->fd, 0L, SEEK_CUR);
    if (pos < 0) return -1L;
    if (fp->flags & _F_DIROUT) {
        pos += fp->level;
    } else {
        pos -= fp->level;
        if (fp->hold != EOF) pos--;
    }
    return pos;
}
