diff options
| author | Miguel <m.i@gmx.at> | 2018-09-21 01:43:25 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-21 01:43:25 +0200 |
| commit | ace0646608c393d8952b14536090c302bed2ee85 (patch) | |
| tree | 5d96e0d0a66c27818b677af3a84ef52af0260be1 | |
| parent | aeefdb37d1fc1c0eb7953b9c196cab09460bc167 (diff) | |
piperei working finally :)
| -rw-r--r-- | fs/fd.c | 124 | ||||
| -rw-r--r-- | fs/fd.h | 4 | ||||
| -rw-r--r-- | kernel/syscalls.c | 85 | ||||
| -rw-r--r-- | userspace/cat.c | 57 | ||||
| -rw-r--r-- | userspace/grep.c | 20 | ||||
| -rw-r--r-- | userspace/newcalls.h | 5 | ||||
| -rw-r--r-- | userspace/piper.c | 31 |
7 files changed, 218 insertions, 108 deletions
@@ -33,6 +33,20 @@ bool fd_close(fd* f) return f->close(f->data); } +fd fd_dupl(fd* f) +{ + return f->dupl(f); +} + +static fd default_dupl(fd *f) +{ + return *f; +} +void default_close(void* x) +{ + // nothin +} + //---- void* ext2_init(char *path) { @@ -109,11 +123,44 @@ void sysfs_close(uint32_t *data) kbfree(data); // free memory holding ringbuffer information } -void pipe_close(uint32_t *data) +void pipe_r_close(uint8_t *data) { - ringbuffer *r=data; - ringbuffer_free(data); // free ringbuffer buffer - kbfree(data); // free memory holding ringbuffer information + uint8_t *mem=data+sizeof(ringbuffer); + *mem-=1; + klog("closing read end of pipe, ref count=%d",*mem); + /* + if(*mem==0) // TODO : check other end too! and close on w_close + { + ringbuffer *r=data; + ringbuffer_free(data); // free ringbuffer buffer + kbfree(data); // free memory holding ringbuffer information + } + */ +} + +void pipe_w_close(uint8_t *data) +{ + uint8_t *mem=data+sizeof(ringbuffer); + mem+=4; + *mem-=1; + klog("closing write end of pipe, ref count=%d",*mem); +} + +static fd pipe_r_dupl(fd *f) +{ + uint8_t *mem=f->data+sizeof(ringbuffer); + *mem+=1; + klog("duplicating read end of pipe, ref count=%d",*mem); + return *f; +} + +static fd pipe_w_dupl(fd *f) +{ + uint8_t *mem=f->data+sizeof(ringbuffer); + mem+=4; + *mem+=1; + klog("duplicating write end of pipe, ref count=%d",*mem); + return *f; } void get_sysfs_data(ringbuffer *r,char *format_string, ...) @@ -135,19 +182,6 @@ bool fifo_eof(uint32_t* data) return false; } -// TODO remove and use fd_from_ringbuffer? -fd fd_from_fifo(fifo* fif) -{ - fd f; - f.type=FD_TYPE_FIFO_BUFFERED; - f.data=fif; - f.read=fifo_get; - f.write=fifo_put; - f.eof=fifo_eof; -// f.close=fd_close; //TODO.. etc also otehr and cleanups - f.has=fifo_has; - return f; -} uint8_t pipe_get(uint32_t *data) { @@ -164,11 +198,19 @@ bool pipe_has(uint32_t *data) return ringbuffer_has(data); } -bool pipe_eof(uint32_t *data) +bool pipe_eof(uint8_t *data) { - return 0; + + uint8_t *mem=data+sizeof(ringbuffer); + mem+=4; + + //we assume EOF if there is no data anymore AND no writers! + return (!ringbuffer_has(data))&&(*mem==0); } + +///// + int fds_from_pipe(fd pipefds[2]) { fd read; @@ -177,24 +219,36 @@ int fds_from_pipe(fd pipefds[2]) read.type=FD_TYPE_PIPE; wrt.type=FD_TYPE_PIPE; - read.data=kballoc(1); - wrt.data=read.data; + uint8_t *mem=kballoc(1); + + read.data=mem; + wrt.data=mem; ringbuffer r=ringbuffer_init(1); - memcpy(read.data,&r,sizeof(ringbuffer)); + memcpy(mem,&r,sizeof(ringbuffer)); + mem+=sizeof(ringbuffer); + *mem=1; + mem+=4; + *mem=1; read.read=pipe_get; + wrt.read=0; + wrt.write=pipe_put; + read.write=0; read.has=pipe_has; - wrt.has=pipe_has; + wrt.has=0; read.eof=pipe_eof; - wrt.eof=pipe_eof; + wrt.eof=0; + + read.close=pipe_r_close; + wrt.close=pipe_w_close; - read.close=0; - wrt.close=0; + read.dupl=pipe_r_dupl; + wrt.dupl=pipe_w_dupl; pipefds[0]=read; pipefds[1]=wrt; @@ -212,6 +266,7 @@ fd fd_from_path(char* path) f.close=ext2_close; f.eof=ext2_eof; f.has=ext2_has; + f.dupl=default_dupl; return f; } @@ -237,6 +292,21 @@ fd fd_from_sysfs(void(*g)(ringbuffer *r,void (*f)(ringbuffer *r,char *fmt, ...)) f.close=sysfs_close; f.has=sysfs_has; f.eof=sysfs_eof; - + f.dupl=default_dupl; + f.close=default_close; + return f; +} + +fd fd_from_fifo(fifo* fif) +{ + fd f; + f.type=FD_TYPE_FIFO; + f.data=fif; + f.read=fifo_get; + f.write=fifo_put; + f.eof=fifo_eof; + f.has=fifo_has; + f.dupl=default_dupl; + f.close=default_close; return f; } @@ -10,7 +10,7 @@ #include "ringbuffer.h" enum FD_TYPE{ - FD_TYPE_FIFO_BUFFERED=1, + FD_TYPE_FIFO=1, FD_TYPE_EXT2_FILE=2, FD_TYPE_EXT2_DIR=3, FD_TYPE_SYSFS=4, @@ -24,6 +24,7 @@ typedef struct fd_struct bool (*has)(struct fd_struct*); bool (*eof)(struct fd_struct*); bool (*close)(struct fd_struct*); + struct fd_struct (*dupl)(struct fd_struct *); uint8_t type; void *data; // opaque data @@ -34,6 +35,7 @@ bool fd_has(fd*); bool fd_eof(fd*); bool fd_write(fd*,uint8_t); bool fd_close(fd*); +fd fd_dupl(fd*); fd fd_from_fifo(fifo* f); fd fd_from_path(char *path); diff --git a/kernel/syscalls.c b/kernel/syscalls.c index dfcdaae..ee100e2 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -28,22 +28,28 @@ //TODO move to process.c and implement per process // static fd fds[MAX_PID][MAX_FD]; -static uint32_t next_fd[MAX_PID]; +static bool open_fd[MAX_PID][MAX_FD]; void fd_init_std_streams(uint32_t pid) { if(pid==0) { //stdin / stdout /stderr - fds[0][next_fd[0]++]=fd_from_ringbuffer(); - fds[0][next_fd[0]++]=fd_from_fb_term(); - fds[0][next_fd[0]++]=fd_from_fb_term(); + fds[0][0]=fd_from_ringbuffer(); + fds[0][1]=fd_from_fb_term(); + fds[0][2]=fd_from_fb_term(); + open_fd[0][0]=true; + open_fd[0][1]=true; + open_fd[0][2]=true; } else { fds[pid][0]=fds[0][0]; fds[pid][1]=fds[0][1]; fds[pid][2]=fds[0][2]; + open_fd[pid][0]=true; + open_fd[pid][1]=true; + open_fd[pid][2]=true; } } @@ -248,22 +254,38 @@ int syscall_execve(const char *name, char *const argv[], char *const env[], int return 0; } +/** helper */ +int nextfd(int pid) +{ + for(int i=0;i<MAX_FD;i++) + if(!open_fd[pid][i]) + { + open_fd[pid][i]=true; + return i; + } + + return -1; +} int syscall_open(char *name, int flags, int mode,uint32_t pid) { - fds[pid][next_fd[pid]]=mount_file_open(name); - if(*(uint32_t *)fds[pid][next_fd[pid]].data==0)return -1; - - next_fd[pid]++; - return next_fd[pid]-1; + uint32_t fdn=nextfd(pid); + fds[pid][fdn]=mount_file_open(name); + if(*(uint32_t *)fds[pid][fdn].data==0)return -1; + return fdn; } // pid_t fork(void); uint32_t syscall_fork(int none1, int none2, int none3, int pid) { uint32_t newpid=task_fork(pid); - fds[newpid][0]=fds[pid][0]; - fds[newpid][1]=fds[pid][1]; - fds[newpid][2]=fds[pid][2]; + + for(int i=0;i<MAX_FD;i++) + { + if(!open_fd[pid][i])continue; + fds[newpid][i]=fd_dupl(&fds[pid][i]); + open_fd[newpid][i]=true; + } + return newpid; } @@ -282,6 +304,15 @@ uint32_t syscall_exit(int status, uint32_t none1, uint32_t none2,int pid) { fixme("free allll mem"); klog("pid %d exited with %d",pid,status); + for(int i=0;i<MAX_FD;i++) + { + if(open_fd[pid][i]) + { + fd_close(&fds[pid][i]); + open_fd[pid][i]=false; + } + + } task_exit(pid); return 0; } @@ -289,15 +320,20 @@ uint32_t syscall_exit(int status, uint32_t none1, uint32_t none2,int pid) // int close (int fd) (TODO; close or not to close open filedescirptors?) int syscall_close(int file,int none1,int none2,int pid) { - if(file<3)return 0; - fd_close(&fds[pid][file]); + if(open_fd[pid][file]) + { + fd_close(&fds[pid][file]); + open_fd[pid][file]=false; + } + return 0; } // TODO: check if file is a termminal! int syscall_isatty(int file,int none1,int none2,int pid) { - return 1; + if(fds[pid][file].type==FD_TYPE_FIFO)return 1; + return 0; } // TODO: per process basis! @@ -324,22 +360,23 @@ uint32_t syscall_pipe(uint32_t *addr,int none1, int none2, uint32_t pid) fd pipfds[2]; int ret=fds_from_pipe(pipfds); - fds[pid][next_fd[pid]]=pipfds[0] ; - *addr=next_fd[pid]; - addr++; + int fd1=nextfd(pid); + int fd2=nextfd(pid); - next_fd[pid]++; + fds[pid][fd1]=pipfds[0] ; + *addr=fd1; + addr++; - fds[pid][next_fd[pid]]=pipfds[1] ; - *addr=next_fd[pid]; - next_fd[pid]++; + fds[pid][fd2]=pipfds[1] ; + *addr=fd2; return ret; } uint32_t syscall_dup2(uint32_t oldfd,int newfd, int none2, uint32_t pid) { - fds[pid][newfd]=fds[pid][oldfd]; + fd_close(&fds[pid][newfd]); + fds[pid][newfd]=fd_dupl(&fds[pid][oldfd]); return newfd; } @@ -350,7 +387,7 @@ uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, case SYSCALL_WAIT : return !task_runs(p1); case SYSCALL_READ : - return fd_has(&fds[pid][p1]); + return fd_has(&fds[pid][p1])||fd_eof(&fds[pid][p1]); } return 1;//other syscalls never block for now. diff --git a/userspace/cat.c b/userspace/cat.c index 94cbdaa..41768ea 100644 --- a/userspace/cat.c +++ b/userspace/cat.c @@ -3,34 +3,39 @@ int main(int argc, char **argv) { - printf("hmm\n"); - printf("pwd=%s\n",getenv("PWD")); - FILE *f; - if(argc>1){ - char buf[256]; - if(argv[1][0]!='/') - { - sprintf(buf,"%s/%s",getenv("PWD"),argv[1]); - printf("cat %s\n",buf); - f=fopen(buf,"r"); - } - else - { - printf("cat %s\n",argv[1]); - f=fopen(argv[1],"r"); - } - } - else f=stdin; + // Input (default stdin) + FILE *in=stdin; + + // Output + FILE *out=stdout; - setvbuf(stdin,NULL,_IONBF,0); - setvbuf(stdout,NULL,_IONBF,0); + // In case a Filename was supplied + if(argc>1){ + char buf[256]; - char c; + // Relative Path + if(argv[1][0]!='/') + { + sprintf(buf,"%s/%s",getenv("PWD"),argv[1]); + in=fopen(buf,"r"); + } - while(fread(&c,1,1,f)) - { - printf("%c",c); - } + // Absolute Path + else + { + in=fopen(argv[1],"r"); + } + } + + char buf[256]; + + while(1) + { + int l=fread(buf,1,255,in); + buf[l]=0; + if(l==0)break; + fwrite(buf,1,l,out); + } - return 0; + return EXIT_SUCCESS; } diff --git a/userspace/grep.c b/userspace/grep.c index c37392f..68d5b7a 100644 --- a/userspace/grep.c +++ b/userspace/grep.c @@ -3,15 +3,17 @@ int main(int argc, char **argv) { - while(1) - { - char buf[256]; - int l=fread(buf,1,255,stdin); - if(l==0)break; - buf[l]=0; - printf("grep: %s",buf); + FILE *in=stdin; + FILE *out=stdout; - } + while(1) + { + char buf[2]; + int l=fread(buf,1,1,in); + if(l==0)break; + buf[l]=0; + fwrite(buf,1,l,out); + } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/userspace/newcalls.h b/userspace/newcalls.h index 9bc55a5..4568711 100644 --- a/userspace/newcalls.h +++ b/userspace/newcalls.h @@ -3,6 +3,7 @@ // this syscall will be moved to newlib later! #define SYSCALL_CLONE 83 #define SYSCALL_PIPE 84 +#define SYSCALL_DUP2 86 int _clone(void) { @@ -12,4 +13,8 @@ int _pipe(uint32_t fds[2]) { return syscall(SYSCALL_PIPE,fds,0,0); } +int _dup2(uint32_t oldfd,uint32_t newfd) +{ + return syscall(SYSCALL_DUP2,oldfd,newfd,0); +} // diff --git a/userspace/piper.c b/userspace/piper.c index f45248e..80cbd27 100644 --- a/userspace/piper.c +++ b/userspace/piper.c @@ -1,38 +1,27 @@ #include <stdio.h> #include "newcalls.h" +extern **environ; + int main() { int fds[2]; _pipe(fds); - printf("opened pipe / in fd=%d,out fd=%d\n",fds[0],fds[1]); - int pid=_fork(); if(pid) { - while(1) // read forever from our pipe and echo to stdout - { - char buf[256]; - int len=fread(buf,1,255,fds[0]); - //int len=_read(fds[0],buf,255); - buf[len]=0; - printf("-\n"); - printf("%s\n",buf); - printf("-\n"); - } - + _close(fds[1]); + _dup2(fds[0],0); // replace stdin with the read-end of pipe + char *args[]={"grep",NULL}; + _execve("/bin/grep",args,environ); } else { - - // write to our pipe - _write(fds[1],"Hello\n",fds[1]); - _write(fds[1],"Bello\n",fds[1]); - - // hang forever - while(1); + _close(fds[0]); + _dup2(fds[1],1); // replace stdout with the write-end of our pipe + char *args[]={"cat","hello.txt",0}; + _execve("/bin/cat",args,environ); } - } |
