diff --git a/src/scheme/pipe.rs b/src/scheme/pipe.rs
index 330b869510ecaee0d43ec0d1962a611ba05be713..9bd5f6790c948b11f585213298c65146fe9cfd86 100644
--- a/src/scheme/pipe.rs
+++ b/src/scheme/pipe.rs
@@ -2,11 +2,12 @@ use alloc::arc::{Arc, Weak};
 use collections::{BTreeMap, VecDeque};
 use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 use spin::{Mutex, Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
-use scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId};
 
+use context;
+use scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId};
 use sync::WaitCondition;
 use syscall::error::{Error, Result, EAGAIN, EBADF, EINVAL, EPIPE, ESPIPE};
-use syscall::flag::{F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK, MODE_FIFO};
+use syscall::flag::{EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK, MODE_FIFO};
 use syscall::scheme::Scheme;
 use syscall::data::Stat;
 
@@ -32,10 +33,11 @@ fn pipes_mut() -> RwLockWriteGuard<'static, (BTreeMap<usize, Arc<PipeRead>>, BTr
 
 pub fn pipe(flags: usize) -> (usize, usize) {
     let mut pipes = pipes_mut();
+    let scheme_id = PIPE_SCHEME_ID.load(Ordering::SeqCst);
     let read_id = PIPE_NEXT_ID.fetch_add(1, Ordering::SeqCst);
     let write_id = PIPE_NEXT_ID.fetch_add(1, Ordering::SeqCst);
-    let read = PipeRead::new(flags);
-    let write = PipeWrite::new(flags, &read);
+    let read = PipeRead::new(scheme_id, read_id, flags);
+    let write = PipeWrite::new(&read, flags);
     pipes.0.insert(read_id, Arc::new(read));
     pipes.1.insert(write_id, Arc::new(write));
     (read_id, write_id)
@@ -117,6 +119,16 @@ impl Scheme for PipeScheme {
         Err(Error::new(EBADF))
     }
 
+    fn fevent(&self, id: usize, flags: usize) -> Result<usize> {
+        let pipes = pipes();
+
+        if let Some(pipe) = pipes.0.get(&id) {
+            return pipe.fevent(flags);
+        }
+
+        Err(Error::new(EBADF))
+    }
+
     fn fpath(&self, _id: usize, buf: &mut [u8]) -> Result<usize> {
         let mut i = 0;
         let scheme_path = b"pipe:";
@@ -156,14 +168,18 @@ impl Scheme for PipeScheme {
 
 /// Read side of a pipe
 pub struct PipeRead {
+    scheme_id: SchemeId,
+    event_id: usize,
     flags: AtomicUsize,
     condition: Arc<WaitCondition>,
     vec: Arc<Mutex<VecDeque<u8>>>
 }
 
 impl PipeRead {
-    pub fn new(flags: usize) -> Self {
+    pub fn new(scheme_id: SchemeId, event_id: usize, flags: usize) -> Self {
         PipeRead {
+            scheme_id: scheme_id,
+            event_id: event_id,
             flags: AtomicUsize::new(flags),
             condition: Arc::new(WaitCondition::new()),
             vec: Arc::new(Mutex::new(VecDeque::new())),
@@ -172,6 +188,8 @@ impl PipeRead {
 
     fn dup(&self) -> Result<Self> {
         Ok(PipeRead {
+            scheme_id: self.scheme_id,
+            event_id: self.event_id,
             flags: AtomicUsize::new(self.flags.load(Ordering::SeqCst)),
             condition: self.condition.clone(),
             vec: self.vec.clone()
@@ -189,6 +207,10 @@ impl PipeRead {
         }
     }
 
+    fn fevent(&self, _flags: usize) -> Result<usize> {
+        Ok(self.event_id)
+    }
+
     fn read(&self, buf: &mut [u8]) -> Result<usize> {
         loop {
             {
@@ -222,14 +244,18 @@ impl PipeRead {
 
 /// Read side of a pipe
 pub struct PipeWrite {
+    scheme_id: SchemeId,
+    event_id: usize,
     flags: AtomicUsize,
     condition: Arc<WaitCondition>,
     vec: Option<Weak<Mutex<VecDeque<u8>>>>
 }
 
 impl PipeWrite {
-    pub fn new(flags: usize, read: &PipeRead) -> Self {
+    pub fn new(read: &PipeRead, flags: usize) -> Self {
         PipeWrite {
+            scheme_id: read.scheme_id,
+            event_id: read.event_id,
             flags: AtomicUsize::new(flags),
             condition: read.condition.clone(),
             vec: Some(Arc::downgrade(&read.vec)),
@@ -238,6 +264,8 @@ impl PipeWrite {
 
     fn dup(&self) -> Result<Self> {
         Ok(PipeWrite {
+            scheme_id: self.scheme_id,
+            event_id: self.event_id,
             flags: AtomicUsize::new(self.flags.load(Ordering::SeqCst)),
             condition: self.condition.clone(),
             vec: self.vec.clone()
@@ -258,12 +286,17 @@ impl PipeWrite {
     fn write(&self, buf: &[u8]) -> Result<usize> {
         if let Some(ref vec_weak) = self.vec {
             if let Some(vec_lock) = vec_weak.upgrade() {
-                let mut vec = vec_lock.lock();
+                let len = {
+                    let mut vec = vec_lock.lock();
 
-                for &b in buf.iter() {
-                    vec.push_back(b);
-                }
+                    for &b in buf.iter() {
+                        vec.push_back(b);
+                    }
+
+                    vec.len()
+                };
 
+                context::event::trigger(self.scheme_id, self.event_id, EVENT_READ, len);
                 self.condition.notify();
 
                 Ok(buf.len())
@@ -279,6 +312,7 @@ impl PipeWrite {
 impl Drop for PipeWrite {
     fn drop(&mut self) {
         drop(self.vec.take());
+        context::event::trigger(self.scheme_id, self.event_id, EVENT_READ, 0);
         self.condition.notify();
     }
 }
diff --git a/src/syscall/debug.rs b/src/syscall/debug.rs
new file mode 100644
index 0000000000000000000000000000000000000000..fee98c06d604808f8fdd808ca85ba1503b2fb8f3
--- /dev/null
+++ b/src/syscall/debug.rs
@@ -0,0 +1,66 @@
+use super::number::*;
+
+pub fn name(call: usize) -> &'static str {
+    match call {
+        SYS_LINK => "LINK",
+        SYS_OPEN => "OPEN",
+        SYS_CHMOD => "CHMOD",
+        SYS_RMDIR => "RMDIR",
+        SYS_UNLINK => "UNLINK",
+
+        SYS_CLOSE => "CLOSE",
+        SYS_DUP => "DUP",
+        SYS_DUP2 => "DUP2",
+        SYS_READ => "READ",
+        SYS_WRITE => "WRITE",
+        SYS_LSEEK => "LSEEK",
+        SYS_FCNTL => "FCNTL",
+        SYS_FEVENT => "FEVENT",
+        SYS_FMAP => "FMAP",
+        SYS_FUNMAP => "FUNMAP",
+        SYS_FPATH => "FPATH",
+        SYS_FSTAT => "FSTAT",
+        SYS_FSTATVFS => "FSTATVFS",
+        SYS_FSYNC => "FSYNC",
+        SYS_FTRUNCATE => "FTRUNCATE",
+        SYS_FUTIMENS => "FUTIMENS",
+
+        SYS_BRK => "BRK",
+        SYS_CHDIR => "CHDIR",
+        SYS_CLOCK_GETTIME => "CLOCK_GETTIME",
+        SYS_CLONE => "CLONE",
+        SYS_EXECVE => "EXECVE",
+        SYS_EXIT => "EXIT",
+        SYS_FUTEX => "FUTEX",
+        SYS_GETCWD => "GETCWD",
+        SYS_GETEGID => "GETEGID",
+        SYS_GETENS => "GETENS",
+        SYS_GETEUID => "GETEUID",
+        SYS_GETGID => "GETGID",
+        SYS_GETNS => "GETNS",
+        SYS_GETPID => "GETPID",
+        SYS_GETPGID => "GETPGID",
+        SYS_GETPPID => "GETPPID",
+        SYS_GETUID => "GETUID",
+        SYS_IOPL => "IOPL",
+        SYS_KILL => "KILL",
+        SYS_MKNS => "MKNS",
+        SYS_NANOSLEEP => "NANOSLEEP",
+        SYS_PHYSALLOC => "PHYSALLOC",
+        SYS_PHYSFREE => "PHYSFREE",
+        SYS_PHYSMAP => "PHYSMAP",
+        SYS_PHYSUNMAP => "PHYSUNMAP",
+        SYS_VIRTTOPHYS => "VIRTTOPHYS",
+        SYS_PIPE2 => "PIPE2",
+        SYS_SETPGID => "SETPGID",
+        SYS_SETREGID => "SETREGID",
+        SYS_SETRENS => "SETRENS",
+        SYS_SETREUID => "SETREUID",
+        SYS_SIGACTION => "SIGACTION",
+        SYS_SIGRETURN => "SIGRETURN",
+        SYS_WAITPID => "WAITPID",
+        SYS_YIELD => "YIELD",
+
+        _ => "?",
+    }
+}
diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs
index a443d72063e1a426a6899e56b9f932e73274f779..f3181b147a70e42c4a1d364a0d6ce843d9700607 100644
--- a/src/syscall/mod.rs
+++ b/src/syscall/mod.rs
@@ -20,6 +20,9 @@ use context::ContextId;
 use interrupt::syscall::SyscallStack;
 use scheme::{FileHandle, SchemeNamespace};
 
+/// Debug
+pub mod debug;
+
 /// Driver syscalls
 pub mod driver;
 
@@ -130,17 +133,54 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
         }
     }
 
+    /*
+    let debug = {
+        let contexts = ::context::contexts();
+        if let Some(context_lock) = contexts.current() {
+            let context = context_lock.read();
+            if unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) } == "file:/bin/acid" {
+                if (a == SYS_WRITE || a == SYS_FSYNC) && (b == 1 || b == 2) {
+                    false
+                } else {
+                    true
+                }
+            } else {
+                false
+            }
+        } else {
+            false
+        }
+    };
+
+    if debug {
+        let contexts = ::context::contexts();
+        if let Some(context_lock) = contexts.current() {
+            let context = context_lock.read();
+            print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into());
+        }
+
+        println!("{} ({:X}), {:X}, {:X}, {:X}", debug::name(a), a, b, c, d);
+    }
+    */
+
     let result = inner(a, b, c, d, e, f, bp, stack);
 
     /*
-    if let Err(ref err) = result {
+    if debug {
         let contexts = ::context::contexts();
         if let Some(context_lock) = contexts.current() {
             let context = context_lock.read();
-            print!("{}: {}: ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into());
+            print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into());
         }
 
-        println!("{:X}, {:X}, {:X}, {:X}: {}", a, b, c, d, err);
+        match result {
+            Ok(ref ok) => {
+                println!("{} ({:X}), {:X}, {:X}, {:X}: Ok({:X})", debug::name(a), a, b, c, d, ok);
+            },
+            Err(ref err) => {
+                println!("{} ({:X}), {:X}, {:X}, {:X}: Err({} ({:X}))", debug::name(a), a, b, c, d, err, err.errno);
+            }
+        }
     }
     */