1.1 --- a/libfsclient/lib/src/client.cc Thu Sep 01 21:40:39 2022 +0200
1.2 +++ b/libfsclient/lib/src/client.cc Thu Sep 01 21:52:41 2022 +0200
1.3 @@ -135,7 +135,9 @@
1.4 /* Within the current pipe region, synchronise with the pipe object. */
1.5
1.6 else
1.7 + {
1.8 return client_current_region(file);
1.9 + }
1.10 }
1.11 }
1.12
1.13 @@ -148,8 +150,8 @@
1.14 static int _operation_blocking(file_t *file, int reading)
1.15 {
1.16 return (file->can_block && !(file->notifications & NOTIFY_PEER_CLOSED) && (
1.17 - (reading && !file_data_available(file)) ||
1.18 - (!reading && !file_data_space(file))));
1.19 + (reading && !file_data_available(file)) ||
1.20 + (!reading && !file_data_space(file))));
1.21 }
1.22
1.23
1.24 @@ -264,12 +266,9 @@
1.25 if (file == NULL)
1.26 return NULL;
1.27
1.28 - if (file_open(file, name, flags, server))
1.29 - {
1.30 - free(file);
1.31 - return NULL;
1.32 - }
1.33 + /* Return any allocated structure even if an error occurs. */
1.34
1.35 + file->error = file_open(file, name, flags, server);
1.36 return file;
1.37 }
1.38
1.39 @@ -296,10 +295,7 @@
1.40
1.41 file_t *reader = client_opendir_at(file);
1.42
1.43 - if (reader == NULL)
1.44 - return NULL;
1.45 -
1.46 - /* Release the directory and return the reader. */
1.47 + /* Release the directory and return the reader even if an error occurs. */
1.48
1.49 client_close(file);
1.50 return reader;
1.51 @@ -311,7 +307,7 @@
1.52
1.53 file_t *client_opendir_at(file_t *file)
1.54 {
1.55 - if (file == NULL)
1.56 + if (!client_opened(file))
1.57 return NULL;
1.58
1.59 file_t *reader = (file_t *) malloc(sizeof(file_t));
1.60 @@ -319,26 +315,23 @@
1.61 if (reader == NULL)
1.62 return NULL;
1.63
1.64 - long err = directory_opendir(file, reader);
1.65 + /* Return any allocated structure even if an error occurs. */
1.66
1.67 - if (err)
1.68 - return NULL;
1.69 + reader->error = directory_opendir(file, reader);
1.70
1.71 /* Set blocking read mode to be able to conveniently read directory entries
1.72 - from the stream. */
1.73 + from the stream. If this fails, the error is set on the structure, but the
1.74 + stream will be open. */
1.75
1.76 - if (client_set_blocking(reader, NOTIFY_CONTENT_AVAILABLE | NOTIFY_PEER_CLOSED))
1.77 - {
1.78 - client_close(reader);
1.79 - return NULL;
1.80 - }
1.81 + if (!reader->error)
1.82 + reader->error = client_set_blocking(reader, NOTIFY_CONTENT_AVAILABLE | NOTIFY_PEER_CLOSED);
1.83
1.84 return reader;
1.85 }
1.86
1.87
1.88
1.89 -/* Open a pipe object. */
1.90 +/* Open a pipe object, returning any error condition. */
1.91
1.92 long client_pipe(file_t **reader, file_t **writer, flags_t flags)
1.93 {
1.94 @@ -349,6 +342,9 @@
1.95
1.96 long client_pipe_using(file_t **reader, file_t **writer, flags_t flags, l4_cap_idx_t server)
1.97 {
1.98 + *reader = NULL;
1.99 + *writer = NULL;
1.100 +
1.101 if (l4_is_invalid_cap(server))
1.102 return -L4_EINVAL;
1.103
1.104 @@ -387,6 +383,15 @@
1.105
1.106
1.107
1.108 +/* Determine whether a file has been successfully opened. */
1.109 +
1.110 +int client_opened(file_t *file)
1.111 +{
1.112 + return (file != NULL) && !file->error;
1.113 +}
1.114 +
1.115 +
1.116 +
1.117 /* Make a directory in the filesystem. */
1.118
1.119 long client_mkdir(const char *path, mode_t mode)
1.120 @@ -463,7 +468,7 @@
1.121
1.122 long client_current_region(file_t *file)
1.123 {
1.124 - if (file == NULL)
1.125 + if (!client_opened(file))
1.126 return -L4_EINVAL;
1.127
1.128 return pipe_current(file);
1.129 @@ -475,7 +480,7 @@
1.130
1.131 long client_flush(file_t *file)
1.132 {
1.133 - if (file == NULL)
1.134 + if (!client_opened(file))
1.135 return -L4_EINVAL;
1.136
1.137 /* Flush and retain most buffer settings. */
1.138 @@ -491,8 +496,8 @@
1.139 offset_t start_visible, offset_t end_visible,
1.140 l4re_rm_flags_t region_flags)
1.141 {
1.142 - if ((file == NULL) || file_mmap(file, position, length, start_visible,
1.143 - end_visible, region_flags))
1.144 + if (!client_opened(file) || file_mmap(file, position, length, start_visible,
1.145 + end_visible, region_flags))
1.146 return NULL;
1.147
1.148 return file->memory;
1.149 @@ -504,7 +509,7 @@
1.150
1.151 long client_next_region(file_t *file)
1.152 {
1.153 - if (file == NULL)
1.154 + if (!client_opened(file))
1.155 return -L4_EINVAL;
1.156
1.157 return pipe_next(file);
1.158 @@ -584,7 +589,7 @@
1.159
1.160 offset_t client_read(file_t *file, void *buf, offset_t count)
1.161 {
1.162 - if (file == NULL)
1.163 + if (!client_opened(file))
1.164 return 0;
1.165
1.166 /* Map memory if none has been mapped so far. */
1.167 @@ -640,7 +645,7 @@
1.168
1.169 offset_t client_seek(file_t *file, offset_t offset, int whence)
1.170 {
1.171 - if (file == NULL)
1.172 + if (!client_opened(file))
1.173 return 0;
1.174
1.175 offset_t position, current = file_data_current_position(file), change;
1.176 @@ -743,7 +748,7 @@
1.177
1.178 long client_subscribe(file_t *file, notify_flags_t flags, file_notifier_t *notifier)
1.179 {
1.180 - if (file == NULL)
1.181 + if (!client_opened(file))
1.182 return -L4_EINVAL;
1.183
1.184 return file_notify_subscribe(file, flags, notifier);
1.185 @@ -755,7 +760,7 @@
1.186
1.187 long client_tell(file_t *file)
1.188 {
1.189 - if (file == NULL)
1.190 + if (!client_opened(file))
1.191 return -L4_EINVAL;
1.192
1.193 return file_data_current_position(file);
1.194 @@ -767,7 +772,7 @@
1.195
1.196 long client_unsubscribe(file_t *file, file_notifier_t *notifier)
1.197 {
1.198 - if (file == NULL)
1.199 + if (!client_opened(file))
1.200 return -L4_EINVAL;
1.201
1.202 return file_notify_unsubscribe(file, notifier);
1.203 @@ -779,7 +784,7 @@
1.204
1.205 long client_wait_file(file_t *file, file_notifier_t *notifier)
1.206 {
1.207 - if (file == NULL)
1.208 + if (!client_opened(file))
1.209 return -L4_EINVAL;
1.210
1.211 return file_notify_wait_file(file, notifier);
1.212 @@ -799,7 +804,7 @@
1.213
1.214 offset_t client_write(file_t *file, const void *buf, offset_t count)
1.215 {
1.216 - if (file == NULL)
1.217 + if (!client_opened(file))
1.218 return 0;
1.219
1.220 /* Map memory if none has been mapped so far. */