aboutsummaryrefslogtreecommitdiff
path: root/src/util/disk.c
diff options
context:
space:
mode:
authorNils Durner <durner@gnunet.org>2009-06-15 20:11:51 +0000
committerNils Durner <durner@gnunet.org>2009-06-15 20:11:51 +0000
commit1088905b5a89a24706d2c1877d289589e3f3c222 (patch)
tree38ec7cdc1b80502aa950c68ebefe1e3f42efa14b /src/util/disk.c
parent7e3df72d6b8a32b15b02110b54c77f77e28928a2 (diff)
downloadgnunet-1088905b5a89a24706d2c1877d289589e3f3c222.tar.gz
gnunet-1088905b5a89a24706d2c1877d289589e3f3c222.zip
more complete DISK API
Diffstat (limited to 'src/util/disk.c')
-rw-r--r--src/util/disk.c566
1 files changed, 452 insertions, 114 deletions
diff --git a/src/util/disk.c b/src/util/disk.c
index 5042f0867..b0d3b18a4 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2005, 2006 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2005, 2006, 2009 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -22,11 +22,14 @@
22 * @file util/disk.c 22 * @file util/disk.c
23 * @brief disk IO convenience methods 23 * @brief disk IO convenience methods
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Nils Durner
25 */ 26 */
26 27
27#include "platform.h" 28#include "platform.h"
29#include "io_handle.h"
28#include "gnunet_common.h" 30#include "gnunet_common.h"
29#include "gnunet_directories.h" 31#include "gnunet_directories.h"
32#include "gnunet_io_lib.h"
30#include "gnunet_disk_lib.h" 33#include "gnunet_disk_lib.h"
31#include "gnunet_scheduler_lib.h" 34#include "gnunet_scheduler_lib.h"
32#include "gnunet_strings_lib.h" 35#include "gnunet_strings_lib.h"
@@ -108,6 +111,44 @@ getSizeRec (void *ptr, const char *fn)
108 return GNUNET_OK; 111 return GNUNET_OK;
109} 112}
110 113
114
115/**
116 * Move the read/write pointer in a file
117 * @param h handle of an open file
118 * @param offset position to move to
119 * @param whence specification to which position the offset parameter relates to
120 * @return the new position on success, GNUNET_SYSERR otherwise
121 */
122off_t
123GNUNET_DISK_file_seek (const struct GNUNET_IO_Handle *h, off_t offset,
124 enum GNUNET_DISK_Seek whence)
125{
126 if (h == NULL)
127 {
128 errno = EINVAL;
129 return GNUNET_SYSERR;
130 }
131
132#ifdef MINGW
133 DWORD ret;
134 static DWORD t[] = { [GNUNET_SEEK_SET] = FILE_BEGIN,
135 [GNUNET_SEEK_CUR] = FILE_CURRENT, [GNUNET_SEEK_END] = FILE_END };
136
137 ret = SetFilePointer (h->h, offset, NULL, t[whence]);
138 if (ret == INVALID_SET_FILE_POINTER)
139 {
140 SetErrnoFromWinError (GetLastError ());
141 return GNUNET_SYSERR;
142 }
143 return ret;
144#else
145 static int t[] = { [GNUNET_SEEK_SET] = SEEK_SET,
146 [GNUNET_SEEK_CUR] = SEEK_CUR, [GNUNET_SEEK_END] = SEEK_END };
147
148 return lseek (h->fd, offset, t[whence]);
149#endif
150}
151
111/** 152/**
112 * Get the size of the file (or directory) 153 * Get the size of the file (or directory)
113 * of the given file (in bytes). 154 * of the given file (in bytes).
@@ -129,6 +170,7 @@ GNUNET_DISK_file_size (const char *filename,
129 return ret; 170 return ret;
130} 171}
131 172
173
132/** 174/**
133 * Get the number of blocks that are left on the partition that 175 * Get the number of blocks that are left on the partition that
134 * contains the given file (for normal users). 176 * contains the given file (for normal users).
@@ -359,30 +401,55 @@ GNUNET_DISK_directory_create_for_file (const char *dir)
359 401
360/** 402/**
361 * Read the contents of a binary file into a buffer. 403 * Read the contents of a binary file into a buffer.
362 * @param fileName the name of the file, not freed, 404 * @param h handle to an open file
363 * must already be expanded! 405 * @param result the buffer to write the result to
364 * @param len the maximum number of bytes to read 406 * @param len the maximum number of bytes to read
407 * @return the number of bytes read on success, GNUNET_SYSERR on failure
408 */
409int
410GNUNET_DISK_file_read (const struct GNUNET_IO_Handle *h, void *result, int len)
411{
412 if (h == NULL)
413 {
414 errno = EINVAL;
415 return GNUNET_SYSERR;
416 }
417
418#ifdef MINGW
419 DWORD bytesRead;
420
421 if (!ReadFile (h->h, result, len, &bytesRead, NULL))
422 {
423 SetErrnoFromWinError (GetLastError ());
424 return GNUNET_SYSERR;
425 }
426 return bytesRead;
427#else
428 return read (h->fd, result, len);
429#endif
430}
431
432
433/**
434 * Read the contents of a binary file into a buffer.
435 * @param fn file name
365 * @param result the buffer to write the result to 436 * @param result the buffer to write the result to
366 * @return the number of bytes read on success, -1 on failure 437 * @param len the maximum number of bytes to read
438 * @return the number of bytes read on success, GNUNET_SYSERR on failure
367 */ 439 */
368int 440int
369GNUNET_DISK_file_read (const char *fileName, int len, void *result) 441GNUNET_DISK_fn_read (const char * const fn, void *result, int len)
370{ 442{
371 /* open file, must exist, open read only */ 443 struct GNUNET_IO_Handle *fh;
372 int handle; 444 int ret;
373 int size; 445
374 446 fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ);
375 GNUNET_assert (fileName != NULL); 447 if (!fh)
376 GNUNET_assert (len > 0); 448 return GNUNET_SYSERR;
377 if (len == 0) 449 ret = GNUNET_DISK_file_read (fh, result, len);
378 return 0; 450 GNUNET_assert(GNUNET_OK == GNUNET_DISK_file_close(&fh));
379 GNUNET_assert (result != NULL); 451
380 handle = GNUNET_DISK_file_open (fileName, O_RDONLY, S_IRUSR); 452 return ret;
381 if (handle < 0)
382 return -1;
383 size = READ (handle, result, len);
384 GNUNET_DISK_file_close (fileName, handle);
385 return size;
386} 453}
387 454
388 455
@@ -404,45 +471,57 @@ atoo (const char *s)
404 471
405/** 472/**
406 * Write a buffer to a file. 473 * Write a buffer to a file.
407 * @param fileName the name of the file, NOT freed! 474 * @param h handle to open file
408 * @param buffer the data to write 475 * @param buffer the data to write
409 * @param n number of bytes to write 476 * @param n number of bytes to write
410 * @param mode permissions to set on the file 477 * @return number of bytes written on success, GNUNET_SYSERR on error
411 * @return GNUNET_OK on success, GNUNET_SYSERR on error
412 */ 478 */
413int 479int
414GNUNET_DISK_file_write (const char *fileName, 480GNUNET_DISK_file_write (const struct GNUNET_IO_Handle *h, const void *buffer,
415 const void *buffer, unsigned int n, const char *mode) 481 unsigned int n)
416{ 482{
417 int handle; 483 if (h == NULL)
418 char *fn;
419
420 /* open file, open with 600, create if not
421 present, otherwise overwrite */
422 GNUNET_assert (fileName != NULL);
423 fn = GNUNET_STRINGS_filename_expand (fileName);
424 handle = GNUNET_DISK_file_open (fn, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
425 if (handle == -1)
426 { 484 {
427 GNUNET_free (fn); 485 errno = EINVAL;
428 return GNUNET_SYSERR; 486 return GNUNET_SYSERR;
429 } 487 }
430 GNUNET_assert ((n == 0) || (buffer != NULL)); 488
431 /* write the buffer take length from the beginning */ 489#ifdef MINGW
432 if (n != WRITE (handle, buffer, n)) 490 DWORD bytesWritten;
491
492 if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL))
433 { 493 {
434 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn); 494 SetErrnoFromWinError (GetLastError ());
435 GNUNET_DISK_file_close (fn, handle);
436 GNUNET_free (fn);
437 return GNUNET_SYSERR; 495 return GNUNET_SYSERR;
438 } 496 }
439 GNUNET_DISK_file_close (fn, handle); 497 return bytesWritten;
440 if (0 != CHMOD (fn, atoo (mode))) 498#else
441 { 499 return write (h->fd, buffer, n);
442 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "chmod", fn); 500#endif
443 } 501}
444 GNUNET_free (fn); 502
445 return GNUNET_OK; 503/**
504 * Write a buffer to a file.
505 * @param fn file name
506 * @param buffer the data to write
507 * @param n number of bytes to write
508 * @return number of bytes written on success, GNUNET_SYSERR on error
509 */
510int
511GNUNET_DISK_fn_write (const char * const fn, const void *buffer,
512 unsigned int n, int mode)
513{
514 struct GNUNET_IO_Handle *fh;
515 int ret;
516
517 fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_WRITE
518 | GNUNET_DISK_OPEN_CREATE, mode);
519 if (!fh)
520 return GNUNET_SYSERR;
521 ret = GNUNET_DISK_file_write (fh, buffer, n);
522 GNUNET_assert(GNUNET_OK == GNUNET_DISK_file_close(&fh));
523
524 return ret;
446} 525}
447 526
448/** 527/**
@@ -724,57 +803,6 @@ GNUNET_DISK_directory_remove (const char *fileName)
724 return GNUNET_OK; 803 return GNUNET_OK;
725} 804}
726 805
727void
728GNUNET_DISK_file_close (const char *filename, int fd)
729{
730 if (0 != CLOSE (fd))
731 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "close", filename);
732}
733
734int
735GNUNET_DISK_file_open (const char *filename, int oflag, ...)
736{
737 char *fn;
738 int mode;
739 int ret;
740#ifdef MINGW
741 char szFile[_MAX_PATH + 1];
742 long lRet;
743
744 if ((lRet = plibc_conv_to_win_path (filename, szFile)) != ERROR_SUCCESS)
745 {
746 errno = ENOENT;
747 SetLastError (lRet);
748 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
749 "plibc_conv_to_win_path", filename);
750 return -1;
751 }
752 fn = GNUNET_strdup (szFile);
753#else
754 fn = GNUNET_STRINGS_filename_expand (filename);
755#endif
756 if (oflag & O_CREAT)
757 {
758 va_list arg;
759 va_start (arg, oflag);
760 mode = va_arg (arg, int);
761 va_end (arg);
762 }
763 else
764 {
765 mode = 0;
766 }
767#ifdef MINGW
768 /* set binary mode */
769 oflag |= O_BINARY;
770#endif
771 ret = OPEN (fn, oflag, mode);
772 if (ret == -1)
773 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "open", fn);
774 GNUNET_free (fn);
775 return ret;
776}
777
778#define COPY_BLK_SIZE 65536 806#define COPY_BLK_SIZE 65536
779 807
780/** 808/**
@@ -788,21 +816,21 @@ GNUNET_DISK_file_copy (const char *src, const char *dst)
788 unsigned long long pos; 816 unsigned long long pos;
789 unsigned long long size; 817 unsigned long long size;
790 unsigned long long len; 818 unsigned long long len;
791 int in; 819 struct GNUNET_IO_Handle *in, *out;
792 int out;
793 820
794 if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES)) 821 if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES))
795 return GNUNET_SYSERR; 822 return GNUNET_SYSERR;
796 pos = 0; 823 pos = 0;
797 in = GNUNET_DISK_file_open (src, O_RDONLY | O_LARGEFILE); 824 in = GNUNET_DISK_file_open (src, GNUNET_DISK_OPEN_READ);
798 if (in == -1) 825 if (!in)
799 return GNUNET_SYSERR; 826 return GNUNET_SYSERR;
800 out = GNUNET_DISK_file_open (dst, 827 out = GNUNET_DISK_file_open (dst, GNUNET_DISK_OPEN_WRITE
801 O_LARGEFILE | O_WRONLY | O_CREAT | O_EXCL, 828 | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_FAILIFEXISTS,
802 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); 829 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE
803 if (out == -1) 830 | GNUNET_DISK_PERM_GROUP_READ | GNUNET_DISK_PERM_GROUP_WRITE);
831 if (!out)
804 { 832 {
805 GNUNET_DISK_file_close (src, in); 833 GNUNET_DISK_file_close (&in);
806 return GNUNET_SYSERR; 834 return GNUNET_SYSERR;
807 } 835 }
808 buf = GNUNET_malloc (COPY_BLK_SIZE); 836 buf = GNUNET_malloc (COPY_BLK_SIZE);
@@ -811,20 +839,20 @@ GNUNET_DISK_file_copy (const char *src, const char *dst)
811 len = COPY_BLK_SIZE; 839 len = COPY_BLK_SIZE;
812 if (len > size - pos) 840 if (len > size - pos)
813 len = size - pos; 841 len = size - pos;
814 if (len != READ (in, buf, len)) 842 if (len != GNUNET_DISK_file_read (in, buf, len))
815 goto FAIL; 843 goto FAIL;
816 if (len != WRITE (out, buf, len)) 844 if (len != GNUNET_DISK_file_write (out, buf, len))
817 goto FAIL; 845 goto FAIL;
818 pos += len; 846 pos += len;
819 } 847 }
820 GNUNET_free (buf); 848 GNUNET_free (buf);
821 GNUNET_DISK_file_close (src, in); 849 GNUNET_DISK_file_close (&in);
822 GNUNET_DISK_file_close (dst, out); 850 GNUNET_DISK_file_close (&out);
823 return GNUNET_OK; 851 return GNUNET_OK;
824FAIL: 852FAIL:
825 GNUNET_free (buf); 853 GNUNET_free (buf);
826 GNUNET_DISK_file_close (src, in); 854 GNUNET_DISK_file_close (&in);
827 GNUNET_DISK_file_close (dst, out); 855 GNUNET_DISK_file_close (&out);
828 return GNUNET_SYSERR; 856 return GNUNET_SYSERR;
829} 857}
830 858
@@ -881,6 +909,177 @@ GNUNET_DISK_file_change_owner (const char *filename, const char *user)
881 909
882 910
883/** 911/**
912 * Lock a part of a file
913 * @param fh file handle
914 * @lockStart absolute position from where to lock
915 * @lockEnd absolute position until where to lock
916 * @return GNUNET_OK on success, GNUNET_SYSERR on error
917 */
918int
919GNUNET_DISK_file_lock(struct GNUNET_IO_Handle *fh, off_t lockStart,
920 off_t lockEnd)
921{
922 if (fh == NULL)
923 {
924 errno = EINVAL;
925 return GNUNET_SYSERR;
926 }
927
928#ifndef MINGW
929 struct flock fl;
930
931 memset(&fl, 0, sizeof(struct flock));
932 fl.l_type = F_WRLCK;
933 fl.l_whence = SEEK_SET;
934 fl.l_start = lockStart;
935 fl.l_len = lockEnd;
936
937 return fcntl(fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
938#else
939 if (!LockFile(fh->h, 0, lockStart, 0, lockEnd))
940 {
941 SetErrnoFromWinError(GetLastError());
942 return GNUNET_SYSERR;
943 }
944
945 return GNUNET_OK;
946#endif
947}
948
949
950/**
951 * Open a file
952 * @param fn file name to be opened
953 * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags
954 * @param perm permissions for the newly created file
955 * @return IO handle on success, NULL on error
956 */
957struct GNUNET_IO_Handle *
958GNUNET_DISK_file_open (const char *fn, int flags, ...)
959{
960 char *expfn;
961 struct GNUNET_IO_Handle *ret;
962#ifdef MINGW
963 DWORD access, disp;
964 HANDLE h;
965#else
966 int oflags, mode;
967 int fd;
968#endif
969
970 expfn = GNUNET_STRINGS_filename_expand (fn);
971
972#ifndef MINGW
973 oflags = 0;
974 if (flags & GNUNET_DISK_OPEN_READ)
975 oflags = O_RDONLY;
976 if (flags & GNUNET_DISK_OPEN_WRITE)
977 oflags |= O_WRONLY;
978 if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
979 oflags |= (O_CREAT & O_EXCL);
980 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
981 oflags |= O_TRUNC;
982 if (flags & GNUNET_DISK_OPEN_CREATE)
983 {
984 oflags |= O_CREAT;
985
986 va_list arg;
987 va_start (arg, oflag);
988 mode = va_arg (arg, int);
989 va_end (arg);
990 }
991 if (flags & GNUNET_DISK_OPEN_APPEND)
992 oflags = O_APPEND;
993
994 fd = open (expfn, oflag | O_LARGEFILE, perm, mode);
995 if (fd == -1)
996 {
997 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "open", fn);
998 return NULL;
999 }
1000#else
1001 access = 0;
1002 disp = OPEN_ALWAYS;
1003
1004 if (flags & GNUNET_DISK_OPEN_READ)
1005 access = FILE_READ_DATA;
1006 if (flags & GNUNET_DISK_OPEN_WRITE)
1007 access = FILE_WRITE_DATA;
1008
1009 if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
1010 disp = CREATE_NEW;
1011 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1012 disp = TRUNCATE_EXISTING;
1013 if (flags & GNUNET_DISK_OPEN_CREATE)
1014 disp |= OPEN_ALWAYS;
1015
1016 /* TODO: access priviledges? */
1017 h = CreateFile (expfn, access, FILE_SHARE_DELETE | FILE_SHARE_READ
1018 | FILE_SHARE_WRITE, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
1019 if (h == INVALID_HANDLE_VALUE)
1020 {
1021 SetErrnoFromWinError (GetLastError ());
1022 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "open", fn);
1023 return NULL;
1024 }
1025
1026 if (flags & GNUNET_DISK_OPEN_APPEND)
1027 if (SetFilePointer (h, 0, 0, FILE_END) == INVALID_SET_FILE_POINTER)
1028 {
1029 SetErrnoFromWinError (GetLastError ());
1030 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "SetFilePointer", fn);
1031 CloseHandle (h);
1032 return NULL;
1033 }
1034#endif
1035
1036 ret = (struct GNUNET_IO_Handle *) GNUNET_malloc(sizeof(struct GNUNET_IO_Handle));
1037#ifdef MINGW
1038 ret->h = h;
1039#else
1040 ret->fd = fd;
1041#endif
1042
1043 return ret;
1044}
1045
1046/**
1047 * Close an open file
1048 * @param h file handle
1049 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
1050 */
1051int
1052GNUNET_DISK_file_close (struct GNUNET_IO_Handle **h)
1053{
1054 if (*h == NULL)
1055 {
1056 errno = EINVAL;
1057 return GNUNET_SYSERR;
1058 }
1059
1060#if MINGW
1061 if (!CloseHandle ((*h)->h))
1062 {
1063 SetErrnoFromWinError (GetLastError ());
1064 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "close");
1065 return GNUNET_SYSERR;
1066 }
1067#else
1068 if (close ((*h)->fd) != 0)
1069 {
1070 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "close");
1071 return GNUNET_SYSERR;
1072 }
1073#endif
1074
1075 GNUNET_IO_handle_invalidate (*h);
1076 free(*h);
1077 *h = NULL;
1078
1079 return GNUNET_OK;
1080}
1081
1082/**
884 * Construct full path to a file inside of the private 1083 * Construct full path to a file inside of the private
885 * directory used by GNUnet. Also creates the corresponding 1084 * directory used by GNUnet. Also creates the corresponding
886 * directory. If the resulting name is supposed to be 1085 * directory. If the resulting name is supposed to be
@@ -949,6 +1148,145 @@ GNUNET_DISK_get_home_filename (struct GNUNET_CONFIGURATION_Handle *cfg,
949 return ret; 1148 return ret;
950} 1149}
951 1150
1151/**
1152 * Map a file into memory
1153 * @param h open file handle
1154 * @param m handle to the new mapping
1155 * @param access access specification, GNUNET_DISK_MAP_xxx
1156 * @param len size of the mapping
1157 * @return pointer to the mapped memory region, NULL on failure
1158 */
1159void *
1160GNUNET_DISK_file_map (const struct GNUNET_IO_Handle *h, struct GNUNET_IO_Handle **m,
1161 int access, size_t len)
1162{
1163 if (h == NULL)
1164 {
1165 errno = EINVAL;
1166 return NULL;
1167 }
1168
1169#ifdef MINGW
1170 DWORD mapAccess, protect;
1171 void *ret;
1172
1173 if (access & GNUNET_DISK_MAP_READ && access & GNUNET_DISK_MAP_WRITE)
1174 {
1175 protect = PAGE_READWRITE;
1176 mapAccess = FILE_MAP_ALL_ACCESS;
1177 }
1178 else if (access & GNUNET_DISK_MAP_READ)
1179 {
1180 protect = PAGE_READONLY;
1181 mapAccess = FILE_MAP_READ;
1182 }
1183 else if (access & GNUNET_DISK_MAP_WRITE)
1184 {
1185 protect = PAGE_READWRITE;
1186 mapAccess = FILE_MAP_WRITE;
1187 }
1188 else
1189 {
1190 GNUNET_break (0);
1191 return NULL;
1192 }
1193
1194 *m = (struct GNUNET_IO_Handle *) GNUNET_malloc (sizeof (struct GNUNET_IO_Handle));
1195 (*m)->h = CreateFileMapping (h->h, NULL, protect, 0, 0, NULL);
1196 if ((*m)->h == INVALID_HANDLE_VALUE)
1197 {
1198 SetErrnoFromWinError (GetLastError ());
1199 GNUNET_free (*m);
1200 return NULL;
1201 }
1202
1203 ret = MapViewOfFile ((*m)->h, mapAccess, 0, 0, len);
1204 if (!ret)
1205 {
1206 SetErrnoFromWinError (GetLastError ());
1207 CloseHandle ((*m)->h);
1208 GNUNET_free (*m);
1209 }
1210
1211 return ret;
1212#else
1213 int prot;
1214
1215 prot = flags = 0;
1216 if (access & GNUNET_DISK_MAP_READ)
1217 prot = PROT_READ;
1218 if (access & GNUNET_DISK_MAP_WRITE)
1219 prot |= PROT_WRITE;
1220
1221 return mmap (NULL, len, prot, MAP_SHARED, h->h, 0);
1222#endif
1223}
1224
1225/**
1226 * Unmap a file
1227 * @param h mapping handle
1228 * @param addr pointer to the mapped memory region
1229 * @param len size of the mapping
1230 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
1231 */
1232int
1233GNUNET_DISK_file_unmap (struct GNUNET_IO_Handle **h, void *addr, size_t len)
1234{
1235#ifdef MINGW
1236 int ret;
1237
1238 if (h == NULL || *h == NULL)
1239 {
1240 errno = EINVAL;
1241 return GNUNET_SYSERR;
1242 }
1243
1244 ret = UnmapViewOfFile (addr) ? GNUNET_OK : GNUNET_SYSERR;
1245 if (ret != GNUNET_OK)
1246 SetErrnoFromWinError (GetLastError ());
1247 if (!CloseHandle ((*h)->h) && ret == GNUNET_OK)
1248 {
1249 ret = GNUNET_SYSERR;
1250 SetErrnoFromWinError (GetLastError ());
1251 }
1252
1253 GNUNET_IO_handle_invalidate (*h);
1254 GNUNET_free (*h);
1255 h = NULL;
1256
1257 return ret;
1258#else
1259 int ret;
1260 ret = munmap (addr, len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1261 GNUNET_IO_handle_invalidate (h);
1262 return ret;
1263#endif
1264}
1265
1266/**
1267 * Write file changes to disk
1268 * @param h handle to an open file
1269 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
1270 */
1271int
1272GNUNET_DISK_file_sync (const struct GNUNET_IO_Handle *h)
1273{
1274 if (h == NULL)
1275 {
1276 errno = EINVAL;
1277 return GNUNET_SYSERR;
1278 }
952 1279
1280#ifdef MINGW
1281 int ret;
1282
1283 ret = FlushFileBuffers (h->h) ? GNUNET_OK : GNUNET_SYSERR;
1284 if (ret != GNUNET_OK)
1285 SetErrnoFromWinError (GetLastError ());
1286 return ret;
1287#else
1288 return fsync (h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
1289#endif
1290}
953 1291
954/* end of disk.c */ 1292/* end of disk.c */