summaryrefslogtreecommitdiff
path: root/lib/libc/stdio/fdopen.c
blob: 23f9484396d9653126117c07391706f7e4e77493 (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
31
32
33
34
35
36
37
38
39
#include <io.h>
#include <libc.h>
#include <unistd.h>
#include <stdio.h>

__weak void __stdio_cleanup(void)
{
}

FILE *fdopen(int fildes, const char *mode)
{
	FILE *fp;

	if (mode == NULL ||
	    (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a')) {
		return NULL;
	}

	if ((fp = calloc(1, sizeof(FILE))) == NULL)
		return NULL;

	fp->fd = fildes;
	atomic_flag_clear(&fp->lock);
	if (mode[0] == 'r') {
		fp->type = _IONBF;
	} else if (mode[0] == 'w') {
		fp->type = _IOLBF;
	} else if (mode[0] == 'a') {
		fp->type = _IONBF;
		off_t offset = lseek(fildes, 0, SEEK_END);
		if (offset == (off_t)-1) {
			free(fp);
			return NULL;
		}
	}

	__libc_fadd(fp);
	return fp;
}