merge the work of two people

master
forever-learner 3 years ago
parent fc3a77a1ce
commit 6e866929e3

@ -0,0 +1 @@
{"buildTargets":[],"launchTargets":[],"customConfigurationProvider":{"workspaceBrowse":{"browsePath":[],"compilerArgs":[]},"fileIndex":[]}}

@ -0,0 +1,4 @@
make.exe --dry-run --always-make --keep-going --print-directory
'make.exe' <20><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD>Ҳ<EEA3AC><D2B2><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD>еij<D0B5><C4B3><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>

@ -49,6 +49,7 @@
"sys.h": "c",
"segment.h": "c",
"stat.h": "c",
"sched.h": "c"
"sched.h": "c",
"system.h": "c"
}
}

@ -0,0 +1,4 @@
make.exe all --print-data-base --no-builtin-variables --no-builtin-rules --question
'make.exe' <20><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD>Ҳ<EEA3AC><D2B2><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD>еij<D0B5><C4B3><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -350,9 +350,9 @@ restart_interp:
current->euid = e_uid;
current->egid = e_gid;
i = ex.a_text+ex.a_data;
printk("start_cod: %x\n",current->start_code);
/* printk("start_cod: %x\n",current->start_code);
printk("brk : %x\n",current->start_code+current->brk);
printk("start_sta: %x\n",current->start_stack+current->start_code);
printk("start_sta: %x\n",current->start_stack+current->start_code); */
while (i&0xfff)
put_fs_byte(0,(char *) (i++));
eip[0] = ex.a_entry; /* eip, magic happens :-) */

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,22 +1,10 @@
#ifndef _MM_H
#define _MM_H
#ifndef _mm_H
#define _mm_H
#define PAGE_SIZE 4096
extern void calc_mem(void);
extern void mem_init(long start_mem, long end_mem);
extern void do_no_page(unsigned long error_code,unsigned long address);
extern int share_page(unsigned long address);
extern int try_to_share(unsigned long address, struct task_struct * p);
extern void get_empty_page(unsigned long address);
extern void write_verify(unsigned long address);
extern void do_wp_page(unsigned long error_code,unsigned long address);
extern void un_wp_page(unsigned long * table_entry);
extern unsigned long get_free_page(void);
extern unsigned long put_page(unsigned long page,unsigned long address);
extern int copy_page_tables(unsigned long from,unsigned long to,long size);
extern int free_page_tables(unsigned long from,unsigned long size);
extern void free_page(unsigned long addr);
extern unsigned long get_free_page(void);
extern void oom(void);
extern void do_exit(long code);
#endif // MACRO
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -11,7 +11,7 @@
* management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'
*/
#include <errno.h>
#include <new.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
@ -70,7 +70,6 @@ int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,
long fs,long es,long ds,
long eip,long cs,long eflags,long esp,long ss)
{
sys_signal(SIGCHLD,NULL,NULL);
struct task_struct *p;
int i;
struct file *f;
@ -149,7 +148,7 @@ int find_empty_process(void)
}
int copy_mem_clone(int nr,struct task_struct * p)
int copy_mem_clone(int nr,struct task_struct * p,int flag)
{
unsigned long old_data_base,new_data_base,data_limit;
unsigned long old_code_base,new_code_base,code_limit;
@ -167,7 +166,7 @@ int copy_mem_clone(int nr,struct task_struct * p)
p->start_code = new_code_base;
set_base(p->ldt[1],new_code_base);
set_base(p->ldt[2],new_data_base);
if (copy_page_tables_clone(old_data_base,new_data_base,data_limit)) {
if (copy_page_tables_clone(old_data_base,new_data_base,data_limit,flag)) {
free_page_tables(new_data_base,data_limit);
return -ENOMEM;
}
@ -193,6 +192,7 @@ int copy_process_clone(int nr,long ebp,long edi,long esi,long gs,long none,
__asm__ volatile ("cld"); /* by wyj */
*p = *current; /* NOTE! this doesn't copy the supervisor stack */
p->state = TASK_UNINTERRUPTIBLE;
//先不让进程变为running不然在时钟中断时进程调度可能会运行子进程
p->pid = last_pid;
p->father = current->pid;
p->counter = p->priority;
@ -205,13 +205,13 @@ int copy_process_clone(int nr,long ebp,long edi,long esi,long gs,long none,
p->tss.back_link = 0;
p->tss.esp0 = PAGE_SIZE + (long) p;
p->tss.ss0 = 0x10;
p->tss.eip = ebx;
p->tss.eip = ebx;//clone.c中的"b" 对应ebx = fn
p->tss.eflags = eflags;
p->tss.eax = 0;
p->tss.eax = 0;//eax是返回值那么子进程返回值是0
p->tss.ecx = ecx;
p->tss.edx = edx;
p->tss.ebx = ebx;
p->tss.esp = ecx;
p->tss.esp = ecx;////clone.c中的"c" 对应ecx = child_stack
p->tss.ebp = ebp;
p->tss.esi = esi;
p->tss.edi = edi;
@ -225,11 +225,13 @@ int copy_process_clone(int nr,long ebp,long edi,long esi,long gs,long none,
p->tss.trace_bitmap = 0x80000000;
if (last_task_used_math == current)
__asm__("clts ; fnsave %0"::"m" (p->tss.i387));
if (copy_mem_clone(nr,p)) {
//复制内存
if (copy_mem_clone(nr,p,edx & CLONE_VM)) {
task[nr] = NULL;
free_page((long) p);
return -EAGAIN;
}
//文件打开者个数++
for (i=0; i<NR_OPEN;i++)
if (f=p->filp[i])
f->f_count++;
@ -241,6 +243,14 @@ int copy_process_clone(int nr,long ebp,long edi,long esi,long gs,long none,
current->executable->i_count++;
set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt));
//设置子进程的信号段
struct sigaction tmp;
tmp.sa_handler =NULL;
tmp.sa_mask = 0;
tmp.sa_flags = SA_ONESHOT | SA_NOMASK;
tmp.sa_restorer = (void (*)(void)) NULL;
p->sigaction[SIGCHLD-1] = tmp;
p->state = TASK_RUNNING; /* do this last, just in case */
return last_pid;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -91,7 +91,7 @@ system_call:
mov %dx,%es
movl $0x17,%edx # fs points to local data space
mov %dx,%fs
pushl %eax #by wyj
call print_nr
popl %eax

Binary file not shown.

@ -468,51 +468,46 @@ void calc_mem(void)
static int my_share(unsigned long address, struct task_struct * p)
{
unsigned long from;
unsigned long to;
unsigned long from_page;
unsigned long to_page;
unsigned long phys_addr;
unsigned long from,to,from_page,to_page,phys_addr; //from address to p
//从页目录 获取页表项地址
from_page = to_page = ((address>>20) & 0xffc);
from_page += ((current->start_code>>20) & 0xffc);
to_page += ((p->start_code>>20) & 0xffc);
to_page += ((p->start_code>>20) & 0xffc);
//从页表项获取页地址
from = *(unsigned long *) from_page;
from &= 0xfffff000;
from_page = from + ((address>>10) & 0xffc);
phys_addr = *(unsigned long *) from_page;
to = *(unsigned long *) to_page;
if (!(to & 1))
if (!(to & 1)) //是否存在
if (to = get_free_page())
*(unsigned long *) to_page = to | 7;
*(unsigned long *) to_page = to | 7; //权限修改
else
return 0;
to &= 0xfffff000;
to_page = to + ((address>>10) & 0xffc);
if (1 & *(unsigned long *) to_page)
if (1 & *(unsigned long *) to_page)
return 0;
/* share them: write-protect */
*(unsigned long *) to_page = *(unsigned long *) from_page;
*(unsigned long *) to_page = *(unsigned long *) from_page; //复制到p进程
phys_addr -= LOW_MEM;
phys_addr >>= 12;
mem_map[phys_addr]++;
mem_map[phys_addr]++; //物理页映射数组,记录该物理页的使用者数量
return 1;
}
// rememeber to sync when munmap exit manual
long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
long sys_mmap(void * start,size_t len,unsigned long * argv)// int prot,int flags,int fd,off_t off
{
/* va_list args;
va_start(args,len); */
int prot=3,flags=2,fd=3,off=0;
/* prot=va_arg(args,int);flags=va_arg(args,int);fd=va_arg(args,int);
off_t off=va_arg(args,off_t);
int *ll=&len;printk("%d,%d,%d,%d,%d\n",*ll,*(ll+1),*(ll+2),*(ll+3),*(ll+4));
va_end(args);
printk("%d,%d,%d,%ld\n",prot,flags,fd,off);
*/
unsigned long a,b,c,d;
a=get_fs_long(argv);
b=get_fs_long(argv+1);
c=get_fs_long(argv+2);
d=get_fs_long(argv+3);
//printk("a,b,c,d:%ld,%ld,%ld,%ld\n",a,b,c,d);
int prot=a,flags=b,fd=c;
off_t off=d;
int block;
size_t l=len;
struct buffer_head * bh;
@ -541,7 +536,7 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
}
if(!(prot& PROT_READ)) return MAP_FAILED;
//permissions of the file ,搬运函数namei.c::permissions
//permissions of the file ,参考函数namei.c::permissions
struct m_inode *inode=current->filp[fd]->f_inode;
int mode = inode->i_mode;
@ -558,8 +553,9 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
}
//end of permission check
//设置用户空间的虚拟地址初始为32MB处这样写在brk增长至32MB时会有bug,我们忽略
//同时,当栈向下增长到一定程度时,也会和当前地址冲突,我们忽略
//设置用户空间的虚拟地址初始为32MB处这样写在brk增长至32MB时会有bug,但是这种情况不会出现,
//因为物理页一共16MBlinux-011没有页替换策略即linux011内核默认虚拟内存利用不会超过16MB
//同时,当栈向下增长到一定程度时,也会和当前地址冲突,这种情况也不可能出现
if(start<=current->brk || start>=current->start_stack-0x8000 || start==NULL)
{
if(!current->mmap_tail)
@ -588,14 +584,7 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
}
//分配物理页
unsigned long from;
unsigned long to;
unsigned long from_page;
unsigned long to_page;
unsigned long phys_addr;
unsigned long tpage;
unsigned long address=mmap->address;
unsigned long from,to,from_page,to_page,phys_addr,tpage,address=mmap->address;
while(address<mmap->endaddr)
{
from_page = ((address>>20) & 0xffc);
@ -626,7 +615,7 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
mem_map[(tpage-LOW_MEM)>>12]++;
}
*(unsigned long *)from_page &= (prot&PROT_WRITE)?0xffffffff:0xfffffffd; //分配读写权限
//设置物理页共享
if(flags & MAP_SHARED)
{
//printk("i am doing sharing.");
@ -638,7 +627,7 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
if (current == *p)
continue;
//在这一部分,我将current->address处的物理页复制给
//所有进程的该区域,可能导致错误,但我们忽略。
//所有进程的该区域
if(!my_share(address,*p))
printk("share failed at task:pid=%d",(*p)->pid);
}
@ -646,7 +635,7 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
address+=PAGE_SIZE;
}
//read and put in
//将文件内容写入共享内存
if (!(block = inode->i_zone[0]))
return NULL;
if (!(bh = bread(inode->i_dev,block)))
@ -664,25 +653,25 @@ static int my_sync(off_t pos, struct m_inode * inode, char * buf, int count)
char * p;
int i=0;
while (i<count) {
while (i<count) {//将count字节写入磁盘
if (!(block = create_block(inode,pos/BLOCK_SIZE)))
break;
if (!(bh=bread(inode->i_dev,block)))
break;
c = pos % BLOCK_SIZE;
c = pos % BLOCK_SIZE;//从偏移里那个开始写
p = c + bh->b_data;
bh->b_dirt = 1;
c = BLOCK_SIZE-c;
c = BLOCK_SIZE-c;//本块要写的数量
if (c > count-i) c = count-i;
pos += c;
pos += c;//已经读了c字节更新偏移量
if (pos > inode->i_size) {
inode->i_size = pos;
inode->i_dirt = 1;
}
i += c;
while (c-->0)
while (c-->0) //暂存到p里面即bh里
*(p++) = get_fs_byte(buf++);
brelse(bh);
brelse(bh);//释放bh同时同步到磁盘
}
inode->i_mtime = CURRENT_TIME;//文件最后修改时间
inode->i_ctime = CURRENT_TIME;//i节点修改时间
@ -694,39 +683,33 @@ int sys_munmap(void * start ,size_t size)
{
struct mmap_struct *temp=current->mmap;
struct mmap_struct *pre=NULL;
while(temp!=NULL)
while(temp!=NULL) //遍历链表
{
if(temp->address==(unsigned long)start)
break;
else temp=temp->next;
pre=temp;
}
if(!temp)
if(!temp) //未找到
{
printk("invalid address.\n");
return -1;
}
if(!pre)
if(!pre) //为头节点
{
if(current->mmap_tail==current->mmap)current->mmap_tail=NULL;
current->mmap=current->mmap->next;
}
else if(temp->next=NULL)
else if(temp->next=NULL) //中间节点
{
current->mmap_tail=pre;
pre->next=NULL;
}
else{
else{ //尾节点
pre->next=temp->next;
}
unsigned long from;
unsigned long to;
unsigned long from_page;
unsigned long to_page;
unsigned long phys_addr;
unsigned long tpage;
unsigned long address=temp->address;
printk("%lx\n",address);
unsigned long from,to,from_page,to_page,phys_addr,tpage,address=temp->address;
//printk("%lx\n",address);
if(!(temp->ps & MAP_SHARED))
goto mytag;
//若为共享,执行下面的代码
@ -740,7 +723,7 @@ int sys_munmap(void * start ,size_t size)
from_page = from + ((address>>10) & 0xffc);
phys_addr = (*(unsigned long *)from_page & 0xfffff000);
//printk("addr: %lx",*(unsigned long *)from_page);
if(!(*(unsigned long *)from_page & 1))
if(!(*(unsigned long *)from_page & 1))//当前进程必须有该映射区物理页
{
printk("error of deleting page at %x.\n",*(unsigned long *)from_page);
printk("current address:%x\n",address);
@ -750,24 +733,24 @@ int sys_munmap(void * start ,size_t size)
{
struct task_struct ** p;
for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
if (!*p)
for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { //遍历所有进程
if (!*p) //空进程
continue;
if (current == *p)
if (current == *p) //排除当前进程
continue;
to_page = ((address>>20) & 0xffc)+(((*p)->start_code>>20) & 0xffc);
to = *(unsigned long *) to_page;
if(!(to & 1))
continue;
if(!(to & 1)) //不存在,肯定未共享过
continue;
to &= 0xfffff000;
to_page = to + ((address>>10) & 0xffc);
if(!(*(unsigned long *)to_page &1))
to_page = to + ((address>>10) & 0xffc);
if(!(*(unsigned long *)to_page &1)) //不存在,肯定未共享过
continue;
to = (*(unsigned long *)to_page & 0xfffff000);
if(phys_addr == to)
{
*(unsigned long *)to_page &= ~1;
mem_map[(phys_addr-LOW_MEM)>>12]--;
*(unsigned long *)to_page &= ~1; //删除页
mem_map[(phys_addr-LOW_MEM)>>12]--; //物理页使用者--
}
}
}
@ -779,7 +762,7 @@ int sys_munmap(void * start ,size_t size)
return -1;
}
mytag:
//取消物理页写权限
//取消删去当前进程映射区物理页
address=temp->address;
while (address < temp ->endaddr)
{
@ -791,19 +774,19 @@ mytag:
from_page = from + ((address>>10) & 0xffc);
phys_addr = (*(unsigned long *)from_page & 0xfffff000);
//printk("addr: %lx",*(unsigned long *)from_page);
if(!(*(unsigned long *)from_page & 1))
if(!(*(unsigned long *)from_page & 1)) //存在
{
printk("error of deleting page at %x.\n",*(unsigned long *)from_page);
printk("current address:%x\n",address);
return -1;
}
else{
*(unsigned long *)from_page &= ~1;
*(unsigned long *)from_page &= ~1; //删除物理页
}
address+=PAGE_SIZE;
}
free(temp->filenode);
free(temp);
free(temp->filenode); //清空节点 mmap->filename
free(temp); //清空 mmap
return 0;
}
@ -927,7 +910,7 @@ int do_clone(int nr,long tmp,int (*fn)(void *), void *child_stack, int flag)
return 0;
}
*/
int copy_page_tables_clone(unsigned long from,unsigned long to,long size )
int copy_page_tables_clone(unsigned long from,unsigned long to,long size,int flag)
{
unsigned long * from_page_table;
unsigned long * to_page_table;
@ -935,6 +918,45 @@ int copy_page_tables_clone(unsigned long from,unsigned long to,long size )
unsigned long * from_dir, * to_dir;
unsigned long nr;
//获取栈区域的物理页
/* child_stack= child_stack?child_stack:(0x2000000-4096);
printk("chid:%lx\n",(unsigned long ) child_stack);
unsigned long sfrom,sfrom_page,tpage;
sfrom_page = ((child_stack>>20) & 0xffc);
sfrom_page += ((current->start_code>>20) & 0xffc);//页目录
printk("11111222222222222221.");
if(!(*(unsigned long *)sfrom_page&1)) //页表项不存在,申请页面
if(!(tpage=get_free_page()))
{
printk("out of memory.\n");
return -1;
}
else
{
*(unsigned long *)sfrom_page= tpage | 7;
mem_map[(tpage-LOW_MEM)>>12]++;
printk("111555555555511.");
}
printk("111111111111111111."); */
/* sfrom=*(unsigned long *)sfrom_page; //页表项
sfrom &= 0xfffff000;
sfrom_page = sfrom + ((child_stack>>10) & 0xffc);
printk("1111133333333.");
if(!(*(unsigned long *)sfrom_page & 1)) //物理页不存在
if(!(tpage=get_free_page()))
{
printk("out of memory.\n");
return -1;
}
else
{
*(unsigned long *)sfrom_page= tpage | 7;
printk("111114444466666664111.");
mem_map[(tpage-LOW_MEM)>>12]++;
printk("11111444444444444111.");
}
printk("11111111133333333333311."); */
//遍历进程size个页目录复制到子进程中
if ((from&0x3fffff) || (to&0x3fffff))
panic("copy_page_tables called with wrong alignment");
from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */
@ -954,6 +976,10 @@ int copy_page_tables_clone(unsigned long from,unsigned long to,long size )
this_page = *from_page_table;
if (!(1 & this_page))
continue;
//如果flag==0 表示创建进程 而非线程
//如果当前物理页是栈区物理页,父子进程都有写权限
if(!flag)// && !(this_page == *(unsigned long *)sfrom_page))
this_page &= ~2;
*to_page_table = this_page;
if (this_page > LOW_MEM) {
*from_page_table = this_page;

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
test-011-2/.DS_Store vendored

Binary file not shown.

@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${default}",
"${workspaceFolder}/include/**"
],
"defines": [],
"macFrameworkPath": [],
"compilerPath": "/usr/local/bin/gcc",
"cStandard": "gnu11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
}

@ -0,0 +1,27 @@
FILES =mmap munmap clone
INC =-nostdinc -I./include
.PHONY: all test clean
all: echo
for i in $(FILES); \
do \
(gcc $(INC) $$i.c -o $$i); \
done
${FILES}: echo
gcc $(INC) $@.c -o $@
echo: echo.c
gcc $(INC) $@.c -o $@
test: echo
@for i in $(FILES); \
do \
(echo "--------------testing " $$i":"); \
(./$$i); \
done
clean:
-(rm ${FILES}; \
rm *.o a.out *.log echo test_mmap.txt) > /dev/null 2>&1

@ -0,0 +1,14 @@
1.新的系统调用号定义在../include/unistd.h中。
2.编译
编译所有文件:
make
编译某个文件,如:
make mmap
3.测试
make test
4.清除中间文件
make clean

@ -0,0 +1,66 @@
/*
*
* "clone success."
*
* "clone error."
*/
#define __LIBRARY__
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <signal.h>
#include "new.h"
int clone(int (*fn)(void *), void *child_stack, ...)
{
register int res;
va_list arg;
va_start(arg,child_stack);
__asm__("int $0x80"
:"=a" (res)
:"0" (__NR_clone),"b" (fn),"c" (child_stack),
"d" (va_arg(arg,int)));
if (res>=0)
return res;
errno = -res;
return -1;
}
int g_shared = 0;
size_t stack[1024] = {0};
int child_pid;
static int child_func(void * arg){
g_shared = 1;
printf(" Child says hello.\n");
exit(0);
}
void test_clone(void){
int wstatus, ret;
child_pid = clone(child_func, stack+1024, SIGCHLD|CLONE_VM);
assert(child_pid != -1);
if (child_pid == 0){
exit(0);
}
printf("child pid: %d\n", child_pid);
ret = wait(&wstatus);
if(ret == child_pid) {
if (g_shared == 1) {
printf("clone success.\n");
}
}
else {
printf("clone error.\n");
}
}
int main(void){
test_clone();
return 0;
}

@ -0,0 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc == 1)
return EXIT_FAILURE;
write(1, argv[1], strlen(argv[1]));
return EXIT_SUCCESS;
}

Binary file not shown.

@ -0,0 +1,34 @@
/* Allow this file to be included multiple times
with different settings of NDEBUG. */
#undef assert
#undef __assert
#ifdef NDEBUG
#define assert(ignore) ((void)0)
#else
void __eprintf (); /* Defined in gnulib */
#ifdef __STDC__
#define assert(expression) \
((expression) ? 0 : (__assert (#expression, __FILE__, __LINE__), 0))
#define __assert(expression, file, line) \
(__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", \
expression, line, file), \
abort ())
#else /* no __STDC__; i.e. -traditional. */
#define assert(expression) \
((expression) ? 0 : __assert (expression, __FILE__, __LINE__))
#define __assert(expression, file, lineno) \
(__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", \
"expression", lineno, file), \
abort ())
#endif /* no __STDC__; i.e. -traditional. */
#endif

@ -0,0 +1,56 @@
#ifndef _FCNTL_H
#define _FCNTL_H
/* I don't think this should be included like this, but it's easier */
#include <sys/types.h>
/* open/fcntl - NOCTTY, NDELAY isn't implemented yet */
#define O_ACCMODE 00003
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_CREAT 00100 /* not fcntl */
#define O_EXCL 00200 /* not fcntl */
#define O_NOCTTY 00400 /* not fcntl */
#define O_TRUNC 01000 /* not fcntl */
#define O_APPEND 02000
#define O_NONBLOCK 04000 /* not fcntl */
#define O_NDELAY O_NONBLOCK
/* Defines for fcntl-commands. Note that currently
* locking isn't supported, and other things aren't really
* tested.
*/
#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
#define F_SETFD 2 /* set f_flags */
#define F_GETFL 3 /* more flags (cloexec) */
#define F_SETFL 4
#define F_GETLK 5 /* not implemented */
#define F_SETLK 6
#define F_SETLKW 7
/* for F_[GET|SET]FL */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* Ok, these are locking features, and aren't implemented at any
* level. POSIX wants them.
*/
#define F_RDLCK 0
#define F_WRLCK 1
#define F_UNLCK 2
/* Once again - not implemented, but ... */
struct flock {
short l_type;
short l_whence;
off_t l_start;
off_t l_len;
pid_t l_pid;
};
extern int creat(const char * filename,mode_t mode);
extern int fcntl(int fildes,int cmd, ...);
extern int open(const char * filename, int flags, ...);
#endif

@ -0,0 +1,69 @@
#ifndef _SIGNAL_H
#define _SIGNAL_H
#include <sys/types.h>
typedef int sig_atomic_t;
typedef unsigned int sigset_t; /* 32 bits */
#define _NSIG 32
#define NSIG _NSIG
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#define SIGUNUSED 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGUSR1 10
#define SIGSEGV 11
#define SIGUSR2 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGTERM 15
#define SIGSTKFLT 16
#define SIGCHLD 17
#define SIGCONT 18
#define SIGSTOP 19
#define SIGTSTP 20
#define SIGTTIN 21
#define SIGTTOU 22
/* Ok, I haven't implemented sigactions, but trying to keep headers POSIX */
#define SA_NOCLDSTOP 1
#define SA_NOMASK 0x40000000
#define SA_ONESHOT 0x80000000
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
#define SIG_SETMASK 2 /* for setting the signal mask */
#define SIG_DFL ((void (*)(int))0) /* default signal handling */
#define SIG_IGN ((void (*)(int))1) /* ignore signal */
#define SIG_ERR ((void (*)(int))-1) /* error return from signal */
struct sigaction {
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
void (*signal(int _sig, void (*_func)(int)))(int);
int raise(int sig);
int kill(pid_t pid, int sig);
int sigaddset(sigset_t *mask, int signo);
int sigdelset(sigset_t *mask, int signo);
int sigemptyset(sigset_t *mask);
int sigfillset(sigset_t *mask);
int sigismember(sigset_t *mask, int signo); /* 1 - is, 0 - not, -1 error */
int sigpending(sigset_t *set);
int sigprocmask(int how, sigset_t *set, sigset_t *oldset);
int sigsuspend(sigset_t *sigmask);
int sigaction(int sig, struct sigaction *act, struct sigaction *oldact);
#endif /* _SIGNAL_H */

@ -0,0 +1,28 @@
#ifndef _STDARG_H
#define _STDARG_H
typedef char *va_list;
/* Amount of space required in an argument list for an arg of type TYPE.
TYPE may alternatively be an expression whose type is used. */
#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
#ifndef __sparc__
#define va_start(AP, LASTARG) \
(AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#else
#define va_start(AP, LASTARG) \
(__builtin_saveregs (), \
AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#endif
void va_end (va_list); /* Defined in gnulib */
#define va_end(AP)
#define va_arg(AP, TYPE) \
(AP += __va_rounded_size (TYPE), \
*((TYPE *) (AP - __va_rounded_size (TYPE))))
#endif /* _STDARG_H */

@ -0,0 +1,256 @@
#ifndef _STDIO_H
#define _STDIO_H
/* s t d i o
*
* Author: C. E. Chew
* Date: August 1989
*
* (C) Copyright C E Chew
*
* Feel free to copy, use and distribute this software provided:
*
* 1. you do not pretend that you wrote it
* 2. you leave this copyright notice intact.
*
* Definitions and user interface for the stream io package.
*
* Patchlevel 2.0
*
* Edit History:
*/
/* Site specific definitions */
/*@*/
#ifndef NULL
# define NULL ((void *)0)
#endif
#define _STDIO_UCHAR_ 0
#define _STDIO_VA_LIST_ char *
#define _STDIO_SIZE_T_ unsigned int /* type returned by sizeof */
#define _STDIO_USIZE_T_ unsigned int
/*=*/
/* Definitions based on ANSI compiler */
#ifdef __STDC__
# ifndef _STDIO_P_
# define _STDIO_P_(x) x
# endif
# ifndef _STDIO_VA_
# define _STDIO_VA_ , ...
# endif
# ifndef _STDIO_UCHAR_
# define _STDIO_UCHAR_ 0
# endif
#else
# ifndef _STDIO_P_
# define _STDIO_P_(x) ()
# endif
# ifndef _STDIO_VA_
# define _STDIO_VA_
# endif
# ifndef _STDIO_UCHAR_
# define _STDIO_UCHAR_ (0xff)
# endif
#endif
#ifndef _STDIO_VA_LIST_
# define _STDIO_VA_LIST_ void *
#endif
#ifndef _STDIO_SIZE_T_
# define _STDIO_SIZE_T_ unsigned int
#endif
#ifndef _STDIO_USIZE_T_
# define _STDIO_USIZE_T_ unsigned int
#endif
/* ANSI Definitions */
#define BUFSIZ 1024 /* default buffer size */
#ifndef NULL
# define NULL ((void *) 0) /* null pointer */
#endif
#define EOF (-1) /* eof flag */
#define FOPEN_MAX 16 /* minimum guarantee */
#define FILENAME_MAX 127 /* maximum length of file name */
#define SEEK_SET 0 /* seek from beginning */
#define SEEK_CUR 1 /* seek from here */
#define SEEK_END 2 /* seek from end */
#define TMP_MAX (0xffff) /* maximum number of temporaries */
#define L_tmpnam (5 + 8 + 4 + 1 + 1) /* length of temporary file name */
#ifndef _FPOS_T
# define _FPOS_T
typedef long fpos_t; /* stream positioning */
#endif
#ifndef _SIZE_T
# define _SIZE_T
typedef _STDIO_SIZE_T_ size_t; /* sizeof type */
#endif
#define _IOFBF 000000 /* fully buffered io */
#define _IOREAD 000001 /* opened for reading */
#define _IOWRITE 000002 /* opened for writing */
#define _IONBF 000004 /* unbuffered */
#define _IOMYBUF 000010 /* allocated buffer */
#define _IOPOOLBUF 000020 /* buffer belongs to pool */
#define _IOEOF 000040 /* eof encountered */
#define _IOERR 000100 /* error encountered */
#define _IOSTRING 000200 /* strings */
#define _IOLBF 000400 /* line buffered */
#define _IORW 001000 /* opened for reading and writing */
#define _IOAPPEND 002000 /* append mode */
#define _IOINSERT 004000 /* insert into __iop chain */
#define _IOSTDX 030000 /* standard stream */
#define _IOSTDIN 010000 /* stdin indication */
#define _IOSTDOUT 020000 /* stdout indication */
#define _IOSTDERR 030000 /* stderr indication */
#define _IORETAIN (_IOSTDX | _IOINSERT) /* flags to be retained */
/* Implementation Definitions */
typedef char __stdiobuf_t; /* stdio buffer type */
typedef _STDIO_USIZE_T_ __stdiosize_t; /* unsigned size_t */
typedef struct __iobuf {
__stdiobuf_t *__rptr; /* pointer into read buffer */
__stdiobuf_t *__rend; /* point at end of read buffer */
__stdiobuf_t *__wptr; /* pointer into write buffer */
__stdiobuf_t *__wend; /* point at end of write buffer */
__stdiobuf_t *__base; /* base of buffer */
__stdiosize_t __bufsiz; /* size of buffer */
short __flag; /* flags */
char __file; /* channel number */
__stdiobuf_t __buf; /* small buffer */
int (*__filbuf) _STDIO_P_((struct __iobuf *)); /* fill input buffer */
int (*__flsbuf) _STDIO_P_((int, struct __iobuf *)); /* flush output buffer */
int (*__flush) _STDIO_P_((struct __iobuf *)); /* flush buffer */
struct __iobuf *__next; /* next in chain */
} FILE;
extern FILE __stdin; /* stdin */
extern FILE __stdout; /* stdout */
extern FILE __stderr; /* stderr */
#define stdin (&__stdin)
#define stdout (&__stdout)
#define stderr (&__stderr)
/* ANSI Stdio Requirements */
int getc _STDIO_P_((FILE *));
#if _STDIO_UCHAR_
# define getc(p) ((p)->__rptr>=(p)->__rend\
?(*(p)->__filbuf)(p)\
:(int)(*(p)->__rptr++&_STDIO_UCHAR_))
#else
# define getc(p) ((p)->__rptr>=(p)->__rend\
?(*(p)->__filbuf)(p)\
:(int)((unsigned char)(*(p)->__rptr++)))
#endif
int getchar _STDIO_P_((void));
#define getchar() getc(stdin)
int putc _STDIO_P_((int, FILE *));
#if _STDIO_UCHAR_
# define putc(x,p) ((p)->__wptr>=(p)->__wend\
?(*(p)->__flsbuf)((x),(p))\
:(int)(*(p)->__wptr++=(x)&_STDIO_UCHAR_))
#else
# define putc(x,p) ((p)->__wptr>=(p)->__wend\
?(*(p)->__flsbuf)((x),(p))\
:(int)((unsigned char)(*(p)->__wptr++=(x))))
#endif
int putchar _STDIO_P_((int));
#define putchar(x) putc(x,stdout)
int feof _STDIO_P_((FILE *));
#define feof(p) (((p)->__flag&_IOEOF)!=0)
int ferror _STDIO_P_((FILE *));
#define ferror(p) (((p)->__flag&_IOERR)!=0)
void clearerr _STDIO_P_((FILE *));
#define clearerr(p) ((p)->__flag&=~(_IOEOF|_IOERR))
FILE *fopen _STDIO_P_((const char *, const char *));
FILE *freopen _STDIO_P_((const char *, const char *, FILE *));
int fflush _STDIO_P_((FILE *));
int fclose _STDIO_P_((FILE *));
int fgetpos _STDIO_P_((FILE *, fpos_t *));
int fsetpos _STDIO_P_((FILE *, fpos_t *));
long ftell _STDIO_P_((FILE *));
int fseek _STDIO_P_((FILE *, long, int));
void rewind _STDIO_P_((FILE *));
int fgetc _STDIO_P_((FILE *));
int fputc _STDIO_P_((int, FILE *));
__stdiosize_t fread _STDIO_P_((void *, __stdiosize_t,
__stdiosize_t, FILE *));
__stdiosize_t fwrite _STDIO_P_((void *, __stdiosize_t,
__stdiosize_t, FILE *));
int getw _STDIO_P_((FILE *));
int putw _STDIO_P_((int, FILE *));
char *gets _STDIO_P_((char *));
char *fgets _STDIO_P_((char *, int, FILE *));
int puts _STDIO_P_((const char *));
int fputs _STDIO_P_((const char *, FILE *));
int ungetc _STDIO_P_((int, FILE *));
int printf _STDIO_P_((const char * _STDIO_VA_));
int fprintf _STDIO_P_((FILE *, const char * _STDIO_VA_));
int sprintf _STDIO_P_((char *, const char * _STDIO_VA_));
int vprintf _STDIO_P_((const char *, _STDIO_VA_LIST_));
int vfprintf _STDIO_P_((FILE *, const char *, _STDIO_VA_LIST_));
int vsprintf _STDIO_P_((char *, const char *, _STDIO_VA_LIST_));
int scanf _STDIO_P_((const char * _STDIO_VA_));
int fscanf _STDIO_P_((FILE *, const char * _STDIO_VA_));
int sscanf _STDIO_P_((const char *, const char * _STDIO_VA_));
void setbuf _STDIO_P_((FILE *, char *));
int setvbuf _STDIO_P_((FILE *, char *, int, __stdiosize_t));
int rename _STDIO_P_((const char *, const char *));
int remove _STDIO_P_((const char *));
void perror _STDIO_P_((const char *));
char * tmpnam _STDIO_P_((char *));
FILE * tmpfile _STDIO_P_((void));
/* Posix Definitions */
int unlink _STDIO_P_((const char *));
#define remove(x) unlink((x))
#define L_ctermid 9
char * ctermid _STDIO_P_((char *s));
#define L_cuserid 9
char * cuserid _STDIO_P_((char *s));
FILE *fdopen _STDIO_P_((int, const char *));
int fileno _STDIO_P_((FILE *));
#define fileno(p) ((p)->__file)
#undef _STDIO_P_
#undef _STDIO_VA_
#undef _STDIO_VA_LIST_
/*ndef _STDIO_UCHAR_*/
#undef _STDIO_SIZE_T_
#undef _STDIO_USIZE_T_
#endif

@ -0,0 +1,43 @@
#ifndef _STDLIB_H
#define _STDLIB_H
#include <sys/types.h>
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
extern double atof(const char * s);
extern int atoi(const char *s);
extern long atol(const char *s);
extern double strtod(const char *s, char **endp);
extern long strtol(const char *s, char **endp, int base);
extern unsigned long strtoul(const char *s, char **endp, int base);
extern int rand(void);
extern void srand(unsigned int seed);
extern void * calloc(size_t nobj, size_t size);
extern void * malloc(size_t size);
extern void * realloc(void * p, size_t size);
extern void free(void * p);
extern void abort(void);
extern volatile void exit(int status);
extern int atexit(void (*fcn)(void));
extern int system(const char *s);
extern char * getenv(const char *name);
extern void * bsearch(const void *key, const void *base,
size_t n, size_t size,
int (*cmp)(const void *keyval, const void *datum));
extern void qsort(void *base, size_t n, size_t size,
int (*cmp)(const void *,const void *));
extern int abs(int n);
extern long labs(long n);
extern div_t div(int num, int denom);
extern ldiv_t ldiv(long num, long denom);
extern char * getcwd(char * buf, size_t size);
#ifdef __GNUC__
#define __alloca(n) __builtin_alloca(n)
#else
#define __alloca(n) alloca(n)
#endif
#endif

@ -0,0 +1,405 @@
#ifndef _STRING_H_
#define _STRING_H_
#ifndef NULL
#define NULL ((void *) 0)
#endif
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif
extern char * strerror(int errno);
/*
* This string-include defines all string functions as inline
* functions. Use gcc. It also assumes ds=es=data space, this should be
* normal. Most of the string-functions are rather heavily hand-optimized,
* see especially strtok,strstr,str[c]spn. They should work, but are not
* very easy to understand. Everything is done entirely within the register
* set, making the functions fast and clean. String instructions have been
* used through-out, making for "slightly" unclear code :-)
*
* (C) 1991 Linus Torvalds
*/
extern inline char * strcpy(char * dest,const char *src)
{
__asm__("cld\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
::"S" (src),"D" (dest):"si","di","ax");
return dest;
}
extern inline char * strncpy(char * dest,const char *src,int count)
{
__asm__("cld\n"
"1:\tdecl %2\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"rep\n\t"
"stosb\n"
"2:"
::"S" (src),"D" (dest),"c" (count):"si","di","ax","cx");
return dest;
}
extern inline char * strcat(char * dest,const char * src)
{
__asm__("cld\n\t"
"repne\n\t"
"scasb\n\t"
"decl %1\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
return dest;
}
extern inline char * strncat(char * dest,const char * src,int count)
{
__asm__("cld\n\t"
"repne\n\t"
"scasb\n\t"
"decl %1\n\t"
"movl %4,%3\n"
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
"2:\txorl %2,%2\n\t"
"stosb"
::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
:"si","di","ax","cx");
return dest;
}
extern inline int strcmp(const char * cs,const char * ct)
{
register int __res __asm__("ax");
__asm__("cld\n"
"1:\tlodsb\n\t"
"scasb\n\t"
"jne 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"xorl %%eax,%%eax\n\t"
"jmp 3f\n"
"2:\tmovl $1,%%eax\n\t"
"jl 3f\n\t"
"negl %%eax\n"
"3:"
:"=a" (__res):"D" (cs),"S" (ct):"si","di");
return __res;
}
extern inline int strncmp(const char * cs,const char * ct,int count)
{
register int __res __asm__("ax");
__asm__("cld\n"
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"scasb\n\t"
"jne 3f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
"2:\txorl %%eax,%%eax\n\t"
"jmp 4f\n"
"3:\tmovl $1,%%eax\n\t"
"jl 4f\n\t"
"negl %%eax\n"
"4:"
:"=a" (__res):"D" (cs),"S" (ct),"c" (count):"si","di","cx");
return __res;
}
extern inline char * strchr(const char * s,char c)
{
register char * __res __asm__("ax");
__asm__("cld\n\t"
"movb %%al,%%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"je 2f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
"movl $1,%1\n"
"2:\tmovl %1,%0\n\t"
"decl %0"
:"=a" (__res):"S" (s),"0" (c):"si");
return __res;
}
extern inline char * strrchr(const char * s,char c)
{
register char * __res __asm__("dx");
__asm__("cld\n\t"
"movb %%al,%%ah\n"
"1:\tlodsb\n\t"
"cmpb %%ah,%%al\n\t"
"jne 2f\n\t"
"movl %%esi,%0\n\t"
"decl %0\n"
"2:\ttestb %%al,%%al\n\t"
"jne 1b"
:"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
return __res;
}
extern inline int strspn(const char * cs, const char * ct)
{
register char * __res __asm__("si");
__asm__("cld\n\t"
"movl %4,%%edi\n\t"
"repne\n\t"
"scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t"
"movl %%ecx,%%edx\n"
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
"movl %4,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne\n\t"
"scasb\n\t"
"je 1b\n"
"2:\tdecl %0"
:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
:"ax","cx","dx","di");
return __res-cs;
}
extern inline int strcspn(const char * cs, const char * ct)
{
register char * __res __asm__("si");
__asm__("cld\n\t"
"movl %4,%%edi\n\t"
"repne\n\t"
"scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t"
"movl %%ecx,%%edx\n"
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
"movl %4,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne\n\t"
"scasb\n\t"
"jne 1b\n"
"2:\tdecl %0"
:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
:"ax","cx","dx","di");
return __res-cs;
}
extern inline char * strpbrk(const char * cs,const char * ct)
{
register char * __res __asm__("si");
__asm__("cld\n\t"
"movl %4,%%edi\n\t"
"repne\n\t"
"scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t"
"movl %%ecx,%%edx\n"
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
"movl %4,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne\n\t"
"scasb\n\t"
"jne 1b\n\t"
"decl %0\n\t"
"jmp 3f\n"
"2:\txorl %0,%0\n"
"3:"
:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
:"ax","cx","dx","di");
return __res;
}
extern inline char * strstr(const char * cs,const char * ct)
{
register char * __res __asm__("ax");
__asm__("cld\n\t" \
"movl %4,%%edi\n\t"
"repne\n\t"
"scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
"movl %%ecx,%%edx\n"
"1:\tmovl %4,%%edi\n\t"
"movl %%esi,%%eax\n\t"
"movl %%edx,%%ecx\n\t"
"repe\n\t"
"cmpsb\n\t"
"je 2f\n\t" /* also works for empty string, see above */
"xchgl %%eax,%%esi\n\t"
"incl %%esi\n\t"
"cmpb $0,-1(%%eax)\n\t"
"jne 1b\n\t"
"xorl %%eax,%%eax\n\t"
"2:"
:"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
:"cx","dx","di","si");
return __res;
}
extern inline int strlen(const char * s)
{
register int __res __asm__("cx");
__asm__("cld\n\t"
"repne\n\t"
"scasb\n\t"
"notl %0\n\t"
"decl %0"
:"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
return __res;
}
extern char * ___strtok;
extern inline char * strtok(char * s,const char * ct)
{
register char * __res __asm__("si");
__asm__("testl %1,%1\n\t"
"jne 1f\n\t"
"testl %0,%0\n\t"
"je 8f\n\t"
"movl %0,%1\n"
"1:\txorl %0,%0\n\t"
"movl $-1,%%ecx\n\t"
"xorl %%eax,%%eax\n\t"
"cld\n\t"
"movl %4,%%edi\n\t"
"repne\n\t"
"scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t"
"je 7f\n\t" /* empty delimeter-string */
"movl %%ecx,%%edx\n"
"2:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 7f\n\t"
"movl %4,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne\n\t"
"scasb\n\t"
"je 2b\n\t"
"decl %1\n\t"
"cmpb $0,(%1)\n\t"
"je 7f\n\t"
"movl %1,%0\n"
"3:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 5f\n\t"
"movl %4,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne\n\t"
"scasb\n\t"
"jne 3b\n\t"
"decl %1\n\t"
"cmpb $0,(%1)\n\t"
"je 5f\n\t"
"movb $0,(%1)\n\t"
"incl %1\n\t"
"jmp 6f\n"
"5:\txorl %1,%1\n"
"6:\tcmpb $0,(%0)\n\t"
"jne 7f\n\t"
"xorl %0,%0\n"
"7:\ttestl %0,%0\n\t"
"jne 8f\n\t"
"movl %0,%1\n"
"8:"
:"=b" (__res),"=S" (___strtok)
:"0" (___strtok),"1" (s),"g" (ct)
:"ax","cx","dx","di");
return __res;
}
extern inline void * memcpy(void * dest,const void * src, int n)
{
__asm__("cld\n\t"
"rep\n\t"
"movsb"
::"c" (n),"S" (src),"D" (dest)
:"cx","si","di");
return dest;
}
extern inline void * memmove(void * dest,const void * src, int n)
{
if (dest<src)
__asm__("cld\n\t"
"rep\n\t"
"movsb"
::"c" (n),"S" (src),"D" (dest)
:"cx","si","di");
else
__asm__("std\n\t"
"rep\n\t"
"movsb"
::"c" (n),"S" (src+n-1),"D" (dest+n-1)
:"cx","si","di");
return dest;
}
extern inline int memcmp(const void * cs,const void * ct,int count)
{
register int __res __asm__("ax");
__asm__("cld\n\t"
"repe\n\t"
"cmpsb\n\t"
"je 1f\n\t"
"movl $1,%%eax\n\t"
"jl 1f\n\t"
"negl %%eax\n"
"1:"
:"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)
:"si","di","cx");
return __res;
}
extern inline void * memchr(const void * cs,char c,int count)
{
register void * __res __asm__("di");
if (!count)
return NULL;
__asm__("cld\n\t"
"repne\n\t"
"scasb\n\t"
"je 1f\n\t"
"movl $1,%0\n"
"1:\tdecl %0"
:"=D" (__res):"a" (c),"D" (cs),"c" (count)
:"cx");
return __res;
}
extern inline void * memset(void * s,char c,int count)
{
__asm__("cld\n\t"
"rep\n\t"
"stosb"
::"a" (c),"D" (s),"c" (count)
:"cx","di");
return s;
}
#endif

@ -0,0 +1,58 @@
#ifndef _SYS_STAT_H
#define _SYS_STAT_H
#include <sys/types.h>
struct stat {
dev_t st_dev;
ino_t st_ino;
umode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
};
#define S_IFMT 00170000
#define S_IFREG 0100000
#define S_IFBLK 0060000
#define S_IFDIR 0040000
#define S_IFCHR 0020000
#define S_IFIFO 0010000
#define S_ISUID 0004000
#define S_ISGID 0002000
#define S_ISVTX 0001000
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001
extern int chmod(const char *_path, mode_t mode);
extern int fstat(int fildes, struct stat *stat_buf);
extern int mkdir(const char *_path, mode_t mode);
extern int mkfifo(const char *_path, mode_t mode);
extern int stat(const char *filename, struct stat *stat_buf);
extern mode_t umask(mode_t mask);
#endif

@ -0,0 +1,15 @@
#ifndef _TIMES_H
#define _TIMES_H
#include <sys/types.h>
struct tms {
time_t tms_utime;
time_t tms_stime;
time_t tms_cutime;
time_t tms_cstime;
};
extern time_t times(struct tms * tp);
#endif

@ -0,0 +1,46 @@
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif
#ifndef _TIME_T
#define _TIME_T
typedef long time_t;
#endif
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef long ptrdiff_t;
#endif
#ifndef NULL
#define NULL ((void *) 0)
#endif
typedef int pid_t;
typedef unsigned short uid_t;
typedef unsigned char gid_t;
typedef unsigned short dev_t;
typedef unsigned short ino_t;
typedef unsigned short mode_t;
typedef unsigned short umode_t;
typedef unsigned char nlink_t;
typedef int daddr_t;
typedef long off_t;
typedef unsigned char u_char;
typedef unsigned short ushort;
typedef struct { int quot,rem; } div_t;
typedef struct { long quot,rem; } ldiv_t;
struct ustat {
daddr_t f_tfree;
ino_t f_tinode;
char f_fname[6];
char f_fpack[6];
};
#endif

@ -0,0 +1,16 @@
#ifndef _SYS_UTSNAME_H
#define _SYS_UTSNAME_H
#include <sys/types.h>
struct utsname {
char sysname[9];
char nodename[9];
char release[9];
char version[9];
char machine[9];
};
extern int uname(struct utsname * utsbuf);
#endif

@ -0,0 +1,278 @@
#ifndef _UNISTD_H
#define _UNISTD_H
/* ok, this may be a joke, but I'm working on it */
#define _POSIX_VERSION 198808L
#define _POSIX_CHOWN_RESTRICTED /* only root can do a chown (I think..) */
#define _POSIX_NO_TRUNC /* no pathname truncation (but see in kernel) */
#define _POSIX_VDISABLE '\0' /* character to disable things like ^C */
/*#define _POSIX_SAVED_IDS */ /* we'll get to this yet */
/*#define _POSIX_JOB_CONTROL */ /* we aren't there quite yet. Soon hopefully */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#ifndef NULL
#define NULL ((void *)0)
#endif
/* access */
#define F_OK 0
#define X_OK 1
#define W_OK 2
#define R_OK 4
/* lseek */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
/* _SC stands for System Configuration. We don't use them much */
#define _SC_ARG_MAX 1
#define _SC_CHILD_MAX 2
#define _SC_CLOCKS_PER_SEC 3
#define _SC_NGROUPS_MAX 4
#define _SC_OPEN_MAX 5
#define _SC_JOB_CONTROL 6
#define _SC_SAVED_IDS 7
#define _SC_VERSION 8
/* more (possibly) configurable things - now pathnames */
#define _PC_LINK_MAX 1
#define _PC_MAX_CANON 2
#define _PC_MAX_INPUT 3
#define _PC_NAME_MAX 4
#define _PC_PATH_MAX 5
#define _PC_PIPE_BUF 6
#define _PC_NO_TRUNC 7
#define _PC_VDISABLE 8
#define _PC_CHOWN_RESTRICTED 9
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/utsname.h>
#include <utime.h>
#ifdef __LIBRARY__
#define __NR_setup 0 /* used only by init, to get system going */
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_chown 16
#define __NR_break 17
#define __NR_stat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_umount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_fstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_stty 31
#define __NR_gtty 32
#define __NR_access 33
#define __NR_nice 34
#define __NR_ftime 35
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_prof 44
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_phys 52
#define __NR_lock 53
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_mpx 56
#define __NR_setpgid 57
#define __NR_ulimit 58
#define __NR_uname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_select 82
#define __NR_symlink 83
#define __NR_lstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_execve2 87
#define __NR_getdents 88
#define __NR_pipe2 89
#define __NR_sleep 90
#define __NR_getcwd 91
#define __NR_mmap 92
#define __NR_munmap 93
#define __NR_clone 94
#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name)); \
if (__res >= 0) \
return (type) __res; \
errno = -__res; \
return -1; \
}
#define _syscall1(type,name,atype,a) \
type name(atype a) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(a))); \
if (__res >= 0) \
return (type) __res; \
errno = -__res; \
return -1; \
}
#define _syscall2(type,name,atype,a,btype,b) \
type name(atype a,btype b) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b))); \
if (__res >= 0) \
return (type) __res; \
errno = -__res; \
return -1; \
}
#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
type name(atype a,btype b,ctype c) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \
if (__res>=0) \
return (type) __res; \
errno=-__res; \
return -1; \
}
#endif /* __LIBRARY__ */
extern int errno;
int access(const char * filename, mode_t mode);
int acct(const char * filename);
int alarm(int sec);
int brk(void * end_data_segment);
void * sbrk(ptrdiff_t increment);
int chdir(const char * filename);
int chmod(const char * filename, mode_t mode);
int chown(const char * filename, uid_t owner, gid_t group);
int chroot(const char * filename);
int close(int fildes);
int creat(const char * filename, mode_t mode);
int dup(int fildes);
int execve(const char * filename, char ** argv, char ** envp);
int execv(const char * pathname, char ** argv);
int execvp(const char * file, char ** argv);
int execl(const char * pathname, char * arg0, ...);
int execlp(const char * file, char * arg0, ...);
int execle(const char * pathname, char * arg0, ...);
volatile void exit(int status);
volatile void _exit(int status);
int fcntl(int fildes, int cmd, ...);
int fork(void);
int getpid(void);
int getuid(void);
int geteuid(void);
int getgid(void);
int getegid(void);
int ioctl(int fildes, int cmd, ...);
int kill(pid_t pid, int signal);
int link(const char * filename1, const char * filename2);
int lseek(int fildes, off_t offset, int origin);
int mknod(const char * filename, mode_t mode, dev_t dev);
int mount(const char * specialfile, const char * dir, int rwflag);
int nice(int val);
int open(const char * filename, int flag, ...);
int pause(void);
int pipe(int * fildes);
int read(int fildes, char * buf, off_t count);
int setpgrp(void);
int setpgid(pid_t pid,pid_t pgid);
int setuid(uid_t uid);
int setgid(gid_t gid);
void (*signal(int sig, void (*fn)(int)))(int);
int stat(const char * filename, struct stat * stat_buf);
int fstat(int fildes, struct stat * stat_buf);
int stime(time_t * tptr);
int sync(void);
time_t time(time_t * tloc);
time_t times(struct tms * tbuf);
int ulimit(int cmd, long limit);
mode_t umask(mode_t mask);
int umount(const char * specialfile);
int uname(struct utsname * name);
int unlink(const char * filename);
int ustat(dev_t dev, struct ustat * ubuf);
int utime(const char * filename, struct utimbuf * times);
pid_t waitpid(pid_t pid,int * wait_stat,int options);
pid_t wait(int * wait_stat);
int write(int fildes, const char * buf, off_t count);
int dup2(int oldfd, int newfd);
int getppid(void);
pid_t getpgrp(void);
pid_t setsid(void);
#define __always_inline inline __attribute__((always_inline))
#endif

@ -0,0 +1,13 @@
#ifndef _UTIME_H
#define _UTIME_H
#include <sys/types.h> /* I know - shouldn't do this, but .. */
struct utimbuf {
time_t actime;
time_t modtime;
};
extern int utime(const char *filename, struct utimbuf *times);
#endif

@ -0,0 +1,66 @@
/*
*
* " Hello, mmap success."
*
* "mmap error."
*/
#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "new.h"
_syscall2(int,munmap,void *,addr,size_t,length)
void *mmap(void *addr, size_t length, ...)
{
register int res;
unsigned long argv_list[4];
va_list arg;
va_start(arg,length);
argv_list[0]=(unsigned long)va_arg(arg,int);
argv_list[1]=(unsigned long)va_arg(arg,int);
argv_list[2]=(unsigned long)va_arg(arg,int);
argv_list[3]=(unsigned long)va_arg(arg,int);
__asm__("int $0x80"
:"=a" (res)
:"0" (__NR_mmap),"b" (addr),"c" (length),
"d" ((unsigned long)argv_list));
if (res>=0)
return (void *)res;
errno = -res;
return (void *)-1;
}
static struct stat kst;
void test_mmap(void){
char *array;
const char *str = " Hello, mmap success.";
int fd;
fd = open("test_mmap.txt", O_RDWR | O_CREAT, S_IRUSR|S_IWUSR);
write(fd, str, strlen(str));
fstat(fd, &kst);
printf("file len: %d\n", (int)kst.st_size);
array = mmap(NULL, kst.st_size, PROT_WRITE | PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
printf("mmap addr: %x\n", (unsigned int)array);
if (array == MAP_FAILED) {
printf("mmap error.\n");
}else{
printf("mmap content: %s\n", array);
munmap(array, kst.st_size);
}
close(fd);
}
int main(void){
test_mmap();
return 0;
}

@ -0,0 +1,67 @@
/*
*
* " Hello, mmap success."
*
* "mmap error."
*/
#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "new.h"
_syscall2(int,munmap,void *,addr,size_t,length)
void *mmap(void *addr, size_t length, ...)
{
register int res;
unsigned long argv_list[4];
va_list arg;
va_start(arg,length);
argv_list[0]=(unsigned long)va_arg(arg,int);
argv_list[1]=(unsigned long)va_arg(arg,int);
argv_list[2]=(unsigned long)va_arg(arg,int);
argv_list[3]=(unsigned long)va_arg(arg,int);
printf("a:%d,%d,%d,%d\n",argv_list[0],argv_list[1],argv_list[2],argv_list[3]);
__asm__("int $0x80"
:"=a" (res)
:"0" (__NR_mmap),"b" (addr),"c" (length),
"d" (argv_list));
if (res>=0)
return (void *)res;
errno = -res;
return (void *)-1;
}
static struct stat kst;
void test_mmap(void){
char *array;
const char *str = " Hello, mmap success.";
int fd;
fd = open("test_mmap.txt", O_RDWR | O_CREAT, S_IRUSR|S_IWUSR);
write(fd, str, strlen(str));
fstat(fd, &kst);
printf("file len: %d\n", (int)kst.st_size);
array = mmap(NULL, kst.st_size, PROT_WRITE | PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
printf("mmap addr: %x\n", (unsigned int)array);
if (array == MAP_FAILED) {
printf("mmap error.\n");
}else{
printf("mmap content: %s\n", array);
munmap(array, kst.st_size);
}
close(fd);
}
int main(void){
test_mmap();
return 0;
}

@ -0,0 +1,74 @@
/*
*
* "munmap success."
*
* "munmap error."
*/
#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "new.h"
_syscall2(int,munmap,void *,addr,size_t,length)
void *mmap(void *addr, size_t length, ...)
{
register int res;
unsigned long argv_list[4];
va_list arg;
va_start(arg,length);
argv_list[0]=(unsigned long)va_arg(arg,int);
argv_list[1]=(unsigned long)va_arg(arg,int);
argv_list[2]=(unsigned long)va_arg(arg,int);
argv_list[3]=(unsigned long)va_arg(arg,int);
__asm__("int $0x80"
:"=a" (res)
:"0" (__NR_mmap),"b" (addr),"c" (length),
"d" ((unsigned long)argv_list));
if (res>=0)
return (void *)res;
errno = -res;
return (void *)-1;
}
static struct stat kst;
void test_unmmap(void){
char *array;
const char *str = " Hello, mmap success.";
int fd, ret;
fd = open("test_mmap.txt", O_RDWR | O_CREAT, S_IRUSR|S_IWUSR);
write(fd, str, strlen(str));
fstat(fd, &kst);
printf("file len: %d\n", (int)kst.st_size);
array = mmap(NULL, kst.st_size, PROT_WRITE | PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
printf("mmap addr: %x\n", (unsigned int)array);
if (array == MAP_FAILED) {
printf("mmap error.\n");
}else{
printf("mmap content: %s\n", array);
ret = munmap(array, kst.st_size);
printf("munmap return: %d\n", ret);
if (ret == 0) {
printf("munmap success.\n");
} else {
printf("munmap error.\n");
}
}
close(fd);
}
int main(void){
test_unmmap();
return 0;
}

@ -0,0 +1,70 @@
/*
*
* "munmap success."
*
* "munmap error."
*/
#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "new.h"
_syscall2(int,munmap,void *,addr,size_t,length)
void *mmap(void *addr, size_t length, ...)
{
register int res;
va_list arg;
va_start(arg,length);
__asm__("int $0x80"
:"=a" (res)
:"0" (__NR_munmap),"b" (addr),"c" (length),
"d" (va_arg(arg,int)));
if (res>=0)
return (void *)res;
errno = -res;
return (void *)-1;
}
static struct stat kst;
void test_unmmap(void){
char *array;
const char *str = " Hello, mmap success.";
int fd, ret;
fd = open("test_mmap.txt", O_RDWR | O_CREAT, S_IRUSR|S_IWUSR);
write(fd, str, strlen(str));
fstat(fd, &kst);
printf("file len: %d\n", (int)kst.st_size);
array = mmap(NULL, kst.st_size, PROT_WRITE | PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
printf("mmap addr: %x\n", (unsigned int)array);
if (array == MAP_FAILED) {
printf("mmap error.\n");
}else{
printf("mmap content: %s\n", array);
ret = munmap(array, kst.st_size);
printf("munmap return: %d\n", ret);
if (ret == 0) {
printf("munmap success.\n");
} else {
printf("munmap error.\n");
}
}
close(fd);
}
int main(void){
test_unmmap();
return 0;
}

@ -0,0 +1,30 @@
#ifndef _NEW_H
#define _NEW_H
#include <sys/types.h>
struct linux_dirent {
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[14];
};
/* Return value of `mmap' in case of an error. */
#define MAP_FAILED ((void *) -1)
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
#define PROT_SEM 0x8 /* page may be used for atomic ops */
#define PROT_NONE 0x0 /* page can not be accessed */
/* compatibility flags */
#define MAP_FILE 0
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
#define CLONE_VM 0x00000100 /* set if VM shared between processes */
#endif
Loading…
Cancel
Save