Permalink
Browse files

Fix another file descriptor bug by removing 'import cgi'.

- Add util.Debug() which logs to a file specified by --debug-file.
- Add configure-bug to the list of passing.

All gold, spec, and unit tests pass!  Finally.
  • Loading branch information...
Andy Chu
Andy Chu committed Sep 4, 2018
1 parent 94c7d78 commit 4222f453c58b861205eb68ca5b46dd82ba69d7cf
Showing with 63 additions and 7 deletions.
  1. +18 −0 asdl/cgi.py
  2. +1 −4 asdl/format.py
  3. +5 −0 bin/oil.py
  4. +18 −3 core/process.py
  5. +20 −0 core/util.py
  6. +1 −0 test/gold.sh
View
@@ -0,0 +1,18 @@
#!/usr/bin/python
"""
cgi.py - Copied from Python stdlib.
We don't want the side effects of importing tempfile, which imports random,
which opens /dev/urandom!
"""
def escape(s, quote=None):
'''Replace special characters "&", "<" and ">" to HTML-safe sequences.
If the optional flag quote is true, the quotation mark character (")
is also translated.'''
s = s.replace("&", "&amp;") # Must be done first!
s = s.replace("<", "&lt;")
s = s.replace(">", "&gt;")
if quote:
s = s.replace('"', "&quot;")
return s
View
@@ -16,13 +16,10 @@
"""
from asdl import asdl_ as asdl
from asdl import cgi
from asdl import pretty
from core import util
import os
if not os.getenv('_OVM_DEPS'):
import cgi
def DetectConsoleOutput(f):
"""Wrapped to auto-detect."""
View
@@ -109,6 +109,7 @@ def OshMain(argv0, argv, login_shell):
spec.LongFlag('--print-status') # TODO: Replace with a shell hook
spec.LongFlag('--hijack-shebang') # TODO: Implement this
spec.LongFlag('--debug-file', args.Str)
# For benchmarks/*.sh
spec.LongFlag('--parser-mem-dump', args.Str)
@@ -160,6 +161,10 @@ def OshMain(argv0, argv, login_shell):
builtin.SetExecOpts(exec_opts, opts.opt_changes)
aliases = {} # feedback between runtime and parser
if opts.debug_file:
util.DEBUG_FILE = fd_state.Open(opts.debug_file, mode='w')
util.Debug('Debug file is %s', util.DEBUG_FILE)
ex = cmd_exec.Executor(mem, fd_state, status_lines, funcs, readline,
completion, comp_lookup, exec_opts, arena, aliases)
View
@@ -52,6 +52,13 @@ def __init__(self, next_fd=10):
self.stack = [self.cur_frame]
def _NextFreeFileDescriptor(self):
"""Return a free file descriptor above 10 that isn't used.
NOTE: This doesn't seem to solve all file descriptor problems, and I
don't understand why! This fixed 'test/gold.sh configure-bug', I still
had ANOTHER bug with 'test/gold.sh nix' that wasn't fixed. That required
removing the 'import cgi'.
"""
done = False
while not done:
try:
@@ -63,7 +70,7 @@ def _NextFreeFileDescriptor(self):
return self.next_fd
def Open(self, path):
def Open(self, path, mode='r'):
"""Opens a path for read, but moves it out of the reserved 3-9 fd range.
Returns:
@@ -72,11 +79,18 @@ def Open(self, path):
Raises:
OSError if the path can't be found.
"""
fd = os.open(path, os.O_RDONLY, 0666)
if mode == 'r':
fd_mode = os.O_RDONLY
elif mode == 'w':
fd_mode = os.O_CREAT | os.O_RDWR
else:
raise AssertionError(mode)
fd = os.open(path, fd_mode, 0666)
new_fd = self._NextFreeFileDescriptor()
os.dup2(fd, new_fd)
os.close(fd)
return os.fdopen(new_fd)
return os.fdopen(new_fd, mode)
def _PushDup(self, fd1, fd2):
"""Save fd2, and dup fd1 onto fd2.
@@ -264,6 +278,7 @@ def Pop(self):
# NOTE: This balances the increments from _PushDup(). But it doesn't
# balance the ones from Open().
self.next_fd -= 1 # Count down
assert self.next_fd >= 10, self.next_fd
for fd in frame.need_close:
#log('Close %d', fd)
View
@@ -249,3 +249,23 @@ def ShowAppVersion(app_name):
print('Bytecode: %s' % pyc_version)
# This was useful for debugging.
def ShowFdState():
import subprocess
subprocess.call(['ls', '-l', '/proc/%d/fd' % os.getpid()])
# NOTE: Should there be one of these per process?
DEBUG_FILE = None
def Debug(msg, *args):
if not DEBUG_FILE:
return
if args:
msg = msg % args
# TODO: Don't get pid every time
msg = '%d %s' % (os.getpid(), msg)
print(msg, file=DEBUG_FILE)
View
@@ -125,6 +125,7 @@ readonly -a PASSING=(
#version-text
configure
configure-bug
nix
and-or

0 comments on commit 4222f45

Please sign in to comment.