2 * (c) 2004-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>,
4 * Frank Mehnert <fm3@os.inf.tu-dresden.de>
5 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU Lesser General Public License 2.1.
8 * Please see the COPYING-LGPL-2.1 file for details.
12 * Some very minor system calls for Linux.
15 #include <l4/lxfuxlibc/lxfuxlc.h>
24 #define __NR_waitpid 7
25 #define __NR_unlink 10
28 #define __NR_getpid 20
30 #define __NR_rename 38
35 #define __NR_gettimeofday 78
36 #define __NR_ftruncate 93
37 #define __NR_socketcall 102
39 #define __NR_lstat 107
40 #define __NR_fstat 108
42 #define __NR_fsync 118
43 #define __NR_select 142 /* new select */
44 #define __NR_readv 145
45 #define __NR_writev 146
46 #define __NR_fdatasync 148
48 #define __NR___lx_priv_ftruncate64 194
49 #define __NR_ftruncate64 194
50 #define __NR_stat64 195
51 #define __NR_fstat64 197
52 #define __NR_getdents64 220
53 #define __NR_fcntl64 221
54 #define __NR_openat 295
55 #define __NR_mkdirat 296
56 #define __NR_unlinkat 301
57 #define __NR_renameat 302
58 #define __NR_faccessat 307
61 /* Some stuff pilfered from linux/include/asm-i386/unistd.h */
63 #define __lx_syscall_return(type, res) \
66 /* This one isn't used anymore and just left for the education of the reader
68 /* user-visible error numbers are in the range -1 to -124, see asm/errno.h */
69 #define __lx_syscall_return_with_errno(type, res) \
71 if ((unsigned long)(res) >= (unsigned long)(-125)) { \
75 return (type) (res); \
78 #define __lx_syscall0(type,name) \
79 type lx_##name(void) \
82 __asm__ __volatile__ ( \
87 __lx_syscall_return(type, __res); \
90 #define __lx_syscall1(type,name,type1,arg1) \
91 type lx_##name(type1 arg1) \
94 __asm__ __volatile__ ( \
97 : "0" (__NR_##name), \
100 __lx_syscall_return(type, __res); \
103 #define __lx_syscall1_e(type,name,type1,arg1) \
104 type lx_##name(type1 arg1) \
107 __asm__ __volatile__ ( \
110 : "a" (__NR_##name), \
116 #define __lx_syscall2(type,name,type1,arg1,type2,arg2) \
117 type lx_##name(type1 arg1, type2 arg2) \
120 __asm__ __volatile__ ( \
123 : "0" (__NR_##name), \
124 "b" ((long)(arg1)), "c" ((long)(arg2)) \
126 __lx_syscall_return(type, __res); \
129 #define __lx_syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
130 type lx_##name(type1 arg1, type2 arg2, type3 arg3) \
133 __asm__ __volatile__ ( \
136 : "0" (__NR_##name), \
137 "b" ((long)(arg1)), "c" ((long)(arg2)), "d" ((long)(arg3)) \
139 __lx_syscall_return(type, __res); \
142 #define __lx_syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
143 type lx_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4 ) \
146 __asm__ __volatile__ ( \
149 : "0" (__NR_##name), \
150 "b" ((long)(arg1)), "c" ((long)(arg2)), "d" ((long)(arg3)), \
153 __lx_syscall_return(type, __res); \
156 #define __lx_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
157 type lx_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
160 __asm__ __volatile__ ( \
163 : "0" (__NR_##name), \
164 "b" ((long)(arg1)), "c" ((long)(arg2)), "d" ((long)(arg3)), \
165 "S" ((long)(arg4)), "D" ((long)(arg5)) \
167 __lx_syscall_return(type, __res); \
170 #define __lx_syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
171 type lx_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
174 __asm__ __volatile__ ( \
175 "push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \
177 : "i" (__NR_##name), \
178 "b" ((long)(arg1)), "c" ((long)(arg2)), "d" ((long)(arg3)), \
179 "S" ((long)(arg4)), "D" ((long)(arg5)), "0" ((long)(arg6)) \
181 __lx_syscall_return(type, __res); \
184 __lx_syscall1_e(void, exit, int, status)
185 __lx_syscall0(lx_pid_t, fork)
186 __lx_syscall3(long, read, unsigned int, fd, void *, buf, unsigned int, count)
187 __lx_syscall3(long, write, unsigned int, fd, const void *, buf, unsigned int, count)
188 __lx_syscall3(long, open, const char *, filename, int, flags, int, mode)
189 __lx_syscall1(long, close, unsigned int, fd)
190 __lx_syscall3(lx_pid_t, waitpid, lx_pid_t, pid, int *, wait_stat, int, options)
191 __lx_syscall1(int, unlink, const char *, filename)
192 __lx_syscall1(int, chdir, const char *, filename)
193 __lx_syscall3(long, lseek, unsigned int, fd, unsigned long, offset, unsigned int, origin)
194 __lx_syscall0(long, getpid)
195 __lx_syscall2(int, kill, lx_pid_t, pid, int, sig)
196 __lx_syscall2(int, rename, const char *, oldpath, const char *, newpath)
197 __lx_syscall2(int, mkdir, const char *, filename, int, mode)
198 __lx_syscall1(int, rmdir, const char *, filename)
199 __lx_syscall1(int, pipe, int *, filedes)
200 __lx_syscall3(long, ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
201 __lx_syscall2(long, gettimeofday, struct lx_timeval *, tv, struct lx_timezone *, tz)
202 __lx_syscall5(int, select, int, n, lx_fd_set *, readfds, lx_fd_set *, writefds, lx_fd_set *, exceptfds, struct lx_timeval *, timeout)
203 __lx_syscall2(int, ftruncate, int, fd, unsigned long, ofs)
204 __lx_syscall2(int, socketcall, int, call, unsigned long *, args);
205 __lx_syscall2(int, stat, const char *, filename, struct lx_stat *, buf)
206 __lx_syscall2(int, lstat, const char *, filename, struct lx_stat *, buf)
207 __lx_syscall2(int, fstat, int, filedes, struct lx_stat *, buf)
208 __lx_syscall6(int, ipc, unsigned int, call, int, first, int, second, int, third, const void *, ptr, long, fifth)
209 __lx_syscall1(int, fsync, int, fd)
210 __lx_syscall3(lx_ssize_t, readv, int, fd, const struct lx_iovec*, iov, int, cnt);
211 __lx_syscall3(lx_ssize_t, writev, int, fd, const struct lx_iovec*, iov, int, cnt);
212 __lx_syscall1(int, fdatasync, int, fd)
213 __lx_syscall3(int, poll, struct lx_pollfd *, fds, lx_nfds_t, nfds, int, timeout)
215 int lx___lx_priv_ftruncate64(int, unsigned long, unsigned long);
216 __lx_syscall3(int, __lx_priv_ftruncate64, int, fd, unsigned long, high_length, unsigned long, low_length);
218 __lx_syscall2(int, ftruncate64, int, fd, unsigned long, length);
220 __lx_syscall2(int, stat64, const char *, pathname, struct lx_stat64 *, buf)
221 __lx_syscall2(int, fstat64, int, fd, struct lx_stat64 *, buf)
222 __lx_syscall3(long, getdents64, int, fd, char *, buf, unsigned int, nbytes)
223 __lx_syscall3(int, fcntl64, int, fd, unsigned int, cmd, unsigned long, arg);
224 __lx_syscall4(int, openat, int, fd, const char *, path, int, flags, int, mode);
225 __lx_syscall3(int, mkdirat, int, fd, const char *, name, int, mode);
226 __lx_syscall3(int, unlinkat, int, fd, const char *, name, int, flags);
227 __lx_syscall4(int, renameat, int, ofd, const char *, oname, int, nfd, const char *, nname);
228 __lx_syscall3(int, faccessat, int, dfd, const char *, filename, int, mode);
231 int lx_ftruncate64(int, unsigned long long);
232 int lx_ftruncate64(int fd, unsigned long long length)
234 return lx___lx_priv_ftruncate64(fd, length << 32, length);
238 /* ========================================================================
239 * pure wrapper stuff w/o syscalls
240 * ========================================================================
243 /* time could also be done through a syscall */
244 long lx_time(int *tloc)
246 struct lx_timeval tv;
247 if (lx_gettimeofday(&tv, NULL) == 0) {
255 unsigned int lx_sleep(unsigned int seconds)
257 struct lx_timeval tv;
261 if (lx_select(1, NULL, NULL, NULL, &tv) < 0)
267 unsigned int lx_msleep(unsigned int mseconds)
269 struct lx_timeval tv;
272 tv.tv_usec = mseconds * 1000;
273 if (lx_select(1, NULL, NULL, NULL, &tv) < 0)
279 lx_pid_t lx_wait(int *wait_stat)
281 return lx_waitpid(-1, wait_stat, 0);
284 void *lx_shmat(int shmid, const void *shmaddr, int shmflg)
287 void *result = (void *)lx_ipc(SHMAT, shmid, shmflg, (int)&raddr, shmaddr, 0);
288 if ((unsigned long)result <= -(unsigned long)8196)
294 enum { SYS_SOCKET = 1, SYS_CONNECT = 3 };
296 int lx_socket(int family, int type, int protocol)
298 unsigned long a[3] = { family, type, protocol };
299 return lx_socketcall(SYS_SOCKET, a);
302 int lx_connect(int sockfd, const struct lx_sockaddr *saddr, unsigned long addrlen)
304 unsigned long a[3] = { sockfd, (unsigned long)saddr, addrlen };
305 return lx_socketcall(SYS_CONNECT, a);
308 /* ------------------------------------------------------------------ */
310 void lx_outchar(unsigned char c)
312 lx_write(1, (char*)&c, 1);
315 void lx_outdec32(unsigned int i)
317 char xx[11]; /* int is 32bit -> up to 10 figues... */
323 xx[count] = '0' + i % 10;
326 lx_write(1, &xx[count], 10 - count);