Search code examples
pythonoutputstdoutscapyarp

ValueError: I/O operation on closed file error


i need help please i try to solve this issue since 2 days ago without success and im new in python please do changes in the code and explain :

this is the code it's and arp scanner via scapy it's take the result from scapy scanning and save the result's of scanning ( ip's and macaddress ) to txt file in linux machine

and then run an external python script called ( doublepulsar-detection-script ) via this command : os.system("python detect_doublepulsar_smb.py --file last.txt")

last.txt = the files contains scapy scanning result's

but when the scanning done i got this error :

Traceback (most recent call last): File "test.py", line 116, in lena = int(raw_input("Enter Number : ")) ValueError: I/O operation on closed file

this is full code :

logging.basicConfig(format='%(asctime)s %(levelname)-5s %(message)s',  datefmt='%Y-%m-%d %H:%M:%S', level=logging.DEBUG)
logger = logging.getLogger(__name__)


def long2net(arg):
if (arg <= 0 or arg >= 0xFFFFFFFF):
    raise ValueError("illegal netmask value", hex(arg))
return 32 - int(round(math.log(0xFFFFFFFF - arg, 2)))


def to_CIDR_notation(bytes_network, bytes_netmask):
network = scapy.utils.ltoa(bytes_network)
netmask = long2net(bytes_netmask)
net = "%s/%s" % (network, netmask)
if netmask < 16:
    logger.warn("%s is too big. skipping" % net)
    return None

return net


def scan_and_print_neighbors(net, interface, timeout=1):
logger.info("arping %s on %s" % (net, interface))
try:
    ans, unans = scapy.layers.l2.arping(net, iface=interface, timeout=timeout, verbose=True)
    for s, r in ans.res:
        line = r.sprintf("%Ether.src%  %ARP.psrc%")
        try:
            hostname = socket.gethostbyaddr(r.psrc)
            line += " " + hostname[0]
        except socket.herror:
            # failed to resolve
            pass
        logger.info(line)
except socket.error as e:
    if e.errno == errno.EPERM:     # Operation not permitted
        logger.error("%s. Did you run as root?", e.strerror)
    else:
        raise

while True:

lena = int(raw_input("Enter Number : "))
print(lena)


if __name__ == "__main__":
    import sys
    import os 
    import time


    sys.stdout = open('textout.txt', 'w+')

    if lena == 1:
        for network, netmask, _, interface, address in scapy.config.conf.route.routes:
            # skip loopback network and default gw
            if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
                continue

            if netmask <= 0 or netmask == 0xFFFFFFFF:
                continue

        net = to_CIDR_notation(network, netmask)
        if interface != scapy.config.conf.iface:
            # see http://trac.secdev.org/scapy/ticket/537
            logger.warn("skipping %s because scapy currently doesn't support arping on non-primary network interfaces", net)

        if net:
            scan_and_print_neighbors(net, interface)

            sys.stdout.close()

            os.system("awk 'NR > 2 {print $2}' textout.txt > last.txt")

            os.system("python detect_doublepulsar_smb.py --file last.txt")


    elif lena == 3 :
        print("bye Bye")
        break

Solution

  • The issue is in your code where it closes the standard out file handler, but then later the input is trying to write "Enter Number : " to it.

        if net:
            scan_and_print_neighbors(net, interface)
    
            sys.stdout.close() # <<<
    

    For a quick fix, save the standard stdout in a different variable, then redirect to it after that close.

    if __name__ == "__main__":
        import sys
        import os 
        import time
    
        saved_stdout = sys.stdout
        sys.stdout = open('textout.txt', 'w+')
    
        ... 
    
        sys.stdout.close()
        sys.stdout = saved_stdout