From b5e8400eedd500b045c1d0f92fa7201c07ac9486 Mon Sep 17 00:00:00 2001 From: Martin 'povik' Poviser Date: Sat, 13 Jun 2009 14:00:28 +0200 Subject: [PATCH] Added pipe() syscall; Fixed some memleaks; --- kernel/arch/i386/syscall.c | 10 ++ kernel/core/commands.c | 169 ++----------------------- kernel/include/pipe.h | 8 +- kernel/lib/stdio/close.c | 7 +- kernel/lib/stdio/read.c | 10 ++ kernel/lib/stdio/write.c | 11 ++ kernel/lib/unistd/pipe.c | 58 ++++++--- libc/Makefile | 2 +- libc/include/unistd.h | 2 + kernel/lib/stdio/close.c => libc/unistd/pipe.c | 33 ++--- 10 files changed, 108 insertions(+), 202 deletions(-) copy kernel/lib/stdio/close.c => libc/unistd/pipe.c (58%) diff --git a/kernel/arch/i386/syscall.c b/kernel/arch/i386/syscall.c index 1af035b..abad088 100644 --- a/kernel/arch/i386/syscall.c +++ b/kernel/arch/i386/syscall.c @@ -32,6 +32,7 @@ #include #include #include +#include extern task_t *_curr_task; @@ -836,6 +837,13 @@ void sys_lseek (struct regs *r) *memptr = ret; } +void sys_pipe (struct regs *r) +{ + int *p = (int *) r->ebx; + + r->eax = pipe (p); +} + void syscall_handler (struct regs *r) { @@ -948,5 +956,7 @@ void syscall_handler (struct regs *r) return sys_getpid (r); case 54: return sys_lseek (r); + case 55: + return sys_pipe (r); } } diff --git a/kernel/core/commands.c b/kernel/core/commands.c index e9591a9..9258fab 100644 --- a/kernel/core/commands.c +++ b/kernel/core/commands.c @@ -46,6 +46,7 @@ #include #include #include +#include command_t command_list; extern partition_t partition_list; @@ -869,162 +870,18 @@ extern unsigned end; extern bool ide_acthandler (unsigned act, partition_t *p, char *block, char *more, int n); unsigned command_test (char *command, unsigned len) { -/* int s, s2, t, l; - sockaddr_un local, remote; - - char str[100]; - - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - printf ("error\n"); - return 0; - } - - local.sun_family = AF_UNIX; - strcpy(local.sun_path, "test"); - // unlink(local.sun_path); - l = strlen(local.sun_path) + sizeof(local.sun_family); - if (bind(s, (sockaddr *) &local, l) == -1) { - printf ("error2\n"); - return 0; - } - - if (listen(s, 5) == -1) { - printf ("error3\n"); - return 0; - } - - - int done, n; - printf("Waiting for a connection... - %d\n", s); - t = sizeof(remote); - if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) { - printf ("accept\n"); - return 0; - } - - printf("Connected - server - %d\n", s2); - - done = 0; - - - unsigned m = 0; - - while (m < 100) { - - if (send(s2, "Jejda", 5, 0) < 0) { - printf ("send\n"); - } - - int ret = recv(s2, str, 99, 0); - - if (ret > 0) { - str[ret] = '\0'; - printf ("recv: %s : %d\n", str, ret); - } - - m ++; - } - - sclose(s2); - -*/ - - //fdisk ("/dev/hda 0 83 50", 16); - - //vfs_dirent (); - - /*partition_t *p = partition_find ("/dev/hda0"); - - if (p) - mount (p, "", "/mnt/hdd/"); - else - printf ("WARNING -> partition /dev/hda0 does not exists\n"); -*/ - //char *t = (char *) 0x400000+0x1; - //*t = 0x1; - - //printf ("ddd: 0x%x, 0x%x\n", start, end); - -/* paging_disable (); - - task_t *task = task_find (0); - - if (!task) - return 0; - char *t = (char *) 0x400000; - *t = 0x12; - - t = (char *) 0x0; - - *t = 0x3; - - printf ("Start2: 0x%x\n", *t); - unsigned r = page_mmap (task->page_cover, (void *) 0x0, (void *) 0x1000, 1, 0); - - if (!r) { - printf ("Oj Oj\n"); - paging_enable (); - return 0; - } - - paging_enable ();*/ - - -/* - t = (char *) 0x0; - - printf ("Start3: 0x%x\n", *t); - - *t = 0x2; - - paging_disable (); - - t = (char *) 0x400000; - - printf ("Start4: 0x%x\n", *t); - - paging_enable ();*/ - - /*init_adm (); - - cd ((char *) "/mnt/floppy"); - - unsigned i = 0; - - //while (++ i < 100) { - command_exec ("exec zde", 8); - schedule (); - //} - - cd (".."); - cd (".."); - - return 1;*/ - - /* Create virtual block device */ -/*#ifdef ARCH_i386 - dev_t *dev = (dev_t *) dev_register ("vbd", "Virtual Block Device", DEV_ATTR_BLOCK, (dev_handler_t *) &ide_acthandler); - - partition_t *p = partition_add (dev, fs_supported ("znfs")); - - znfs_init (partition_add (dev, fs_supported ("znfs")), "192.168.0.2"); // small HACK - - if (p) - mount (p, "", "/mnt/hdd/"); - else - printf ("WARNING -> partition /dev/hda0 does not exists\n"); - - cd ((char *) "/mnt/hdd"); -#endif*/ -//printf ("Je to na 0x%x\n", vesafb); -/* - partition_t *p = partition_find ("/dev/hda0"); - - memcpy (file_cache, "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", 10); - file_cache_id = 10; - - zexfs_write_file (p, argparse (command)); -*/ + int fds[2]; + char buffer[512]; + pipe (fds); + strcpy (buffer, "Ahoj"); + write (fds[1], buffer, 4); + strcpy (buffer, " svete!"); + write (fds[1], buffer, 7); + read (fds[0], buffer, 11); + printf ("%s\n", buffer); + + close (fds[1]); + close (fds[0]); return 1; } diff --git a/kernel/include/pipe.h b/kernel/include/pipe.h index f2ead0f..b8815e3 100644 --- a/kernel/include/pipe.h +++ b/kernel/include/pipe.h @@ -35,14 +35,14 @@ typedef struct pipe { pipe_buffer_t *buffer_list_end; unsigned int buffer_start_pos; unsigned int buffer_end_len; - unsigned int fd_a, fd_b; + int fd_a, fd_b; struct pipe *next, *prev; } pipe_t; -pipe_t *pipe_get (unsigned int fd); -void pipe_close (unsigned int fd); +pipe_t *pipe_get (int fd); +void pipe_close (int fd); bool pipe_write (pipe_t *p, BYTE *buffer, unsigned int buffer_len); unsigned int pipe_read (pipe_t *p, BYTE *buffer, unsigned int buffer_max_len); -void pipe (unsigned int fds[2]); +int pipe (int fds[2]); #endif diff --git a/kernel/lib/stdio/close.c b/kernel/lib/stdio/close.c index 5a254f3..b779249 100644 --- a/kernel/lib/stdio/close.c +++ b/kernel/lib/stdio/close.c @@ -2,6 +2,7 @@ * ZeX/OS * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) + * Copyright (C) 2009 Martin 'povik' Poviser (martin.povik@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +23,7 @@ #include #include #include +#include int close (int fd) { @@ -32,7 +34,10 @@ int close (int fd) if (f->flags & FD_SOCK) // socket close sclose (fd); - + + if (f->flags & FD_PIPE) // pipe close + pipe_close (fd); + f->id = 0; f->flags = 0; f->e = 0; diff --git a/kernel/lib/stdio/read.c b/kernel/lib/stdio/read.c index 65b6e47..17f0de3 100644 --- a/kernel/lib/stdio/read.c +++ b/kernel/lib/stdio/read.c @@ -3,6 +3,7 @@ * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) + * Copyright (C) 2009 Martin 'povik' Poviser (martin.povik@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +25,7 @@ #include #include #include +#include int read (unsigned fd, void *buf, unsigned len) { @@ -32,6 +34,14 @@ int read (unsigned fd, void *buf, unsigned len) if (!d) return 0; + if (d->flags & FD_PIPE) { + pipe_t *p = pipe_get (fd); + if (p) { + return pipe_read (p, buf, len); + } else + return 0; + } + if (len > d->e) len = d->e; diff --git a/kernel/lib/stdio/write.c b/kernel/lib/stdio/write.c index 64790ec..b373e6d 100644 --- a/kernel/lib/stdio/write.c +++ b/kernel/lib/stdio/write.c @@ -2,6 +2,7 @@ * ZeX/OS * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) + * Copyright (C) 2009 Martin 'povik' Poviser (martin.povik@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +27,10 @@ #include #include #include +#include /* TODO: flags */ + int write (unsigned fd, void *buf, unsigned len) { fd_t *d = fd_get (fd); @@ -35,6 +38,14 @@ int write (unsigned fd, void *buf, unsigned len) if (!d) return 0; + if (d->flags & FD_PIPE) { + pipe_t *p = pipe_get (fd); + if (p) { + return pipe_write (p, buf, len); + } else + return 0; + } + char *file = dir[d->index].name; if (!file) { diff --git a/kernel/lib/unistd/pipe.c b/kernel/lib/unistd/pipe.c index 54223c4..c27e03d 100644 --- a/kernel/lib/unistd/pipe.c +++ b/kernel/lib/unistd/pipe.c @@ -18,15 +18,24 @@ #include #include +#include #include pipe_t *pipe_list_start; pipe_t *pipe_list_end; -void pipe (unsigned int fds[2]) +int pipe (int fds[2]) { pipe_t *p = ((pipe_t*) kmalloc (sizeof (pipe_t))); + fd_count ++; + fd_create (fd_count, FD_PIPE); + fds[0] = fd_count; + + fd_count ++; + fd_create (fd_count, FD_PIPE); + fds[1] = fd_count; + if(!pipe_list_start) { pipe_list_end = p; pipe_list_start = p; @@ -42,15 +51,17 @@ void pipe (unsigned int fds[2]) p->fd_a = fds[0]; p->fd_b = fds[1]; - p->buffer_list_start = ((pipe_buffer_t*) kmalloc (sizeof (sizeof(pipe_buffer_t)))); + p->buffer_list_start = ((pipe_buffer_t*) kmalloc (sizeof(pipe_buffer_t))); p->buffer_list_end = p->buffer_list_start; p->buffer_list_start->next = NULL; p->buffer_list_start->prev = NULL; p->buffer_end_len = 0; p->buffer_start_pos = 0; + + return 0; } -pipe_t *pipe_get (unsigned int fd) +pipe_t *pipe_get (int fd) { pipe_t *p = pipe_list_start; @@ -78,12 +89,11 @@ unsigned int pipe_write (pipe_t *p, BYTE* buffer, unsigned int buffer_len) unsigned int block_size = 0; unsigned int buffer_pos = 0; pipe_buffer_t *ptr; - while (buffer_pos < buffer_len) { if ((buffer_len - buffer_pos) >= (PIPE_BUFFER_PART_SIZE - p->buffer_end_len)) { ptr = p->buffer_list_end; block_size = PIPE_BUFFER_PART_SIZE - p->buffer_end_len; - memcpy (&ptr->buffer + p->buffer_end_len, &buffer + buffer_pos, block_size); + memcpy (*((&ptr->buffer) + p->buffer_end_len), ((buffer) + buffer_pos), block_size); buffer_pos += block_size; p->buffer_list_end = ((pipe_buffer_t*) kmalloc(sizeof (pipe_buffer_t))); @@ -91,9 +101,9 @@ unsigned int pipe_write (pipe_t *p, BYTE* buffer, unsigned int buffer_len) ptr->next = p->buffer_list_end; p->buffer_list_end->prev = ptr; } else { - ptr = p->buffer_list_end; + ptr = p->buffer_list_end; block_size = buffer_len - buffer_pos; - memcpy (&ptr->buffer + p->buffer_end_len, &buffer + buffer_pos, block_size); + memcpy (((ptr->buffer) + p->buffer_end_len), ((buffer) + buffer_pos), block_size); p->buffer_end_len += block_size; buffer_pos += block_size; } @@ -106,6 +116,7 @@ unsigned int pipe_write (pipe_t *p, BYTE* buffer, unsigned int buffer_len) unsigned int pipe_read (pipe_t *p, BYTE* buffer, unsigned int buffer_max_len) { unsigned int buffer_pos = 0; + if ((!p) || (!buffer) || (!buffer_max_len) || (!p->buffer_list_start)) return 0; @@ -122,17 +133,15 @@ unsigned int pipe_read (pipe_t *p, BYTE* buffer, unsigned int buffer_max_len) if(p->buffer_start_pos == p->buffer_end_len) break; - - ptr = p->buffer_list_start; - memcpy (&buffer + buffer_pos, &ptr->buffer + p->buffer_start_pos, block_size); + memcpy (((buffer) + buffer_pos), ((ptr->buffer) + p->buffer_start_pos), block_size); p->buffer_start_pos += block_size; buffer_pos += block_size; } else if (buffer_space >= PIPE_BUFFER_PART_SIZE - p->buffer_start_pos) { ptr = p->buffer_list_start; block_size = PIPE_BUFFER_PART_SIZE - p->buffer_start_pos; - memcpy (&buffer + buffer_pos, &ptr->buffer + p->buffer_start_pos, block_size); + memcpy (((buffer) + buffer_pos), ((ptr->buffer) + p->buffer_start_pos), block_size); buffer_pos += block_size; p->buffer_start_pos = 0; @@ -141,7 +150,7 @@ unsigned int pipe_read (pipe_t *p, BYTE* buffer, unsigned int buffer_max_len) kfree(ptr); } else { ptr = p->buffer_list_start; - memcpy (&buffer + buffer_pos, &ptr->buffer + p->buffer_start_pos, buffer_space); + memcpy (((buffer) + buffer_pos), ((ptr->buffer) + p->buffer_start_pos), buffer_space); p->buffer_start_pos += buffer_space; } } @@ -170,26 +179,39 @@ void pipe_remove (pipe_t *pipe) if (pipe->next) pipe_list_start = pipe->next; else - pipe_list_end = NULL; + pipe_list_start = NULL; + } + + { + pipe_buffer_t *tmp; + pipe_buffer_t *p = pipe->buffer_list_start; + + while (p) { + tmp = p; + p = p->next; + kfree (tmp); + } } kfree (pipe); } -void pipe_close (unsigned int fds) +void pipe_close (int fd) { pipe_t *p = pipe_list_start; while (true) { - if (p->fd_a == fds) { + if (p->fd_a == fd) { + fd_delete (fd_get (fd)); p->fd_a = -1; - if (!p->fd_b) + if (0 > p->fd_b) pipe_remove(p); return; } - if (p->fd_b == fds) { + if (p->fd_b == fd) { + fd_delete (fd_get (fd)); p->fd_b = -1; - if (!p->fd_b) + if (0 > p->fd_a) pipe_remove(p); return; } diff --git a/libc/Makefile b/libc/Makefile index 6076140..a6f2d6c 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -11,7 +11,7 @@ STDIO =stdio/doprintf.o stdio/delay.o stdio/printf.o stdio/sprintf.o stdio/puts. STRING =string/memset.o string/memsetw.o string/memcpy.o string/memcmp.o string/memchr.o string/strlen.o string/strchr.o string/strcpy.o string/strncpy.o string/strcat.o string/strncat.o string/strcmp.o string/strstr.o string/strspn.o string/strdup.o string/strpbrk.o X86 =x86/inportb.o x86/outportb.o x86/disable.o x86/enable.o x86/dma.o STDLIB =stdlib/memory.o stdlib/exit.o stdlib/schedule.o stdlib/strtol.o stdlib/atoi.o stdlib/itoa.o stdlib/abort.o stdlib/abs.o stdlib/system.o stdlib/rand.o -UNISTD =unistd/sleep.o unistd/fcntl.o unistd/dup.o unistd/lseek.o unistd/unlink.o +UNISTD =unistd/sleep.o unistd/fcntl.o unistd/dup.o unistd/lseek.o unistd/unlink.o unistd/pipe.o SOCKET =socket/connect.o socket/socket.o socket/send.o socket/gethostbyname.o socket/htons.o socket/recv.o socket/bind.o socket/listen.o socket/accept.o socket/sendto.o socket/recvfrom.o socket/inet_ntop.o SIGNAL =signal/signal.o VFS =vfs/mount.o diff --git a/libc/include/unistd.h b/libc/include/unistd.h index d521ebe..cd1a26a 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -2,6 +2,7 @@ * ZeX/OS * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) + * Copyright (C) 2009 Martin 'povik' Poviser (martin.povik@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,5 +52,6 @@ extern int dup2 (int fildes, int fildes2); extern off_t lseek (int fd, off_t offset, int whence); extern int unlink (const char *pathname); extern pid_t getpid (); +int pipe (int fds[2]); #endif diff --git a/kernel/lib/stdio/close.c b/libc/unistd/pipe.c similarity index 58% copy from kernel/lib/stdio/close.c copy to libc/unistd/pipe.c index 5a254f3..b494acf 100644 --- a/kernel/lib/stdio/close.c +++ b/libc/unistd/pipe.c @@ -1,7 +1,6 @@ /* * ZeX/OS - * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) - * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com) + * Copyright (C) 2009 Martin 'povik' Poviser (martin.povik@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,29 +17,19 @@ */ -#include -#include -#include -#include +#include -int close (int fd) +int pipe (int fds[2]) { - fd_t *f = fd_get (fd); + int ret = 0; - if (!f) - return 0; + asm volatile ( + "movl $55, %%eax;" + "movl %1, %%ebx;" + "int $0x80;" + "movl %%eax, %0;": "=g" (ret) : "g" (fds) : "%eax", "%ebx"); - if (f->flags & FD_SOCK) // socket close - sclose (fd); - f->id = 0; - f->flags = 0; - f->e = 0; + return ret; +} - /* delete old file descriptor from fd_list */ - f->next->prev = f->prev; - f->prev->next = f->next; - - return 1; -} - -- 2.11.4.GIT