func: static int unix_stream_recvmsg(struct socket *sock, struct msghdr size_t size, int flags) struct unix_stream_read_state state . recv_actor = unix_stream_read_actor . socket = sock . msg = msg . size = size . flags = flags return unix_stream_read_generic ( & state ) ; static int unix_stream_read_generic(struct unix_stream_read_state *state) struct scm_cookie scm ; struct socket * sock = state -> socket ; struct sock * sk = sock -> sk ; int copied = 0 ; int flags = state -> flags ; int noblock = flags & MSG_DONTWAIT ; bool check_creds = false ; int target ; long timeo ; int skip ; size_t size = state -> size ; unsigned int last_len ; err = - EINVAL; if ( sk -> sk_state != TCP_ESTABLISHED )  if ( flags & MSG_OOB )  target = sock_rcvlowat ( sk , flags & MSG_WAITALL , size ); timeo = sock_rcvtimeo ( sk , noblock ); memset ( & scm , 0 , sizeof ( scm ) ); if ( flags & MSG_PEEK )  skip = sk_peek_offset ( sk , flags ); skip = 0; int chunk ; bool drop_skb ; struct sk_buff * skb , * last ; if ( sock_flag ( sk , SOCK_DEAD ) )  last = skb = skb_peek ( & sk -> sk_receive_queue ); last_len = last ? last -> len : 0; if ( skb == NULL )  if ( copied >= target )  err = sock_error ( sk ); if ( err )  if ( sk -> sk_shutdown & RCV_SHUTDOWN )  if ( ! timeo )  timeo = unix_stream_data_wait ( sk , timeo , last , last_len ); static long unix_stream_data_wait(struct sock *sk, long struct sk_buff *last, unsigned int last_len) struct sk_buff * tail ; tail = skb_peek_tail ( & sk -> sk_receive_queue ); if ( tail != last || ( tail && tail -> len != last_len ) || sk -> sk_err || ( sk -> sk_shutdown & RCV_SHUTDOWN ) || signal_pending ( current ) || ! timeo )  timeo = freezable_schedule_timeout ( timeo ); if ( sock_flag ( sk , SOCK_DEAD ) )  return timeo ; if ( signal_pending ( current ) )  while ( skip >= unix_skb_len ( skb ) )  static unsigned int unix_skb_len(const struct sk_buff *skb) return skb -> len - UNIXCB ( skb ) . consumed ; skip -= unix_skb_len ( skb ); static unsigned int unix_skb_len(const struct sk_buff *skb) return skb -> len - UNIXCB ( skb ) . consumed ; last = skb; last_len = skb -> len; skb = skb_peek_next ( skb , & sk -> sk_receive_queue ); if ( ! skb )  if ( check_creds )  if ( ! unix_skb_scm_eq ( skb , & scm ) )  static bool unix_skb_scm_eq(struct sk_buff struct scm_cookie *scm) const struct unix_skb_parms * u = & UNIXCB ( skb ) ; return u -> pid == scm -> pid && uid_eq ( u -> uid , scm -> creds . uid ) && gid_eq ( u -> gid , scm -> creds . gid ) && unix_secdata_eq ( scm , skb ) ; static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb) return ( scm -> secid == UNIXCB ( skb ) . secid ) ; if ( test_bit ( SOCK_PASSCRED , & sock -> flags ) )  check_creds = true; if ( state -> msg && state -> msg -> msg_name )  unix_copy_addr ( state -> msg , skb -> sk ); chunk = min_t ( unsigned int , unix_skb_len ( skb ) - skip , size ) static unsigned int unix_skb_len(const struct sk_buff *skb) return skb -> len - UNIXCB ( skb ) . consumed ; chunk = state -> recv_actor ( skb , skip , chunk , state ); drop_skb = ! unix_skb_len ( skb ); static unsigned int unix_skb_len(const struct sk_buff *skb) return skb -> len - UNIXCB ( skb ) . consumed ; if ( chunk < 0 )  copied += chunk; size -= chunk; if ( drop_skb )  if ( ! ( flags & MSG_PEEK ) )  UNIXCB ( skb ) . consumed += chunk; if ( unix_skb_len ( skb ) )  static unsigned int unix_skb_len(const struct sk_buff *skb) return skb -> len - UNIXCB ( skb ) . consumed ; if ( scm . fp )  if ( UNIXCB ( skb ) . fp )  scm . fp = scm_fp_dup ( UNIXCB ( skb ) . fp ); if ( UNIXCB ( skb ) . fp )  skip = 0; last = skb; last_len = skb -> len; skb = skb_peek_next ( skb , & sk -> sk_receive_queue ); if ( skb )  while ( size )  static void unix_copy_addr(struct msghdr *msg, struct sock *sk) struct unix_sock * u = unix_sk ( sk ) ; if ( u -> addr )  msg -> msg_namelen = u -> addr -> len; memcpy ( msg -> msg_name , u -> addr -> name , u -> addr -> len ); 