diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-12-19 18:43:38 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-12-19 18:43:38 +0100 |
commit | 3636ea628d051cf2ba7a9038c50528c561d0aeaa (patch) | |
tree | 87664b904950052e8b6997a371ed5ecb1ea4b310 /src/util/disk.c | |
parent | 74d7528e6bd53cf5acc939c63a5be74a001e5ce1 (diff) | |
download | gnunet-3636ea628d051cf2ba7a9038c50528c561d0aeaa.tar.gz gnunet-3636ea628d051cf2ba7a9038c50528c561d0aeaa.zip |
change GNUNET_DISK_fn_write() to always do atomic writes and to NOT overwrite existing files; also change the return value to not return the size of the written file but GNUNET_OK on success, and integrate creating the directory if needed; breaks API, hence bumping libgnunetutil version
Diffstat (limited to 'src/util/disk.c')
-rw-r--r-- | src/util/disk.c | 561 |
1 files changed, 155 insertions, 406 deletions
diff --git a/src/util/disk.c b/src/util/disk.c index c95e9753c..3bafe311d 100644 --- a/src/util/disk.c +++ b/src/util/disk.c | |||
@@ -92,7 +92,7 @@ struct GetFileSizeData | |||
92 | int include_sym_links; | 92 | int include_sym_links; |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * GNUNET_YES if mode is file-only (return total == -1 for directories). | 95 | * #GNUNET_YES if mode is file-only (return total == -1 for directories). |
96 | */ | 96 | */ |
97 | int single_file_mode; | 97 | int single_file_mode; |
98 | }; | 98 | }; |
@@ -142,8 +142,8 @@ translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm) | |||
142 | * @param fn current filename we are looking at | 142 | * @param fn current filename we are looking at |
143 | * @return #GNUNET_SYSERR on serious errors, otherwise #GNUNET_OK | 143 | * @return #GNUNET_SYSERR on serious errors, otherwise #GNUNET_OK |
144 | */ | 144 | */ |
145 | static int | 145 | static enum GNUNET_GenericReturnValue |
146 | getSizeRec (void *cls, const char *fn) | 146 | get_size_rec (void *cls, const char *fn) |
147 | { | 147 | { |
148 | struct GetFileSizeData *gfsd = cls; | 148 | struct GetFileSizeData *gfsd = cls; |
149 | 149 | ||
@@ -175,35 +175,23 @@ getSizeRec (void *cls, const char *fn) | |||
175 | if ((S_ISDIR (buf.st_mode)) && (0 == access (fn, X_OK)) && | 175 | if ((S_ISDIR (buf.st_mode)) && (0 == access (fn, X_OK)) && |
176 | ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))) | 176 | ((! S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))) |
177 | { | 177 | { |
178 | if (GNUNET_SYSERR == GNUNET_DISK_directory_scan (fn, &getSizeRec, gfsd)) | 178 | if (GNUNET_SYSERR == GNUNET_DISK_directory_scan (fn, &get_size_rec, gfsd)) |
179 | return GNUNET_SYSERR; | 179 | return GNUNET_SYSERR; |
180 | } | 180 | } |
181 | return GNUNET_OK; | 181 | return GNUNET_OK; |
182 | } | 182 | } |
183 | 183 | ||
184 | 184 | ||
185 | /** | 185 | enum GNUNET_GenericReturnValue |
186 | * Checks whether a handle is invalid | ||
187 | * | ||
188 | * @param h handle to check | ||
189 | * @return #GNUNET_YES if invalid, #GNUNET_NO if valid | ||
190 | */ | ||
191 | int | ||
192 | GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h) | 186 | GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h) |
193 | { | 187 | { |
194 | return ((! h) || (h->fd == -1)) ? GNUNET_YES : GNUNET_NO; | 188 | return ((! h) || (h->fd == -1)) ? GNUNET_YES : GNUNET_NO; |
195 | } | 189 | } |
196 | 190 | ||
197 | 191 | ||
198 | /** | 192 | enum GNUNET_GenericReturnValue |
199 | * Get the size of an open file. | 193 | GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh, |
200 | * | 194 | off_t *size) |
201 | * @param fh open file handle | ||
202 | * @param size where to write size of the file | ||
203 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
204 | */ | ||
205 | int | ||
206 | GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh, off_t *size) | ||
207 | { | 195 | { |
208 | struct stat sbuf; | 196 | struct stat sbuf; |
209 | 197 | ||
@@ -214,80 +202,42 @@ GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh, off_t *size) | |||
214 | } | 202 | } |
215 | 203 | ||
216 | 204 | ||
217 | /** | ||
218 | * Move the read/write pointer in a file | ||
219 | * | ||
220 | * @param h handle of an open file | ||
221 | * @param offset position to move to | ||
222 | * @param whence specification to which position the offset parameter relates to | ||
223 | * @return the new position on success, #GNUNET_SYSERR otherwise | ||
224 | */ | ||
225 | off_t | 205 | off_t |
226 | GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, | 206 | GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, |
227 | off_t offset, | 207 | off_t offset, |
228 | enum GNUNET_DISK_Seek whence) | 208 | enum GNUNET_DISK_Seek whence) |
229 | { | 209 | { |
210 | static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END }; | ||
211 | |||
230 | if (h == NULL) | 212 | if (h == NULL) |
231 | { | 213 | { |
232 | errno = EINVAL; | 214 | errno = EINVAL; |
233 | return GNUNET_SYSERR; | 215 | return GNUNET_SYSERR; |
234 | } | 216 | } |
235 | |||
236 | static int t[] = { SEEK_SET, SEEK_CUR, SEEK_END }; | ||
237 | |||
238 | return lseek (h->fd, offset, t[whence]); | 217 | return lseek (h->fd, offset, t[whence]); |
239 | } | 218 | } |
240 | 219 | ||
241 | 220 | ||
242 | /** | 221 | enum GNUNET_GenericReturnValue |
243 | * Get the size of the file (or directory) of the given file (in | ||
244 | * bytes). | ||
245 | * | ||
246 | * @param filename name of the file or directory | ||
247 | * @param size set to the size of the file (or, | ||
248 | * in the case of directories, the sum | ||
249 | * of all sizes of files in the directory) | ||
250 | * @param include_symbolic_links should symbolic links be | ||
251 | * included? | ||
252 | * @param single_file_mode #GNUNET_YES to only get size of one file | ||
253 | * and return #GNUNET_SYSERR for directories. | ||
254 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
255 | */ | ||
256 | int | ||
257 | GNUNET_DISK_file_size (const char *filename, | 222 | GNUNET_DISK_file_size (const char *filename, |
258 | uint64_t *size, | 223 | uint64_t *size, |
259 | int include_symbolic_links, | 224 | int include_symbolic_links, |
260 | int single_file_mode) | 225 | int single_file_mode) |
261 | { | 226 | { |
262 | struct GetFileSizeData gfsd; | 227 | struct GetFileSizeData gfsd; |
263 | int ret; | 228 | enum GNUNET_GenericReturnValue ret; |
264 | 229 | ||
265 | GNUNET_assert (size != NULL); | 230 | GNUNET_assert (size != NULL); |
266 | gfsd.total = 0; | 231 | gfsd.total = 0; |
267 | gfsd.include_sym_links = include_symbolic_links; | 232 | gfsd.include_sym_links = include_symbolic_links; |
268 | gfsd.single_file_mode = single_file_mode; | 233 | gfsd.single_file_mode = single_file_mode; |
269 | ret = getSizeRec (&gfsd, filename); | 234 | ret = get_size_rec (&gfsd, filename); |
270 | *size = gfsd.total; | 235 | *size = gfsd.total; |
271 | return ret; | 236 | return ret; |
272 | } | 237 | } |
273 | 238 | ||
274 | 239 | ||
275 | /** | 240 | enum GNUNET_GenericReturnValue |
276 | * Obtain some unique identifiers for the given file | ||
277 | * that can be used to identify it in the local system. | ||
278 | * This function is used between GNUnet processes to | ||
279 | * quickly check if two files with the same absolute path | ||
280 | * are actually identical. The two processes represent | ||
281 | * the same peer but may communicate over the network | ||
282 | * (and the file may be on an NFS volume). This function | ||
283 | * may not be supported on all operating systems. | ||
284 | * | ||
285 | * @param filename name of the file | ||
286 | * @param dev set to the device ID | ||
287 | * @param ino set to the inode ID | ||
288 | * @return #GNUNET_OK on success | ||
289 | */ | ||
290 | int | ||
291 | GNUNET_DISK_file_get_identifiers (const char *filename, | 241 | GNUNET_DISK_file_get_identifiers (const char *filename, |
292 | uint64_t *dev, | 242 | uint64_t *dev, |
293 | uint64_t *ino) | 243 | uint64_t *ino) |
@@ -367,14 +317,6 @@ mktemp_name (const char *t) | |||
367 | } | 317 | } |
368 | 318 | ||
369 | 319 | ||
370 | /** | ||
371 | * Update POSIX permissions mask of a file on disk. If both argumets | ||
372 | * are #GNUNET_NO, the file is made world-read-write-executable (777). | ||
373 | * | ||
374 | * @param fn name of the file to update | ||
375 | * @param require_uid_match #GNUNET_YES means 700 | ||
376 | * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set | ||
377 | */ | ||
378 | void | 320 | void |
379 | GNUNET_DISK_fix_permissions (const char *fn, | 321 | GNUNET_DISK_fix_permissions (const char *fn, |
380 | int require_uid_match, | 322 | int require_uid_match, |
@@ -394,17 +336,6 @@ GNUNET_DISK_fix_permissions (const char *fn, | |||
394 | } | 336 | } |
395 | 337 | ||
396 | 338 | ||
397 | /** | ||
398 | * Create an (empty) temporary directory on disk. If the given name is not | ||
399 | * an absolute path, the current 'TMPDIR' will be prepended. In any case, | ||
400 | * 6 random characters will be appended to the name to create a unique | ||
401 | * filename. | ||
402 | * | ||
403 | * @param t component to use for the name; | ||
404 | * does NOT contain "XXXXXX" or "/tmp/". | ||
405 | * @return NULL on error, otherwise name of fresh | ||
406 | * file on disk in directory for temporary files | ||
407 | */ | ||
408 | char * | 339 | char * |
409 | GNUNET_DISK_mkdtemp (const char *t) | 340 | GNUNET_DISK_mkdtemp (const char *t) |
410 | { | 341 | { |
@@ -425,13 +356,6 @@ GNUNET_DISK_mkdtemp (const char *t) | |||
425 | } | 356 | } |
426 | 357 | ||
427 | 358 | ||
428 | /** | ||
429 | * Move a file out of the way (create a backup) by | ||
430 | * renaming it to "orig.NUM~" where NUM is the smallest | ||
431 | * number that is not used yet. | ||
432 | * | ||
433 | * @param fil name of the file to back up | ||
434 | */ | ||
435 | void | 359 | void |
436 | GNUNET_DISK_file_backup (const char *fil) | 360 | GNUNET_DISK_file_backup (const char *fil) |
437 | { | 361 | { |
@@ -453,17 +377,6 @@ GNUNET_DISK_file_backup (const char *fil) | |||
453 | } | 377 | } |
454 | 378 | ||
455 | 379 | ||
456 | /** | ||
457 | * Create an (empty) temporary file on disk. If the given name is not | ||
458 | * an absolute path, the current 'TMPDIR' will be prepended. In any case, | ||
459 | * 6 random characters will be appended to the name to create a unique | ||
460 | * filename. | ||
461 | * | ||
462 | * @param t component to use for the name; | ||
463 | * does NOT contain "XXXXXX" or "/tmp/". | ||
464 | * @return NULL on error, otherwise name of fresh | ||
465 | * file on disk in directory for temporary files | ||
466 | */ | ||
467 | char * | 380 | char * |
468 | GNUNET_DISK_mktemp (const char *t) | 381 | GNUNET_DISK_mktemp (const char *t) |
469 | { | 382 | { |
@@ -487,19 +400,7 @@ GNUNET_DISK_mktemp (const char *t) | |||
487 | } | 400 | } |
488 | 401 | ||
489 | 402 | ||
490 | /** | 403 | enum GNUNET_GenericReturnValue |
491 | * Test if @a fil is a directory and listable. Optionally, also check if the | ||
492 | * directory is readable. Will not print an error message if the directory does | ||
493 | * not exist. Will log errors if #GNUNET_SYSERR is returned (i.e., a file exists | ||
494 | * with the same name). | ||
495 | * | ||
496 | * @param fil filename to test | ||
497 | * @param is_readable #GNUNET_YES to additionally check if @a fil is readable; | ||
498 | * #GNUNET_NO to disable this check | ||
499 | * @return #GNUNET_YES if yes, #GNUNET_NO if not; #GNUNET_SYSERR if it | ||
500 | * does not exist or stat'ed | ||
501 | */ | ||
502 | int | ||
503 | GNUNET_DISK_directory_test (const char *fil, int is_readable) | 404 | GNUNET_DISK_directory_test (const char *fil, int is_readable) |
504 | { | 405 | { |
505 | struct stat filestat; | 406 | struct stat filestat; |
@@ -532,15 +433,7 @@ GNUNET_DISK_directory_test (const char *fil, int is_readable) | |||
532 | } | 433 | } |
533 | 434 | ||
534 | 435 | ||
535 | /** | 436 | enum GNUNET_GenericReturnValue |
536 | * Check that fil corresponds to a filename | ||
537 | * (of a file that exists and that is not a directory). | ||
538 | * | ||
539 | * @param fil filename to check | ||
540 | * @return #GNUNET_YES if yes, #GNUNET_NO if not a file, #GNUNET_SYSERR if something | ||
541 | * else (will print an error message in that case, too). | ||
542 | */ | ||
543 | int | ||
544 | GNUNET_DISK_file_test (const char *fil) | 437 | GNUNET_DISK_file_test (const char *fil) |
545 | { | 438 | { |
546 | struct stat filestat; | 439 | struct stat filestat; |
@@ -552,7 +445,7 @@ GNUNET_DISK_file_test (const char *fil) | |||
552 | return GNUNET_SYSERR; | 445 | return GNUNET_SYSERR; |
553 | 446 | ||
554 | ret = stat (rdir, &filestat); | 447 | ret = stat (rdir, &filestat); |
555 | if (ret != 0) | 448 | if (0 != ret) |
556 | { | 449 | { |
557 | if (errno != ENOENT) | 450 | if (errno != ENOENT) |
558 | { | 451 | { |
@@ -579,13 +472,7 @@ GNUNET_DISK_file_test (const char *fil) | |||
579 | } | 472 | } |
580 | 473 | ||
581 | 474 | ||
582 | /** | 475 | enum GNUNET_GenericReturnValue |
583 | * Implementation of "mkdir -p" | ||
584 | * | ||
585 | * @param dir the directory to create | ||
586 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure | ||
587 | */ | ||
588 | int | ||
589 | GNUNET_DISK_directory_create (const char *dir) | 476 | GNUNET_DISK_directory_create (const char *dir) |
590 | { | 477 | { |
591 | char *rdir; | 478 | char *rdir; |
@@ -671,22 +558,13 @@ GNUNET_DISK_directory_create (const char *dir) | |||
671 | } | 558 | } |
672 | 559 | ||
673 | 560 | ||
674 | /** | 561 | enum GNUNET_GenericReturnValue |
675 | * Create the directory structure for storing a file. | ||
676 | * | ||
677 | * @param filename name of a file in the directory | ||
678 | * @returns #GNUNET_OK on success, | ||
679 | * #GNUNET_SYSERR on failure, | ||
680 | * #GNUNET_NO if the directory | ||
681 | * exists but is not writeable for us | ||
682 | */ | ||
683 | int | ||
684 | GNUNET_DISK_directory_create_for_file (const char *filename) | 562 | GNUNET_DISK_directory_create_for_file (const char *filename) |
685 | { | 563 | { |
686 | char *rdir; | 564 | char *rdir; |
687 | size_t len; | 565 | size_t len; |
688 | int ret; | ||
689 | int eno; | 566 | int eno; |
567 | enum GNUNET_GenericReturnValue res; | ||
690 | 568 | ||
691 | rdir = GNUNET_STRINGS_filename_expand (filename); | 569 | rdir = GNUNET_STRINGS_filename_expand (filename); |
692 | if (NULL == rdir) | 570 | if (NULL == rdir) |
@@ -699,7 +577,6 @@ GNUNET_DISK_directory_create_for_file (const char *filename) | |||
699 | GNUNET_free (rdir); | 577 | GNUNET_free (rdir); |
700 | return GNUNET_OK; | 578 | return GNUNET_OK; |
701 | } | 579 | } |
702 | |||
703 | len = strlen (rdir); | 580 | len = strlen (rdir); |
704 | while ((len > 0) && (rdir[len] != DIR_SEPARATOR)) | 581 | while ((len > 0) && (rdir[len] != DIR_SEPARATOR)) |
705 | len--; | 582 | len--; |
@@ -710,24 +587,17 @@ GNUNET_DISK_directory_create_for_file (const char *filename) | |||
710 | GNUNET_free (rdir); | 587 | GNUNET_free (rdir); |
711 | rdir = GNUNET_strdup ("/"); | 588 | rdir = GNUNET_strdup ("/"); |
712 | } | 589 | } |
713 | ret = GNUNET_DISK_directory_create (rdir); | 590 | res = GNUNET_DISK_directory_create (rdir); |
714 | if ((GNUNET_OK == ret) && (0 != access (rdir, W_OK))) | 591 | if ( (GNUNET_OK == res) && |
715 | ret = GNUNET_NO; | 592 | (0 != access (rdir, W_OK)) ) |
593 | res = GNUNET_NO; | ||
716 | eno = errno; | 594 | eno = errno; |
717 | GNUNET_free (rdir); | 595 | GNUNET_free (rdir); |
718 | errno = eno; | 596 | errno = eno; |
719 | return ret; | 597 | return res; |
720 | } | 598 | } |
721 | 599 | ||
722 | 600 | ||
723 | /** | ||
724 | * Read the contents of a binary file into a buffer. | ||
725 | * | ||
726 | * @param h handle to an open file | ||
727 | * @param result the buffer to write the result to | ||
728 | * @param len the maximum number of bytes to read | ||
729 | * @return the number of bytes read on success, #GNUNET_SYSERR on failure | ||
730 | */ | ||
731 | ssize_t | 601 | ssize_t |
732 | GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h, | 602 | GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h, |
733 | void *result, | 603 | void *result, |
@@ -738,35 +608,23 @@ GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h, | |||
738 | errno = EINVAL; | 608 | errno = EINVAL; |
739 | return GNUNET_SYSERR; | 609 | return GNUNET_SYSERR; |
740 | } | 610 | } |
741 | |||
742 | return read (h->fd, result, len); | 611 | return read (h->fd, result, len); |
743 | } | 612 | } |
744 | 613 | ||
745 | 614 | ||
746 | /** | ||
747 | * Read the contents of a binary file into a buffer. | ||
748 | * Guarantees not to block (returns GNUNET_SYSERR and sets errno to EAGAIN | ||
749 | * when no data can be read). | ||
750 | * | ||
751 | * @param h handle to an open file | ||
752 | * @param result the buffer to write the result to | ||
753 | * @param len the maximum number of bytes to read | ||
754 | * @return the number of bytes read on success, #GNUNET_SYSERR on failure | ||
755 | */ | ||
756 | ssize_t | 615 | ssize_t |
757 | GNUNET_DISK_file_read_non_blocking (const struct GNUNET_DISK_FileHandle *h, | 616 | GNUNET_DISK_file_read_non_blocking (const struct GNUNET_DISK_FileHandle *h, |
758 | void *result, | 617 | void *result, |
759 | size_t len) | 618 | size_t len) |
760 | { | 619 | { |
620 | int flags; | ||
621 | ssize_t ret; | ||
622 | |||
761 | if (NULL == h) | 623 | if (NULL == h) |
762 | { | 624 | { |
763 | errno = EINVAL; | 625 | errno = EINVAL; |
764 | return GNUNET_SYSERR; | 626 | return GNUNET_SYSERR; |
765 | } | 627 | } |
766 | |||
767 | int flags; | ||
768 | ssize_t ret; | ||
769 | |||
770 | /* set to non-blocking, read, then set back */ | 628 | /* set to non-blocking, read, then set back */ |
771 | flags = fcntl (h->fd, F_GETFL); | 629 | flags = fcntl (h->fd, F_GETFL); |
772 | if (0 == (flags & O_NONBLOCK)) | 630 | if (0 == (flags & O_NONBLOCK)) |
@@ -782,22 +640,18 @@ GNUNET_DISK_file_read_non_blocking (const struct GNUNET_DISK_FileHandle *h, | |||
782 | } | 640 | } |
783 | 641 | ||
784 | 642 | ||
785 | /** | ||
786 | * Read the contents of a binary file into a buffer. | ||
787 | * | ||
788 | * @param fn file name | ||
789 | * @param result the buffer to write the result to | ||
790 | * @param len the maximum number of bytes to read | ||
791 | * @return number of bytes read, #GNUNET_SYSERR on failure | ||
792 | */ | ||
793 | ssize_t | 643 | ssize_t |
794 | GNUNET_DISK_fn_read (const char *fn, void *result, size_t len) | 644 | GNUNET_DISK_fn_read (const char *fn, |
645 | void *result, | ||
646 | size_t len) | ||
795 | { | 647 | { |
796 | struct GNUNET_DISK_FileHandle *fh; | 648 | struct GNUNET_DISK_FileHandle *fh; |
797 | ssize_t ret; | 649 | ssize_t ret; |
798 | int eno; | 650 | int eno; |
799 | 651 | ||
800 | fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); | 652 | fh = GNUNET_DISK_file_open (fn, |
653 | GNUNET_DISK_OPEN_READ, | ||
654 | GNUNET_DISK_PERM_NONE); | ||
801 | if (NULL == fh) | 655 | if (NULL == fh) |
802 | return GNUNET_SYSERR; | 656 | return GNUNET_SYSERR; |
803 | ret = GNUNET_DISK_file_read (fh, result, len); | 657 | ret = GNUNET_DISK_file_read (fh, result, len); |
@@ -808,14 +662,6 @@ GNUNET_DISK_fn_read (const char *fn, void *result, size_t len) | |||
808 | } | 662 | } |
809 | 663 | ||
810 | 664 | ||
811 | /** | ||
812 | * Write a buffer to a file. | ||
813 | * | ||
814 | * @param h handle to open file | ||
815 | * @param buffer the data to write | ||
816 | * @param n number of bytes to write | ||
817 | * @return number of bytes written on success, #GNUNET_SYSERR on error | ||
818 | */ | ||
819 | ssize_t | 665 | ssize_t |
820 | GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h, | 666 | GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h, |
821 | const void *buffer, | 667 | const void *buffer, |
@@ -831,29 +677,19 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h, | |||
831 | } | 677 | } |
832 | 678 | ||
833 | 679 | ||
834 | /** | ||
835 | * Write a buffer to a file, blocking, if necessary. | ||
836 | * | ||
837 | * @param h handle to open file | ||
838 | * @param buffer the data to write | ||
839 | * @param n number of bytes to write | ||
840 | * @return number of bytes written on success, #GNUNET_SYSERR on error | ||
841 | */ | ||
842 | ssize_t | 680 | ssize_t |
843 | GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle *h, | 681 | GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle *h, |
844 | const void *buffer, | 682 | const void *buffer, |
845 | size_t n) | 683 | size_t n) |
846 | { | 684 | { |
685 | int flags; | ||
686 | ssize_t ret; | ||
687 | |||
847 | if (NULL == h) | 688 | if (NULL == h) |
848 | { | 689 | { |
849 | errno = EINVAL; | 690 | errno = EINVAL; |
850 | return GNUNET_SYSERR; | 691 | return GNUNET_SYSERR; |
851 | } | 692 | } |
852 | |||
853 | |||
854 | int flags; | ||
855 | ssize_t ret; | ||
856 | |||
857 | /* set to blocking, write, then set back */ | 693 | /* set to blocking, write, then set back */ |
858 | flags = fcntl (h->fd, F_GETFL); | 694 | flags = fcntl (h->fd, F_GETFL); |
859 | if (0 != (flags & O_NONBLOCK)) | 695 | if (0 != (flags & O_NONBLOCK)) |
@@ -865,48 +701,95 @@ GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle *h, | |||
865 | } | 701 | } |
866 | 702 | ||
867 | 703 | ||
868 | /** | 704 | enum GNUNET_GenericReturnValue |
869 | * Write a buffer to a file. If the file is longer than the | ||
870 | * number of bytes that will be written, it will be truncated. | ||
871 | * | ||
872 | * @param fn file name | ||
873 | * @param buffer the data to write | ||
874 | * @param n number of bytes to write | ||
875 | * @param mode file permissions | ||
876 | * @return number of bytes written on success, #GNUNET_SYSERR on error | ||
877 | */ | ||
878 | ssize_t | ||
879 | GNUNET_DISK_fn_write (const char *fn, | 705 | GNUNET_DISK_fn_write (const char *fn, |
880 | const void *buffer, | 706 | const void *buf, |
881 | size_t n, | 707 | size_t buf_size, |
882 | enum GNUNET_DISK_AccessPermissions mode) | 708 | enum GNUNET_DISK_AccessPermissions mode) |
883 | { | 709 | { |
884 | struct GNUNET_DISK_FileHandle *fh; | 710 | char *tmpl; |
885 | ssize_t ret; | 711 | int fd; |
886 | 712 | ||
887 | fh = | 713 | if (GNUNET_OK != |
888 | GNUNET_DISK_file_open (fn, | 714 | GNUNET_DISK_directory_create_for_file (fn)) |
889 | GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE | 715 | { |
890 | | GNUNET_DISK_OPEN_CREATE, | 716 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, |
891 | mode); | 717 | "mkstemp", |
892 | if (! fh) | 718 | fn); |
893 | return GNUNET_SYSERR; | 719 | return GNUNET_SYSERR; |
894 | ret = GNUNET_DISK_file_write (fh, buffer, n); | 720 | } |
895 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); | 721 | { |
896 | return ret; | 722 | char *dname; |
723 | |||
724 | dname = GNUNET_strdup (fn); | ||
725 | GNUNET_asprintf (&tmpl, | ||
726 | "%s/XXXXXX", | ||
727 | dirname (dname)); | ||
728 | GNUNET_free (dname); | ||
729 | } | ||
730 | fd = mkstemp (tmpl); | ||
731 | if (-1 == fd) | ||
732 | { | ||
733 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
734 | "mkstemp", | ||
735 | tmpl); | ||
736 | GNUNET_free (tmpl); | ||
737 | return GNUNET_SYSERR; | ||
738 | } | ||
739 | |||
740 | if (0 != fchmod (fd, | ||
741 | translate_unix_perms (mode))) | ||
742 | { | ||
743 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
744 | "chmod", | ||
745 | tmpl); | ||
746 | GNUNET_assert (0 == close (fd)); | ||
747 | if (0 != unlink (tmpl)) | ||
748 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
749 | "unlink", | ||
750 | tmpl); | ||
751 | GNUNET_free (tmpl); | ||
752 | return GNUNET_SYSERR; | ||
753 | } | ||
754 | if (buf_size != | ||
755 | write (fd, | ||
756 | buf, | ||
757 | buf_size)) | ||
758 | { | ||
759 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
760 | "write", | ||
761 | tmpl); | ||
762 | GNUNET_assert (0 == close (fd)); | ||
763 | if (0 != unlink (tmpl)) | ||
764 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
765 | "unlink", | ||
766 | tmpl); | ||
767 | GNUNET_free (tmpl); | ||
768 | return GNUNET_SYSERR; | ||
769 | } | ||
770 | GNUNET_assert (0 == close (fd)); | ||
771 | |||
772 | if (0 != link (tmpl, | ||
773 | fn)) | ||
774 | { | ||
775 | if (0 != unlink (tmpl)) | ||
776 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
777 | "unlink", | ||
778 | tmpl); | ||
779 | GNUNET_free (tmpl); | ||
780 | return GNUNET_NO; | ||
781 | } | ||
782 | if (0 != unlink (tmpl)) | ||
783 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
784 | "unlink", | ||
785 | tmpl); | ||
786 | GNUNET_free (tmpl); | ||
787 | return GNUNET_OK; | ||
788 | |||
789 | |||
897 | } | 790 | } |
898 | 791 | ||
899 | 792 | ||
900 | /** | ||
901 | * Scan a directory for files. | ||
902 | * | ||
903 | * @param dir_name the name of the directory | ||
904 | * @param callback the method to call for each file, | ||
905 | * can be NULL, in that case, we only count | ||
906 | * @param callback_cls closure for @a callback | ||
907 | * @return the number of files found, #GNUNET_SYSERR on error or | ||
908 | * ieration aborted by callback returning #GNUNET_SYSERR | ||
909 | */ | ||
910 | int | 793 | int |
911 | GNUNET_DISK_directory_scan (const char *dir_name, | 794 | GNUNET_DISK_directory_scan (const char *dir_name, |
912 | GNUNET_FileNameCallback callback, | 795 | GNUNET_FileNameCallback callback, |
@@ -916,7 +799,7 @@ GNUNET_DISK_directory_scan (const char *dir_name, | |||
916 | struct dirent *finfo; | 799 | struct dirent *finfo; |
917 | struct stat istat; | 800 | struct stat istat; |
918 | int count = 0; | 801 | int count = 0; |
919 | int ret; | 802 | enum GNUNET_GenericReturnValue ret; |
920 | char *name; | 803 | char *name; |
921 | char *dname; | 804 | char *dname; |
922 | unsigned int name_len; | 805 | unsigned int name_len; |
@@ -1008,8 +891,9 @@ GNUNET_DISK_directory_scan (const char *dir_name, | |||
1008 | * @param fn directory to remove | 891 | * @param fn directory to remove |
1009 | * @return #GNUNET_OK | 892 | * @return #GNUNET_OK |
1010 | */ | 893 | */ |
1011 | static int | 894 | static enum GNUNET_GenericReturnValue |
1012 | remove_helper (void *unused, const char *fn) | 895 | remove_helper (void *unused, |
896 | const char *fn) | ||
1013 | { | 897 | { |
1014 | (void) unused; | 898 | (void) unused; |
1015 | (void) GNUNET_DISK_directory_remove (fn); | 899 | (void) GNUNET_DISK_directory_remove (fn); |
@@ -1017,14 +901,7 @@ remove_helper (void *unused, const char *fn) | |||
1017 | } | 901 | } |
1018 | 902 | ||
1019 | 903 | ||
1020 | /** | 904 | enum GNUNET_GenericReturnValue |
1021 | * Remove all files in a directory (rm -r). Call with | ||
1022 | * caution. | ||
1023 | * | ||
1024 | * @param filename the file to remove | ||
1025 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1026 | */ | ||
1027 | int | ||
1028 | GNUNET_DISK_directory_remove (const char *filename) | 905 | GNUNET_DISK_directory_remove (const char *filename) |
1029 | { | 906 | { |
1030 | struct stat istat; | 907 | struct stat istat; |
@@ -1036,14 +913,17 @@ GNUNET_DISK_directory_remove (const char *filename) | |||
1036 | } | 913 | } |
1037 | if (0 != lstat (filename, &istat)) | 914 | if (0 != lstat (filename, &istat)) |
1038 | return GNUNET_NO; /* file may not exist... */ | 915 | return GNUNET_NO; /* file may not exist... */ |
1039 | (void) chmod (filename, S_IWUSR | S_IRUSR | S_IXUSR); | 916 | (void) chmod (filename, |
917 | S_IWUSR | S_IRUSR | S_IXUSR); | ||
1040 | if (0 == unlink (filename)) | 918 | if (0 == unlink (filename)) |
1041 | return GNUNET_OK; | 919 | return GNUNET_OK; |
1042 | if ((errno != EISDIR) && | 920 | if ( (errno != EISDIR) && |
1043 | /* EISDIR is not sufficient in all cases, e.g. | 921 | /* EISDIR is not sufficient in all cases, e.g. |
1044 | * sticky /tmp directory may result in EPERM on BSD. | 922 | * sticky /tmp directory may result in EPERM on BSD. |
1045 | * So we also explicitly check "isDirectory" */ | 923 | * So we also explicitly check "isDirectory" */ |
1046 | (GNUNET_YES != GNUNET_DISK_directory_test (filename, GNUNET_YES))) | 924 | (GNUNET_YES != |
925 | GNUNET_DISK_directory_test (filename, | ||
926 | GNUNET_YES)) ) | ||
1047 | { | 927 | { |
1048 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", filename); | 928 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", filename); |
1049 | return GNUNET_SYSERR; | 929 | return GNUNET_SYSERR; |
@@ -1060,15 +940,9 @@ GNUNET_DISK_directory_remove (const char *filename) | |||
1060 | } | 940 | } |
1061 | 941 | ||
1062 | 942 | ||
1063 | /** | 943 | enum GNUNET_GenericReturnValue |
1064 | * Copy a file. | 944 | GNUNET_DISK_file_copy (const char *src, |
1065 | * | 945 | const char *dst) |
1066 | * @param src file to copy | ||
1067 | * @param dst destination file name | ||
1068 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1069 | */ | ||
1070 | int | ||
1071 | GNUNET_DISK_file_copy (const char *src, const char *dst) | ||
1072 | { | 946 | { |
1073 | char *buf; | 947 | char *buf; |
1074 | uint64_t pos; | 948 | uint64_t pos; |
@@ -1131,10 +1005,6 @@ FAIL: | |||
1131 | } | 1005 | } |
1132 | 1006 | ||
1133 | 1007 | ||
1134 | /** | ||
1135 | * @brief Removes special characters as ':' from a filename. | ||
1136 | * @param fn the filename to canonicalize | ||
1137 | */ | ||
1138 | void | 1008 | void |
1139 | GNUNET_DISK_filename_canonicalize (char *fn) | 1009 | GNUNET_DISK_filename_canonicalize (char *fn) |
1140 | { | 1010 | { |
@@ -1157,15 +1027,9 @@ GNUNET_DISK_filename_canonicalize (char *fn) | |||
1157 | } | 1027 | } |
1158 | 1028 | ||
1159 | 1029 | ||
1160 | /** | 1030 | enum GNUNET_GenericReturnValue |
1161 | * @brief Change owner of a file | 1031 | GNUNET_DISK_file_change_owner (const char *filename, |
1162 | * | 1032 | const char *user) |
1163 | * @param filename name of file to change the owner of | ||
1164 | * @param user name of the new owner | ||
1165 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure | ||
1166 | */ | ||
1167 | int | ||
1168 | GNUNET_DISK_file_change_owner (const char *filename, const char *user) | ||
1169 | { | 1033 | { |
1170 | struct passwd *pws; | 1034 | struct passwd *pws; |
1171 | 1035 | ||
@@ -1187,18 +1051,6 @@ GNUNET_DISK_file_change_owner (const char *filename, const char *user) | |||
1187 | } | 1051 | } |
1188 | 1052 | ||
1189 | 1053 | ||
1190 | /** | ||
1191 | * Open a file. Note that the access permissions will only be | ||
1192 | * used if a new file is created and if the underlying operating | ||
1193 | * system supports the given permissions. | ||
1194 | * | ||
1195 | * @param fn file name to be opened | ||
1196 | * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags | ||
1197 | * @param perm permissions for the newly created file, use | ||
1198 | * #GNUNET_DISK_PERM_NONE if a file could not be created by this | ||
1199 | * call (because of flags) | ||
1200 | * @return IO handle on success, NULL on error | ||
1201 | */ | ||
1202 | struct GNUNET_DISK_FileHandle * | 1054 | struct GNUNET_DISK_FileHandle * |
1203 | GNUNET_DISK_file_open (const char *fn, | 1055 | GNUNET_DISK_file_open (const char *fn, |
1204 | enum GNUNET_DISK_OpenFlags flags, | 1056 | enum GNUNET_DISK_OpenFlags flags, |
@@ -1270,42 +1122,28 @@ GNUNET_DISK_file_open (const char *fn, | |||
1270 | } | 1122 | } |
1271 | 1123 | ||
1272 | 1124 | ||
1273 | /** | 1125 | enum GNUNET_GenericReturnValue |
1274 | * Close an open file. | ||
1275 | * | ||
1276 | * @param h file handle | ||
1277 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | ||
1278 | */ | ||
1279 | int | ||
1280 | GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h) | 1126 | GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h) |
1281 | { | 1127 | { |
1282 | int ret; | 1128 | enum GNUNET_GenericReturnValue ret; |
1283 | 1129 | ||
1284 | if (h == NULL) | 1130 | if (NULL == h) |
1285 | { | 1131 | { |
1286 | errno = EINVAL; | 1132 | errno = EINVAL; |
1287 | return GNUNET_SYSERR; | 1133 | return GNUNET_SYSERR; |
1288 | } | 1134 | } |
1289 | 1135 | ||
1290 | ret = GNUNET_OK; | 1136 | ret = GNUNET_OK; |
1291 | 1137 | if (0 != close (h->fd)) | |
1292 | if (close (h->fd) != 0) | ||
1293 | { | 1138 | { |
1294 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "close"); | 1139 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "close"); |
1295 | ret = GNUNET_SYSERR; | 1140 | ret = GNUNET_SYSERR; |
1296 | } | 1141 | } |
1297 | |||
1298 | GNUNET_free (h); | 1142 | GNUNET_free (h); |
1299 | return ret; | 1143 | return ret; |
1300 | } | 1144 | } |
1301 | 1145 | ||
1302 | 1146 | ||
1303 | /** | ||
1304 | * Get a handle from a native integer FD. | ||
1305 | * | ||
1306 | * @param fno native integer file descriptor | ||
1307 | * @return file handle corresponding to the descriptor, NULL on error | ||
1308 | */ | ||
1309 | struct GNUNET_DISK_FileHandle * | 1147 | struct GNUNET_DISK_FileHandle * |
1310 | GNUNET_DISK_get_handle_from_int_fd (int fno) | 1148 | GNUNET_DISK_get_handle_from_int_fd (int fno) |
1311 | { | 1149 | { |
@@ -1322,12 +1160,6 @@ GNUNET_DISK_get_handle_from_int_fd (int fno) | |||
1322 | } | 1160 | } |
1323 | 1161 | ||
1324 | 1162 | ||
1325 | /** | ||
1326 | * Get a handle from a native streaming FD. | ||
1327 | * | ||
1328 | * @param fd native streaming file descriptor | ||
1329 | * @return file handle corresponding to the descriptor | ||
1330 | */ | ||
1331 | struct GNUNET_DISK_FileHandle * | 1163 | struct GNUNET_DISK_FileHandle * |
1332 | GNUNET_DISK_get_handle_from_native (FILE *fd) | 1164 | GNUNET_DISK_get_handle_from_native (FILE *fd) |
1333 | { | 1165 | { |
@@ -1336,7 +1168,6 @@ GNUNET_DISK_get_handle_from_native (FILE *fd) | |||
1336 | fno = fileno (fd); | 1168 | fno = fileno (fd); |
1337 | if (-1 == fno) | 1169 | if (-1 == fno) |
1338 | return NULL; | 1170 | return NULL; |
1339 | |||
1340 | return GNUNET_DISK_get_handle_from_int_fd (fno); | 1171 | return GNUNET_DISK_get_handle_from_int_fd (fno); |
1341 | } | 1172 | } |
1342 | 1173 | ||
@@ -1362,15 +1193,7 @@ struct GNUNET_DISK_MapHandle | |||
1362 | #define MAP_FAILED ((void *) -1) | 1193 | #define MAP_FAILED ((void *) -1) |
1363 | #endif | 1194 | #endif |
1364 | 1195 | ||
1365 | /** | 1196 | |
1366 | * Map a file into memory | ||
1367 | * | ||
1368 | * @param h open file handle | ||
1369 | * @param m handle to the new mapping | ||
1370 | * @param access access specification, GNUNET_DISK_MAP_TYPE_xxx | ||
1371 | * @param len size of the mapping | ||
1372 | * @return pointer to the mapped memory region, NULL on failure | ||
1373 | */ | ||
1374 | void * | 1197 | void * |
1375 | GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h, | 1198 | GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h, |
1376 | struct GNUNET_DISK_MapHandle **m, | 1199 | struct GNUNET_DISK_MapHandle **m, |
@@ -1402,16 +1225,10 @@ GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h, | |||
1402 | } | 1225 | } |
1403 | 1226 | ||
1404 | 1227 | ||
1405 | /** | 1228 | enum GNUNET_GenericReturnValue |
1406 | * Unmap a file | ||
1407 | * | ||
1408 | * @param h mapping handle | ||
1409 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | ||
1410 | */ | ||
1411 | int | ||
1412 | GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h) | 1229 | GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h) |
1413 | { | 1230 | { |
1414 | int ret; | 1231 | enum GNUNET_GenericReturnValue ret; |
1415 | 1232 | ||
1416 | if (NULL == h) | 1233 | if (NULL == h) |
1417 | { | 1234 | { |
@@ -1424,12 +1241,7 @@ GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h) | |||
1424 | } | 1241 | } |
1425 | 1242 | ||
1426 | 1243 | ||
1427 | /** | 1244 | enum GNUNET_GenericReturnValue |
1428 | * Write file changes to disk | ||
1429 | * @param h handle to an open file | ||
1430 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | ||
1431 | */ | ||
1432 | int | ||
1433 | GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h) | 1245 | GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h) |
1434 | { | 1246 | { |
1435 | if (h == NULL) | 1247 | if (h == NULL) |
@@ -1446,12 +1258,6 @@ GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h) | |||
1446 | } | 1258 | } |
1447 | 1259 | ||
1448 | 1260 | ||
1449 | /** | ||
1450 | * Creates an interprocess channel | ||
1451 | * | ||
1452 | * @param pf how to configure the pipe | ||
1453 | * @return handle to the new pipe, NULL on error | ||
1454 | */ | ||
1455 | struct GNUNET_DISK_PipeHandle * | 1261 | struct GNUNET_DISK_PipeHandle * |
1456 | GNUNET_DISK_pipe (enum GNUNET_DISK_PipeFlags pf) | 1262 | GNUNET_DISK_pipe (enum GNUNET_DISK_PipeFlags pf) |
1457 | { | 1263 | { |
@@ -1469,15 +1275,6 @@ GNUNET_DISK_pipe (enum GNUNET_DISK_PipeFlags pf) | |||
1469 | } | 1275 | } |
1470 | 1276 | ||
1471 | 1277 | ||
1472 | /** | ||
1473 | * Creates a pipe object from a couple of file descriptors. | ||
1474 | * Useful for wrapping existing pipe FDs. | ||
1475 | * | ||
1476 | * @param pf how to configure the pipe | ||
1477 | * @param fd an array of two fd values. One of them may be -1 for read-only or write-only pipes | ||
1478 | * | ||
1479 | * @return handle to the new pipe, NULL on error | ||
1480 | */ | ||
1481 | struct GNUNET_DISK_PipeHandle * | 1278 | struct GNUNET_DISK_PipeHandle * |
1482 | GNUNET_DISK_pipe_from_fd (enum GNUNET_DISK_PipeFlags pf, | 1279 | GNUNET_DISK_pipe_from_fd (enum GNUNET_DISK_PipeFlags pf, |
1483 | int fd[2]) | 1280 | int fd[2]) |
@@ -1551,18 +1348,11 @@ GNUNET_DISK_pipe_from_fd (enum GNUNET_DISK_PipeFlags pf, | |||
1551 | } | 1348 | } |
1552 | 1349 | ||
1553 | 1350 | ||
1554 | /** | 1351 | enum GNUNET_GenericReturnValue |
1555 | * Closes an interprocess channel | ||
1556 | * | ||
1557 | * @param p pipe to close | ||
1558 | * @param end which end of the pipe to close | ||
1559 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | ||
1560 | */ | ||
1561 | int | ||
1562 | GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p, | 1352 | GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p, |
1563 | enum GNUNET_DISK_PipeEnd end) | 1353 | enum GNUNET_DISK_PipeEnd end) |
1564 | { | 1354 | { |
1565 | int ret = GNUNET_OK; | 1355 | enum GNUNET_GenericReturnValue ret = GNUNET_OK; |
1566 | 1356 | ||
1567 | if (end == GNUNET_DISK_PIPE_END_READ) | 1357 | if (end == GNUNET_DISK_PIPE_END_READ) |
1568 | { | 1358 | { |
@@ -1580,23 +1370,10 @@ GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p, | |||
1580 | p->fd[1] = NULL; | 1370 | p->fd[1] = NULL; |
1581 | } | 1371 | } |
1582 | } | 1372 | } |
1583 | |||
1584 | return ret; | 1373 | return ret; |
1585 | } | 1374 | } |
1586 | 1375 | ||
1587 | 1376 | ||
1588 | /** | ||
1589 | * Detaches one of the ends from the pipe. | ||
1590 | * Detached end is a fully-functional FileHandle, it will | ||
1591 | * not be affected by anything you do with the pipe afterwards. | ||
1592 | * Each end of a pipe can only be detched from it once (i.e. | ||
1593 | * it is not duplicated). | ||
1594 | * | ||
1595 | * @param p pipe to detach an end from | ||
1596 | * @param end which end of the pipe to detach | ||
1597 | * @return Detached end on success, NULL on failure | ||
1598 | * (or if that end is not present or is closed). | ||
1599 | */ | ||
1600 | struct GNUNET_DISK_FileHandle * | 1377 | struct GNUNET_DISK_FileHandle * |
1601 | GNUNET_DISK_pipe_detach_end (struct GNUNET_DISK_PipeHandle *p, | 1378 | GNUNET_DISK_pipe_detach_end (struct GNUNET_DISK_PipeHandle *p, |
1602 | enum GNUNET_DISK_PipeEnd end) | 1379 | enum GNUNET_DISK_PipeEnd end) |
@@ -1624,13 +1401,7 @@ GNUNET_DISK_pipe_detach_end (struct GNUNET_DISK_PipeHandle *p, | |||
1624 | } | 1401 | } |
1625 | 1402 | ||
1626 | 1403 | ||
1627 | /** | 1404 | enum GNUNET_GenericReturnValue |
1628 | * Closes an interprocess channel | ||
1629 | * | ||
1630 | * @param p pipe to close | ||
1631 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | ||
1632 | */ | ||
1633 | int | ||
1634 | GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p) | 1405 | GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p) |
1635 | { | 1406 | { |
1636 | int ret = GNUNET_OK; | 1407 | int ret = GNUNET_OK; |
@@ -1661,13 +1432,6 @@ GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p) | |||
1661 | } | 1432 | } |
1662 | 1433 | ||
1663 | 1434 | ||
1664 | /** | ||
1665 | * Get the handle to a particular pipe end | ||
1666 | * | ||
1667 | * @param p pipe | ||
1668 | * @param n end to access | ||
1669 | * @return handle for the respective end | ||
1670 | */ | ||
1671 | const struct GNUNET_DISK_FileHandle * | 1435 | const struct GNUNET_DISK_FileHandle * |
1672 | GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, | 1436 | GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, |
1673 | enum GNUNET_DISK_PipeEnd n) | 1437 | enum GNUNET_DISK_PipeEnd n) |
@@ -1685,26 +1449,16 @@ GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, | |||
1685 | } | 1449 | } |
1686 | 1450 | ||
1687 | 1451 | ||
1688 | /** | 1452 | enum GNUNET_GenericReturnValue |
1689 | * Retrieve OS file handle | ||
1690 | * @internal | ||
1691 | * @param fh GNUnet file descriptor | ||
1692 | * @param dst destination buffer | ||
1693 | * @param dst_len length of dst | ||
1694 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | ||
1695 | */ | ||
1696 | int | ||
1697 | GNUNET_DISK_internal_file_handle_ (const struct GNUNET_DISK_FileHandle *fh, | 1453 | GNUNET_DISK_internal_file_handle_ (const struct GNUNET_DISK_FileHandle *fh, |
1698 | void *dst, | 1454 | void *dst, |
1699 | size_t dst_len) | 1455 | size_t dst_len) |
1700 | { | 1456 | { |
1701 | if (NULL == fh) | 1457 | if (NULL == fh) |
1702 | return GNUNET_SYSERR; | 1458 | return GNUNET_SYSERR; |
1703 | |||
1704 | if (dst_len < sizeof(int)) | 1459 | if (dst_len < sizeof(int)) |
1705 | return GNUNET_SYSERR; | 1460 | return GNUNET_SYSERR; |
1706 | *((int *) dst) = fh->fd; | 1461 | *((int *) dst) = fh->fd; |
1707 | |||
1708 | return GNUNET_OK; | 1462 | return GNUNET_OK; |
1709 | } | 1463 | } |
1710 | 1464 | ||
@@ -1716,8 +1470,9 @@ GNUNET_DISK_internal_file_handle_ (const struct GNUNET_DISK_FileHandle *fh, | |||
1716 | * @param cfg our configuration | 1470 | * @param cfg our configuration |
1717 | * @return #GNUNET_OK on success | 1471 | * @return #GNUNET_OK on success |
1718 | */ | 1472 | */ |
1719 | static int | 1473 | static enum GNUNET_GenericReturnValue |
1720 | purge_cfg_dir (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | 1474 | purge_cfg_dir (void *cls, |
1475 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
1721 | { | 1476 | { |
1722 | const char *option = cls; | 1477 | const char *option = cls; |
1723 | char *tmpname; | 1478 | char *tmpname; |
@@ -1739,15 +1494,9 @@ purge_cfg_dir (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1739 | } | 1494 | } |
1740 | 1495 | ||
1741 | 1496 | ||
1742 | /** | ||
1743 | * Remove the directory given under @a option in | ||
1744 | * section [PATHS] in configuration under @a cfg_filename | ||
1745 | * | ||
1746 | * @param cfg_filename configuration file to parse | ||
1747 | * @param option option with the dir name to purge | ||
1748 | */ | ||
1749 | void | 1497 | void |
1750 | GNUNET_DISK_purge_cfg_dir (const char *cfg_filename, const char *option) | 1498 | GNUNET_DISK_purge_cfg_dir (const char *cfg_filename, |
1499 | const char *option) | ||
1751 | { | 1500 | { |
1752 | GNUNET_break (GNUNET_OK == | 1501 | GNUNET_break (GNUNET_OK == |
1753 | GNUNET_CONFIGURATION_parse_and_run (cfg_filename, | 1502 | GNUNET_CONFIGURATION_parse_and_run (cfg_filename, |