#
#Help on built-in function sendmsg:
#
#sendmsg(...)
#    sendmsg(data,[addr,[[(msg-level,msg-type,msg-data),...],[flags]]]) ->
#    sendlen
#
#    Send data over a socket. You can additionally send ancilliary messages
#    over the socket by specifying them as a list (or any other iterable).
#    All other parameters are just as they are to sendto().
#
#
#Help on built-in function recvmsg:
#
#recvmsg(...)
#    recvmsg(len,[addr,[ancmsg,[flags]]]) ->
#    (data,[data,...],msg_flags)
#
#    Receive data (and possible ancilliary messages) from the remote end
#    of this socket. Ancilliary messages are split into tuples, which are
#    then returned as a list. In case no message is available, returns an
#    empty list. Otherwise the function is similar to recv().



import socket
import os
import struct

sp = socket.socketpair(socket.AF_UNIX, socket.SOCK_SEQPACKET)

pid = os.fork()
if pid == 0:
	ipc = sp[0]
	sp[1].close()
	print "[+] Child forked"
	fp = ipc.recvmsg(1)[1][0][0]
	print "[+] Child received the file descriptor, the contents:"
	print(fp.read(10000))
else:
	ipc = sp[1]
	sp[0].close()

	fp = open("/etc/passwd")

	print "[+] Parent forked child with pid", pid
	ret = ipc.sendmsg("x", None, [(socket.SOL_SOCKET, socket.SCM_RIGHTS,
			  struct.pack("i", fp.fileno()))], 0)
	print "[+] Parent has sent the open file descriptor"

