summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Makefile69
-rw-r--r--src/lib/_exit.c13
-rw-r--r--src/lib/close.c10
-rw-r--r--src/lib/ctype.c35
-rw-r--r--src/lib/dup.c10
-rw-r--r--src/lib/errno.c7
-rw-r--r--src/lib/execve.c10
-rw-r--r--src/lib/malloc.c232
-rw-r--r--src/lib/open.c25
-rw-r--r--src/lib/setsid.c10
-rw-r--r--src/lib/string.c392
-rw-r--r--src/lib/wait.c16
-rw-r--r--src/lib/write.c10
13 files changed, 839 insertions, 0 deletions
diff --git a/src/lib/Makefile b/src/lib/Makefile
new file mode 100644
index 0000000..2ac16b0
--- /dev/null
+++ b/src/lib/Makefile
@@ -0,0 +1,69 @@
1#
2# Makefile for some libs needed in the kernel.
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8
9include ../Makefile.header
10
11CFLAGS += -I../include
12CPP += -I../include
13
14.c.s:
15 @$(CC) $(CFLAGS) \
16 -S -o $*.s $<
17.s.o:
18 @$(AS) -o $*.o $<
19.c.o:
20 @$(CC) $(CFLAGS) \
21 -c -o $*.o $<
22
23OBJS = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \
24 execve.o wait.o string.o malloc.o
25
26lib.a: $(OBJS)
27 @$(AR) rcs lib.a $(OBJS)
28 @sync
29
30clean:
31 @rm -f core *.o *.a tmp_make
32 @for i in *.c;do rm -f `basename $$i .c`.s;done
33
34dep:
35 @sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
36 @(for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \
37 $(CPP) -M $$i;done) >> tmp_make
38 @cp tmp_make Makefile
39
40### Dependencies:
41_exit.s _exit.o : _exit.c ../include/unistd.h ../include/sys/stat.h \
42 ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
43 ../include/utime.h
44close.s close.o : close.c ../include/unistd.h ../include/sys/stat.h \
45 ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
46 ../include/utime.h
47ctype.s ctype.o : ctype.c ../include/ctype.h
48dup.s dup.o : dup.c ../include/unistd.h ../include/sys/stat.h \
49 ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
50 ../include/utime.h
51errno.s errno.o : errno.c
52execve.s execve.o : execve.c ../include/unistd.h ../include/sys/stat.h \
53 ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
54 ../include/utime.h
55malloc.s malloc.o : malloc.c ../include/linux/kernel.h ../include/linux/mm.h \
56 ../include/asm/system.h
57open.s open.o : open.c ../include/unistd.h ../include/sys/stat.h \
58 ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
59 ../include/utime.h ../include/stdarg.h
60setsid.s setsid.o : setsid.c ../include/unistd.h ../include/sys/stat.h \
61 ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
62 ../include/utime.h
63string.s string.o : string.c ../include/string.h
64wait.s wait.o : wait.c ../include/unistd.h ../include/sys/stat.h \
65 ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
66 ../include/utime.h ../include/sys/wait.h
67write.s write.o : write.c ../include/unistd.h ../include/sys/stat.h \
68 ../include/sys/types.h ../include/sys/times.h ../include/sys/utsname.h \
69 ../include/utime.h
diff --git a/src/lib/_exit.c b/src/lib/_exit.c
new file mode 100644
index 0000000..09e31f6
--- /dev/null
+++ b/src/lib/_exit.c
@@ -0,0 +1,13 @@
1/*
2 * linux/lib/_exit.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#define __LIBRARY__
8#include <unistd.h>
9
10void _exit(int exit_code)
11{
12 __asm__ __volatile__ ("int $0x80"::"a" (__NR_exit),"b" (exit_code));
13}
diff --git a/src/lib/close.c b/src/lib/close.c
new file mode 100644
index 0000000..afd8364
--- /dev/null
+++ b/src/lib/close.c
@@ -0,0 +1,10 @@
1/*
2 * linux/lib/close.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#define __LIBRARY__
8#include <unistd.h>
9
10_syscall1(int,close,int,fd)
diff --git a/src/lib/ctype.c b/src/lib/ctype.c
new file mode 100644
index 0000000..877e629
--- /dev/null
+++ b/src/lib/ctype.c
@@ -0,0 +1,35 @@
1/*
2 * linux/lib/ctype.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#include <ctype.h>
8
9char _ctmp;
10unsigned char _ctype[] = {0x00, /* EOF */
11_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
12_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
13_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
14_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
15_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
16_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
17_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
18_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
19_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
20_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
21_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
22_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
23_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
24_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
25_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
26_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
280,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
290,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 160-175 */
300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 176-191 */
310,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 192-207 */
320,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 208-223 */
330,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 224-239 */
340,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* 240-255 */
35
diff --git a/src/lib/dup.c b/src/lib/dup.c
new file mode 100644
index 0000000..dd13414
--- /dev/null
+++ b/src/lib/dup.c
@@ -0,0 +1,10 @@
1/*
2 * linux/lib/dup.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#define __LIBRARY__
8#include <unistd.h>
9
10_syscall1(int,dup,int,fd)
diff --git a/src/lib/errno.c b/src/lib/errno.c
new file mode 100644
index 0000000..50aca2e
--- /dev/null
+++ b/src/lib/errno.c
@@ -0,0 +1,7 @@
1/*
2 * linux/lib/errno.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7int errno;
diff --git a/src/lib/execve.c b/src/lib/execve.c
new file mode 100644
index 0000000..a89726d
--- /dev/null
+++ b/src/lib/execve.c
@@ -0,0 +1,10 @@
1/*
2 * linux/lib/execve.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#define __LIBRARY__
8#include <unistd.h>
9
10_syscall3(int,execve,const char *,file,char **,argv,char **,envp)
diff --git a/src/lib/malloc.c b/src/lib/malloc.c
new file mode 100644
index 0000000..ef7abf3
--- /dev/null
+++ b/src/lib/malloc.c
@@ -0,0 +1,232 @@
1/*
2 * malloc.c --- a general purpose kernel memory allocator for Linux.
3 *
4 * Written by Theodore Ts'o (tytso@mit.edu), 11/29/91
5 *
6 * This routine is written to be as fast as possible, so that it
7 * can be called from the interrupt level.
8 *
9 * Limitations: maximum size of memory we can allocate using this routine
10 * is 4k, the size of a page in Linux.
11 *
12 * The general game plan is that each page (called a bucket) will only hold
13 * objects of a given size. When all of the object on a page are released,
14 * the page can be returned to the general free pool. When malloc() is
15 * called, it looks for the smallest bucket size which will fulfill its
16 * request, and allocate a piece of memory from that bucket pool.
17 *
18 * Each bucket has as its control block a bucket descriptor which keeps
19 * track of how many objects are in use on that page, and the free list
20 * for that page. Like the buckets themselves, bucket descriptors are
21 * stored on pages requested from get_free_page(). However, unlike buckets,
22 * pages devoted to bucket descriptor pages are never released back to the
23 * system. Fortunately, a system should probably only need 1 or 2 bucket
24 * descriptor pages, since a page can hold 256 bucket descriptors (which
25 * corresponds to 1 megabyte worth of bucket pages.) If the kernel is using
26 * that much allocated memory, it's probably doing something wrong. :-)
27 *
28 * Note: malloc() and free() both call get_free_page() and free_page()
29 * in sections of code where interrupts are turned off, to allow
30 * malloc() and free() to be safely called from an interrupt routine.
31 * (We will probably need this functionality when networking code,
32 * particularily things like NFS, is added to Linux.) However, this
33 * presumes that get_free_page() and free_page() are interrupt-level
34 * safe, which they may not be once paging is added. If this is the
35 * case, we will need to modify malloc() to keep a few unused pages
36 * "pre-allocated" so that it can safely draw upon those pages if
37 * it is called from an interrupt routine.
38 *
39 * Another concern is that get_free_page() should not sleep; if it
40 * does, the code is carefully ordered so as to avoid any race
41 * conditions. The catch is that if malloc() is called re-entrantly,
42 * there is a chance that unecessary pages will be grabbed from the
43 * system. Except for the pages for the bucket descriptor page, the
44 * extra pages will eventually get released back to the system, though,
45 * so it isn't all that bad.
46 */
47
48#include <linux/kernel.h>
49#include <linux/mm.h>
50#include <asm/system.h>
51
52struct bucket_desc { /* 16 bytes */
53 void *page;
54 struct bucket_desc *next;
55 void *freeptr;
56 unsigned short refcnt;
57 unsigned short bucket_size;
58};
59
60struct _bucket_dir { /* 8 bytes */
61 int size;
62 struct bucket_desc *chain;
63};
64
65/*
66 * The following is the where we store a pointer to the first bucket
67 * descriptor for a given size.
68 *
69 * If it turns out that the Linux kernel allocates a lot of objects of a
70 * specific size, then we may want to add that specific size to this list,
71 * since that will allow the memory to be allocated more efficiently.
72 * However, since an entire page must be dedicated to each specific size
73 * on this list, some amount of temperance must be exercised here.
74 *
75 * Note that this list *must* be kept in order.
76 */
77struct _bucket_dir bucket_dir[] = {
78 { 16, (struct bucket_desc *) 0},
79 { 32, (struct bucket_desc *) 0},
80 { 64, (struct bucket_desc *) 0},
81 { 128, (struct bucket_desc *) 0},
82 { 256, (struct bucket_desc *) 0},
83 { 512, (struct bucket_desc *) 0},
84 { 1024, (struct bucket_desc *) 0},
85 { 2048, (struct bucket_desc *) 0},
86 { 4096, (struct bucket_desc *) 0},
87 { 0, (struct bucket_desc *) 0}}; /* End of list marker */
88
89/*
90 * This contains a linked list of free bucket descriptor blocks
91 */
92struct bucket_desc *free_bucket_desc = (struct bucket_desc *) 0;
93
94/*
95 * This routine initializes a bucket description page.
96 */
97static inline void init_bucket_desc()
98{
99 struct bucket_desc *bdesc, *first;
100 int i;
101
102 first = bdesc = (struct bucket_desc *) get_free_page();
103 if (!bdesc)
104 panic("Out of memory in init_bucket_desc()");
105 for (i = PAGE_SIZE/sizeof(struct bucket_desc); i > 1; i--) {
106 bdesc->next = bdesc+1;
107 bdesc++;
108 }
109 /*
110 * This is done last, to avoid race conditions in case
111 * get_free_page() sleeps and this routine gets called again....
112 */
113 bdesc->next = free_bucket_desc;
114 free_bucket_desc = first;
115}
116
117void *malloc(unsigned int len)
118{
119 struct _bucket_dir *bdir;
120 struct bucket_desc *bdesc;
121 void *retval;
122
123 /*
124 * First we search the bucket_dir to find the right bucket change
125 * for this request.
126 */
127 for (bdir = bucket_dir; bdir->size; bdir++)
128 if (bdir->size >= len)
129 break;
130 if (!bdir->size) {
131 printk("malloc called with impossibly large argument (%d)\n",
132 len);
133 panic("malloc: bad arg");
134 }
135 /*
136 * Now we search for a bucket descriptor which has free space
137 */
138 cli(); /* Avoid race conditions */
139 for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next)
140 if (bdesc->freeptr)
141 break;
142 /*
143 * If we didn't find a bucket with free space, then we'll
144 * allocate a new one.
145 */
146 if (!bdesc) {
147 char *cp;
148 int i;
149
150 if (!free_bucket_desc)
151 init_bucket_desc();
152 bdesc = free_bucket_desc;
153 free_bucket_desc = bdesc->next;
154 bdesc->refcnt = 0;
155 bdesc->bucket_size = bdir->size;
156 bdesc->page = bdesc->freeptr = (void *) (cp = (char *) get_free_page());
157 if (!cp)
158 panic("Out of memory in kernel malloc()");
159 /* Set up the chain of free objects */
160 for (i=PAGE_SIZE/bdir->size; i > 1; i--) {
161 *((char **) cp) = cp + bdir->size;
162 cp += bdir->size;
163 }
164 *((char **) cp) = 0;
165 bdesc->next = bdir->chain; /* OK, link it in! */
166 bdir->chain = bdesc;
167 }
168 retval = (void *) bdesc->freeptr;
169 bdesc->freeptr = *((void **) retval);
170 bdesc->refcnt++;
171 sti(); /* OK, we're safe again */
172 return(retval);
173}
174
175/*
176 * Here is the free routine. If you know the size of the object that you
177 * are freeing, then free_s() will use that information to speed up the
178 * search for the bucket descriptor.
179 *
180 * We will #define a macro so that "free(x)" is becomes "free_s(x, 0)"
181 */
182void free_s(void *obj, int size)
183{
184 void *page;
185 struct _bucket_dir *bdir;
186 struct bucket_desc *bdesc, *prev;
187 bdesc = prev = 0;
188 /* Calculate what page this object lives in */
189 page = (void *) ((unsigned long) obj & 0xfffff000);
190 /* Now search the buckets looking for that page */
191 for (bdir = bucket_dir; bdir->size; bdir++) {
192 prev = 0;
193 /* If size is zero then this conditional is always false */
194 if (bdir->size < size)
195 continue;
196 for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next) {
197 if (bdesc->page == page)
198 goto found;
199 prev = bdesc;
200 }
201 }
202 panic("Bad address passed to kernel free_s()");
203found:
204 cli(); /* To avoid race conditions */
205 *((void **)obj) = bdesc->freeptr;
206 bdesc->freeptr = obj;
207 bdesc->refcnt--;
208 if (bdesc->refcnt == 0) {
209 /*
210 * We need to make sure that prev is still accurate. It
211 * may not be, if someone rudely interrupted us....
212 */
213 if ((prev && (prev->next != bdesc)) ||
214 (!prev && (bdir->chain != bdesc)))
215 for (prev = bdir->chain; prev; prev = prev->next)
216 if (prev->next == bdesc)
217 break;
218 if (prev)
219 prev->next = bdesc->next;
220 else {
221 if (bdir->chain != bdesc)
222 panic("malloc bucket chains corrupted");
223 bdir->chain = bdesc->next;
224 }
225 free_page((unsigned long) bdesc->page);
226 bdesc->next = free_bucket_desc;
227 free_bucket_desc = bdesc;
228 }
229 sti();
230 return;
231}
232
diff --git a/src/lib/open.c b/src/lib/open.c
new file mode 100644
index 0000000..8c3fc58
--- /dev/null
+++ b/src/lib/open.c
@@ -0,0 +1,25 @@
1/*
2 * linux/lib/open.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#define __LIBRARY__
8#include <unistd.h>
9#include <stdarg.h>
10
11int open(const char * filename, int flag, ...)
12{
13 register int res;
14 va_list arg;
15
16 va_start(arg,flag);
17 __asm__("int $0x80"
18 :"=a" (res)
19 :"0" (__NR_open),"b" (filename),"c" (flag),
20 "d" (va_arg(arg,int)));
21 if (res>=0)
22 return res;
23 errno = -res;
24 return -1;
25}
diff --git a/src/lib/setsid.c b/src/lib/setsid.c
new file mode 100644
index 0000000..68516c7
--- /dev/null
+++ b/src/lib/setsid.c
@@ -0,0 +1,10 @@
1/*
2 * linux/lib/setsid.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#define __LIBRARY__
8#include <unistd.h>
9
10_syscall0(pid_t,setsid)
diff --git a/src/lib/string.c b/src/lib/string.c
new file mode 100644
index 0000000..cca9e60
--- /dev/null
+++ b/src/lib/string.c
@@ -0,0 +1,392 @@
1/*
2 * linux/lib/string.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#ifndef __GNUC__
8#error I want gcc!
9#endif
10
11#define extern
12#define inline
13#define static
14#define __LIBRARY__
15#include <string.h>
16
17inline char * strcpy(char * dest,const char *src)
18{
19 __asm__("cld\n"
20 "1:\tlodsb\n\t"
21 "stosb\n\t"
22 "testb %%al,%%al\n\t"
23 "jne 1b"
24 ::"S" (src),"D" (dest));
25 return dest;
26}
27
28static inline char * strncpy(char * dest,const char *src,int count)
29{
30 __asm__("cld\n"
31 "1:\tdecl %2\n\t"
32 "js 2f\n\t"
33 "lodsb\n\t"
34 "stosb\n\t"
35 "testb %%al,%%al\n\t"
36 "jne 1b\n\t"
37 "rep\n\t"
38 "stosb\n"
39 "2:"
40 ::"S" (src),"D" (dest),"c" (count));
41 return dest;
42}
43
44inline char * strcat(char * dest,const char * src)
45{
46 __asm__("cld\n\t"
47 "repne\n\t"
48 "scasb\n\t"
49 "decl %1\n"
50 "1:\tlodsb\n\t"
51 "stosb\n\t"
52 "testb %%al,%%al\n\t"
53 "jne 1b"
54 ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff));
55 return dest;
56}
57
58static inline char * strncat(char * dest,const char * src,int count)
59{
60 __asm__("cld\n\t"
61 "repne\n\t"
62 "scasb\n\t"
63 "decl %1\n\t"
64 "movl %4,%3\n"
65 "1:\tdecl %3\n\t"
66 "js 2f\n\t"
67 "lodsb\n\t"
68 "stosb\n\t"
69 "testb %%al,%%al\n\t"
70 "jne 1b\n"
71 "2:\txorl %2,%2\n\t"
72 "stosb"
73 ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
74 );
75 return dest;
76}
77
78inline int strcmp(const char * cs,const char * ct)
79{
80 register int __res ;
81 __asm__("cld\n"
82 "1:\tlodsb\n\t"
83 "scasb\n\t"
84 "jne 2f\n\t"
85 "testb %%al,%%al\n\t"
86 "jne 1b\n\t"
87 "xorl %%eax,%%eax\n\t"
88 "jmp 3f\n"
89 "2:\tmovl $1,%%eax\n\t"
90 "jl 3f\n\t"
91 "negl %%eax\n"
92 "3:"
93 :"=a" (__res):"D" (cs),"S" (ct));
94 return __res;
95}
96
97
98static inline int strncmp(const char * cs,const char * ct,int count)
99{
100 register int __res ;
101 __asm__("cld\n"
102 "1:\tdecl %3\n\t"
103 "js 2f\n\t"
104 "lodsb\n\t"
105 "scasb\n\t"
106 "jne 3f\n\t"
107 "testb %%al,%%al\n\t"
108 "jne 1b\n"
109 "2:\txorl %%eax,%%eax\n\t"
110 "jmp 4f\n"
111 "3:\tmovl $1,%%eax\n\t"
112 "jl 4f\n\t"
113 "negl %%eax\n"
114 "4:"
115 :"=a" (__res):"D" (cs),"S" (ct),"c" (count));
116 return __res;
117}
118
119static inline char * strchr(const char * s,char c)
120{
121 register char * __res ;
122 __asm__("cld\n\t"
123 "movb %%al,%%ah\n"
124 "1:\tlodsb\n\t"
125 "cmpb %%ah,%%al\n\t"
126 "je 2f\n\t"
127 "testb %%al,%%al\n\t"
128 "jne 1b\n\t"
129 "movl $1,%1\n"
130 "2:\tmovl %1,%0\n\t"
131 "decl %0"
132 :"=a" (__res):"S" (s),"0" (c));
133 return __res;
134}
135
136static inline char * strrchr(const char * s,char c)
137{
138 register char * __res;
139 __asm__("cld\n\t"
140 "movb %%al,%%ah\n"
141 "1:\tlodsb\n\t"
142 "cmpb %%ah,%%al\n\t"
143 "jne 2f\n\t"
144 "movl %%esi,%0\n\t"
145 "decl %0\n"
146 "2:\ttestb %%al,%%al\n\t"
147 "jne 1b"
148 :"=d" (__res):"0" (0),"S" (s),"a" (c));
149 return __res;
150}
151
152inline int strspn(const char * cs, const char * ct)
153{
154 register char * __res;
155 __asm__("cld\n\t"
156 "movl %4,%%edi\n\t"
157 "repne\n\t"
158 "scasb\n\t"
159 "notl %%ecx\n\t"
160 "decl %%ecx\n\t"
161 "movl %%ecx,%%edx\n"
162 "1:\tlodsb\n\t"
163 "testb %%al,%%al\n\t"
164 "je 2f\n\t"
165 "movl %4,%%edi\n\t"
166 "movl %%edx,%%ecx\n\t"
167 "repne\n\t"
168 "scasb\n\t"
169 "je 1b\n"
170 "2:\tdecl %0"
171 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
172 );
173 return __res-cs;
174}
175
176inline int strcspn(const char * cs, const char * ct)
177{
178 register char * __res;
179 __asm__("cld\n\t"
180 "movl %4,%%edi\n\t"
181 "repne\n\t"
182 "scasb\n\t"
183 "notl %%ecx\n\t"
184 "decl %%ecx\n\t"
185 "movl %%ecx,%%edx\n"
186 "1:\tlodsb\n\t"
187 "testb %%al,%%al\n\t"
188 "je 2f\n\t"
189 "movl %4,%%edi\n\t"
190 "movl %%edx,%%ecx\n\t"
191 "repne\n\t"
192 "scasb\n\t"
193 "jne 1b\n"
194 "2:\tdecl %0"
195 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
196 );
197 return __res-cs;
198}
199
200inline char * strpbrk(const char * cs,const char * ct)
201{
202 register char * __res ;
203 __asm__("cld\n\t"
204 "movl %4,%%edi\n\t"
205 "repne\n\t"
206 "scasb\n\t"
207 "notl %%ecx\n\t"
208 "decl %%ecx\n\t"
209 "movl %%ecx,%%edx\n"
210 "1:\tlodsb\n\t"
211 "testb %%al,%%al\n\t"
212 "je 2f\n\t"
213 "movl %4,%%edi\n\t"
214 "movl %%edx,%%ecx\n\t"
215 "repne\n\t"
216 "scasb\n\t"
217 "jne 1b\n\t"
218 "decl %0\n\t"
219 "jmp 3f\n"
220 "2:\txorl %0,%0\n"
221 "3:"
222 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
223 );
224 return __res;
225}
226
227inline char * strstr(const char * cs,const char * ct)
228{
229 register char * __res ;
230 __asm__("cld\n\t" \
231 "movl %4,%%edi\n\t"
232 "repne\n\t"
233 "scasb\n\t"
234 "notl %%ecx\n\t"
235 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
236 "movl %%ecx,%%edx\n"
237 "1:\tmovl %4,%%edi\n\t"
238 "movl %%esi,%%eax\n\t"
239 "movl %%edx,%%ecx\n\t"
240 "repe\n\t"
241 "cmpsb\n\t"
242 "je 2f\n\t" /* also works for empty string, see above */
243 "xchgl %%eax,%%esi\n\t"
244 "incl %%esi\n\t"
245 "cmpb $0,-1(%%eax)\n\t"
246 "jne 1b\n\t"
247 "xorl %%eax,%%eax\n\t"
248 "2:"
249 :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
250 );
251 return __res;
252}
253
254inline int strlen(const char * s)
255{
256 register int __res ;
257 __asm__("cld\n\t"
258 "repne\n\t"
259 "scasb\n\t"
260 "notl %0\n\t"
261 "decl %0"
262 :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff));
263 return __res;
264}
265
266inline char * strtok(char * s,const char * ct)
267{
268 register char * __res ;
269 __asm__("testl %1,%1\n\t"
270 "jne 1f\n\t"
271 "testl %0,%0\n\t"
272 "je 8f\n\t"
273 "movl %0,%1\n"
274 "1:\txorl %0,%0\n\t"
275 "movl $-1,%%ecx\n\t"
276 "xorl %%eax,%%eax\n\t"
277 "cld\n\t"
278 "movl %4,%%edi\n\t"
279 "repne\n\t"
280 "scasb\n\t"
281 "notl %%ecx\n\t"
282 "decl %%ecx\n\t"
283 "je 7f\n\t" /* empty delimeter-string */
284 "movl %%ecx,%%edx\n"
285 "2:\tlodsb\n\t"
286 "testb %%al,%%al\n\t"
287 "je 7f\n\t"
288 "movl %4,%%edi\n\t"
289 "movl %%edx,%%ecx\n\t"
290 "repne\n\t"
291 "scasb\n\t"
292 "je 2b\n\t"
293 "decl %1\n\t"
294 "cmpb $0,(%1)\n\t"
295 "je 7f\n\t"
296 "movl %1,%0\n"
297 "3:\tlodsb\n\t"
298 "testb %%al,%%al\n\t"
299 "je 5f\n\t"
300 "movl %4,%%edi\n\t"
301 "movl %%edx,%%ecx\n\t"
302 "repne\n\t"
303 "scasb\n\t"
304 "jne 3b\n\t"
305 "decl %1\n\t"
306 "cmpb $0,(%1)\n\t"
307 "je 5f\n\t"
308 "movb $0,(%1)\n\t"
309 "incl %1\n\t"
310 "jmp 6f\n"
311 "5:\txorl %1,%1\n"
312 "6:\tcmpb $0,(%0)\n\t"
313 "jne 7f\n\t"
314 "xorl %0,%0\n"
315 "7:\ttestl %0,%0\n\t"
316 "jne 8f\n\t"
317 "movl %0,%1\n"
318 "8:"
319 :"=b" (__res),"=S" (___strtok)
320 :"0" (___strtok),"1" (s),"g" (ct)
321 );
322 return __res;
323}
324
325inline void * memcpy(void * dest,const void * src, int n)
326{
327 __asm__ ("cld\n\t"
328 "rep\n\t"
329 "movsb"
330 ::"c" (n),"S" (src),"D" (dest)
331 );
332 return dest;
333}
334
335inline void * memmove(void * dest,const void * src, int n)
336{
337 if (dest<src)
338 __asm__("cld\n\t"
339 "rep\n\t"
340 "movsb"
341 ::"c" (n),"S" (src),"D" (dest)
342 );
343 else
344 __asm__("std\n\t"
345 "rep\n\t"
346 "movsb"
347 ::"c" (n),"S" (src+n-1),"D" (dest+n-1)
348 );
349 return dest;
350}
351
352static inline int memcmp(const void * cs,const void * ct,int count)
353{
354 register int __res ;
355 __asm__("cld\n\t"
356 "repe\n\t"
357 "cmpsb\n\t"
358 "je 1f\n\t"
359 "movl $1,%%eax\n\t"
360 "jl 1f\n\t"
361 "negl %%eax\n"
362 "1:"
363 :"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)
364 );
365 return __res;
366}
367
368inline void * memchr(const void * cs,char c,int count)
369{
370 register void * __res ;
371 if (!count)
372 return NULL;
373 __asm__("cld\n\t"
374 "repne\n\t"
375 "scasb\n\t"
376 "je 1f\n\t"
377 "movl $1,%0\n"
378 "1:\tdecl %0"
379 :"=D" (__res):"a" (c),"D" (cs),"c" (count)
380 );
381 return __res;
382}
383
384static inline void * memset(void * s,char c,int count)
385{
386 __asm__("cld\n\t"
387 "rep\n\t"
388 "stosb"
389 ::"a" (c),"D" (s),"c" (count)
390 );
391 return s;
392} \ No newline at end of file
diff --git a/src/lib/wait.c b/src/lib/wait.c
new file mode 100644
index 0000000..2815c16
--- /dev/null
+++ b/src/lib/wait.c
@@ -0,0 +1,16 @@
1/*
2 * linux/lib/wait.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#define __LIBRARY__
8#include <unistd.h>
9#include <sys/wait.h>
10
11_syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
12
13pid_t wait(int * wait_stat)
14{
15 return waitpid(-1,wait_stat,0);
16}
diff --git a/src/lib/write.c b/src/lib/write.c
new file mode 100644
index 0000000..df52e74
--- /dev/null
+++ b/src/lib/write.c
@@ -0,0 +1,10 @@
1/*
2 * linux/lib/write.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#define __LIBRARY__
8#include <unistd.h>
9
10_syscall3(int,write,int,fd,const char *,buf,off_t,count)