annotate c_kernel/kernel.py @ 9:101e99452042

Dockerized project :)
author Brendan Rius <brendan@omixy.com>
date Sat, 26 Mar 2016 14:54:39 +0000
parents aa54c85303b6
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
1 from ipykernel.kernelbase import Kernel
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
2 import subprocess
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
3 import tempfile
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
4 import os
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
5
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
6
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
7 class CKernel(Kernel):
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
8 implementation = 'c_kernel'
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
9 implementation_version = '1.0'
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
10 language = 'c'
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
11 language_version = 'C11'
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
12 language_info = {'name': 'c',
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
13 'mimetype': 'text/plain',
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
14 'file_extension': 'c'}
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
15 banner = "C kernel.\n" \
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
16 "Uses gcc, compiles in C11, and creates source code files and executables in temporary folder.\n"
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
17
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
18 def __init__(self, *args, **kwargs):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
19 super(CKernel, self).__init__(*args, **kwargs)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
20 self.files = []
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
21
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
22 def cleanup_files(self):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
23 """Remove all the temporary files created by the kernel"""
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
24 for file in self.files:
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
25 os.remove(file)
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
26
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
27 def new_temp_file(self, **kwargs):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
28 """Create a new temp file to be deleted when the kernel shuts down"""
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
29 # We don't want the file to be deleted when closed, but only when the kernel stops
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
30 kwargs['delete'] = False
9
101e99452042 Dockerized project :)
Brendan Rius <brendan@omixy.com>
parents: 7
diff changeset
31 kwargs['mode'] = 'w'
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
32 file = tempfile.NamedTemporaryFile(**kwargs)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
33 self.files.append(file.name)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
34 return file
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
35
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
36 @staticmethod
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
37 def execute_command(cmd):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
38 """Execute a command and returns the return code, stdout and stderr"""
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
39 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
40 stdout, stderr = p.communicate()
9
101e99452042 Dockerized project :)
Brendan Rius <brendan@omixy.com>
parents: 7
diff changeset
41 return p.returncode, stdout.decode('utf-8'), stderr.decode('utf-8')
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
42
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
43 @staticmethod
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
44 def compile_with_gcc(source_filename, binary_filename):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
45 args = ['gcc', source_filename, '-std=c11', '-o', binary_filename]
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
46 return CKernel.execute_command(args)
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
47
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
48 def do_execute(self, code, silent, store_history=True,
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
49 user_expressions=None, allow_stdin=False):
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
50
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
51 retcode, stdout, stderr = None, '', ''
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
52 with self.new_temp_file(suffix='.c') as source_file:
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
53 source_file.write(code)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
54 source_file.flush()
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
55 with self.new_temp_file(suffix='.out') as binary_file:
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
56 retcode, stdout, stderr = self.compile_with_gcc(source_file.name, binary_file.name)
3
8ddfdd2a8574 Add retcode to stderr to make errors such as segfaults visible
Brendan Rius <brendan@omixy.com>
parents: 2
diff changeset
57 if retcode != 0:
4
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
58 stderr += "[C kernel] GCC exited with code {}, the executable will not be executed".format(retcode)
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
59 self.log.info("GCC return code: {}".format(retcode))
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
60 self.log.info("GCC stdout: {}".format(stdout))
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
61 self.log.info("GCC stderr: {}".format(stderr))
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
62
4
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
63 if retcode == 0: # If the compilation succeeded
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
64 retcode, out, err = CKernel.execute_command([binary_file.name])
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
65 if retcode != 0:
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
66 stderr += "[C kernel] Executable exited with code {}".format(retcode)
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
67 self.log.info("Executable retcode: {}".format(retcode))
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
68 self.log.info("Executable stdout: {}".format(out))
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
69 self.log.info("Executable stderr: {}".format(err))
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
70 stdout += out
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
71 stderr += err
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
72 else:
5c4b5066fab0 Do not try to execute the executable if compilation failed
Brendan Rius <brendan@omixy.com>
parents: 3
diff changeset
73 self.log.info('Compilation failed, the program will not be executed')
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
74
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
75 if not silent:
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
76 stream_content = {'name': 'stderr', 'text': stderr}
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
77 self.send_response(self.iopub_socket, 'stream', stream_content)
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
78 stream_content = {'name': 'stdout', 'text': stdout}
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
79 self.send_response(self.iopub_socket, 'stream', stream_content)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
80 return {'status': 'ok', 'execution_count': self.execution_count, 'payload': [], 'user_expressions': {}}
7
aa54c85303b6 Remove temporary files when shutting down the kernel
Brendan Rius <brendan@omixy.com>
parents: 4
diff changeset
81
aa54c85303b6 Remove temporary files when shutting down the kernel
Brendan Rius <brendan@omixy.com>
parents: 4
diff changeset
82 def do_shutdown(self, restart):
aa54c85303b6 Remove temporary files when shutting down the kernel
Brendan Rius <brendan@omixy.com>
parents: 4
diff changeset
83 """Cleanup the created source code files and executables when shutting down the kernel"""
aa54c85303b6 Remove temporary files when shutting down the kernel
Brendan Rius <brendan@omixy.com>
parents: 4
diff changeset
84 self.cleanup_files()