1.1 --- a/file.cc Sat Mar 13 22:38:33 2021 +0100
1.2 +++ b/file.cc Sat Mar 13 23:22:31 2021 +0100
1.3 @@ -55,36 +55,62 @@
1.4 long err;
1.5
1.6 file_init(file);
1.7 +
1.8 err = opener.context(&file->ref);
1.9 -
1.10 if (err)
1.11 return err;
1.12
1.13 client_Dataspace context_ds(file->ref);
1.14
1.15 err = context_ds.info(&size, &flags);
1.16 -
1.17 if (err)
1.18 return err;
1.19
1.20 + file->start_pos = 0;
1.21 + file->end_pos = size;
1.22 +
1.23 return ipc_attach_dataspace(file->ref, size, (void **) &file->memory);
1.24 }
1.25
1.26 +/* Open a file using the given structure and context. */
1.27 +
1.28 +long file_context_open(file_t *file, file_t *context)
1.29 +{
1.30 + client_OpenerContext openercontext(context->ref);
1.31 + file_init(file);
1.32 + return openercontext.open(L4_FPAGE_RW, &file->size, &file->ref);
1.33 +}
1.34 +
1.35 /* Initialise the given file structure. */
1.36
1.37 void file_init(file_t *file)
1.38 {
1.39 file->memory = NULL;
1.40 file->ref = L4_INVALID_CAP;
1.41 + file->start_pos = 0;
1.42 + file->end_pos = 0;
1.43 + file->data_end = 0;
1.44 }
1.45
1.46 -/* Open a file using the given structure and context. */
1.47 +/* Open a file using the given structure, indicating the filename and
1.48 + filesystem server. This is a convenience function invoking file_context and
1.49 + file_context_open. */
1.50
1.51 -long file_open(file_t *file, file_t *context)
1.52 +long file_open(file_t *file, const char *filename, l4_cap_idx_t server)
1.53 {
1.54 - client_OpenerContext openercontext(context->ref);
1.55 - file_init(file);
1.56 - return openercontext.open(L4_FPAGE_RW, &file->size, &file->ref);
1.57 + file_t context;
1.58 + long err;
1.59 +
1.60 + err = file_context(&context, server);
1.61 + if (err)
1.62 + return err;
1.63 +
1.64 + if (!file_string_set(&context, filename, 0, NULL))
1.65 + return -L4_ENOMEM;
1.66 +
1.67 + err = file_context_open(file, &context);
1.68 + file_close(&context);
1.69 + return err;
1.70 }
1.71
1.72
1.73 @@ -132,20 +158,26 @@
1.74 return NULL;
1.75 }
1.76
1.77 -/* Copy a string to the mapped region at the given offset, returning the number
1.78 - of copied characters excluding the zero terminator. */
1.79 +/* Copy a string to the mapped region at the given offset, returning 1 (true)
1.80 + where all characters were copied, 0 (false) otherwise. The precise number of
1.81 + characters copied, excluding the zero terminator is provided via the written
1.82 + parameter if it is not specified as NULL. */
1.83
1.84 -offset_t file_string_set(file_t *file, const char *data, offset_t offset)
1.85 +int file_string_set(file_t *file, const char *data, offset_t offset,
1.86 + offset_t *written)
1.87 {
1.88 - offset_t i, pos, limit = file_span(file) - 1;
1.89 + offset_t i, pos, limit = file_span(file);
1.90
1.91 /* Do not attempt to copy data with an invalid offset. */
1.92
1.93 - if (offset > limit)
1.94 + if (offset >= limit)
1.95 + {
1.96 + if (written != NULL)
1.97 + *written = 0;
1.98 return 0;
1.99 + }
1.100
1.101 - /* Copy the data to the given offset, stopping before the final byte of the
1.102 - region. */
1.103 + /* Copy the data to the given offset, stopping at the end of the region. */
1.104
1.105 for (i = 0, pos = offset; pos < limit; i++, pos++)
1.106 {
1.107 @@ -154,13 +186,19 @@
1.108 /* Terminator written, can return immediately. */
1.109
1.110 if (!data[i])
1.111 - return pos - offset - 1;
1.112 + {
1.113 + if (written != NULL)
1.114 + *written = pos - offset;
1.115 + return 1;
1.116 + }
1.117 }
1.118
1.119 /* Terminate the incomplete string at the end of the region. */
1.120
1.121 - file->memory[limit] = '\0';
1.122 - return limit - offset;
1.123 + file->memory[limit - 1] = '\0';
1.124 + if (written != NULL)
1.125 + *written = limit - 1 - offset;
1.126 + return 0;
1.127 }
1.128
1.129 // vim: tabstop=2 expandtab shiftwidth=2