# Path: sio/workers/ft.py
# def get_url_hash(filetracker_url):
# def get_cache_dir(filetracker_url):
# def init_instance(filetracker_url):
# def instance():
# def set_instance(client):
# def _use_filetracker(name, environ):
# def download(environ, key, dest=None, skip_if_exists=False, **kwargs):
# def upload(environ, key, source, dest=None, **kwargs):
# def _do_launch():
# def launch_filetracker_server():
# 
# Path: sio/workers/executors.py
# class DetailedUnprotectedExecutor(UnprotectedExecutor):
#     """This executor returns extended process status (over UnprotectedExecutor.)
# 
#     .. note:: It reserves process stderr for time counting, so ``stderr``
#               arg is ignored.
# 
#     This class adds the following keys to ``renv``:
# 
#       ``time_used``: Linux user-time used by process
# 
#       ``result_code``: TLE, OK, RE.
# 
#       ``result_string``: string describing ``result_code``
#     """
# 
#     def _execute(self, command, **kwargs):
#         command = ['bash', '-c', [noquote('time')] + command]
#         stderr = tempfile.TemporaryFile()
#         kwargs['stderr'] = stderr
#         kwargs['forward_stderr'] = False
#         renv = super(DetailedUnprotectedExecutor, self)._execute(command, **kwargs)
#         stderr.seek(0)
#         output = stderr.read()
#         stderr.close()
#         time_output_matches = TIME_OUTPUT_RE.findall(output.decode())
#         if time_output_matches:
#             mins, secs = time_output_matches[-1]
#             renv['time_used'] = int((int(mins) * 60 + float(secs)) * 1000)
#         elif 'real_time_killed' in renv:
#             renv['time_used'] = renv['real_time_used']
#         else:
#             raise RuntimeError(
#                 'Could not find output of time program. ' 'Captured output: %s' % output
#             )
# 
#         if (
#             kwargs['time_limit'] is not None
#             and renv['time_used'] >= 0.95 * kwargs['time_limit']
#         ):
#             renv['result_string'] = 'time limit exceeded'
#             renv['result_code'] = 'TLE'
#         elif 'real_time_killed' in renv:
#             renv['result_string'] = 'real time limit exceeded'
#             renv['result_code'] = 'TLE'
#         elif renv['return_code'] == 0:
#             renv['result_string'] = 'ok'
#             renv['result_code'] = 'OK'
#         elif renv['return_code'] > 128:  # os.WIFSIGNALED(1) returns True
#             renv['result_string'] = 'program exited due to signal %d' % os.WTERMSIG(
#                 renv['return_code']
#             )
#             renv['result_code'] = 'RE'
#         else:
#             renv['result_string'] = 'program exited with code %d' % renv['return_code']
#             renv['result_code'] = 'RE'
# 
#         renv['mem_used'] = 0
#         renv['num_syscalls'] = 0
# 
#         return renv
# 
# class SupervisedExecutor(_SIOSupervisedExecutor):
#     """Executes program in supervised mode.
# 
#        Sandboxing limitations may be controlled by passing following arguments
#        to constructor:
# 
#          ``allow_local_open`` Allow opening files within current directory in \
#                               read-only mode
# 
#          ``use_program_return_code`` Makes supervisor pass the program return \
#                                      code to renv['return_code'] rather than \
#                                      the sandbox return code.
# 
#        Following new arguments are recognized in ``__call__``:
# 
#           ``ignore_return`` Do not treat non-zero return code as runtime error.
# 
#           ``java_sandbox`` Sandbox name with JRE.
# 
#        Executed programs may only use stdin/stdout/stderr and manage it's
#        own memory. Returns extended statistics in ``renv`` containing:
# 
#        ``time_used``: processor user time (in ms).
# 
#        ``mem_used``: memory used (in KiB).
# 
#        ``num_syscall``: number of times a syscall has been called
# 
#        ``result_code``: short code reporting result of rule obeying. Is one of \
#                         ``OK``, ``RE``, ``TLE``, ``OLE``, ``MLE``, ``RV``
# 
#        ``result_string``: string describing ``result_code``
#     """
# 
#     def __init__(self, allow_local_open=False, use_program_return_code=False, **kwargs):
#         self.options = ['-q', '-f', '3']
#         if allow_local_open:
#             self.options += ['-l']
#         if use_program_return_code:
#             self.options += ['-r']
#         super(SupervisedExecutor, self).__init__('exec-sandbox', **kwargs)
# 
#     def _execute(self, command, **kwargs):
#         options = self.options
#         if kwargs.get('ignore_return', False):
#             options = options + ['-R']
# 
#         if kwargs.get('java_sandbox', ''):
#             java = get_sandbox(kwargs['java_sandbox'])
#             options = options + ['-j', os.path.join(java.path, 'usr', 'bin', 'java')]
#         else:
#             # Null context-manager
#             java = null_ctx_manager()
# 
#         command = [os.path.join(self.rpath, 'bin', 'supervisor')] + options + command
#         with java:
#             return super(SupervisedExecutor, self)._execute(command, **kwargs)
# 
# Path: sio/workers/util.py
# def tempcwd(path=None):
#     # Someone might call tempcwd twice, i.e. tempcwd(tempcwd('something'))
#     # Do nothing in this case.
#     if path is not None and os.path.isabs(path):
#         return path
#     d = threadlocal_dir.tmpdir
#     if path:
#         return os.path.join(d, path)
#     else:
#         return d


import logging
import os
from sio.workers import ft
from sio.workers.executors import DetailedUnprotectedExecutor, SupervisedExecutor
from sio.workers.util import tempcwd
from __future__ import absolute_import


logger = logging.getLogger(__name__)

DEFAULT_INWER_TIME_LIMIT = 300000  # in ms
DEFAULT_INWER_MEM_LIMIT = 256 * 2 ** 10  # in KiB

# Path: sio/workers/ft.py
# def get_url_hash(filetracker_url):
# def get_cache_dir(filetracker_url):
# def init_instance(filetracker_url):
# def instance():
# def set_instance(client):
# def _use_filetracker(name, environ):
# def download(environ, key, dest=None, skip_if_exists=False, **kwargs):
# def upload(environ, key, source, dest=None, **kwargs):
# def _do_launch():
# def launch_filetracker_server():
# 
# Path: sio/workers/executors.py
# class DetailedUnprotectedExecutor(UnprotectedExecutor):
#     """This executor returns extended process status (over UnprotectedExecutor.)
# 
#     .. note:: It reserves process stderr for time counting, so ``stderr``
#               arg is ignored.
# 
#     This class adds the following keys to ``renv``:
# 
#       ``time_used``: Linux user-time used by process
# 
#       ``result_code``: TLE, OK, RE.
# 
#       ``result_string``: string describing ``result_code``
#     """
# 
#     def _execute(self, command, **kwargs):
#         command = ['bash', '-c', [noquote('time')] + command]
#         stderr = tempfile.TemporaryFile()
#         kwargs['stderr'] = stderr
#         kwargs['forward_stderr'] = False
#         renv = super(DetailedUnprotectedExecutor, self)._execute(command, **kwargs)
#         stderr.seek(0)
#         output = stderr.read()
#         stderr.close()
#         time_output_matches = TIME_OUTPUT_RE.findall(output.decode())
#         if time_output_matches:
#             mins, secs = time_output_matches[-1]
#             renv['time_used'] = int((int(mins) * 60 + float(secs)) * 1000)
#         elif 'real_time_killed' in renv:
#             renv['time_used'] = renv['real_time_used']
#         else:
#             raise RuntimeError(
#                 'Could not find output of time program. ' 'Captured output: %s' % output
#             )
# 
#         if (
#             kwargs['time_limit'] is not None
#             and renv['time_used'] >= 0.95 * kwargs['time_limit']
#         ):
#             renv['result_string'] = 'time limit exceeded'
#             renv['result_code'] = 'TLE'
#         elif 'real_time_killed' in renv:
#             renv['result_string'] = 'real time limit exceeded'
#             renv['result_code'] = 'TLE'
#         elif renv['return_code'] == 0:
#             renv['result_string'] = 'ok'
#             renv['result_code'] = 'OK'
#         elif renv['return_code'] > 128:  # os.WIFSIGNALED(1) returns True
#             renv['result_string'] = 'program exited due to signal %d' % os.WTERMSIG(
#                 renv['return_code']
#             )
#             renv['result_code'] = 'RE'
#         else:
#             renv['result_string'] = 'program exited with code %d' % renv['return_code']
#             renv['result_code'] = 'RE'
# 
#         renv['mem_used'] = 0
#         renv['num_syscalls'] = 0
# 
#         return renv
# 
# class SupervisedExecutor(_SIOSupervisedExecutor):
#     """Executes program in supervised mode.
# 
#        Sandboxing limitations may be controlled by passing following arguments
#        to constructor:
# 
#          ``allow_local_open`` Allow opening files within current directory in \
#                               read-only mode
# 
#          ``use_program_return_code`` Makes supervisor pass the program return \
#                                      code to renv['return_code'] rather than \
#                                      the sandbox return code.
# 
#        Following new arguments are recognized in ``__call__``:
# 
#           ``ignore_return`` Do not treat non-zero return code as runtime error.
# 
#           ``java_sandbox`` Sandbox name with JRE.
# 
#        Executed programs may only use stdin/stdout/stderr and manage it's
#        own memory. Returns extended statistics in ``renv`` containing:
# 
#        ``time_used``: processor user time (in ms).
# 
#        ``mem_used``: memory used (in KiB).
# 
#        ``num_syscall``: number of times a syscall has been called
# 
#        ``result_code``: short code reporting result of rule obeying. Is one of \
#                         ``OK``, ``RE``, ``TLE``, ``OLE``, ``MLE``, ``RV``
# 
#        ``result_string``: string describing ``result_code``
#     """
# 
#     def __init__(self, allow_local_open=False, use_program_return_code=False, **kwargs):
#         self.options = ['-q', '-f', '3']
#         if allow_local_open:
#             self.options += ['-l']
#         if use_program_return_code:
#             self.options += ['-r']
#         super(SupervisedExecutor, self).__init__('exec-sandbox', **kwargs)
# 
#     def _execute(self, command, **kwargs):
#         options = self.options
#         if kwargs.get('ignore_return', False):
#             options = options + ['-R']
# 
#         if kwargs.get('java_sandbox', ''):
#             java = get_sandbox(kwargs['java_sandbox'])
#             options = options + ['-j', os.path.join(java.path, 'usr', 'bin', 'java')]
#         else:
#             # Null context-manager
#             java = null_ctx_manager()
# 
#         command = [os.path.join(self.rpath, 'bin', 'supervisor')] + options + command
#         with java:
#             return super(SupervisedExecutor, self)._execute(command, **kwargs)
# 
# Path: sio/workers/util.py
# def tempcwd(path=None):
#     # Someone might call tempcwd twice, i.e. tempcwd(tempcwd('something'))
#     # Do nothing in this case.
#     if path is not None and os.path.isabs(path):
#         return path
#     d = threadlocal_dir.tmpdir
#     if path:
#         return os.path.join(d, path)
#     else:
#         return d


# Path: sio/executors/inwer.py
import logging
import os
from sio.workers import ft
from sio.workers.executors import DetailedUnprotectedExecutor, SupervisedExecutor
from sio.workers.util import tempcwd

from __future__ import absolute_import


logger = logging.getLogger(__name__)

DEFAULT_INWER_TIME_LIMIT = 300000  # in ms
DEFAULT_INWER_MEM_LIMIT = 256 * 2 ** 10  # in KiB

DEFAULT_INWER_OUTPUT_LIMIT = 10 * 2 ** 10  # in B