From f170cc6f64b3849556dc5df2cd6992edd5031d8b Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Thu, 13 Dec 2018 08:56:42 +0000 Subject: [PATCH] cli: ignore EINTR caused by SIGWINCH when calling poll() This can happen when adjusting a tmux pane running mininet cli. The process will receive SIGWINCH causing the poll() call to raise select.error Below is a session dump with strace 09:55:52.498106 poll([{fd=0, events=POLLIN}, {fd=28, events=POLLIN}], 2, -1) = ? ERESTART_RESTARTBLOCK (Interrupted by signal) 09:55:52.606734 --- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} --- 09:55:52.606770 rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call) Traceback (most recent call last): File "examples/topofac.py", line 527, in run() File "examples/topofac.py", line 522, in run CLI( net ) File "/home/yunion/git-repo/mininet/mininet/cli.py", line 68, in __init__ self.run() File "/home/yunion/git-repo/mininet/mininet/cli.py", line 103, in run self.cmdloop() File "/home/yunion/.usr/lib/python2.7/cmd.py", line 142, in cmdloop stop = self.onecmd(line) File "/home/yunion/.usr/lib/python2.7/cmd.py", line 220, in onecmd return self.default(line) File "/home/yunion/git-repo/mininet/mininet/cli.py", line 422, in default self.waitForNode( node ) File "/home/yunion/git-repo/mininet/mininet/cli.py", line 440, in waitForNode bothPoller.poll() select.error: (4, 'Interrupted system call') 09:55:52.622076 rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7ff9a9b936d0}, {0x7ff9a9ef2230, [], SA_RESTORER, 0x7ff9a9b936d0}, 8) = 0 09:55:52.631905 +++ exited with 1 +++ --- mininet/cli.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mininet/cli.py b/mininet/cli.py index 5b4a292..a4cecaa 100644 --- a/mininet/cli.py +++ b/mininet/cli.py @@ -29,6 +29,8 @@ from subprocess import call from cmd import Cmd from os import isatty from select import poll, POLLIN +import select +import errno import sys import time import os @@ -459,6 +461,13 @@ class CLI( Cmd ): # it's possible to interrupt ourselves after we've # read data but before it has been printed. node.sendInt() + except select.error as e: + # pylint: disable=unpacking-non-sequence + errno_, errmsg = e.args + # pylint: enable=unpacking-non-sequence + if errno_ != errno.EINTR: + error( "select.error: %d, %s" % (errno_, errmsg) ) + node.sendInt() def precmd( self, line ): "allow for comments in the cli"