Rev 4347 | Rev 4389 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4347 | Rev 4348 | ||
|---|---|---|---|
| Line 58... | Line 58... | ||
| 58 | /** Pending mount structure. */ |
58 | /** Pending mount structure. */ |
| 59 | typedef struct { |
59 | typedef struct { |
| 60 | link_t link; |
60 | link_t link; |
| 61 | char *fs_name; /**< File system name */ |
61 | char *fs_name; /**< File system name */ |
| 62 | char *mp; /**< Mount point */ |
62 | char *mp; /**< Mount point */ |
| - | 63 | char *opts; /**< Mount options. */ |
|
| 63 | ipc_callid_t callid; /**< Call ID waiting for the mount */ |
64 | ipc_callid_t callid; /**< Call ID waiting for the mount */ |
| 64 | ipc_callid_t rid; /**< Request ID */ |
65 | ipc_callid_t rid; /**< Request ID */ |
| 65 | dev_handle_t dev_handle; /**< Device handle */ |
66 | dev_handle_t dev_handle; /**< Device handle */ |
| 66 | } pending_req_t; |
67 | } pending_req_t; |
| 67 | 68 | ||
| Line 78... | Line 79... | ||
| 78 | .fs_handle = 0, |
79 | .fs_handle = 0, |
| 79 | .dev_handle = 0 |
80 | .dev_handle = 0 |
| 80 | }; |
81 | }; |
| 81 | 82 | ||
| 82 | static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle, |
83 | static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle, |
| 83 | fs_handle_t fs_handle, char *mp) |
84 | fs_handle_t fs_handle, char *mp, char *opts) |
| 84 | { |
85 | { |
| 85 | /* Resolve the path to the mountpoint. */ |
- | |
| 86 | vfs_lookup_res_t mp_res; |
86 | vfs_lookup_res_t mp_res; |
| 87 | vfs_node_t *mp_node = NULL; |
87 | vfs_node_t *mp_node = NULL; |
| 88 | int rc; |
88 | ipcarg_t rc; |
| 89 | int phone; |
89 | int phone; |
| - | 90 | aid_t msg; |
|
| - | 91 | ipc_call_t answer; |
|
| - | 92 | ||
| - | 93 | /* Resolve the path to the mountpoint. */ |
|
| 90 | futex_down(&rootfs_futex); |
94 | futex_down(&rootfs_futex); |
| 91 | if (rootfs.fs_handle) { |
95 | if (rootfs.fs_handle) { |
| 92 | /* We already have the root FS. */ |
96 | /* We already have the root FS. */ |
| 93 | rwlock_write_lock(&namespace_rwlock); |
97 | rwlock_write_lock(&namespace_rwlock); |
| 94 | if ((strlen(mp) == 1) && (mp[0] == '/')) { |
98 | if (str_cmp(mp, "/") == 0) { |
| 95 | /* Trying to mount root FS over root FS */ |
99 | /* Trying to mount root FS over root FS */ |
| 96 | rwlock_write_unlock(&namespace_rwlock); |
100 | rwlock_write_unlock(&namespace_rwlock); |
| 97 | futex_up(&rootfs_futex); |
101 | futex_up(&rootfs_futex); |
| 98 | ipc_answer_0(rid, EBUSY); |
102 | ipc_answer_0(rid, EBUSY); |
| 99 | return; |
103 | return; |
| Line 122... | Line 126... | ||
| 122 | * This prevents the mount point from being deleted. |
126 | * This prevents the mount point from being deleted. |
| 123 | */ |
127 | */ |
| 124 | rwlock_write_unlock(&namespace_rwlock); |
128 | rwlock_write_unlock(&namespace_rwlock); |
| 125 | } else { |
129 | } else { |
| 126 | /* We still don't have the root file system mounted. */ |
130 | /* We still don't have the root file system mounted. */ |
| 127 | if ((strlen(mp) == 1) && (mp[0] == '/')) { |
131 | if (str_cmp(mp, "/") == 0) { |
| 128 | vfs_lookup_res_t mr_res; |
132 | vfs_lookup_res_t mr_res; |
| 129 | vfs_node_t *mr_node; |
133 | vfs_node_t *mr_node; |
| 130 | ipcarg_t rindex; |
134 | fs_index_t rindex; |
| 131 | ipcarg_t rsize; |
135 | size_t rsize; |
| 132 | ipcarg_t rlnkcnt; |
136 | unsigned rlnkcnt; |
| 133 | 137 | ||
| 134 | /* |
138 | /* |
| 135 | * For this simple, but important case, |
139 | * For this simple, but important case, |
| 136 | * we are almost done. |
140 | * we are almost done. |
| 137 | */ |
141 | */ |
| 138 | 142 | ||
| 139 | /* Tell the mountee that it is being mounted. */ |
143 | /* Tell the mountee that it is being mounted. */ |
| 140 | phone = vfs_grab_phone(fs_handle); |
144 | phone = vfs_grab_phone(fs_handle); |
| 141 | rc = async_req_1_3(phone, VFS_MOUNTED, |
145 | msg = async_send_1(phone, VFS_MOUNTED, |
| 142 | (ipcarg_t) dev_handle, &rindex, &rsize, &rlnkcnt); |
146 | (ipcarg_t) dev_handle, &answer); |
| - | 147 | /* send the mount options */ |
|
| - | 148 | rc = ipc_data_write_start(phone, (void *)opts, |
|
| - | 149 | str_size(opts)); |
|
| - | 150 | if (rc != EOK) { |
|
| - | 151 | async_wait_for(msg, NULL); |
|
| - | 152 | vfs_release_phone(phone); |
|
| - | 153 | futex_up(&rootfs_futex); |
|
| - | 154 | ipc_answer_0(rid, rc); |
|
| - | 155 | return; |
|
| - | 156 | } |
|
| - | 157 | async_wait_for(msg, &rc); |
|
| 143 | vfs_release_phone(phone); |
158 | vfs_release_phone(phone); |
| 144 | 159 | ||
| 145 | if (rc != EOK) { |
160 | if (rc != EOK) { |
| 146 | futex_up(&rootfs_futex); |
161 | futex_up(&rootfs_futex); |
| 147 | ipc_answer_0(rid, rc); |
162 | ipc_answer_0(rid, rc); |
| 148 | return; |
163 | return; |
| 149 | } |
164 | } |
| - | 165 | ||
| - | 166 | rindex = (fs_index_t) IPC_GET_ARG1(answer); |
|
| - | 167 | rsize = (size_t) IPC_GET_ARG2(answer); |
|
| - | 168 | rlnkcnt = (unsigned) IPC_GET_ARG3(answer); |
|
| 150 | 169 | ||
| 151 | mr_res.triplet.fs_handle = fs_handle; |
170 | mr_res.triplet.fs_handle = fs_handle; |
| 152 | mr_res.triplet.dev_handle = dev_handle; |
171 | mr_res.triplet.dev_handle = dev_handle; |
| 153 | mr_res.triplet.index = (fs_index_t) rindex; |
172 | mr_res.triplet.index = rindex; |
| 154 | mr_res.size = (size_t) rsize; |
173 | mr_res.size = rsize; |
| 155 | mr_res.lnkcnt = (unsigned) rlnkcnt; |
174 | mr_res.lnkcnt = rlnkcnt; |
| 156 | mr_res.type = VFS_NODE_DIRECTORY; |
175 | mr_res.type = VFS_NODE_DIRECTORY; |
| 157 | 176 | ||
| 158 | rootfs.fs_handle = fs_handle; |
177 | rootfs.fs_handle = fs_handle; |
| 159 | rootfs.dev_handle = dev_handle; |
178 | rootfs.dev_handle = dev_handle; |
| 160 | futex_up(&rootfs_futex); |
179 | futex_up(&rootfs_futex); |
| Line 181... | Line 200... | ||
| 181 | * At this point, we have all necessary pieces: file system and device |
200 | * At this point, we have all necessary pieces: file system and device |
| 182 | * handles, and we know the mount point VFS node. |
201 | * handles, and we know the mount point VFS node. |
| 183 | */ |
202 | */ |
| 184 | 203 | ||
| 185 | phone = vfs_grab_phone(mp_res.triplet.fs_handle); |
204 | phone = vfs_grab_phone(mp_res.triplet.fs_handle); |
| 186 | rc = async_req_4_0(phone, VFS_MOUNT, |
205 | msg = async_send_4(phone, VFS_MOUNT, |
| 187 | (ipcarg_t) mp_res.triplet.dev_handle, |
206 | (ipcarg_t) mp_res.triplet.dev_handle, |
| 188 | (ipcarg_t) mp_res.triplet.index, |
207 | (ipcarg_t) mp_res.triplet.index, |
| 189 | (ipcarg_t) fs_handle, |
208 | (ipcarg_t) fs_handle, |
| 190 | (ipcarg_t) dev_handle); |
209 | (ipcarg_t) dev_handle, &answer); |
| - | 210 | /* send the mount options */ |
|
| - | 211 | rc = ipc_data_write_start(phone, (void *)opts, str_size(opts)); |
|
| - | 212 | if (rc != EOK) { |
|
| - | 213 | async_wait_for(msg, NULL); |
|
| - | 214 | vfs_release_phone(phone); |
|
| - | 215 | /* Mount failed, drop reference to mp_node. */ |
|
| - | 216 | if (mp_node) |
|
| - | 217 | vfs_node_put(mp_node); |
|
| - | 218 | ipc_answer_0(rid, rc); |
|
| - | 219 | return; |
|
| - | 220 | } |
|
| - | 221 | async_wait_for(msg, &rc); |
|
| 191 | vfs_release_phone(phone); |
222 | vfs_release_phone(phone); |
| 192 | 223 | ||
| 193 | if (rc != EOK) { |
224 | if (rc != EOK) { |
| 194 | /* Mount failed, drop reference to mp_node. */ |
225 | /* Mount failed, drop reference to mp_node. */ |
| 195 | if (mp_node) |
226 | if (mp_node) |
| Line 214... | Line 245... | ||
| 214 | 245 | ||
| 215 | /* Acknowledge that we know fs_name. */ |
246 | /* Acknowledge that we know fs_name. */ |
| 216 | ipc_answer_0(pr->callid, EOK); |
247 | ipc_answer_0(pr->callid, EOK); |
| 217 | 248 | ||
| 218 | /* Do the mount */ |
249 | /* Do the mount */ |
| 219 | vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp); |
250 | vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp, |
| - | 251 | pr->opts); |
|
| 220 | 252 | ||
| 221 | free(pr->fs_name); |
253 | free(pr->fs_name); |
| 222 | free(pr->mp); |
254 | free(pr->mp); |
| - | 255 | free(pr->opts); |
|
| 223 | list_remove(cur); |
256 | list_remove(cur); |
| 224 | free(pr); |
257 | free(pr); |
| 225 | goto loop; |
258 | goto loop; |
| 226 | } |
259 | } |
| 227 | } |
260 | } |
| Line 270... | Line 303... | ||
| 270 | } |
303 | } |
| 271 | 304 | ||
| 272 | /* Deliver the mount point. */ |
305 | /* Deliver the mount point. */ |
| 273 | ipcarg_t retval = ipc_data_write_finalize(callid, mp, size); |
306 | ipcarg_t retval = ipc_data_write_finalize(callid, mp, size); |
| 274 | if (retval != EOK) { |
307 | if (retval != EOK) { |
| 275 | ipc_answer_0(rid, EREFUSED); |
308 | ipc_answer_0(rid, retval); |
| 276 | free(mp); |
309 | free(mp); |
| 277 | return; |
310 | return; |
| 278 | } |
311 | } |
| 279 | mp[size] = '\0'; |
312 | mp[size] = '\0'; |
| 280 | 313 | ||
| - | 314 | /* Now we expect to receive the mount options. */ |
|
| - | 315 | if (!ipc_data_write_receive(&callid, &size)) { |
|
| - | 316 | ipc_answer_0(callid, EINVAL); |
|
| - | 317 | ipc_answer_0(rid, EINVAL); |
|
| - | 318 | free(mp); |
|
| - | 319 | return; |
|
| - | 320 | } |
|
| - | 321 | ||
| - | 322 | /* Check the offered options size. */ |
|
| - | 323 | if (size < 0 || size > MAX_MNTOPTS_LEN) { |
|
| - | 324 | ipc_answer_0(callid, EINVAL); |
|
| - | 325 | ipc_answer_0(rid, EINVAL); |
|
| - | 326 | free(mp); |
|
| - | 327 | return; |
|
| - | 328 | } |
|
| - | 329 | ||
| - | 330 | /* Allocate buffer for the mount options. */ |
|
| - | 331 | char *opts = (char *) malloc(size + 1); |
|
| - | 332 | if (!opts) { |
|
| - | 333 | ipc_answer_0(callid, ENOMEM); |
|
| - | 334 | ipc_answer_0(rid, ENOMEM); |
|
| - | 335 | free(mp); |
|
| - | 336 | return; |
|
| - | 337 | } |
|
| - | 338 | ||
| - | 339 | /* Deliver the mount options. */ |
|
| - | 340 | retval = ipc_data_write_finalize(callid, opts, size); |
|
| - | 341 | if (retval != EOK) { |
|
| - | 342 | ipc_answer_0(rid, retval); |
|
| - | 343 | free(mp); |
|
| - | 344 | free(opts); |
|
| - | 345 | return; |
|
| - | 346 | } |
|
| - | 347 | opts[size] = '\0'; |
|
| - | 348 | ||
| 281 | /* |
349 | /* |
| 282 | * Now, we expect the client to send us data with the name of the file |
350 | * Now, we expect the client to send us data with the name of the file |
| 283 | * system. |
351 | * system. |
| 284 | */ |
352 | */ |
| 285 | if (!ipc_data_write_receive(&callid, &size)) { |
353 | if (!ipc_data_write_receive(&callid, &size)) { |
| 286 | ipc_answer_0(callid, EINVAL); |
354 | ipc_answer_0(callid, EINVAL); |
| 287 | ipc_answer_0(rid, EINVAL); |
355 | ipc_answer_0(rid, EINVAL); |
| 288 | free(mp); |
356 | free(mp); |
| - | 357 | free(opts); |
|
| 289 | return; |
358 | return; |
| 290 | } |
359 | } |
| 291 | 360 | ||
| 292 | /* |
361 | /* |
| 293 | * Don't receive more than is necessary for storing a full file system |
362 | * Don't receive more than is necessary for storing a full file system |
| Line 295... | Line 364... | ||
| 295 | */ |
364 | */ |
| 296 | if ((size < 1) || (size > FS_NAME_MAXLEN)) { |
365 | if ((size < 1) || (size > FS_NAME_MAXLEN)) { |
| 297 | ipc_answer_0(callid, EINVAL); |
366 | ipc_answer_0(callid, EINVAL); |
| 298 | ipc_answer_0(rid, EINVAL); |
367 | ipc_answer_0(rid, EINVAL); |
| 299 | free(mp); |
368 | free(mp); |
| - | 369 | free(opts); |
|
| 300 | return; |
370 | return; |
| 301 | } |
371 | } |
| 302 | 372 | ||
| 303 | /* |
373 | /* |
| 304 | * Allocate buffer for file system name. |
374 | * Allocate buffer for file system name. |
| 305 | */ |
375 | */ |
| 306 | char *fs_name = (char *) malloc(size + 1); |
376 | char *fs_name = (char *) malloc(size + 1); |
| 307 | if (fs_name == NULL) { |
377 | if (fs_name == NULL) { |
| 308 | ipc_answer_0(callid, ENOMEM); |
378 | ipc_answer_0(callid, ENOMEM); |
| 309 | ipc_answer_0(rid, EREFUSED); |
379 | ipc_answer_0(rid, ENOMEM); |
| 310 | free(mp); |
380 | free(mp); |
| - | 381 | free(opts); |
|
| 311 | return; |
382 | return; |
| 312 | } |
383 | } |
| 313 | 384 | ||
| 314 | /* Deliver the file system name. */ |
385 | /* Deliver the file system name. */ |
| 315 | retval = ipc_data_write_finalize(callid, fs_name, size); |
386 | retval = ipc_data_write_finalize(callid, fs_name, size); |
| 316 | if (retval != EOK) { |
387 | if (retval != EOK) { |
| 317 | ipc_answer_0(rid, EREFUSED); |
388 | ipc_answer_0(rid, retval); |
| 318 | free(mp); |
389 | free(mp); |
| - | 390 | free(opts); |
|
| 319 | free(fs_name); |
391 | free(fs_name); |
| 320 | return; |
392 | return; |
| 321 | } |
393 | } |
| 322 | fs_name[size] = '\0'; |
394 | fs_name[size] = '\0'; |
| - | 395 | ||
| - | 396 | /* |
|
| - | 397 | * Wait for IPC_M_PING so that we can return an error if we don't know |
|
| - | 398 | * fs_name. |
|
| - | 399 | */ |
|
| - | 400 | ipc_call_t data; |
|
| - | 401 | callid = async_get_call(&data); |
|
| - | 402 | if (IPC_GET_METHOD(data) != IPC_M_PING) { |
|
| - | 403 | ipc_answer_0(callid, ENOTSUP); |
|
| - | 404 | ipc_answer_0(rid, ENOTSUP); |
|
| - | 405 | free(mp); |
|
| - | 406 | free(opts); |
|
| - | 407 | free(fs_name); |
|
| - | 408 | return; |
|
| 323 | 409 | } |
|
| - | 410 | ||
| 324 | /* |
411 | /* |
| 325 | * Check if we know a file system with the same name as is in fs_name. |
412 | * Check if we know a file system with the same name as is in fs_name. |
| 326 | * This will also give us its file system handle. |
413 | * This will also give us its file system handle. |
| 327 | */ |
414 | */ |
| 328 | fs_handle_t fs_handle = fs_name_to_handle(fs_name, true); |
415 | fs_handle_t fs_handle = fs_name_to_handle(fs_name, true); |
| 329 | if (!fs_handle) { |
416 | if (!fs_handle) { |
| 330 | if (flags & IPC_FLAG_BLOCKING) { |
417 | if (flags & IPC_FLAG_BLOCKING) { |
| - | 418 | pending_req_t *pr; |
|
| - | 419 | ||
| 331 | /* Blocking mount, add to pending list */ |
420 | /* Blocking mount, add to pending list */ |
| 332 | pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
421 | pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
| 333 | if (!pr) { |
422 | if (!pr) { |
| 334 | ipc_answer_0(callid, ENOMEM); |
423 | ipc_answer_0(callid, ENOMEM); |
| 335 | ipc_answer_0(rid, ENOMEM); |
424 | ipc_answer_0(rid, ENOMEM); |
| 336 | free(mp); |
425 | free(mp); |
| 337 | free(fs_name); |
426 | free(fs_name); |
| - | 427 | free(opts); |
|
| 338 | return; |
428 | return; |
| 339 | } |
429 | } |
| 340 | 430 | ||
| 341 | pr->fs_name = fs_name; |
431 | pr->fs_name = fs_name; |
| 342 | pr->mp = mp; |
432 | pr->mp = mp; |
| - | 433 | pr->opts = opts; |
|
| 343 | pr->callid = callid; |
434 | pr->callid = callid; |
| 344 | pr->rid = rid; |
435 | pr->rid = rid; |
| 345 | pr->dev_handle = dev_handle; |
436 | pr->dev_handle = dev_handle; |
| 346 | link_initialize(&pr->link); |
437 | link_initialize(&pr->link); |
| 347 | list_append(&pr->link, &pending_req); |
438 | list_append(&pr->link, &pending_req); |
| Line 350... | Line 441... | ||
| 350 | 441 | ||
| 351 | ipc_answer_0(callid, ENOENT); |
442 | ipc_answer_0(callid, ENOENT); |
| 352 | ipc_answer_0(rid, ENOENT); |
443 | ipc_answer_0(rid, ENOENT); |
| 353 | free(mp); |
444 | free(mp); |
| 354 | free(fs_name); |
445 | free(fs_name); |
| - | 446 | free(opts); |
|
| 355 | return; |
447 | return; |
| 356 | } |
448 | } |
| 357 | 449 | ||
| 358 | /* Acknowledge that we know fs_name. */ |
450 | /* Acknowledge that we know fs_name. */ |
| 359 | ipc_answer_0(callid, EOK); |
451 | ipc_answer_0(callid, EOK); |
| 360 | 452 | ||
| 361 | /* Do the mount */ |
453 | /* Do the mount */ |
| 362 | vfs_mount_internal(rid, dev_handle, fs_handle, mp); |
454 | vfs_mount_internal(rid, dev_handle, fs_handle, mp, opts); |
| 363 | free(mp); |
455 | free(mp); |
| 364 | free(fs_name); |
456 | free(fs_name); |
| - | 457 | free(opts); |
|
| 365 | } |
458 | } |
| 366 | 459 | ||
| 367 | void vfs_open(ipc_callid_t rid, ipc_call_t *request) |
460 | void vfs_open(ipc_callid_t rid, ipc_call_t *request) |
| 368 | { |
461 | { |
| 369 | if (!vfs_files_init()) { |
462 | if (!vfs_files_init()) { |
| Line 802... | Line 895... | ||
| 802 | ipc_answer_0(rid, EOK); |
895 | ipc_answer_0(rid, EOK); |
| 803 | } |
896 | } |
| 804 | 897 | ||
| 805 | void vfs_rename(ipc_callid_t rid, ipc_call_t *request) |
898 | void vfs_rename(ipc_callid_t rid, ipc_call_t *request) |
| 806 | { |
899 | { |
| 807 | size_t len; |
900 | size_t olen, nlen; |
| 808 | ipc_callid_t callid; |
901 | ipc_callid_t callid; |
| 809 | int rc; |
902 | int rc; |
| 810 | 903 | ||
| 811 | /* Retrieve the old path. */ |
904 | /* Retrieve the old path. */ |
| 812 | if (!ipc_data_write_receive(&callid, &len)) { |
905 | if (!ipc_data_write_receive(&callid, &olen)) { |
| 813 | ipc_answer_0(callid, EINVAL); |
906 | ipc_answer_0(callid, EINVAL); |
| 814 | ipc_answer_0(rid, EINVAL); |
907 | ipc_answer_0(rid, EINVAL); |
| 815 | return; |
908 | return; |
| 816 | } |
909 | } |
| 817 | char *old = malloc(len + 1); |
910 | char *old = malloc(olen + 1); |
| 818 | if (!old) { |
911 | if (!old) { |
| 819 | ipc_answer_0(callid, ENOMEM); |
912 | ipc_answer_0(callid, ENOMEM); |
| 820 | ipc_answer_0(rid, ENOMEM); |
913 | ipc_answer_0(rid, ENOMEM); |
| 821 | return; |
914 | return; |
| 822 | } |
915 | } |
| 823 | if ((rc = ipc_data_write_finalize(callid, old, len))) { |
916 | if ((rc = ipc_data_write_finalize(callid, old, olen))) { |
| 824 | ipc_answer_0(rid, rc); |
917 | ipc_answer_0(rid, rc); |
| 825 | free(old); |
918 | free(old); |
| 826 | return; |
919 | return; |
| 827 | } |
920 | } |
| 828 | old[len] = '\0'; |
921 | old[olen] = '\0'; |
| 829 | 922 | ||
| 830 | /* Retrieve the new path. */ |
923 | /* Retrieve the new path. */ |
| 831 | if (!ipc_data_write_receive(&callid, &len)) { |
924 | if (!ipc_data_write_receive(&callid, &nlen)) { |
| 832 | ipc_answer_0(callid, EINVAL); |
925 | ipc_answer_0(callid, EINVAL); |
| 833 | ipc_answer_0(rid, EINVAL); |
926 | ipc_answer_0(rid, EINVAL); |
| 834 | free(old); |
927 | free(old); |
| 835 | return; |
928 | return; |
| 836 | } |
929 | } |
| 837 | char *new = malloc(len + 1); |
930 | char *new = malloc(nlen + 1); |
| 838 | if (!new) { |
931 | if (!new) { |
| 839 | ipc_answer_0(callid, ENOMEM); |
932 | ipc_answer_0(callid, ENOMEM); |
| 840 | ipc_answer_0(rid, ENOMEM); |
933 | ipc_answer_0(rid, ENOMEM); |
| 841 | free(old); |
934 | free(old); |
| 842 | return; |
935 | return; |
| 843 | } |
936 | } |
| 844 | if ((rc = ipc_data_write_finalize(callid, new, len))) { |
937 | if ((rc = ipc_data_write_finalize(callid, new, nlen))) { |
| 845 | ipc_answer_0(rid, rc); |
938 | ipc_answer_0(rid, rc); |
| 846 | free(old); |
939 | free(old); |
| 847 | free(new); |
940 | free(new); |
| 848 | return; |
941 | return; |
| 849 | } |
942 | } |
| 850 | new[len] = '\0'; |
943 | new[nlen] = '\0'; |
| 851 | 944 | ||
| 852 | char *oldc = canonify(old, &len); |
945 | char *oldc = canonify(old, &olen); |
| 853 | char *newc = canonify(new, NULL); |
946 | char *newc = canonify(new, &nlen); |
| 854 | if (!oldc || !newc) { |
947 | if (!oldc || !newc) { |
| 855 | ipc_answer_0(rid, EINVAL); |
948 | ipc_answer_0(rid, EINVAL); |
| 856 | free(old); |
949 | free(old); |
| 857 | free(new); |
950 | free(new); |
| 858 | return; |
951 | return; |
| 859 | } |
952 | } |
| - | 953 | oldc[olen] = '\0'; |
|
| - | 954 | newc[nlen] = '\0'; |
|
| 860 | if (!strncmp(newc, oldc, len)) { |
955 | if (!str_lcmp(newc, oldc, str_length(oldc))) { |
| 861 | /* oldc is a prefix of newc */ |
956 | /* oldc is a prefix of newc */ |
| 862 | ipc_answer_0(rid, EINVAL); |
957 | ipc_answer_0(rid, EINVAL); |
| 863 | free(old); |
958 | free(old); |
| 864 | free(new); |
959 | free(new); |
| 865 | return; |
960 | return; |