aboutsummaryrefslogtreecommitdiff
path: root/libstore/encode.c
diff options
context:
space:
mode:
Diffstat (limited to 'libstore/encode.c')
-rw-r--r--libstore/encode.c87
1 files changed, 69 insertions, 18 deletions
diff --git a/libstore/encode.c b/libstore/encode.c
index 38490cc0..df27250d 100644
--- a/libstore/encode.c
+++ b/libstore/encode.c
@@ -1,9 +1,7 @@
/* Store wire encoding
- Copyright (C) 1996 Free Software Foundation, Inc.
-
- Written by Miles Bader <miles@gnu.ai.mit.edu>
-
+ Copyright (C) 1996,97,99,2001,02 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.org>
This file is part of the GNU Hurd.
The GNU Hurd is free software; you can redistribute it and/or
@@ -18,9 +16,10 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
#include <string.h>
+#include <sys/mman.h>
#include "store.h"
@@ -32,13 +31,20 @@ store_std_leaf_allocate_encoding (const struct store *store,
{
enc->num_ports++;
enc->num_ints += 6;
- enc->num_offsets += store->num_runs;
+ enc->num_offsets += store->num_runs * 2;
if (store->name)
enc->data_len += strlen (store->name) + 1;
enc->data_len += store->misc_len;
return 0;
}
+/* The RPC protocol uses 32-bit off_t's, but store_offset_t is now 64 bits. */
+static inline int too_big (store_offset_t ofs)
+{
+ off_t o = (off_t) ofs;
+ return o < 0 || ((store_offset_t) o != ofs);
+}
+
error_t
store_std_leaf_encode (const struct store *store, struct store_enc *enc)
{
@@ -56,6 +62,10 @@ store_std_leaf_encode (const struct store *store, struct store_enc *enc)
for (i = 0; i < store->num_runs; i++)
{
+ if (sizeof (*enc->offsets) != sizeof (store->runs[i].start)
+ && (too_big (store->runs[i].start)
+ || too_big (store->runs[i].start + store->runs[i].length)))
+ return EOVERFLOW;
enc->offsets[enc->cur_offset++] = store->runs[i].start;
enc->offsets[enc->cur_offset++] = store->runs[i].length;
}
@@ -82,8 +92,9 @@ store_std_leaf_encode (const struct store *store, struct store_enc *enc)
error_t
store_encode (const struct store *store, struct store_enc *enc)
{
+ void *buf;
error_t err;
- struct store_class *class = store->class;
+ const struct store_class *class = store->class;
/* We zero each vector length for the allocate_encoding method to work, so
save the old values. */
mach_msg_type_number_t init_num_ports = enc->num_ports;
@@ -102,19 +113,36 @@ store_encode (const struct store *store, struct store_enc *enc)
if (err)
return err;
+ errno = 0;
if (enc->num_ports > init_num_ports)
- err = vm_allocate (mach_task_self (),
- (vm_address_t *)&enc->ports, enc->num_ports, 1);
- if (!err && enc->num_ints > init_num_ints)
- err = vm_allocate (mach_task_self (),
- (vm_address_t *)&enc->ints, enc->num_ints, 1);
- if (!err && enc->num_offsets > init_num_offsets)
- err = vm_allocate (mach_task_self (),
- (vm_address_t *)&enc->offsets, enc->num_offsets, 1);
- if (!err && enc->data_len > init_data_len)
- err = vm_allocate (mach_task_self (),
- (vm_address_t *)&enc->data, enc->data_len, 1);
+ {
+ buf = mmap (0, enc->num_ports * sizeof *enc->ports,
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ if (buf != (void *) -1)
+ enc->ports = buf;
+ }
+ if (!errno && enc->num_ints > init_num_ints)
+ {
+ buf = mmap (0, enc->num_ints * sizeof *enc->ints,
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ if (buf != (void *) -1)
+ enc->ints = buf;
+ }
+ if (!errno && enc->num_offsets > init_num_offsets)
+ {
+ buf = mmap (0, enc->num_offsets * sizeof *enc->offsets,
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ if (buf != (void *) -1)
+ enc->offsets = buf;
+ }
+ if (!errno && enc->data_len > init_data_len)
+ {
+ buf = mmap (0, enc->data_len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ if (buf != (void *) -1)
+ enc->data = buf;
+ }
+ err = errno;
if (! err)
err = (*class->encode) (store, enc);
@@ -125,3 +153,26 @@ store_encode (const struct store *store, struct store_enc *enc)
return err;
}
+
+/* Encode STORE into the given return variables, suitably for returning from a
+ file_get_storage_info rpc. */
+error_t
+store_return (const struct store *store,
+ mach_port_t **ports, mach_msg_type_number_t *num_ports,
+ int **ints, mach_msg_type_number_t *num_ints,
+ off_t **offsets, mach_msg_type_number_t *num_offsets,
+ char **data, mach_msg_type_number_t *data_len)
+{
+ error_t err;
+ struct store_enc enc;
+
+ store_enc_init (&enc, *ports, *num_ports, *ints, *num_ints,
+ *offsets, *num_offsets, *data, *data_len);
+ err = store_encode (store, &enc);
+ if (err)
+ store_enc_dealloc (&enc);
+ else
+ store_enc_return (&enc, ports, num_ports, ints, num_ints,
+ offsets, num_offsets, data, data_len);
+ return err;
+}