summaryrefslogtreecommitdiff
path: root/src/util/disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/disk.c')
-rw-r--r--src/util/disk.c842
1 files changed, 12 insertions, 830 deletions
diff --git a/src/util/disk.c b/src/util/disk.c
index c5ea42ee6..01d5efbe2 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -208,23 +208,11 @@ GNUNET_DISK_handle_invalid(const struct GNUNET_DISK_FileHandle *h)
208int 208int
209GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size) 209GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
210{ 210{
211#if WINDOWS
212 BOOL b;
213 LARGE_INTEGER li;
214 b = GetFileSizeEx(fh->h, &li);
215 if (!b)
216 {
217 SetErrnoFromWinError(GetLastError());
218 return GNUNET_SYSERR;
219 }
220 *size = (off_t)li.QuadPart;
221#else
222 struct stat sbuf; 211 struct stat sbuf;
223 212
224 if (0 != fstat(fh->fd, &sbuf)) 213 if (0 != fstat(fh->fd, &sbuf))
225 return GNUNET_SYSERR; 214 return GNUNET_SYSERR;
226 *size = sbuf.st_size; 215 *size = sbuf.st_size;
227#endif
228 return GNUNET_OK; 216 return GNUNET_OK;
229} 217}
230 218
@@ -324,29 +312,6 @@ GNUNET_DISK_file_get_identifiers(const char *filename,
324 uint64_t *dev, 312 uint64_t *dev,
325 uint64_t *ino) 313 uint64_t *ino)
326{ 314{
327#if WINDOWS
328 {
329 // FIXME NILS: test this
330 struct GNUNET_DISK_FileHandle *fh;
331 BY_HANDLE_FILE_INFORMATION info;
332 int succ;
333
334 fh = GNUNET_DISK_file_open(filename,
335 GNUNET_DISK_OPEN_READ,
336 GNUNET_DISK_PERM_NONE);
337 if (NULL == fh)
338 return GNUNET_SYSERR;
339 succ = GetFileInformationByHandle(fh->h, &info);
340 GNUNET_DISK_file_close(fh);
341 if (!succ)
342 {
343 return GNUNET_SYSERR;
344 }
345 *dev = info.dwVolumeSerialNumber;
346 *ino = ((((uint64_t)info.nFileIndexHigh) << (sizeof(DWORD) * 8)) |
347 info.nFileIndexLow);
348 }
349#else /* !WINDOWS */
350#if HAVE_STAT 315#if HAVE_STAT
351 { 316 {
352 struct stat sbuf; 317 struct stat sbuf;
@@ -384,7 +349,6 @@ GNUNET_DISK_file_get_identifiers(const char *filename,
384#else 349#else
385 *dev = 0; 350 *dev = 0;
386#endif 351#endif
387#endif /* !WINDOWS */
388 return GNUNET_OK; 352 return GNUNET_OK;
389} 353}
390 354
@@ -402,11 +366,7 @@ mktemp_name(const char *t)
402 char *tmpl; 366 char *tmpl;
403 char *fn; 367 char *fn;
404 368
405 if ((t[0] != '/') && (t[0] != '\\') 369 if ((t[0] != '/') && (t[0] != '\\'))
406#if WINDOWS
407 && !(isalpha((int)t[0]) && (t[0] != '\0') && (t[1] == ':'))
408#endif
409 )
410 { 370 {
411 /* FIXME: This uses system codepage on W32, not UTF-8 */ 371 /* FIXME: This uses system codepage on W32, not UTF-8 */
412 tmpdir = getenv("TMPDIR"); 372 tmpdir = getenv("TMPDIR");
@@ -422,71 +382,10 @@ mktemp_name(const char *t)
422 { 382 {
423 GNUNET_asprintf(&tmpl, "%s%s", t, "XXXXXX"); 383 GNUNET_asprintf(&tmpl, "%s%s", t, "XXXXXX");
424 } 384 }
425#ifdef MINGW
426 fn = (char *)GNUNET_malloc(MAX_PATH + 1);
427 if (ERROR_SUCCESS != plibc_conv_to_win_path(tmpl, fn))
428 {
429 GNUNET_free(fn);
430 GNUNET_free(tmpl);
431 return NULL;
432 }
433 GNUNET_free(tmpl);
434#else
435 fn = tmpl; 385 fn = tmpl;
436#endif
437 return fn;
438}
439
440
441#if WINDOWS
442static char *
443mkdtemp(char *fn)
444{
445 char *random_fn;
446 char *tfn;
447
448 while (1)
449 {
450 tfn = GNUNET_strdup(fn);
451 random_fn = _mktemp(tfn);
452 if (NULL == random_fn)
453 {
454 GNUNET_free(tfn);
455 return NULL;
456 }
457 /* FIXME: assume fn to be UTF-8-encoded and do the right thing */
458 if (0 == CreateDirectoryA(tfn, NULL))
459 {
460 DWORD error = GetLastError();
461 GNUNET_free(tfn);
462 if (ERROR_ALREADY_EXISTS == error)
463 continue;
464 return NULL;
465 }
466 break;
467 }
468 strcpy(fn, tfn);
469 return fn; 386 return fn;
470} 387}
471 388
472/**
473 * Update POSIX permissions mask of a file on disk. If both argumets
474 * are #GNUNET_NO, the file is made world-read-write-executable (777).
475 * Does nothing on W32.
476 *
477 * @param fn name of the file to update
478 * @param require_uid_match #GNUNET_YES means 700
479 * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set
480 */
481void
482GNUNET_DISK_fix_permissions(const char *fn,
483 int require_uid_match,
484 int require_gid_match)
485{
486 /* nothing on W32 */
487}
488
489#else
490 389
491/** 390/**
492 * Update POSIX permissions mask of a file on disk. If both argumets 391 * Update POSIX permissions mask of a file on disk. If both argumets
@@ -514,7 +413,6 @@ GNUNET_DISK_fix_permissions(const char *fn,
514 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING, "chmod", fn); 413 GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_WARNING, "chmod", fn);
515} 414}
516 415
517#endif
518 416
519/** 417/**
520 * Create an (empty) temporary directory on disk. If the given name is not 418 * Create an (empty) temporary directory on disk. If the given name is not
@@ -724,28 +622,9 @@ GNUNET_DISK_directory_create(const char *dir)
724 } 622 }
725 623
726 len = strlen(rdir); 624 len = strlen(rdir);
727#ifndef MINGW 625
728 pos = 1; /* skip heading '/' */ 626 pos = 1; /* skip heading '/' */
729#else 627
730 /* Local or Network path? */
731 if (strncmp(rdir, "\\\\", 2) == 0)
732 {
733 pos = 2;
734 while (rdir[pos])
735 {
736 if (rdir[pos] == '\\')
737 {
738 pos++;
739 break;
740 }
741 pos++;
742 }
743 }
744 else
745 {
746 pos = 3; /* strlen("C:\\") */
747 }
748#endif
749 /* Check which low level directories already exist */ 628 /* Check which low level directories already exist */
750 pos2 = len; 629 pos2 = len;
751 rdir[len] = DIR_SEPARATOR; 630 rdir[len] = DIR_SEPARATOR;
@@ -792,17 +671,10 @@ GNUNET_DISK_directory_create(const char *dir)
792 } 671 }
793 if (GNUNET_SYSERR == ret) 672 if (GNUNET_SYSERR == ret)
794 { 673 {
795#ifndef MINGW
796 ret = mkdir(rdir, 674 ret = mkdir(rdir,
797 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | 675 S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH |
798 S_IXOTH); /* 755 */ 676 S_IXOTH); /* 755 */
799#else 677
800 wchar_t wrdir[MAX_PATH + 1];
801 if (ERROR_SUCCESS == plibc_conv_to_win_pathwconv(rdir, wrdir))
802 ret = !CreateDirectoryW(wrdir, NULL);
803 else
804 ret = 1;
805#endif
806 if ((ret != 0) && (errno != EEXIST)) 678 if ((ret != 0) && (errno != EEXIST))
807 { 679 {
808 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, "mkdir", rdir); 680 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, "mkdir", rdir);
@@ -887,42 +759,7 @@ GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h,
887 return GNUNET_SYSERR; 759 return GNUNET_SYSERR;
888 } 760 }
889 761
890#ifdef MINGW
891 DWORD bytes_read;
892
893 if (h->type == GNUNET_DISK_HANLDE_TYPE_FILE)
894 {
895 if (!ReadFile(h->h, result, len, &bytes_read, NULL))
896 {
897 SetErrnoFromWinError(GetLastError());
898 return GNUNET_SYSERR;
899 }
900 }
901 else if (h->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
902 {
903 if (!ReadFile(h->h, result, len, &bytes_read, h->oOverlapRead))
904 {
905 if (GetLastError() != ERROR_IO_PENDING)
906 {
907 LOG(GNUNET_ERROR_TYPE_DEBUG,
908 "Error reading from pipe: %u\n",
909 GetLastError());
910 SetErrnoFromWinError(GetLastError());
911 return GNUNET_SYSERR;
912 }
913 LOG(GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n");
914 GetOverlappedResult(h->h, h->oOverlapRead, &bytes_read, TRUE);
915 }
916 LOG(GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes from pipe\n", bytes_read);
917 }
918 else
919 {
920 bytes_read = 0;
921 }
922 return bytes_read;
923#else
924 return read(h->fd, result, len); 762 return read(h->fd, result, len);
925#endif
926} 763}
927 764
928 765
@@ -947,45 +784,6 @@ GNUNET_DISK_file_read_non_blocking(const struct GNUNET_DISK_FileHandle *h,
947 return GNUNET_SYSERR; 784 return GNUNET_SYSERR;
948 } 785 }
949 786
950#ifdef MINGW
951 DWORD bytes_read;
952
953 if (h->type == GNUNET_DISK_HANLDE_TYPE_FILE)
954 {
955 if (!ReadFile(h->h, result, len, &bytes_read, NULL))
956 {
957 SetErrnoFromWinError(GetLastError());
958 return GNUNET_SYSERR;
959 }
960 }
961 else if (h->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
962 {
963 if (!ReadFile(h->h, result, len, &bytes_read, h->oOverlapRead))
964 {
965 if (GetLastError() != ERROR_IO_PENDING)
966 {
967 LOG(GNUNET_ERROR_TYPE_DEBUG,
968 "Error reading from pipe: %u\n",
969 GetLastError());
970 SetErrnoFromWinError(GetLastError());
971 return GNUNET_SYSERR;
972 }
973 else
974 {
975 LOG(GNUNET_ERROR_TYPE_DEBUG, "ReadFile() queued a read, cancelling\n");
976 CancelIo(h->h);
977 errno = EAGAIN;
978 return GNUNET_SYSERR;
979 }
980 }
981 LOG(GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes\n", bytes_read);
982 }
983 else
984 {
985 bytes_read = 0;
986 }
987 return bytes_read;
988#else
989 int flags; 787 int flags;
990 ssize_t ret; 788 ssize_t ret;
991 789
@@ -1001,7 +799,6 @@ GNUNET_DISK_file_read_non_blocking(const struct GNUNET_DISK_FileHandle *h,
1001 errno = eno; 799 errno = eno;
1002 } 800 }
1003 return ret; 801 return ret;
1004#endif
1005} 802}
1006 803
1007 804
@@ -1050,78 +847,8 @@ GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h,
1050 return GNUNET_SYSERR; 847 return GNUNET_SYSERR;
1051 } 848 }
1052 849
1053#ifdef MINGW
1054 DWORD bytes_written;
1055 850
1056 if (h->type == GNUNET_DISK_HANLDE_TYPE_FILE)
1057 {
1058 if (!WriteFile(h->h, buffer, n, &bytes_written, NULL))
1059 {
1060 SetErrnoFromWinError(GetLastError());
1061 return GNUNET_SYSERR;
1062 }
1063 }
1064 else if (h->type == GNUNET_DISK_HANLDE_TYPE_PIPE)
1065 {
1066 LOG(GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to write %u bytes\n", n);
1067 if (!WriteFile(h->h, buffer, n, &bytes_written, h->oOverlapWrite))
1068 {
1069 if (GetLastError() != ERROR_IO_PENDING)
1070 {
1071 SetErrnoFromWinError(GetLastError());
1072 LOG(GNUNET_ERROR_TYPE_DEBUG,
1073 "Error writing to pipe: %u\n",
1074 GetLastError());
1075 return GNUNET_SYSERR;
1076 }
1077 LOG(GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n");
1078 if (!GetOverlappedResult(h->h, h->oOverlapWrite, &bytes_written, TRUE))
1079 {
1080 SetErrnoFromWinError(GetLastError());
1081 LOG(GNUNET_ERROR_TYPE_DEBUG,
1082 "Error getting overlapped result while writing to pipe: %u\n",
1083 GetLastError());
1084 return GNUNET_SYSERR;
1085 }
1086 }
1087 else
1088 {
1089 DWORD ovr;
1090 if (!GetOverlappedResult(h->h, h->oOverlapWrite, &ovr, TRUE))
1091 {
1092 LOG(GNUNET_ERROR_TYPE_DEBUG,
1093 "Error getting control overlapped result while writing to pipe: %u\n",
1094 GetLastError());
1095 }
1096 else
1097 {
1098 LOG(GNUNET_ERROR_TYPE_DEBUG,
1099 "Wrote %u bytes (ovr says %u), picking the greatest\n",
1100 bytes_written,
1101 ovr);
1102 }
1103 }
1104 if (bytes_written == 0)
1105 {
1106 if (n > 0)
1107 {
1108 LOG(GNUNET_ERROR_TYPE_DEBUG,
1109 "Wrote %u bytes, returning -1 with EAGAIN\n",
1110 bytes_written);
1111 errno = EAGAIN;
1112 return GNUNET_SYSERR;
1113 }
1114 }
1115 LOG(GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytes_written);
1116 }
1117 else
1118 {
1119 bytes_written = 0;
1120 }
1121 return bytes_written;
1122#else
1123 return write(h->fd, buffer, n); 851 return write(h->fd, buffer, n);
1124#endif
1125} 852}
1126 853
1127 854
@@ -1144,34 +871,7 @@ GNUNET_DISK_file_write_blocking(const struct GNUNET_DISK_FileHandle *h,
1144 return GNUNET_SYSERR; 871 return GNUNET_SYSERR;
1145 } 872 }
1146 873
1147#ifdef MINGW 874
1148 DWORD bytes_written;
1149 /* We do a non-overlapped write, which is as blocking as it gets */
1150 LOG(GNUNET_ERROR_TYPE_DEBUG, "Writing %u bytes\n", n);
1151 if (!WriteFile(h->h, buffer, n, &bytes_written, NULL))
1152 {
1153 SetErrnoFromWinError(GetLastError());
1154 LOG(GNUNET_ERROR_TYPE_DEBUG,
1155 "Error writing to pipe: %u\n",
1156 GetLastError());
1157 return GNUNET_SYSERR;
1158 }
1159 if (bytes_written == 0 && n > 0)
1160 {
1161 LOG(GNUNET_ERROR_TYPE_DEBUG, "Waiting for pipe to clean\n");
1162 WaitForSingleObject(h->h, INFINITE);
1163 if (!WriteFile(h->h, buffer, n, &bytes_written, NULL))
1164 {
1165 SetErrnoFromWinError(GetLastError());
1166 LOG(GNUNET_ERROR_TYPE_DEBUG,
1167 "Error writing to pipe: %u\n",
1168 GetLastError());
1169 return GNUNET_SYSERR;
1170 }
1171 }
1172 LOG(GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytes_written);
1173 return bytes_written;
1174#else
1175 int flags; 875 int flags;
1176 ssize_t ret; 876 ssize_t ret;
1177 877
@@ -1183,7 +883,6 @@ GNUNET_DISK_file_write_blocking(const struct GNUNET_DISK_FileHandle *h,
1183 if (0 == (flags & O_NONBLOCK)) 883 if (0 == (flags & O_NONBLOCK))
1184 (void)fcntl(h->fd, F_SETFL, flags); 884 (void)fcntl(h->fd, F_SETFL, flags);
1185 return ret; 885 return ret;
1186#endif
1187} 886}
1188 887
1189 888
@@ -1486,7 +1185,6 @@ GNUNET_DISK_filename_canonicalize(char *fn)
1486int 1185int
1487GNUNET_DISK_file_change_owner(const char *filename, const char *user) 1186GNUNET_DISK_file_change_owner(const char *filename, const char *user)
1488{ 1187{
1489#ifndef MINGW
1490 struct passwd *pws; 1188 struct passwd *pws;
1491 1189
1492 pws = getpwnam(user); 1190 pws = getpwnam(user);
@@ -1503,7 +1201,6 @@ GNUNET_DISK_file_change_owner(const char *filename, const char *user)
1503 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "chown", filename); 1201 LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "chown", filename);
1504 return GNUNET_SYSERR; 1202 return GNUNET_SYSERR;
1505 } 1203 }
1506#endif
1507 return GNUNET_OK; 1204 return GNUNET_OK;
1508} 1205}
1509 1206
@@ -1529,7 +1226,6 @@ GNUNET_DISK_file_lock(struct GNUNET_DISK_FileHandle *fh,
1529 return GNUNET_SYSERR; 1226 return GNUNET_SYSERR;
1530 } 1227 }
1531 1228
1532#ifndef MINGW
1533 struct flock fl; 1229 struct flock fl;
1534 1230
1535 memset(&fl, 0, sizeof(struct flock)); 1231 memset(&fl, 0, sizeof(struct flock));
@@ -1539,33 +1235,6 @@ GNUNET_DISK_file_lock(struct GNUNET_DISK_FileHandle *fh,
1539 fl.l_len = lock_end; 1235 fl.l_len = lock_end;
1540 1236
1541 return fcntl(fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK; 1237 return fcntl(fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
1542#else
1543 OVERLAPPED o;
1544 off_t diff = lock_end - lock_start;
1545 DWORD diff_low, diff_high;
1546 diff_low = (DWORD)(diff & 0xFFFFFFFF);
1547 diff_high = (DWORD)((diff >> (sizeof(DWORD) * 8)) & 0xFFFFFFFF);
1548
1549 memset(&o, 0, sizeof(OVERLAPPED));
1550 o.Offset = (DWORD)(lock_start & 0xFFFFFFFF);
1551 ;
1552 o.OffsetHigh =
1553 (DWORD)(((lock_start & ~0xFFFFFFFF) >> (sizeof(DWORD) * 8)) & 0xFFFFFFFF);
1554
1555 if (!LockFileEx(fh->h,
1556 (excl ? LOCKFILE_EXCLUSIVE_LOCK : 0) |
1557 LOCKFILE_FAIL_IMMEDIATELY,
1558 0,
1559 diff_low,
1560 diff_high,
1561 &o))
1562 {
1563 SetErrnoFromWinError(GetLastError());
1564 return GNUNET_SYSERR;
1565 }
1566
1567 return GNUNET_OK;
1568#endif
1569} 1238}
1570 1239
1571 1240
@@ -1588,7 +1257,6 @@ GNUNET_DISK_file_unlock(struct GNUNET_DISK_FileHandle *fh,
1588 return GNUNET_SYSERR; 1257 return GNUNET_SYSERR;
1589 } 1258 }
1590 1259
1591#ifndef MINGW
1592 struct flock fl; 1260 struct flock fl;
1593 1261
1594 memset(&fl, 0, sizeof(struct flock)); 1262 memset(&fl, 0, sizeof(struct flock));
@@ -1598,27 +1266,6 @@ GNUNET_DISK_file_unlock(struct GNUNET_DISK_FileHandle *fh,
1598 fl.l_len = unlock_end; 1266 fl.l_len = unlock_end;
1599 1267
1600 return fcntl(fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK; 1268 return fcntl(fh->fd, F_SETLK, &fl) != 0 ? GNUNET_SYSERR : GNUNET_OK;
1601#else
1602 OVERLAPPED o;
1603 off_t diff = unlock_end - unlock_start;
1604 DWORD diff_low, diff_high;
1605 diff_low = (DWORD)(diff & 0xFFFFFFFF);
1606 diff_high = (DWORD)((diff >> (sizeof(DWORD) * 8)) & 0xFFFFFFFF);
1607
1608 memset(&o, 0, sizeof(OVERLAPPED));
1609 o.Offset = (DWORD)(unlock_start & 0xFFFFFFFF);
1610 ;
1611 o.OffsetHigh = (DWORD)(
1612 ((unlock_start & ~0xFFFFFFFF) >> (sizeof(DWORD) * 8)) & 0xFFFFFFFF);
1613
1614 if (!UnlockFileEx(fh->h, 0, diff_low, diff_high, &o))
1615 {
1616 SetErrnoFromWinError(GetLastError());
1617 return GNUNET_SYSERR;
1618 }
1619
1620 return GNUNET_OK;
1621#endif
1622} 1269}
1623 1270
1624 1271
@@ -1642,16 +1289,9 @@ GNUNET_DISK_file_open(const char *fn,
1642 char *expfn; 1289 char *expfn;
1643 struct GNUNET_DISK_FileHandle *ret; 1290 struct GNUNET_DISK_FileHandle *ret;
1644 1291
1645#ifdef MINGW
1646 DWORD access;
1647 DWORD disp;
1648 HANDLE h;
1649 wchar_t wexpfn[MAX_PATH + 1];
1650#else
1651 int oflags; 1292 int oflags;
1652 int mode; 1293 int mode;
1653 int fd; 1294 int fd;
1654#endif
1655 1295
1656 expfn = GNUNET_STRINGS_filename_expand(fn); 1296 expfn = GNUNET_STRINGS_filename_expand(fn);
1657 if (NULL == expfn) 1297 if (NULL == expfn)
@@ -1767,12 +1407,9 @@ GNUNET_DISK_file_open(const char *fn,
1767#endif 1407#endif
1768 1408
1769 ret = GNUNET_new(struct GNUNET_DISK_FileHandle); 1409 ret = GNUNET_new(struct GNUNET_DISK_FileHandle);
1770#ifdef MINGW 1410
1771 ret->h = h;
1772 ret->type = GNUNET_DISK_HANLDE_TYPE_FILE;
1773#else
1774 ret->fd = fd; 1411 ret->fd = fd;
1775#endif 1412
1776 GNUNET_free(expfn); 1413 GNUNET_free(expfn);
1777 return ret; 1414 return ret;
1778} 1415}
@@ -1797,111 +1434,17 @@ GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
1797 1434
1798 ret = GNUNET_OK; 1435 ret = GNUNET_OK;
1799 1436
1800#if MINGW
1801 if (!CloseHandle(h->h))
1802 {
1803 SetErrnoFromWinError(GetLastError());
1804 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "close");
1805 ret = GNUNET_SYSERR;
1806 }
1807 if (h->oOverlapRead)
1808 {
1809 if (!CloseHandle(h->oOverlapRead->hEvent))
1810 {
1811 SetErrnoFromWinError(GetLastError());
1812 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "close");
1813 ret = GNUNET_SYSERR;
1814 }
1815 GNUNET_free(h->oOverlapRead);
1816 }
1817 if (h->oOverlapWrite)
1818 {
1819 if (!CloseHandle(h->oOverlapWrite->hEvent))
1820 {
1821 SetErrnoFromWinError(GetLastError());
1822 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "close");
1823 ret = GNUNET_SYSERR;
1824 }
1825 GNUNET_free(h->oOverlapWrite);
1826 }
1827#else
1828 if (close(h->fd) != 0) 1437 if (close(h->fd) != 0)
1829 { 1438 {
1830 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "close"); 1439 LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "close");
1831 ret = GNUNET_SYSERR; 1440 ret = GNUNET_SYSERR;
1832 } 1441 }
1833#endif 1442
1834 GNUNET_free(h); 1443 GNUNET_free(h);
1835 return ret; 1444 return ret;
1836} 1445}
1837 1446
1838 1447
1839#ifdef WINDOWS
1840/**
1841 * Get a GNUnet file handle from a W32 handle.
1842 *
1843 * @param handle native handle
1844 * @return GNUnet file handle corresponding to the W32 handle
1845 */
1846struct GNUNET_DISK_FileHandle *
1847GNUNET_DISK_get_handle_from_w32_handle(HANDLE osfh)
1848{
1849 struct GNUNET_DISK_FileHandle *fh;
1850 DWORD dwret;
1851 enum GNUNET_FILE_Type ftype;
1852
1853 dwret = GetFileType(osfh);
1854 switch (dwret)
1855 {
1856 case FILE_TYPE_DISK:
1857 ftype = GNUNET_DISK_HANLDE_TYPE_FILE;
1858 break;
1859
1860 case FILE_TYPE_PIPE:
1861 ftype = GNUNET_DISK_HANLDE_TYPE_PIPE;
1862 break;
1863
1864 case FILE_TYPE_UNKNOWN:
1865 if ((GetLastError() == NO_ERROR) ||
1866 (GetLastError() == ERROR_INVALID_HANDLE))
1867 {
1868 if (0 != ResetEvent(osfh))
1869 ftype = GNUNET_DISK_HANLDE_TYPE_EVENT;
1870 else
1871 return NULL;
1872 }
1873 else
1874 return NULL;
1875 break;
1876
1877 default:
1878 return NULL;
1879 }
1880
1881 fh = GNUNET_new(struct GNUNET_DISK_FileHandle);
1882
1883 fh->h = osfh;
1884 fh->type = ftype;
1885 if (ftype == GNUNET_DISK_HANLDE_TYPE_PIPE)
1886 {
1887 /**
1888 * Note that we can't make it overlapped if it isn't already.
1889 * (ReOpenFile() is only available in 2003/Vista).
1890 * The process that opened this file in the first place (usually a parent
1891 * process, if this is stdin/stdout/stderr) must make it overlapped,
1892 * otherwise we're screwed, as selecting on non-overlapped handle
1893 * will block.
1894 */
1895 fh->oOverlapRead = GNUNET_new(OVERLAPPED);
1896 fh->oOverlapWrite = GNUNET_new(OVERLAPPED);
1897 fh->oOverlapRead->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1898 fh->oOverlapWrite->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1899 }
1900
1901 return fh;
1902}
1903#endif
1904
1905/** 1448/**
1906 * Get a handle from a native integer FD. 1449 * Get a handle from a native integer FD.
1907 * 1450 *
@@ -1916,19 +1459,9 @@ GNUNET_DISK_get_handle_from_int_fd(int fno)
1916 if ((((off_t)-1) == lseek(fno, 0, SEEK_CUR)) && (EBADF == errno)) 1459 if ((((off_t)-1) == lseek(fno, 0, SEEK_CUR)) && (EBADF == errno))
1917 return NULL; /* invalid FD */ 1460 return NULL; /* invalid FD */
1918 1461
1919#ifndef WINDOWS
1920 fh = GNUNET_new(struct GNUNET_DISK_FileHandle); 1462 fh = GNUNET_new(struct GNUNET_DISK_FileHandle);
1921 1463
1922 fh->fd = fno; 1464 fh->fd = fno;
1923#else
1924 intptr_t osfh;
1925
1926 osfh = _get_osfhandle(fno);
1927 if (INVALID_HANDLE_VALUE == (HANDLE)osfh)
1928 return NULL;
1929
1930 fh = GNUNET_DISK_get_handle_from_w32_handle((HANDLE)osfh);
1931#endif
1932 1465
1933 return fh; 1466 return fh;
1934} 1467}
@@ -1962,17 +1495,10 @@ struct GNUNET_DISK_MapHandle {
1962 */ 1495 */
1963 void *addr; 1496 void *addr;
1964 1497
1965#ifdef MINGW
1966 /**
1967 * Underlying OS handle.
1968 */
1969 HANDLE h;
1970#else
1971 /** 1498 /**
1972 * Number of bytes mapped. 1499 * Number of bytes mapped.
1973 */ 1500 */
1974 size_t len; 1501 size_t len;
1975#endif
1976}; 1502};
1977 1503
1978 1504
@@ -2001,50 +1527,6 @@ GNUNET_DISK_file_map(const struct GNUNET_DISK_FileHandle *h,
2001 return NULL; 1527 return NULL;
2002 } 1528 }
2003 1529
2004#ifdef MINGW
2005 DWORD mapAccess, protect;
2006
2007 if ((access & GNUNET_DISK_MAP_TYPE_READ) &&
2008 (access & GNUNET_DISK_MAP_TYPE_WRITE))
2009 {
2010 protect = PAGE_READWRITE;
2011 mapAccess = FILE_MAP_ALL_ACCESS;
2012 }
2013 else if (access & GNUNET_DISK_MAP_TYPE_READ)
2014 {
2015 protect = PAGE_READONLY;
2016 mapAccess = FILE_MAP_READ;
2017 }
2018 else if (access & GNUNET_DISK_MAP_TYPE_WRITE)
2019 {
2020 protect = PAGE_READWRITE;
2021 mapAccess = FILE_MAP_WRITE;
2022 }
2023 else
2024 {
2025 GNUNET_break(0);
2026 return NULL;
2027 }
2028
2029 *m = GNUNET_new(struct GNUNET_DISK_MapHandle);
2030 (*m)->h = CreateFileMapping(h->h, NULL, protect, 0, 0, NULL);
2031 if ((*m)->h == INVALID_HANDLE_VALUE)
2032 {
2033 SetErrnoFromWinError(GetLastError());
2034 GNUNET_free(*m);
2035 return NULL;
2036 }
2037
2038 (*m)->addr = MapViewOfFile((*m)->h, mapAccess, 0, 0, len);
2039 if (!(*m)->addr)
2040 {
2041 SetErrnoFromWinError(GetLastError());
2042 CloseHandle((*m)->h);
2043 GNUNET_free(*m);
2044 }
2045
2046 return (*m)->addr;
2047#else
2048 int prot; 1530 int prot;
2049 1531
2050 prot = 0; 1532 prot = 0;
@@ -2062,7 +1544,6 @@ GNUNET_DISK_file_map(const struct GNUNET_DISK_FileHandle *h,
2062 } 1544 }
2063 (*m)->len = len; 1545 (*m)->len = len;
2064 return (*m)->addr; 1546 return (*m)->addr;
2065#endif
2066} 1547}
2067 1548
2068/** 1549/**
@@ -2081,18 +1562,8 @@ GNUNET_DISK_file_unmap(struct GNUNET_DISK_MapHandle *h)
2081 return GNUNET_SYSERR; 1562 return GNUNET_SYSERR;
2082 } 1563 }
2083 1564
2084#ifdef MINGW
2085 ret = UnmapViewOfFile(h->addr) ? GNUNET_OK : GNUNET_SYSERR;
2086 if (ret != GNUNET_OK)
2087 SetErrnoFromWinError(GetLastError());
2088 if (!CloseHandle(h->h) && (ret == GNUNET_OK))
2089 {
2090 ret = GNUNET_SYSERR;
2091 SetErrnoFromWinError(GetLastError());
2092 }
2093#else
2094 ret = munmap(h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR; 1565 ret = munmap(h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
2095#endif 1566
2096 GNUNET_free(h); 1567 GNUNET_free(h);
2097 return ret; 1568 return ret;
2098} 1569}
@@ -2112,14 +1583,7 @@ GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
2112 return GNUNET_SYSERR; 1583 return GNUNET_SYSERR;
2113 } 1584 }
2114 1585
2115#ifdef MINGW 1586#if defined(FREEBSD) || defined(OPENBSD) || defined(DARWIN)
2116 int ret;
2117
2118 ret = FlushFileBuffers(h->h) ? GNUNET_OK : GNUNET_SYSERR;
2119 if (ret != GNUNET_OK)
2120 SetErrnoFromWinError(GetLastError());
2121 return ret;
2122#elif defined(FREEBSD) || defined(OPENBSD) || defined(DARWIN)
2123 return fsync(h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK; 1587 return fsync(h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
2124#else 1588#else
2125 return fdatasync(h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK; 1589 return fdatasync(h->fd) == -1 ? GNUNET_SYSERR : GNUNET_OK;
@@ -2127,151 +1591,6 @@ GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
2127} 1591}
2128 1592
2129 1593
2130#if WINDOWS
2131#ifndef PIPE_BUF
2132#define PIPE_BUF 512
2133#endif
2134/* Copyright Bob Byrnes <byrnes <at> curl.com>
2135 http://permalink.gmane.org/gmane.os.cygwin.patches/2121
2136 */
2137/* Create a pipe, and return handles to the read and write ends,
2138 just like CreatePipe, but ensure that the write end permits
2139 FILE_READ_ATTRIBUTES access, on later versions of win32 where
2140 this is supported. This access is needed by NtQueryInformationFile,
2141 which is used to implement select and nonblocking writes.
2142 Note that the return value is either NO_ERROR or GetLastError,
2143 unlike CreatePipe, which returns a bool for success or failure. */
2144static int
2145create_selectable_pipe(PHANDLE read_pipe_ptr,
2146 PHANDLE write_pipe_ptr,
2147 LPSECURITY_ATTRIBUTES sa_ptr,
2148 DWORD psize,
2149 DWORD dwReadMode,
2150 DWORD dwWriteMode)
2151{
2152 /* Default to error. */
2153 *read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE;
2154
2155 HANDLE read_pipe;
2156 HANDLE write_pipe;
2157
2158 /* Ensure that there is enough pipe buffer space for atomic writes. */
2159 if (psize < PIPE_BUF)
2160 psize = PIPE_BUF;
2161
2162 char pipename[MAX_PATH];
2163
2164 /* Retry CreateNamedPipe as long as the pipe name is in use.
2165 * Retrying will probably never be necessary, but we want
2166 * to be as robust as possible. */
2167 while (1)
2168 {
2169 static volatile LONG pipe_unique_id;
2170
2171 snprintf(pipename,
2172 sizeof pipename,
2173 "\\\\.\\pipe\\gnunet-%d-%ld",
2174 getpid(),
2175 InterlockedIncrement((LONG *)&pipe_unique_id));
2176 LOG(GNUNET_ERROR_TYPE_DEBUG,
2177 "CreateNamedPipe: name = %s, size = %lu\n",
2178 pipename,
2179 psize);
2180 /* Use CreateNamedPipe instead of CreatePipe, because the latter
2181 * returns a write handle that does not permit FILE_READ_ATTRIBUTES
2182 * access, on versions of win32 earlier than WinXP SP2.
2183 * CreatePipe also stupidly creates a full duplex pipe, which is
2184 * a waste, since only a single direction is actually used.
2185 * It's important to only allow a single instance, to ensure that
2186 * the pipe was not created earlier by some other process, even if
2187 * the pid has been reused. */
2188 read_pipe = CreateNamedPipeA(pipename,
2189 PIPE_ACCESS_INBOUND |
2190 FILE_FLAG_FIRST_PIPE_INSTANCE | dwReadMode,
2191 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
2192 1, /* max instances */
2193 psize, /* output buffer size */
2194 psize, /* input buffer size */
2195 NMPWAIT_USE_DEFAULT_WAIT,
2196 sa_ptr);
2197
2198 if (read_pipe != INVALID_HANDLE_VALUE)
2199 {
2200 LOG(GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", read_pipe);
2201 break;
2202 }
2203
2204 DWORD err = GetLastError();
2205
2206 switch (err)
2207 {
2208 case ERROR_PIPE_BUSY:
2209 /* The pipe is already open with compatible parameters.
2210 * Pick a new name and retry. */
2211 LOG(GNUNET_ERROR_TYPE_DEBUG, "pipe busy, retrying\n");
2212 continue;
2213
2214 case ERROR_ACCESS_DENIED:
2215 /* The pipe is already open with incompatible parameters.
2216 * Pick a new name and retry. */
2217 LOG(GNUNET_ERROR_TYPE_DEBUG, "pipe access denied, retrying\n");
2218 continue;
2219
2220 case ERROR_CALL_NOT_IMPLEMENTED:
2221 /* We are on an older Win9x platform without named pipes.
2222 * Return an anonymous pipe as the best approximation. */
2223 LOG(GNUNET_ERROR_TYPE_DEBUG,
2224 "CreateNamedPipe not implemented, resorting to "
2225 "CreatePipe: size = %lu\n",
2226 psize);
2227 if (CreatePipe(read_pipe_ptr, write_pipe_ptr, sa_ptr, psize))
2228 {
2229 LOG(GNUNET_ERROR_TYPE_DEBUG,
2230 "pipe read handle = %p, write handle = %p\n",
2231 *read_pipe_ptr,
2232 *write_pipe_ptr);
2233 return GNUNET_OK;
2234 }
2235 err = GetLastError();
2236 LOG(GNUNET_ERROR_TYPE_ERROR, "CreatePipe failed: %d\n", err);
2237 return err;
2238
2239 default:
2240 LOG(GNUNET_ERROR_TYPE_ERROR, "CreateNamedPipe failed: %d\n", err);
2241 return err;
2242 }
2243 /* NOTREACHED */
2244 }
2245 LOG(GNUNET_ERROR_TYPE_DEBUG, "CreateFile: name = %s\n", pipename);
2246
2247 /* Open the named pipe for writing.
2248 * Be sure to permit FILE_READ_ATTRIBUTES access. */
2249 write_pipe = CreateFileA(pipename,
2250 GENERIC_WRITE | FILE_READ_ATTRIBUTES,
2251 0, /* share mode */
2252 sa_ptr,
2253 OPEN_EXISTING,
2254 dwWriteMode, /* flags and attributes */
2255 0); /* handle to template file */
2256
2257 if (write_pipe == INVALID_HANDLE_VALUE)
2258 {
2259 /* Failure. */
2260 DWORD err = GetLastError();
2261
2262 LOG(GNUNET_ERROR_TYPE_DEBUG, "CreateFile failed: %d\n", err);
2263 CloseHandle(read_pipe);
2264 return err;
2265 }
2266 LOG(GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", write_pipe);
2267 /* Success. */
2268 *read_pipe_ptr = read_pipe;
2269 *write_pipe_ptr = write_pipe;
2270 return GNUNET_OK;
2271}
2272#endif
2273
2274
2275/** 1594/**
2276 * Creates an interprocess channel 1595 * Creates an interprocess channel
2277 * 1596 *
@@ -2287,7 +1606,6 @@ GNUNET_DISK_pipe(int blocking_read,
2287 int inherit_read, 1606 int inherit_read,
2288 int inherit_write) 1607 int inherit_write)
2289{ 1608{
2290#ifndef MINGW
2291 int fd[2]; 1609 int fd[2];
2292 int ret; 1610 int ret;
2293 int eno; 1611 int eno;
@@ -2303,99 +1621,6 @@ GNUNET_DISK_pipe(int blocking_read,
2303 return NULL; 1621 return NULL;
2304 } 1622 }
2305 return GNUNET_DISK_pipe_from_fd(blocking_read, blocking_write, fd); 1623 return GNUNET_DISK_pipe_from_fd(blocking_read, blocking_write, fd);
2306#else
2307 struct GNUNET_DISK_PipeHandle *p;
2308 BOOL ret;
2309 HANDLE tmp_handle;
2310 int save_errno;
2311
2312 p = GNUNET_new(struct GNUNET_DISK_PipeHandle);
2313 p->fd[0] = GNUNET_new(struct GNUNET_DISK_FileHandle);
2314 p->fd[1] = GNUNET_new(struct GNUNET_DISK_FileHandle);
2315
2316 /* All pipes are overlapped. If you want them to block - just
2317 * call WriteFile() and ReadFile() with NULL overlapped pointer.
2318 * NOTE: calling with NULL overlapped pointer works only
2319 * for pipes, and doesn't seem to be a documented feature.
2320 * It will NOT work for files, because overlapped files need
2321 * to read offsets from the overlapped structure, regardless.
2322 * Pipes are not seekable, and need no offsets, which is
2323 * probably why it works for them.
2324 */
2325 ret = create_selectable_pipe(&p->fd[0]->h,
2326 &p->fd[1]->h,
2327 NULL,
2328 0,
2329 FILE_FLAG_OVERLAPPED,
2330 FILE_FLAG_OVERLAPPED);
2331 if (!ret)
2332 {
2333 SetErrnoFromWinError(GetLastError());
2334 save_errno = errno;
2335 GNUNET_free(p->fd[0]);
2336 GNUNET_free(p->fd[1]);
2337 GNUNET_free(p);
2338 errno = save_errno;
2339 return NULL;
2340 }
2341 if (!DuplicateHandle(GetCurrentProcess(),
2342 p->fd[0]->h,
2343 GetCurrentProcess(),
2344 &tmp_handle,
2345 0,
2346 inherit_read == GNUNET_YES ? TRUE : FALSE,
2347 DUPLICATE_SAME_ACCESS))
2348 {
2349 SetErrnoFromWinError(GetLastError());
2350 save_errno = errno;
2351 CloseHandle(p->fd[0]->h);
2352 CloseHandle(p->fd[1]->h);
2353 GNUNET_free(p->fd[0]);
2354 GNUNET_free(p->fd[1]);
2355 GNUNET_free(p);
2356 errno = save_errno;
2357 return NULL;
2358 }
2359 CloseHandle(p->fd[0]->h);
2360 p->fd[0]->h = tmp_handle;
2361
2362 if (!DuplicateHandle(GetCurrentProcess(),
2363 p->fd[1]->h,
2364 GetCurrentProcess(),
2365 &tmp_handle,
2366 0,
2367 inherit_write == GNUNET_YES ? TRUE : FALSE,
2368 DUPLICATE_SAME_ACCESS))
2369 {
2370 SetErrnoFromWinError(GetLastError());
2371 save_errno = errno;
2372 CloseHandle(p->fd[0]->h);
2373 CloseHandle(p->fd[1]->h);
2374 GNUNET_free(p->fd[0]);
2375 GNUNET_free(p->fd[1]);
2376 GNUNET_free(p);
2377 errno = save_errno;
2378 return NULL;
2379 }
2380 CloseHandle(p->fd[1]->h);
2381 p->fd[1]->h = tmp_handle;
2382
2383 p->fd[0]->type = GNUNET_DISK_HANLDE_TYPE_PIPE;
2384 p->fd[1]->type = GNUNET_DISK_HANLDE_TYPE_PIPE;
2385
2386 p->fd[0]->oOverlapRead = GNUNET_new(OVERLAPPED);
2387 p->fd[0]->oOverlapWrite = GNUNET_new(OVERLAPPED);
2388 p->fd[1]->oOverlapRead = GNUNET_new(OVERLAPPED);
2389 p->fd[1]->oOverlapWrite = GNUNET_new(OVERLAPPED);
2390
2391 p->fd[0]->oOverlapRead->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2392 p->fd[0]->oOverlapWrite->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2393
2394 p->fd[1]->oOverlapRead->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2395 p->fd[1]->oOverlapWrite->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2396
2397 return p;
2398#endif
2399} 1624}
2400 1625
2401 1626
@@ -2416,7 +1641,6 @@ GNUNET_DISK_pipe_from_fd(int blocking_read, int blocking_write, int fd[2])
2416 1641
2417 p = GNUNET_new(struct GNUNET_DISK_PipeHandle); 1642 p = GNUNET_new(struct GNUNET_DISK_PipeHandle);
2418 1643
2419#ifndef MINGW
2420 int ret; 1644 int ret;
2421 int flags; 1645 int flags;
2422 int eno = 0; /* make gcc happy */ 1646 int eno = 0; /* make gcc happy */
@@ -2481,44 +1705,7 @@ GNUNET_DISK_pipe_from_fd(int blocking_read, int blocking_write, int fd[2])
2481 errno = eno; 1705 errno = eno;
2482 return NULL; 1706 return NULL;
2483 } 1707 }
2484#else 1708
2485 if (fd[0] >= 0)
2486 {
2487 p->fd[0] = GNUNET_new(struct GNUNET_DISK_FileHandle);
2488 p->fd[0]->h = (HANDLE)_get_osfhandle(fd[0]);
2489 if (p->fd[0]->h != INVALID_HANDLE_VALUE)
2490 {
2491 p->fd[0]->type = GNUNET_DISK_HANLDE_TYPE_PIPE;
2492 p->fd[0]->oOverlapRead = GNUNET_new(OVERLAPPED);
2493 p->fd[0]->oOverlapWrite = GNUNET_new(OVERLAPPED);
2494 p->fd[0]->oOverlapRead->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2495 p->fd[0]->oOverlapWrite->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2496 }
2497 else
2498 {
2499 GNUNET_free(p->fd[0]);
2500 p->fd[0] = NULL;
2501 }
2502 }
2503 if (fd[1] >= 0)
2504 {
2505 p->fd[1] = GNUNET_new(struct GNUNET_DISK_FileHandle);
2506 p->fd[1]->h = (HANDLE)_get_osfhandle(fd[1]);
2507 if (p->fd[1]->h != INVALID_HANDLE_VALUE)
2508 {
2509 p->fd[1]->type = GNUNET_DISK_HANLDE_TYPE_PIPE;
2510 p->fd[1]->oOverlapRead = GNUNET_new(OVERLAPPED);
2511 p->fd[1]->oOverlapWrite = GNUNET_new(OVERLAPPED);
2512 p->fd[1]->oOverlapRead->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2513 p->fd[1]->oOverlapWrite->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2514 }
2515 else
2516 {
2517 GNUNET_free(p->fd[1]);
2518 p->fd[1] = NULL;
2519 }
2520 }
2521#endif
2522 return p; 1709 return p;
2523} 1710}
2524 1711
@@ -2671,15 +1858,10 @@ GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh,
2671{ 1858{
2672 if (NULL == fh) 1859 if (NULL == fh)
2673 return GNUNET_SYSERR; 1860 return GNUNET_SYSERR;
2674#ifdef MINGW 1861
2675 if (dst_len < sizeof(HANDLE))
2676 return GNUNET_SYSERR;
2677 *((HANDLE *)dst) = fh->h;
2678#else
2679 if (dst_len < sizeof(int)) 1862 if (dst_len < sizeof(int))
2680 return GNUNET_SYSERR; 1863 return GNUNET_SYSERR;
2681 *((int *)dst) = fh->fd; 1864 *((int *)dst) = fh->fd;
2682#endif
2683 1865
2684 return GNUNET_OK; 1866 return GNUNET_OK;
2685} 1867}