summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/core/linux/linux_api.c
blob: 17b1f3fd4d9f69c9c308bcd0c29fb1094072fed6 (plain) (blame)
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
 * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */

FILE_LICENCE ( GPL2_OR_LATER );

/** @file
 *
 * Implementation of most of the linux API.
 */

#include <linux_api.h>

#include <stdarg.h>
#include <asm/unistd.h>
#include <string.h>

int linux_open ( const char *pathname, int flags ) {
	return linux_syscall ( __NR_open, pathname, flags );
}

int linux_close ( int fd ) {
	return linux_syscall ( __NR_close, fd );
}

off_t linux_lseek ( int fd, off_t offset, int whence ) {
	return linux_syscall ( __NR_lseek, fd, offset, whence );
}

__kernel_ssize_t linux_read ( int fd, void *buf, __kernel_size_t count ) {
	return linux_syscall ( __NR_read, fd, buf, count );
}

__kernel_ssize_t linux_write ( int fd, const void *buf,
			       __kernel_size_t count ) {
	return linux_syscall  (  __NR_write, fd, buf, count );
}

int linux_fcntl ( int fd, int cmd, ... ) {
	long arg;
	va_list list;

	va_start ( list, cmd );
	arg = va_arg ( list, long );
	va_end ( list );

	return linux_syscall ( __NR_fcntl, fd, cmd, arg );
}

int linux_ioctl ( int fd, int request, ... ) {
	void *arg;
	va_list list;

	va_start ( list, request );
	arg = va_arg ( list, void * );
	va_end ( list );

	return linux_syscall ( __NR_ioctl, fd, request, arg );
}

int linux_poll ( struct pollfd *fds, nfds_t nfds, int timeout ) {
	return linux_syscall ( __NR_poll, fds, nfds, timeout );
}

int linux_nanosleep ( const struct timespec *req, struct timespec *rem ) {
	return linux_syscall ( __NR_nanosleep, req, rem );
}

int linux_usleep ( useconds_t usec ) {
	struct timespec ts = {
		.tv_sec = ( ( long ) ( usec / 1000000 ) ),
		.tv_nsec = ( ( long ) ( usec % 1000000 ) * 1000UL ),
	};

	return linux_nanosleep ( &ts, NULL );
}

int linux_gettimeofday ( struct timeval *tv, struct timezone *tz ) {
	return linux_syscall ( __NR_gettimeofday, tv, tz );
}

void * linux_mmap ( void *addr, __kernel_size_t length, int prot, int flags,
		    int fd, __kernel_off_t offset ) {
	return ( void * ) linux_syscall ( __SYSCALL_mmap, addr, length, prot,
					  flags, fd, offset );
}

void * linux_mremap ( void *old_address, __kernel_size_t old_size,
		      __kernel_size_t new_size, int flags ) {
	return ( void * ) linux_syscall ( __NR_mremap, old_address, old_size,
					  new_size, flags );
}

int linux_munmap ( void *addr, __kernel_size_t length ) {
	return linux_syscall ( __NR_munmap, addr, length );
}

int linux_socket ( int domain, int type_, int protocol ) {
#ifdef __NR_socket
	return linux_syscall ( __NR_socket, domain, type_, protocol );
#else
#ifndef SOCKOP_socket
# define SOCKOP_socket 1
#endif
	unsigned long sc_args[] = { domain, type_, protocol };
	return linux_syscall ( __NR_socketcall, SOCKOP_socket, sc_args );
#endif
}

int linux_bind ( int fd, const struct sockaddr *addr, socklen_t addrlen ) {
#ifdef __NR_bind
	return linux_syscall ( __NR_bind, fd, addr, addrlen );
#else
#ifndef SOCKOP_bind
# define SOCKOP_bind 2
#endif
	unsigned long sc_args[] = { fd, (unsigned long)addr, addrlen };
	return linux_syscall ( __NR_socketcall, SOCKOP_bind, sc_args );
#endif
}

ssize_t linux_sendto ( int fd, const void *buf, size_t len, int flags,
		       const struct sockaddr *daddr, socklen_t addrlen ) {
#ifdef __NR_sendto
	return linux_syscall ( __NR_sendto, fd, buf, len, flags,
			       daddr, addrlen );
#else
#ifndef SOCKOP_sendto
# define SOCKOP_sendto 11
#endif
	unsigned long sc_args[] = { fd, (unsigned long)buf, len,
				    flags, (unsigned long)daddr, addrlen };
	return linux_syscall ( __NR_socketcall, SOCKOP_sendto, sc_args );
#endif
}