import os,glob,re
def cmdline(pid):
    try:
        with open('/proc/'+pid+'/cmdline','rb') as f:
            return f.read().replace(b'\x00',b' ').decode(errors='replace')[:120]
    except: return '?'
def inode_of_socket_fd(pid, fd):
    try:
        return os.readlink('/proc/'+pid+'/fd/'+fd)
    except: return None
# find listening inode on 9000
inode=None
with open('/proc/net/tcp') as f:
    for line in f:
        parts=line.split()
        if len(parts)>=10 and parts[1]=='0100007F:2328' and parts[3]=='0A':
            inode=parts[9]; print('LISTEN inode =',inode,'line=',line.strip())
print('searching processes for socket inode', inode)
for pid in glob.glob('/proc/[0-9]*'):
    pid=pid.split('/')[-1]
    try:
        fds=os.listdir('/proc/'+pid+'/fd')
    except:
        continue
    for fd in fds:
        t=inode_of_socket_fd(pid,fd)
        if t and t.startswith('socket:[') and t==('socket:['+inode+']'):
            print('MATCH PID',pid,'cmdline:',cmdline(pid))
# Also: report all processes that CAN list their fd (to know what's readable)
readable=[]
for pid in glob.glob('/proc/[0-9]*'):
    pid=pid.split('/')[-1]
    try:
        n=len(os.listdir('/proc/'+pid+'/fd')); readable.append((pid,n))
    except: pass
print('readable fd procs:', readable)
# dump all listeners on 9000-related ports just in case
with open('/proc/net/tcp') as f:
    for line in f:
        parts=line.split()
        if len(parts)>=10 and parts[3]=='0A' and parts[1].endswith(':2328'):
            print('TCP-LISTEN',line.strip())
