patch-2.1.91 linux/net/unix/af_unix.c

Next file: linux/Documentation/Configure.help
Previous file: linux/net/sunrpc/svcsock.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.90/linux/net/unix/af_unix.c linux/net/unix/af_unix.c
@@ -687,17 +687,19 @@
 	 
 		skb=sock_alloc_send_skb(sk, len, 0, nonblock, &err); /* Marker object */
 		if(skb==NULL)
-			return err;
+			goto out;
 		memcpy(&UNIXCB(skb), cmsg, sizeof(*cmsg));
-		if (len)
-			memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
+		if (len) {
+			err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov,
+						len);
+			if (err)
+				goto out_free;
+		}
+
 		sk->state=TCP_CLOSE;
 		other=unix_find_other(sunaddr, addr_len, sk->type, hash, &err);
 		if(other==NULL)
-		{
-			kfree_skb(skb);
-			return err;
-		}
+			goto out_free;
 		other->ack_backlog++;
 		unix_peer(sk)=other;
 		skb_queue_tail(&other->receive_queue,skb);
@@ -738,6 +740,11 @@
 	if (!sk->protinfo.af_unix.addr)
 		unix_autobind(sock);
 	return 0;
+
+out_free:
+	kfree_skb(skb);
+out:
+	return err;
 }
 
 
@@ -908,8 +915,8 @@
 			      struct scm_cookie *scm)
 {
 	struct sock *sk = sock->sk;
-	unix_socket *other;
 	struct sockaddr_un *sunaddr=msg->msg_name;
+	unix_socket *other;
 	int namelen = 0; /* fake GCC */
 	int err;
 	unsigned hash;
@@ -918,7 +925,7 @@
 	if (msg->msg_flags&MSG_OOB)
 		return -EOPNOTSUPP;
 
-	if (msg->msg_flags&~MSG_DONTWAIT)
+	if (msg->msg_flags&~(MSG_DONTWAIT|MSG_NOSIGNAL))
 		return -EINVAL;
 
 	if (msg->msg_namelen) {
@@ -935,9 +942,8 @@
 		unix_autobind(sock);
 
 	skb = sock_alloc_send_skb(sk, len, 0, msg->msg_flags&MSG_DONTWAIT, &err);
-		
 	if (skb==NULL)
-		return err;
+		goto out;
 
 	memcpy(UNIXCREDS(skb), &scm->creds, sizeof(struct ucred));
 	UNIXCB(skb).attr = msg->msg_flags;
@@ -945,7 +951,9 @@
 		unix_attach_fds(scm, skb);
 
 	skb->h.raw = skb->data;
-	memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
+	err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
+	if (err)
+		goto out_free;
 
 	other = unix_peer(sk);
 	if (other && other->dead)
@@ -957,26 +965,18 @@
 		unix_unlock(other);
 		unix_peer(sk)=NULL;
 		other = NULL;
-		if (sunaddr == NULL) {
-			kfree_skb(skb);
-			return -ECONNRESET;
-		}
+		err = -ECONNRESET;
+		if (sunaddr == NULL)
+			goto out_free;
 	}
 	if (!other)
 	{
 		other = unix_find_other(sunaddr, namelen, sk->type, hash, &err);
-		
 		if (other==NULL)
-		{
-			kfree_skb(skb);
-			return err;
-		}
+			goto out_free;
+		err = -EINVAL;
 		if (!unix_may_send(sk, other))
-		{
-			unix_unlock(other);
-			kfree_skb(skb);
-			return -EINVAL;
-		}
+			goto out_unlock;
 	}
 
 	skb_queue_tail(&other->receive_queue, skb);
@@ -985,6 +985,13 @@
 	if (!unix_peer(sk))
 		unix_unlock(other);
 	return len;
+
+out_unlock:
+	unix_unlock(other);
+out_free:
+	kfree_skb(skb);
+out:
+	return err;
 }
 
 		
@@ -1005,7 +1012,7 @@
 	if (msg->msg_flags&MSG_OOB)
 		return -EOPNOTSUPP;
 
-	if (msg->msg_flags&~MSG_DONTWAIT)
+	if (msg->msg_flags&~(MSG_DONTWAIT|MSG_NOSIGNAL))
 		return -EINVAL;
 
 	if (msg->msg_namelen) {
@@ -1020,7 +1027,8 @@
 	}
 
 	if (sk->shutdown&SEND_SHUTDOWN) {
-		send_sig(SIGPIPE,current,0);
+		if (!(msg->msg_flags&MSG_NOSIGNAL))
+			send_sig(SIGPIPE,current,0);
 		return -EPIPE;
 	}
 
@@ -1085,7 +1093,8 @@
 			kfree_skb(skb);
 			if(sent)
 				goto out;
-			send_sig(SIGPIPE,current,0);
+			if (!(msg->msg_flags&MSG_NOSIGNAL))
+				send_sig(SIGPIPE,current,0);
 			return -EPIPE;
 		}
 
@@ -1265,9 +1274,7 @@
 		}
 
 		chunk = min(skb->len, size);
-		/* N.B. This could fail with a non-zero value (which means -EFAULT
-		 *      and the non-zero value is the number of bytes not copied).
-		 */
+		/* N.B. This could fail with -EFAULT */
 		memcpy_toiovec(msg->msg_iov, skb->data, chunk);
 		copied += chunk;
 		size -= chunk;


FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov