Welcome to The Fiwix Project
A UNIX-like kernel for the i386 architecture
1 /* 2 * fiwix/fs/pipefs/fifo.c 3 * 4 * Copyright 2018, Jordi Sanfeliu. All rights reserved. 5 * Distributed under the terms of the Fiwix License. 6 */ 7 8 #include <fiwix/types.h> 9 #include <fiwix/errno.h> 10 #include <fiwix/fs.h> 11 #include <fiwix/filesystems.h> 12 #include <fiwix/fs_pipe.h> 13 #include <fiwix/stat.h> 14 #include <fiwix/mm.h> 15 #include <fiwix/sleep.h> 16 #include <fiwix/fcntl.h> 17 #include <fiwix/sched.h> 18 #include <fiwix/stdio.h> 19 20 int fifo_open(struct inode *i, struct fd *fd_table) 21 { 22 /* first open */ 23 if(i->count == 1) { 24 if(!(i->u.pipefs.i_data = (void *)kmalloc())) { 25 return -ENOMEM; 26 } 27 i->u.pipefs.i_readoff = 0; 28 i->u.pipefs.i_writeoff = 0; 29 } 30 31 if((fd_table->flags & O_ACCMODE) == O_RDONLY) { 32 i->u.pipefs.i_readers++; 33 wakeup(&pipefs_write); 34 if(!(fd_table->flags & O_NONBLOCK)) { 35 while(!i->u.pipefs.i_writers) { 36 if(sleep(&pipefs_read, PROC_INTERRUPTIBLE)) { 37 if(!--i->u.pipefs.i_readers) { 38 wakeup(&pipefs_write); 39 } 40 return -EINTR; 41 } 42 } 43 } 44 } 45 46 if((fd_table->flags & O_ACCMODE) == O_WRONLY) { 47 if((fd_table->flags & O_NONBLOCK) && !i->u.pipefs.i_readers) { 48 return -ENXIO; 49 } 50 51 i->u.pipefs.i_writers++; 52 wakeup(&pipefs_read); 53 if(!(fd_table->flags & O_NONBLOCK)) { 54 while(!i->u.pipefs.i_readers) { 55 if(sleep(&pipefs_write, PROC_INTERRUPTIBLE)) { 56 if(!--i->u.pipefs.i_writers) { 57 wakeup(&pipefs_read); 58 } 59 return -EINTR; 60 } 61 } 62 } 63 } 64 65 if((fd_table->flags & O_ACCMODE) == O_RDWR) { 66 i->u.pipefs.i_readers++; 67 i->u.pipefs.i_writers++; 68 wakeup(&pipefs_write); 69 wakeup(&pipefs_read); 70 } 71 72 return 0; 73 }