diff options
author | Pavel Emelyanov <xemul@parallels.com> | 2012-02-21 07:31:34 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-02-21 15:03:48 -0500 |
commit | ef64a54f6e558155b4f149bb10666b9e914b6c54 (patch) | |
tree | bd7adba8d802aff2aaec0f5f2a9e2ba5431cafcc /net/core | |
parent | da5ef6e51b327b41180b5d1000c06e8d3595a936 (diff) | |
download | op-kernel-dev-ef64a54f6e558155b4f149bb10666b9e914b6c54.zip op-kernel-dev-ef64a54f6e558155b4f149bb10666b9e914b6c54.tar.gz |
sock: Introduce the SO_PEEK_OFF sock option
This one specifies where to start MSG_PEEK-ing queue data from. When
set to negative value means that MSG_PEEK works as ususally -- peeks
from the head of the queue always.
When some bytes are peeked from queue and the peeking offset is non
negative it is moved forward so that the next peek will return next
portion of data.
When non-peeking recvmsg occurs and the peeking offset is non negative
is is moved backward so that the next peek will still peek the proper
data (i.e. the one that would have been picked if there were no non
peeking recv in between).
The offset is set using per-proto opteration to let the protocol handle
the locking issues and to check whether the peeking offset feature is
supported by the protocol the socket belongs to.
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/sock.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 02f8dfe..19942d4 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -793,6 +793,12 @@ set_rcvbuf: sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool); break; + case SO_PEEK_OFF: + if (sock->ops->set_peek_off) + sock->ops->set_peek_off(sk, val); + else + ret = -EOPNOTSUPP; + break; default: ret = -ENOPROTOOPT; break; @@ -1018,6 +1024,12 @@ int sock_getsockopt(struct socket *sock, int level, int optname, v.val = !!sock_flag(sk, SOCK_WIFI_STATUS); break; + case SO_PEEK_OFF: + if (!sock->ops->set_peek_off) + return -EOPNOTSUPP; + + v.val = sk->sk_peek_off; + break; default: return -ENOPROTOOPT; } @@ -2092,6 +2104,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_sndmsg_page = NULL; sk->sk_sndmsg_off = 0; + sk->sk_peek_off = -1; sk->sk_peer_pid = NULL; sk->sk_peer_cred = NULL; |