Skip to content

Commit

Permalink
Do not raise an exception on EINTR from os.close or os.dup2
Browse files Browse the repository at this point in the history
  • Loading branch information
dashea committed Jun 23, 2015
1 parent a620b47 commit f97feab
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 16 deletions.
2 changes: 1 addition & 1 deletion anaconda
Expand Up @@ -969,7 +969,7 @@ if __name__ == "__main__":
pidfile_created = True
pid_string = "%s\n" % os.getpid()
iutil.eintr_retry_call(os.write, pidfile, pid_string.encode("utf-8"))
os.close(pidfile)
iutil.eintr_ignore(os.close, pidfile)
except FileExistsError:
log.error("%s already exists, exiting", pidfile_path)

Expand Down
2 changes: 1 addition & 1 deletion pyanaconda/anaconda.py
Expand Up @@ -203,7 +203,7 @@ def dumpState(self):
dump_text += threads
dump_text = dump_text.encode("utf-8")
iutil.eintr_retry_call(os.write, fd, dump_text)
os.close(fd)
iutil.eintr_ignore(os.close, fd)

# append to a given file
with open("/tmp/anaconda-tb-all.log", "a+") as f:
Expand Down
10 changes: 5 additions & 5 deletions pyanaconda/bootloader.py
Expand Up @@ -61,7 +61,7 @@ def get_boot_block(device, seek_blocks=0):
if seek_blocks:
os.lseek(fd, seek_blocks * block_size, 0)
block = iutil.eintr_retry_call(os.read, fd, 512)
os.close(fd)
iutil.eintr_ignore(os.close, fd)
if not status:
try:
device.teardown(recursive=True)
Expand Down Expand Up @@ -1347,11 +1347,11 @@ def install(self, args=None):
"stage2dev": self.grub_device_name(stage2dev)})
(pread, pwrite) = os.pipe()
iutil.eintr_retry_call(os.write, pwrite, cmd.encode("utf-8"))
os.close(pwrite)
iutil.eintr_ignore(os.close, pwrite)
args = ["--batch", "--no-floppy",
"--device-map=%s" % self.device_map_file]
rc = iutil.execInSysroot("grub", args, stdin=pread)
os.close(pread)
iutil.eintr_ignore(os.close, pread)
if rc:
raise BootLoaderError("boot loader install failed")

Expand Down Expand Up @@ -1540,11 +1540,11 @@ def _encrypt_password(self):
(pread, pwrite) = os.pipe()
passwords = "%s\n%s\n" % (self.password, self.password)
iutil.eintr_retry_call(os.write, pwrite, passwords.encode("utf-8"))
os.close(pwrite)
iutil.eintr_ignore(os.close, pwrite)
buf = iutil.execWithCapture("grub2-mkpasswd-pbkdf2", [],
stdin=pread,
root=iutil.getSysroot())
os.close(pread)
iutil.eintr_ignore(os.close, pread)
self.encrypted_password = buf.split()[-1].strip()
if not self.encrypted_password.startswith("grub.pbkdf2."):
raise BootLoaderError("failed to encrypt boot loader password")
Expand Down
10 changes: 5 additions & 5 deletions pyanaconda/exception.py
Expand Up @@ -196,11 +196,11 @@ def runDebug(self, exc_info):
iutil.vtActivate(1)

iutil.eintr_retry_call(os.open, "/dev/console", os.O_RDWR) # reclaim stdin
os.dup2(0, 1) # reclaim stdout
os.dup2(0, 2) # reclaim stderr
# ^
# |
# +------ dup2 is magic, I tells ya!
iutil.eintr_ignore(os.dup2, 0, 1) # reclaim stdout
iutil.eintr_ignore(os.dup2, 0, 2) # reclaim stderr
# ^
# |
# +------ dup2 is magic, I tells ya!

# bring back the echo
import termios
Expand Down
14 changes: 13 additions & 1 deletion pyanaconda/iutil.py
Expand Up @@ -1287,7 +1287,7 @@ def ipmi_report(event):
# Event data 2 & 3 - always 0x0 for us
event_string = "0x4 0x1F 0x0 0x6f %#x 0x0 0x0\n" % event
eintr_retry_call(os.write, fd, event_string.encode("utf-8"))
os.close(fd)
eintr_ignore(os.close, fd)

execWithCapture("ipmitool", ["sel", "add", path])

Expand All @@ -1302,6 +1302,18 @@ def eintr_retry_call(func, *args, **kwargs):
except InterruptedError:
continue

def eintr_ignore(func, *args, **kwargs):
"""Call a function and ignore EINTR.
This is useful for calls to close() and dup2(), which can return EINTR
but which should *not* be retried, since by the time the return the
file descriptor is already closed.
"""
try:
return func(*args, **kwargs)
except InterruptedError:
pass

def parent_dir(directory):
"""Return the parent's path"""
return "/".join(os.path.normpath(directory).split("/")[:-1])
Expand Down
2 changes: 1 addition & 1 deletion pyanaconda/kickstart.py
Expand Up @@ -105,7 +105,7 @@ def run(self, chroot):
(fd, path) = tempfile.mkstemp("", "ks-script-", scriptRoot + "/tmp")

iutil.eintr_retry_call(os.write, fd, self.script.encode("utf-8"))
os.close(fd)
iutil.eintr_ignore(os.close, fd)
iutil.eintr_retry_call(os.chmod, path, 0o700)

# Always log stdout/stderr from scripts. Using --log just lets you
Expand Down
4 changes: 2 additions & 2 deletions pyanaconda/vnc.py
Expand Up @@ -88,8 +88,8 @@ def setVNCPassword(self):
rc = iutil.execWithRedirect("vncpasswd", ["-f"],
stdin=r, stdout=pw_file, binary_output=True, log_output=False)

os.close(r)
os.close(w)
iutil.eintr_ignore(os.close, r)
iutil.eintr_ignore(os.close, w)

return rc

Expand Down
1 change: 1 addition & 0 deletions tests/gui/outside/__init__.py
Expand Up @@ -19,6 +19,7 @@

# Ignore any interruptible calls
# pylint: disable=interruptible-system-call
# pylint: disable=ignorable-system-call

__all__ = ["Creator", "OutsideMixin"]

Expand Down

0 comments on commit f97feab

Please sign in to comment.