diff --git a/Dockerfile b/Dockerfile
index 8ff4b8b..38acb16 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
 FROM jupyter/minimal-notebook
-MAINTAINER Brendan Rius <ping@brendan-rius.com>
+MAINTAINER Xaver Klemenschits <klemenschits@iue.tuwien.ac.at>
 
 USER root
 
@@ -7,8 +7,8 @@ WORKDIR /tmp
 
 COPY ./ jupyter_c_kernel/
 
-RUN pip install --no-cache-dir jupyter_c_kernel/
-RUN cd jupyter_c_kernel && install_c_kernel --user
+RUN pip install --no-cache-dir -e jupyter_c_kernel/ > piplog.txt
+RUN cd jupyter_c_kernel && install_c_kernel --user > installlog.txt
 
 WORKDIR /home/$NB_USER/
 
diff --git a/README.md b/README.md
index 7d96ad1..4c9e57a 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,10 @@
 
 ## Use with Docker (recommended)
 
- * `docker pull brendanrius/jupyter-c-kernel`
- * `docker run -p 8888:8888 brendanrius/jupyter-c-kernel`
+ * `docker pull xaverklemenschits/jupyter-c-kernel`
+ * `docker run -p 8888:8888 xaverklemenschits/jupyter-c-kernel`
  * Copy the given URL containing the token, and browse to it. For instance:
- 
+
  ```
  Copy/paste this URL into your browser when you connect for the first time,
  to login with a token:
@@ -24,9 +24,14 @@ Works only on Linux and OS X. Windows is not supported yet. If you want to use t
   * pip
 
 ### Step-by-step:
- * `pip install jupyter-c-kernel`
- * `install_c_kernel`
- * `jupyter-notebook`. Enjoy!
+```bash
+git clone https://github.com/XaverKlemenschits/jupyter-c-kernel.git
+cd jupyter-c-kernel
+pip install -e .
+cd jupyter_c_kernel && install_c_kernel --user
+# now you can start the notebook
+jupyter notebook
+```
 
 ## Example of notebook
 
@@ -47,9 +52,10 @@ change the code in real-time in Docker. For that, just run the docker box like
 that:
 
 ```bash
-git clone https://github.com/brendan-rius/jupyter-c-kernel.git
+git clone https://github.com/XaverKlemenschits/jupyter-c-kernel.git
 cd jupyter-c-kernel
-docker run -v $(pwd):/jupyter/jupyter_c_kernel/ -p 8888:8888 brendanrius/jupyter-c-kernel
+docker build -t myName/jupyter .
+docker run -v $(pwd):/tmp/jupyter_c_kernel/ -p 8888:8888 myName/jupyter
 ```
 
 This clones the source, run the kernel, and binds the current folder (the one
diff --git a/jupyter_c_kernel/install_c_kernel b/jupyter_c_kernel/install_c_kernel
index fcd009d..4b23026 100644
--- a/jupyter_c_kernel/install_c_kernel
+++ b/jupyter_c_kernel/install_c_kernel
@@ -29,7 +29,7 @@ def install_my_kernel_spec(user=True, prefix=None):
         # TODO: Copy resources once they're specified
 
         print('Installing IPython kernel spec')
-        KernelSpecManager().install_kernel_spec(td, 'c', user=user, replace=True, prefix=prefix)
+        KernelSpecManager().install_kernel_spec(td, 'c', user=user, prefix=prefix)
 
 
 def _is_root():
diff --git a/jupyter_c_kernel/kernel.py b/jupyter_c_kernel/kernel.py
index 7ed7e71..81f97a2 100644
--- a/jupyter_c_kernel/kernel.py
+++ b/jupyter_c_kernel/kernel.py
@@ -14,7 +14,9 @@ class RealTimeSubprocess(subprocess.Popen):
     A subprocess that allows to read its stdout and stderr in real time
     """
 
-    def __init__(self, cmd, write_to_stdout, write_to_stderr):
+    inputRequest = "<inputRequest>"
+
+    def __init__(self, cmd, write_to_stdout, write_to_stderr, read_from_stdin):
         """
         :param cmd: the command to execute
         :param write_to_stdout: a callable that will be called with chunks of data from stdout
@@ -22,8 +24,9 @@ class RealTimeSubprocess(subprocess.Popen):
         """
         self._write_to_stdout = write_to_stdout
         self._write_to_stderr = write_to_stderr
+        self._read_from_stdin = read_from_stdin
 
-        super().__init__(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0)
+        super().__init__(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, bufsize=0)
 
         self._stdout_queue = Queue()
         self._stdout_thread = Thread(target=RealTimeSubprocess._enqueue_output, args=(self.stdout, self._stdout_queue))
@@ -60,10 +63,23 @@ class RealTimeSubprocess(subprocess.Popen):
 
         stdout_contents = read_all_from_queue(self._stdout_queue)
         if stdout_contents:
-            self._write_to_stdout(stdout_contents)
+            contents = stdout_contents.decode()
+            # if there is input request, make output and then
+            # ask frontend for input
+            start = contents.find(self.__class__.inputRequest)
+            if(start >= 0):
+                contents = contents.replace(self.__class__.inputRequest, '')
+                if(len(contents) > 0):
+                    self._write_to_stdout(contents)
+                readLine = self._read_from_stdin()
+                self.stdin.write(readLine.encode())
+                self.stdin.write(b"\n")
+            else:
+                self._write_to_stdout(contents)
+
         stderr_contents = read_all_from_queue(self._stderr_queue)
         if stderr_contents:
-            self._write_to_stderr(stderr_contents)
+            self._write_to_stderr(stderr_contents.decode())
 
 
 class CKernel(Kernel):
@@ -71,25 +87,36 @@ class CKernel(Kernel):
     implementation_version = '1.0'
     language = 'c'
     language_version = 'C11'
-    language_info = {'name': 'c',
+    language_info = {'name': 'text/x-csrc',
                      'mimetype': 'text/plain',
                      'file_extension': '.c'}
     banner = "C kernel.\n" \
              "Uses gcc, compiles in C11, and creates source code files and executables in temporary folder.\n"
 
+    main_head = "#include <stdio.h>\n" \
+            "#include <math.h>\n" \
+            "int main(){\n"
+
+    main_foot = "\nreturn 0;\n}"
+
     def __init__(self, *args, **kwargs):
         super(CKernel, self).__init__(*args, **kwargs)
+        self._allow_stdin = True
         self.files = []
         mastertemp = tempfile.mkstemp(suffix='.out')
         os.close(mastertemp[0])
         self.master_path = mastertemp[1]
-        filepath = path.join(path.dirname(path.realpath(__file__)), 'resources', 'master.c')
+        self.resDir = path.join(path.dirname(path.realpath(__file__)), 'resources')
+        filepath = path.join(self.resDir, 'master.c')
         subprocess.call(['gcc', filepath, '-std=c11', '-rdynamic', '-ldl', '-o', self.master_path])
 
     def cleanup_files(self):
         """Remove all the temporary files created by the kernel"""
+        # keep the list of files create in case there is an exception
+        # before they can be deleted as usual
         for file in self.files:
-            os.remove(file)
+            if(os.path.exists(file)):
+                os.remove(file)
         os.remove(self.master_path)
 
     def new_temp_file(self, **kwargs):
@@ -107,10 +134,14 @@ class CKernel(Kernel):
     def _write_to_stderr(self, contents):
         self.send_response(self.iopub_socket, 'stream', {'name': 'stderr', 'text': contents})
 
+    def _read_from_stdin(self):
+        return self.raw_input()
+
     def create_jupyter_subprocess(self, cmd):
         return RealTimeSubprocess(cmd,
-                                  lambda contents: self._write_to_stdout(contents.decode()),
-                                  lambda contents: self._write_to_stderr(contents.decode()))
+                                  self._write_to_stdout,
+                                  self._write_to_stderr,
+                                  self._read_from_stdin)
 
     def compile_with_gcc(self, source_filename, binary_filename, cflags=None, ldflags=None):
         cflags = ['-std=c11', '-fPIC', '-shared', '-rdynamic'] + cflags
@@ -123,6 +154,8 @@ class CKernel(Kernel):
                   'ldflags': [],
                   'args': []}
 
+        actualCode = ''
+
         for line in code.splitlines():
             if line.startswith('//%'):
                 key, value = line[3:].split(":", 2)
@@ -136,12 +169,33 @@ class CKernel(Kernel):
                     for argument in re.findall(r'(?:[^\s,"]|"(?:\\.|[^"])*")+', value):
                         magics['args'] += [argument.strip('"')]
 
-        return magics
+            # only keep lines which did not contain magics
+            else:
+                actualCode += line + '\n'
+
+        return magics, actualCode
+
+    # check whether int main() is specified, if not add it around the code
+    # also add common magics like -lm
+    def _add_main(self, magics, code):
+        x = re.search("int\s+main\s*\(", code)
+        if x is None:
+            code = self.main_head + code + self.main_foot
+            magics['cflags'] += ['-lm']
+
+        return magics, code
 
     def do_execute(self, code, silent, store_history=True,
-                   user_expressions=None, allow_stdin=False):
+                   user_expressions=None, allow_stdin=True):
 
-        magics = self._filter_magics(code)
+        magics, code = self._filter_magics(code)
+
+        magics, code = self._add_main(magics, code)
+
+        # replace stdio with wrapped version
+        headerDir = "\"" + self.resDir + "/stdio_wrap.h" + "\""
+        code = code.replace("<stdio.h>", headerDir)
+        code = code.replace("\"stdio.h\"", headerDir)
 
         with self.new_temp_file(suffix='.c') as source_file:
             source_file.write(code)
@@ -155,6 +209,11 @@ class CKernel(Kernel):
                     self._write_to_stderr(
                             "[C kernel] GCC exited with code {}, the executable will not be executed".format(
                                     p.returncode))
+
+                    # delete source files before exit
+                    os.remove(source_file.name)
+                    os.remove(binary_file.name)
+
                     return {'status': 'ok', 'execution_count': self.execution_count, 'payload': [],
                             'user_expressions': {}}
 
@@ -163,6 +222,10 @@ class CKernel(Kernel):
             p.write_contents()
         p.write_contents()
 
+        # now remove the files we have just created
+        os.remove(source_file.name)
+        os.remove(binary_file.name)
+
         if p.returncode != 0:
             self._write_to_stderr("[C kernel] Executable exited with code {}".format(p.returncode))
         return {'status': 'ok', 'execution_count': self.execution_count, 'payload': [], 'user_expressions': {}}
diff --git a/jupyter_c_kernel/resources/stdio_wrap.h b/jupyter_c_kernel/resources/stdio_wrap.h
new file mode 100644
index 0000000..0374711
--- /dev/null
+++ b/jupyter_c_kernel/resources/stdio_wrap.h
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+/* Replace all the necessary input functions */
+#define scanf(...) printf("<inputRequest>");\
+fflush(stdout);\
+scanf(__VA_ARGS__);
+
+#define getchar() printf("<inputRequest>");\
+fflush(stdout);\
+getchar();