summaryrefslogtreecommitdiff
path: root/lib/libc/stdio/fseek.c
blob: 7a6754f7af4188d52245a8ac2ff700449aed84ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "__stdio.h" // for __FILE, _IO_EOF, _IO_ERR
#include "stddef.h"  // for NULL

#include <atomic.h> // for LIBC_LOCK, LIBC_UNLOCK
#include <stdio.h>  // for FILE, fseek
#include <unistd.h> // for lseek, off_t

int fseek(FILE *stream, long offset, int whence)
{
	if (stream == NULL || __FILE(stream)->fd < 0)
		return -1;

	LIBC_LOCK(__FILE(stream)->lock);

	__FILE(stream)->buf_pos = 0;
	__FILE(stream)->buf_len = 0;
	__FILE(stream)->flags &= ~_IO_EOF;

	off_t result = lseek(__FILE(stream)->fd, offset, whence);

	LIBC_UNLOCK(__FILE(stream)->lock);

	if (result == (off_t)-1) {
		__FILE(stream)->flags |= _IO_ERR;
		return -1;
	}

	__FILE(stream)->offset = result;
	return 0;
}