]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/lxfuxlibc/lib/src/lxfuxlc.c
update: sync
[l4.git] / l4 / pkg / lxfuxlibc / lib / src / lxfuxlc.c
1 /*
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.
9  */
10
11 /*
12  * Some very minor system calls for Linux.
13  */
14
15 #include <l4/lxfuxlibc/lxfuxlc.h>
16
17 /* unistd.h stuff */
18 #define __NR_exit               1
19 #define __NR_fork               2
20 #define __NR_read               3
21 #define __NR_write              4
22 #define __NR_open               5
23 #define __NR_close              6
24 #define __NR_waitpid            7
25 #define __NR_unlink             10
26 #define __NR_chdir              12
27 #define __NR_lseek              19
28 #define __NR_getpid             20
29 #define __NR_kill               37
30 #define __NR_rename             38
31 #define __NR_mkdir              39
32 #define __NR_rmdir              40
33 #define __NR_pipe               42
34 #define __NR_ioctl              54
35 #define __NR_gettimeofday       78
36 #define __NR_ftruncate          93
37 #define __NR_socketcall         102
38 #define __NR_stat               106
39 #define __NR_lstat              107
40 #define __NR_fstat              108
41 #define __NR_ipc                117
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
47 #define __NR_poll               168
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
59 #define __NR_preadv             333
60 #define __NR_pwritev            334
61
62
63 /* Some stuff pilfered from linux/include/asm-i386/unistd.h */
64
65 #define __lx_syscall_return(type, res)                                  \
66   return (type) (res)
67
68 /* This one isn't used anymore and just left for the education of the reader
69  */
70 /* user-visible error numbers are in the range -1 to -124, see asm/errno.h */
71 #define __lx_syscall_return_with_errno(type, res)                                       \
72 do {                                                                    \
73   if ((unsigned long)(res) >= (unsigned long)(-125)) {                  \
74     lx_errno = -(res);                                                  \
75     res = -1;                                                           \
76   }                                                                     \
77   return (type) (res);                                                  \
78 } while (0)
79
80 #define __lx_syscall0(type,name)                                        \
81 type lx_##name(void)                                                    \
82 {                                                                       \
83   long __res;                                                           \
84   __asm__ __volatile__ (                                                \
85       "int      $0x80\n"                                                \
86       : "=a" (__res)                                                    \
87       : "0" (__NR_##name)                                               \
88       : "memory");                                                      \
89   __lx_syscall_return(type, __res);                                     \
90 }
91
92 #define __lx_syscall1(type,name,type1,arg1)                             \
93 type lx_##name(type1 arg1)                                              \
94 {                                                                       \
95   long __res;                                                           \
96   __asm__ __volatile__ (                                                \
97       "int      $0x80\n"                                                \
98       : "=a" (__res)                                                    \
99       : "0" (__NR_##name),                                              \
100         "b" ((long)(arg1))                                              \
101       : "memory");                                                      \
102   __lx_syscall_return(type, __res);                                     \
103 }
104
105 #define __lx_syscall1_e(type,name,type1,arg1)                           \
106 type lx_##name(type1 arg1)                                              \
107 {                                                                       \
108 loop:                                                                   \
109   __asm__ __volatile__ (                                                \
110       "int      $0x80\n"                                                \
111       :                                                                 \
112       : "a" (__NR_##name),                                              \
113         "b" ((long)(arg1))                                              \
114       : "memory");                                                      \
115   goto loop;                                                            \
116 }
117
118 #define __lx_syscall2(type,name,type1,arg1,type2,arg2)                  \
119 type lx_##name(type1 arg1, type2 arg2)                                  \
120 {                                                                       \
121   long __res;                                                           \
122   __asm__ __volatile__ (                                                \
123       "int      $0x80\n"                                                \
124       : "=a" (__res)                                                    \
125       : "0" (__NR_##name),                                              \
126         "b" ((long)(arg1)), "c" ((long)(arg2))                          \
127       : "memory");                                                      \
128   __lx_syscall_return(type, __res);                                     \
129 }
130
131 #define __lx_syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)       \
132 type lx_##name(type1 arg1, type2 arg2, type3 arg3)                      \
133 {                                                                       \
134   long __res;                                                           \
135   __asm__ __volatile__ (                                                \
136       "int      $0x80\n"                                                \
137       : "=a" (__res)                                                    \
138       : "0" (__NR_##name),                                              \
139         "b" ((long)(arg1)), "c" ((long)(arg2)), "d" ((long)(arg3))      \
140       : "memory");                                                      \
141   __lx_syscall_return(type, __res);                                     \
142 }
143
144 #define __lx_syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)    \
145 type lx_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4   )       \
146 {                                                                       \
147   long __res;                                                           \
148   __asm__ __volatile__ (                                                \
149       "int      $0x80\n"                                                \
150       : "=a" (__res)                                                    \
151       : "0" (__NR_##name),                                              \
152         "b" ((long)(arg1)), "c" ((long)(arg2)), "d" ((long)(arg3)),     \
153         "S" ((long)(arg4))                                              \
154       : "memory");                                                      \
155   __lx_syscall_return(type, __res);                                     \
156 }
157
158 #define __lx_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
159 type lx_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)      \
160 {                                                                       \
161   long __res;                                                           \
162   __asm__ __volatile__ (                                                \
163       "int      $0x80\n"                                                \
164       : "=a" (__res)                                                    \
165       : "0" (__NR_##name),                                              \
166         "b" ((long)(arg1)), "c" ((long)(arg2)), "d" ((long)(arg3)),     \
167         "S" ((long)(arg4)), "D" ((long)(arg5))                          \
168       : "memory");                                                      \
169   __lx_syscall_return(type, __res);                                     \
170 }
171
172 #define __lx_syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6)      \
173 type lx_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6)  \
174 {                                                                       \
175   long __res;                                                           \
176   __asm__ __volatile__ (                                                \
177       "push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp"   \
178       : "=a" (__res)                                                    \
179       : "i" (__NR_##name),                                              \
180         "b" ((long)(arg1)), "c" ((long)(arg2)), "d" ((long)(arg3)),     \
181         "S" ((long)(arg4)), "D" ((long)(arg5)), "0" ((long)(arg6))      \
182       : "memory");                                                      \
183   __lx_syscall_return(type, __res);                                     \
184 }
185
186 __lx_syscall1_e(void, exit, int, status)
187 __lx_syscall0(lx_pid_t, fork)
188 __lx_syscall3(long, read,  unsigned int, fd, void *, buf, unsigned int, count)
189 __lx_syscall3(long, write, unsigned int, fd, const void *, buf, unsigned int, count)
190 __lx_syscall3(long, open, const char *, filename, int, flags, int, mode)
191 __lx_syscall1(long, close, unsigned int, fd)
192 __lx_syscall3(lx_pid_t, waitpid, lx_pid_t, pid, int *, wait_stat, int, options)
193 __lx_syscall1(int, unlink, const char *, filename)
194 __lx_syscall1(int, chdir, const char *, filename)
195 __lx_syscall3(long, lseek, unsigned int, fd, unsigned long, offset, unsigned int, origin)
196 __lx_syscall0(long, getpid)
197 __lx_syscall2(int, kill, lx_pid_t, pid, int, sig)
198 __lx_syscall2(int, rename, const char *, oldpath, const char *, newpath)
199 __lx_syscall2(int, mkdir, const char *, filename, int, mode)
200 __lx_syscall1(int, rmdir, const char *, filename)
201 __lx_syscall1(int, pipe, int *, filedes)
202 __lx_syscall3(long, ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
203 __lx_syscall2(long, gettimeofday, struct lx_timeval *, tv, struct lx_timezone *, tz)
204 __lx_syscall5(int, select, int, n, lx_fd_set *, readfds, lx_fd_set *, writefds, lx_fd_set *, exceptfds, struct lx_timeval *, timeout)
205 __lx_syscall2(int, ftruncate, int, fd, unsigned long, ofs)
206 __lx_syscall2(int, socketcall, int, call, unsigned long *, args);
207 __lx_syscall2(int, stat, const char *, filename, struct lx_stat *, buf)
208 __lx_syscall2(int, lstat, const char *, filename, struct lx_stat *, buf)
209 __lx_syscall2(int, fstat, int, filedes, struct lx_stat *, buf)
210 __lx_syscall6(int, ipc, unsigned int, call, int, first, int, second, int, third, const void *, ptr, long, fifth)
211 __lx_syscall1(int, fsync, int, fd)
212 __lx_syscall3(lx_ssize_t, readv, int, fd, const struct lx_iovec*, iov, int, cnt);
213 __lx_syscall3(lx_ssize_t, writev, int, fd, const struct lx_iovec*, iov, int, cnt);
214 __lx_syscall1(int, fdatasync, int, fd)
215 __lx_syscall3(int, poll, struct lx_pollfd *, fds, lx_nfds_t, nfds, int, timeout)
216 #ifdef __i386__
217 int lx___lx_priv_ftruncate64(int, unsigned long, unsigned long);
218 __lx_syscall3(int, __lx_priv_ftruncate64, int, fd, unsigned long, high_length, unsigned long, low_length);
219 #else
220 __lx_syscall2(int, ftruncate64, int, fd, unsigned long, length);
221 #endif
222 __lx_syscall2(int, stat64,  const char *, pathname, struct lx_stat64 *, buf)
223 __lx_syscall2(int, fstat64, int, fd, struct lx_stat64 *, buf)
224 __lx_syscall3(long, getdents64, int, fd, char *, buf, unsigned int, nbytes)
225 __lx_syscall3(int, fcntl64, int, fd, unsigned int, cmd, unsigned long, arg);
226 __lx_syscall4(int, openat,  int, fd, const char *, path, int, flags, int, mode);
227 __lx_syscall3(int, mkdirat, int, fd, const char *, name, int, mode);
228 __lx_syscall3(int, unlinkat, int, fd, const char *, name, int, flags);
229 __lx_syscall4(int, renameat, int, ofd, const char *, oname, int, nfd, const char *, nname);
230 __lx_syscall3(int, faccessat, int, dfd, const char *, filename, int, mode);
231 __lx_syscall5(lx_ssize_t, preadv, int, fd, const struct lx_iovec*, iov, int, cnt, unsigned long, pl, unsigned long, ph);
232 __lx_syscall5(lx_ssize_t, pwritev, int, fd, const struct lx_iovec*, iov, int, cnt, unsigned long, pl, unsigned long, ph);
233
234 #ifdef __i386__
235 int lx_ftruncate64(int, unsigned long long);
236 int lx_ftruncate64(int fd, unsigned long long length)
237 {
238   return lx___lx_priv_ftruncate64(fd, length << 32, length);
239 }
240 #endif
241
242 /* ========================================================================
243  *                   pure wrapper stuff w/o syscalls
244  * ========================================================================
245  */
246
247 /* time could also be done through a syscall */
248 long lx_time(int *tloc)
249 {
250   struct lx_timeval tv;
251   if (lx_gettimeofday(&tv, NULL) == 0) {
252     if (tloc)
253       *tloc = tv.tv_sec;
254     return tv.tv_sec;
255   }
256   return -1;
257 }
258
259 unsigned int lx_sleep(unsigned int seconds)
260 {
261   struct lx_timeval tv;
262
263   tv.tv_sec  = seconds;
264   tv.tv_usec = 0;
265   if (lx_select(1, NULL, NULL, NULL, &tv) < 0)
266     return 0;
267
268   return tv.tv_sec;
269 }
270
271 unsigned int lx_msleep(unsigned int mseconds)
272 {
273   struct lx_timeval tv;
274
275   tv.tv_sec  = 0;
276   tv.tv_usec = mseconds * 1000;
277   if (lx_select(1, NULL, NULL, NULL, &tv) < 0)
278     return 0;
279
280   return tv.tv_sec;
281 }
282
283 lx_pid_t lx_wait(int *wait_stat)
284 {
285   return lx_waitpid(-1, wait_stat, 0);
286 }
287
288 void *lx_shmat(int shmid, const void *shmaddr, int shmflg)
289 {
290   void *raddr;
291   void *result = (void *)lx_ipc(SHMAT, shmid, shmflg, (int)&raddr, shmaddr, 0);
292   if ((unsigned long)result <= -(unsigned long)8196)
293     result = raddr;
294   return result;
295
296 }
297
298 enum { SYS_SOCKET = 1, SYS_CONNECT = 3 };
299
300 int lx_socket(int family, int type, int protocol)
301 {
302   unsigned long a[3] = { family, type, protocol };
303   return lx_socketcall(SYS_SOCKET, a);
304 }
305
306 int lx_connect(int sockfd, const struct lx_sockaddr *saddr, unsigned long addrlen)
307 {
308   unsigned long a[3] = { sockfd, (unsigned long)saddr, addrlen };
309   return lx_socketcall(SYS_CONNECT, a);
310 }
311
312 /* ------------------------------------------------------------------ */
313
314 void lx_outchar(unsigned char c)
315 {
316   lx_write(1, (char*)&c, 1);
317 }
318
319 void lx_outdec32(unsigned int i)
320 {
321   char xx[11]; /* int is 32bit -> up to 10 figues... */
322   int count = 10;
323
324   xx[10] = 0;
325   do {
326     count--;
327     xx[count] = '0' + i % 10;
328     i /= 10;
329   } while (i);
330   lx_write(1, &xx[count], 10 - count); 
331 }