summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2012-04-27 15:32:39 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2012-04-27 15:32:39 +0200
commit980e2112cf7a987df40b3157a417ad0e3a831476 (patch)
treee447c8095073e225102360ccbfce8a42eda83f4d
parent69bd9b1d600debf7b758cc7f8353b747430259b4 (diff)
Add MSG_PEEK support to pflocal
* libpipe/pq.h (packet_peek): Declare new function. * libpipe/pq.c (packet_read): Move code to new `packet_fetch' function, call it with `remove' set to 1. (packet_fetch): New function with code from `packet_read', but do not remove data if `remove' is 0. (packet_peek): New function, calls `packet_fetch' with `remove' set to 0. * libpipe/dgram.c (dgram_read): When MSG_PEEK is in *flags, do not dequeue and only peek data. * libpipe/seqpack.c (seqpack_read): Likewise. * libpipe/stream.c (stream_read): Likewise. * pflocal/socket.c (S_socket_recv): Pass MSG_PEEK flag to libpipe.
-rw-r--r--libpipe/dgram.c12
-rw-r--r--libpipe/pq.c37
-rw-r--r--libpipe/pq.h7
-rw-r--r--libpipe/seqpack.c13
-rw-r--r--libpipe/stream.c13
-rw-r--r--pflocal/socket.c2
6 files changed, 70 insertions, 14 deletions
diff --git a/libpipe/dgram.c b/libpipe/dgram.c
index 3f3b2ab6..30695f1e 100644
--- a/libpipe/dgram.c
+++ b/libpipe/dgram.c
@@ -40,8 +40,16 @@ static error_t
dgram_read (struct packet *packet, int *dequeue, unsigned *flags,
char **data, size_t *data_len, size_t amount)
{
- *dequeue = 1;
- return packet_read (packet, data, data_len, amount);
+ if (flags && *flags & MSG_PEEK)
+ {
+ *dequeue = 0;
+ return packet_peek (packet, data, data_len, amount);
+ }
+ else
+ {
+ *dequeue = 1;
+ return packet_read (packet, data, data_len, amount);
+ }
}
struct pipe_class _dgram_pipe_class =
diff --git a/libpipe/pq.c b/libpipe/pq.c
index afdda051..102f3ee3 100644
--- a/libpipe/pq.c
+++ b/libpipe/pq.c
@@ -349,13 +349,13 @@ packet_write (struct packet *packet,
return 0;
}
-/* Removes up to AMOUNT bytes from the beginning of the data in PACKET, and
+/* Remove or peek up to AMOUNT bytes from the beginning of the data in PACKET, and
puts it into *DATA, and the amount read into DATA_LEN. If more than the
original *DATA_LEN bytes are available, new memory is vm_allocated, and
the address and length of this array put into DATA and DATA_LEN. */
-error_t
-packet_read (struct packet *packet,
- char **data, size_t *data_len, size_t amount)
+static error_t
+packet_fetch (struct packet *packet,
+ char **data, size_t *data_len, size_t amount, int remove)
{
char *start = packet->buf_start;
char *end = packet->buf_end;
@@ -367,7 +367,7 @@ packet_read (struct packet *packet,
{
char *buf = packet->buf;
- if (packet->buf_vm_alloced && amount >= vm_page_size)
+ if (remove && packet->buf_vm_alloced && amount >= vm_page_size)
/* We can return memory from BUF directly without copying. */
{
if (buf + vm_page_size <= start)
@@ -414,7 +414,7 @@ packet_read (struct packet *packet,
bcopy (start, *data, amount);
start += amount;
- if (start - buf > 2 * PACKET_SIZE_LARGE)
+ if (remove && start - buf > 2 * PACKET_SIZE_LARGE)
/* Get rid of unused space at the beginning of the buffer -- we
know it's vm_alloced because of the size, and this will allow
the buffer to just slide through memory. Because we wait for
@@ -430,10 +430,33 @@ packet_read (struct packet *packet,
packet->buf_len -= dealloc;
}
- packet->buf_start = start;
+ if (remove)
+ packet->buf_start = start;
}
}
*data_len = amount;
return 0;
}
+
+/* Removes up to AMOUNT bytes from the beginning of the data in PACKET, and
+ puts it into *DATA, and the amount read into DATA_LEN. If more than the
+ original *DATA_LEN bytes are available, new memory is vm_allocated, and
+ the address and length of this array put into DATA and DATA_LEN. */
+error_t
+packet_read (struct packet *packet,
+ char **data, size_t *data_len, size_t amount)
+{
+ return packet_fetch (packet, data, data_len, amount, 1);
+}
+
+/* Peek up to AMOUNT bytes from the beginning of the data in PACKET, and
+ puts it into *DATA, and the amount read into DATA_LEN. If more than the
+ original *DATA_LEN bytes are available, new memory is vm_allocated, and
+ the address and length of this array put into DATA and DATA_LEN. */
+error_t
+packet_peek (struct packet *packet,
+ char **data, size_t *data_len, size_t amount)
+{
+ return packet_fetch (packet, data, data_len, amount, 0);
+}
diff --git a/libpipe/pq.h b/libpipe/pq.h
index 0fffe254..4e500b6c 100644
--- a/libpipe/pq.h
+++ b/libpipe/pq.h
@@ -98,6 +98,13 @@ error_t packet_write (struct packet *packet,
error_t packet_read (struct packet *packet,
char **data, size_t *data_len, size_t amount);
+/* Peek up to AMOUNT bytes from the beginning of the data in PACKET, and
+ puts it into *DATA, and the amount read into DATA_LEN. If more than the
+ original *DATA_LEN bytes are available, new memory is vm_allocated, and
+ the address and length of this array put into DATA and DATA_LEN. */
+error_t packet_peek (struct packet *packet,
+ char **data, size_t *data_len, size_t amount);
+
/* Returns any ports in PACKET in PORTS and NUM_PORTS, and removes them from
PACKET. */
error_t packet_read_ports (struct packet *packet,
diff --git a/libpipe/seqpack.c b/libpipe/seqpack.c
index 44a15a03..041abb74 100644
--- a/libpipe/seqpack.c
+++ b/libpipe/seqpack.c
@@ -43,8 +43,17 @@ static error_t
seqpack_read (struct packet *packet, int *dequeue, unsigned *flags,
char **data, size_t *data_len, size_t amount)
{
- error_t err = packet_read (packet, data, data_len, amount);
- *dequeue = (packet_readable (packet) == 0);
+ error_t err;
+ if (flags && *flags & MSG_PEEK)
+ {
+ err = packet_peek (packet, data, data_len, amount);
+ *dequeue = 0;
+ }
+ else
+ {
+ err = packet_read (packet, data, data_len, amount);
+ *dequeue = (packet_readable (packet) == 0);
+ }
return err;
}
diff --git a/libpipe/stream.c b/libpipe/stream.c
index 8eb90435..671907e7 100644
--- a/libpipe/stream.c
+++ b/libpipe/stream.c
@@ -56,8 +56,17 @@ static error_t
stream_read (struct packet *packet, int *dequeue, unsigned *flags,
char **data, size_t *data_len, size_t amount)
{
- error_t err = packet_read (packet, data, data_len, amount);
- *dequeue = (packet_readable (packet) == 0);
+ error_t err;
+ if (flags && *flags & MSG_PEEK)
+ {
+ err = packet_peek (packet, data, data_len, amount);
+ *dequeue = 0;
+ }
+ else
+ {
+ err = packet_read (packet, data, data_len, amount);
+ *dequeue = (packet_readable (packet) == 0);
+ }
return err;
}
diff --git a/pflocal/socket.c b/pflocal/socket.c
index 2684a723..a0e5b1da 100644
--- a/pflocal/socket.c
+++ b/pflocal/socket.c
@@ -372,7 +372,7 @@ S_socket_recv (struct sock_user *user,
return EINVAL; /* XXX */
/* Fill in the pipe FLAGS from any corresponding ones in IN_FLAGS. */
- flags = 0;
+ flags = in_flags & MSG_PEEK;
err = sock_acquire_read_pipe (user->sock, &pipe);
if (err == EPIPE)