aboutsummaryrefslogtreecommitdiff
path: root/src/util/disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/disk.c')
-rw-r--r--src/util/disk.c1437
1 files changed, 715 insertions, 722 deletions
diff --git a/src/util/disk.c b/src/util/disk.c
index 12f985791..2bdcf3262 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -67,8 +67,8 @@
67#define PIPE_BUF 512 67#define PIPE_BUF 512
68ULONG PipeSerialNumber; 68ULONG PipeSerialNumber;
69#endif 69#endif
70#define _IFMT 0170000 /* type of file */ 70#define _IFMT 0170000 /* type of file */
71#define _IFLNK 0120000 /* symbolic link */ 71#define _IFLNK 0120000 /* symbolic link */
72#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK) 72#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
73#else 73#else
74#error PORT-ME: need to port statfs (how much space is left on the drive?) 74#error PORT-ME: need to port statfs (how much space is left on the drive?)
@@ -165,25 +165,25 @@ getSizeRec (void *cls, const char *fn)
165 165
166#ifdef HAVE_STAT64 166#ifdef HAVE_STAT64
167 if (0 != STAT64 (fn, &buf)) 167 if (0 != STAT64 (fn, &buf))
168 { 168 {
169 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat64", fn); 169 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat64", fn);
170 return GNUNET_SYSERR; 170 return GNUNET_SYSERR;
171 } 171 }
172#else 172#else
173 if (0 != STAT (fn, &buf)) 173 if (0 != STAT (fn, &buf))
174 { 174 {
175 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", fn); 175 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", fn);
176 return GNUNET_SYSERR; 176 return GNUNET_SYSERR;
177 } 177 }
178#endif 178#endif
179 if ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)) 179 if ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))
180 gfsd->total += buf.st_size; 180 gfsd->total += buf.st_size;
181 if ((S_ISDIR (buf.st_mode)) && (0 == ACCESS (fn, X_OK)) && 181 if ((S_ISDIR (buf.st_mode)) && (0 == ACCESS (fn, X_OK)) &&
182 ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES))) 182 ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)))
183 { 183 {
184 if (GNUNET_SYSERR == GNUNET_DISK_directory_scan (fn, &getSizeRec, gfsd)) 184 if (GNUNET_SYSERR == GNUNET_DISK_directory_scan (fn, &getSizeRec, gfsd))
185 return GNUNET_SYSERR; 185 return GNUNET_SYSERR;
186 } 186 }
187 return GNUNET_OK; 187 return GNUNET_OK;
188} 188}
189 189
@@ -215,13 +215,13 @@ GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h)
215 */ 215 */
216off_t 216off_t
217GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, off_t offset, 217GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, off_t offset,
218 enum GNUNET_DISK_Seek whence) 218 enum GNUNET_DISK_Seek whence)
219{ 219{
220 if (h == NULL) 220 if (h == NULL)
221 { 221 {
222 errno = EINVAL; 222 errno = EINVAL;
223 return GNUNET_SYSERR; 223 return GNUNET_SYSERR;
224 } 224 }
225 225
226#ifdef MINGW 226#ifdef MINGW
227 DWORD ret; 227 DWORD ret;
@@ -232,10 +232,10 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, off_t offset,
232 232
233 ret = SetFilePointer (h->h, offset, NULL, t[whence]); 233 ret = SetFilePointer (h->h, offset, NULL, t[whence]);
234 if (ret == INVALID_SET_FILE_POINTER) 234 if (ret == INVALID_SET_FILE_POINTER)
235 { 235 {
236 SetErrnoFromWinError (GetLastError ()); 236 SetErrnoFromWinError (GetLastError ());
237 return GNUNET_SYSERR; 237 return GNUNET_SYSERR;
238 } 238 }
239 return ret; 239 return ret;
240#else 240#else
241 static int t[] = {[GNUNET_DISK_SEEK_SET] = SEEK_SET, 241 static int t[] = {[GNUNET_DISK_SEEK_SET] = SEEK_SET,
@@ -261,7 +261,7 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, off_t offset,
261 */ 261 */
262int 262int
263GNUNET_DISK_file_size (const char *filename, uint64_t * size, 263GNUNET_DISK_file_size (const char *filename, uint64_t * size,
264 int includeSymLinks) 264 int includeSymLinks)
265{ 265{
266 struct GetFileSizeData gfsd; 266 struct GetFileSizeData gfsd;
267 int ret; 267 int ret;
@@ -292,29 +292,29 @@ GNUNET_DISK_file_size (const char *filename, uint64_t * size,
292 */ 292 */
293int 293int
294GNUNET_DISK_file_get_identifiers (const char *filename, uint64_t * dev, 294GNUNET_DISK_file_get_identifiers (const char *filename, uint64_t * dev,
295 uint64_t * ino) 295 uint64_t * ino)
296{ 296{
297#if LINUX 297#if LINUX
298 struct stat sbuf; 298 struct stat sbuf;
299 struct statvfs fbuf; 299 struct statvfs fbuf;
300 300
301 if ((0 == stat (filename, &sbuf)) && (0 == statvfs (filename, &fbuf))) 301 if ((0 == stat (filename, &sbuf)) && (0 == statvfs (filename, &fbuf)))
302 { 302 {
303 *dev = (uint64_t) fbuf.f_fsid; 303 *dev = (uint64_t) fbuf.f_fsid;
304 *ino = (uint64_t) sbuf.st_ino; 304 *ino = (uint64_t) sbuf.st_ino;
305 return GNUNET_OK; 305 return GNUNET_OK;
306 } 306 }
307#elif SOMEBSD 307#elif SOMEBSD
308 struct stat sbuf; 308 struct stat sbuf;
309 struct statfs fbuf; 309 struct statfs fbuf;
310 310
311 if ((0 == stat (filename, &sbuf)) && (0 == statfs (filename, &fbuf))) 311 if ((0 == stat (filename, &sbuf)) && (0 == statfs (filename, &fbuf)))
312 { 312 {
313 *dev = ((uint64_t) fbuf.f_fsid.val[0]) << 32 || 313 *dev = ((uint64_t) fbuf.f_fsid.val[0]) << 32 ||
314 ((uint64_t) fbuf.f_fsid.val[1]); 314 ((uint64_t) fbuf.f_fsid.val[1]);
315 *ino = (uint64_t) sbuf.st_ino; 315 *ino = (uint64_t) sbuf.st_ino;
316 return GNUNET_OK; 316 return GNUNET_OK;
317 } 317 }
318#elif WINDOWS 318#elif WINDOWS
319 // FIXME NILS: test this 319 // FIXME NILS: test this
320 struct GNUNET_DISK_FileHandle *fh; 320 struct GNUNET_DISK_FileHandle *fh;
@@ -327,11 +327,11 @@ GNUNET_DISK_file_get_identifiers (const char *filename, uint64_t * dev,
327 succ = GetFileInformationByHandle (fh->h, &info); 327 succ = GetFileInformationByHandle (fh->h, &info);
328 GNUNET_DISK_file_close (fh); 328 GNUNET_DISK_file_close (fh);
329 if (succ) 329 if (succ)
330 { 330 {
331 *dev = info.dwVolumeSerialNumber; 331 *dev = info.dwVolumeSerialNumber;
332 *ino = ((info.nFileIndexHigh << sizeof (DWORD)) | info.nFileIndexLow); 332 *ino = ((info.nFileIndexHigh << sizeof (DWORD)) | info.nFileIndexLow);
333 return GNUNET_OK; 333 return GNUNET_OK;
334 } 334 }
335 else 335 else
336 return GNUNET_SYSERR; 336 return GNUNET_SYSERR;
337 337
@@ -363,35 +363,35 @@ GNUNET_DISK_mktemp (const char *t)
363#if WINDOWS 363#if WINDOWS
364 && !(isalpha ((int) t[0]) && (t[0] != '\0') && (t[1] == ':')) 364 && !(isalpha ((int) t[0]) && (t[0] != '\0') && (t[1] == ':'))
365#endif 365#endif
366 ) 366 )
367 { 367 {
368 tmpdir = getenv ("TMPDIR"); 368 tmpdir = getenv ("TMPDIR");
369 tmpdir = tmpdir ? tmpdir : "/tmp"; 369 tmpdir = tmpdir ? tmpdir : "/tmp";
370 GNUNET_asprintf (&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX"); 370 GNUNET_asprintf (&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX");
371 } 371 }
372 else 372 else
373 { 373 {
374 GNUNET_asprintf (&tmpl, "%s%s", t, "XXXXXX"); 374 GNUNET_asprintf (&tmpl, "%s%s", t, "XXXXXX");
375 } 375 }
376#ifdef MINGW 376#ifdef MINGW
377 fn = (char *) GNUNET_malloc (MAX_PATH + 1); 377 fn = (char *) GNUNET_malloc (MAX_PATH + 1);
378 if (ERROR_SUCCESS != plibc_conv_to_win_path (tmpl, fn)) 378 if (ERROR_SUCCESS != plibc_conv_to_win_path (tmpl, fn))
379 { 379 {
380 GNUNET_free (fn); 380 GNUNET_free (fn);
381 GNUNET_free (tmpl); 381 GNUNET_free (tmpl);
382 return NULL; 382 return NULL;
383 } 383 }
384 GNUNET_free (tmpl); 384 GNUNET_free (tmpl);
385#else 385#else
386 fn = tmpl; 386 fn = tmpl;
387#endif 387#endif
388 fd = mkstemp (fn); 388 fd = mkstemp (fn);
389 if (fd == -1) 389 if (fd == -1)
390 { 390 {
391 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "mkstemp", fn); 391 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "mkstemp", fn);
392 GNUNET_free (fn); 392 GNUNET_free (fn);
393 return NULL; 393 return NULL;
394 } 394 }
395 if (0 != CLOSE (fd)) 395 if (0 != CLOSE (fd))
396 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "close", fn); 396 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "close", fn);
397 return fn; 397 return fn;
@@ -412,10 +412,10 @@ GNUNET_DISK_get_blocks_available (const char *part)
412 struct statvfs buf; 412 struct statvfs buf;
413 413
414 if (0 != statvfs (part, &buf)) 414 if (0 != statvfs (part, &buf))
415 { 415 {
416 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "statfs", part); 416 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "statfs", part);
417 return -1; 417 return -1;
418 } 418 }
419 return buf.f_bavail; 419 return buf.f_bavail;
420#elif MINGW 420#elif MINGW
421 DWORD dwDummy; 421 DWORD dwDummy;
@@ -430,22 +430,21 @@ GNUNET_DISK_get_blocks_available (const char *part)
430 GNUNET_free (path); 430 GNUNET_free (path);
431 szDrive[3] = 0; 431 szDrive[3] = 0;
432 if (!GetDiskFreeSpace (szDrive, &dwDummy, &dwDummy, &dwBlocks, &dwDummy)) 432 if (!GetDiskFreeSpace (szDrive, &dwDummy, &dwDummy, &dwBlocks, &dwDummy))
433 { 433 {
434 LOG (GNUNET_ERROR_TYPE_WARNING, 434 LOG (GNUNET_ERROR_TYPE_WARNING, _("`%s' failed for drive `%s': %u\n"),
435 _("`%s' failed for drive `%s': %u\n"), "GetDiskFreeSpace", 435 "GetDiskFreeSpace", szDrive, GetLastError ());
436 szDrive, GetLastError ());
437 436
438 return -1; 437 return -1;
439 } 438 }
440 return dwBlocks; 439 return dwBlocks;
441#else 440#else
442 struct statfs s; 441 struct statfs s;
443 442
444 if (0 != statfs (part, &s)) 443 if (0 != statfs (part, &s))
445 { 444 {
446 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "statfs", part); 445 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "statfs", part);
447 return -1; 446 return -1;
448 } 447 }
449 return s.f_bavail; 448 return s.f_bavail;
450#endif 449#endif
451} 450}
@@ -469,21 +468,21 @@ GNUNET_DISK_directory_test (const char *fil)
469 468
470 ret = STAT (fil, &filestat); 469 ret = STAT (fil, &filestat);
471 if (ret != 0) 470 if (ret != 0)
471 {
472 if (errno != ENOENT)
472 { 473 {
473 if (errno != ENOENT) 474 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", fil);
474 { 475 return GNUNET_SYSERR;
475 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", fil);
476 return GNUNET_SYSERR;
477 }
478 return GNUNET_NO;
479 } 476 }
477 return GNUNET_NO;
478 }
480 if (!S_ISDIR (filestat.st_mode)) 479 if (!S_ISDIR (filestat.st_mode))
481 return GNUNET_NO; 480 return GNUNET_NO;
482 if (ACCESS (fil, R_OK | X_OK) < 0) 481 if (ACCESS (fil, R_OK | X_OK) < 0)
483 { 482 {
484 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", fil); 483 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", fil);
485 return GNUNET_SYSERR; 484 return GNUNET_SYSERR;
486 } 485 }
487 return GNUNET_YES; 486 return GNUNET_YES;
488} 487}
489 488
@@ -508,27 +507,27 @@ GNUNET_DISK_file_test (const char *fil)
508 507
509 ret = STAT (rdir, &filestat); 508 ret = STAT (rdir, &filestat);
510 if (ret != 0) 509 if (ret != 0)
510 {
511 if (errno != ENOENT)
511 { 512 {
512 if (errno != ENOENT) 513 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", rdir);
513 {
514 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", rdir);
515 GNUNET_free (rdir);
516 return GNUNET_SYSERR;
517 }
518 GNUNET_free (rdir); 514 GNUNET_free (rdir);
519 return GNUNET_NO; 515 return GNUNET_SYSERR;
520 } 516 }
517 GNUNET_free (rdir);
518 return GNUNET_NO;
519 }
521 if (!S_ISREG (filestat.st_mode)) 520 if (!S_ISREG (filestat.st_mode))
522 { 521 {
523 GNUNET_free (rdir); 522 GNUNET_free (rdir);
524 return GNUNET_NO; 523 return GNUNET_NO;
525 } 524 }
526 if (ACCESS (rdir, R_OK) < 0) 525 if (ACCESS (rdir, R_OK) < 0)
527 { 526 {
528 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", rdir); 527 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", rdir);
529 GNUNET_free (rdir); 528 GNUNET_free (rdir);
530 return GNUNET_SYSERR; 529 return GNUNET_SYSERR;
531 } 530 }
532 GNUNET_free (rdir); 531 GNUNET_free (rdir);
533 return GNUNET_YES; 532 return GNUNET_YES;
534} 533}
@@ -553,56 +552,56 @@ GNUNET_DISK_directory_create (const char *dir)
553 552
554 len = strlen (rdir); 553 len = strlen (rdir);
555#ifndef MINGW 554#ifndef MINGW
556 pos = 1; /* skip heading '/' */ 555 pos = 1; /* skip heading '/' */
557#else 556#else
558 /* Local or Network path? */ 557 /* Local or Network path? */
559 if (strncmp (rdir, "\\\\", 2) == 0) 558 if (strncmp (rdir, "\\\\", 2) == 0)
559 {
560 pos = 2;
561 while (rdir[pos])
560 { 562 {
561 pos = 2; 563 if (rdir[pos] == '\\')
562 while (rdir[pos]) 564 {
563 { 565 pos++;
564 if (rdir[pos] == '\\') 566 break;
565 { 567 }
566 pos++; 568 pos++;
567 break;
568 }
569 pos++;
570 }
571 } 569 }
570 }
572 else 571 else
573 { 572 {
574 pos = 3; /* strlen("C:\\") */ 573 pos = 3; /* strlen("C:\\") */
575 } 574 }
576#endif 575#endif
577 while (pos <= len) 576 while (pos <= len)
577 {
578 if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
578 { 579 {
579 if ((rdir[pos] == DIR_SEPARATOR) || (pos == len)) 580 rdir[pos] = '\0';
580 { 581 ret = GNUNET_DISK_directory_test (rdir);
581 rdir[pos] = '\0'; 582 if (ret == GNUNET_SYSERR)
582 ret = GNUNET_DISK_directory_test (rdir); 583 {
583 if (ret == GNUNET_SYSERR) 584 GNUNET_free (rdir);
584 { 585 return GNUNET_SYSERR;
585 GNUNET_free (rdir); 586 }
586 return GNUNET_SYSERR; 587 if (ret == GNUNET_NO)
587 } 588 {
588 if (ret == GNUNET_NO)
589 {
590#ifndef MINGW 589#ifndef MINGW
591 ret = mkdir (rdir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); /* 755 */ 590 ret = mkdir (rdir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); /* 755 */
592#else 591#else
593 ret = mkdir (rdir); 592 ret = mkdir (rdir);
594#endif 593#endif
595 if ((ret != 0) && (errno != EEXIST)) 594 if ((ret != 0) && (errno != EEXIST))
596 { 595 {
597 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "mkdir", rdir); 596 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "mkdir", rdir);
598 GNUNET_free (rdir); 597 GNUNET_free (rdir);
599 return GNUNET_SYSERR; 598 return GNUNET_SYSERR;
600 } 599 }
601 } 600 }
602 rdir[pos] = DIR_SEPARATOR; 601 rdir[pos] = DIR_SEPARATOR;
603 }
604 pos++;
605 } 602 }
603 pos++;
604 }
606 GNUNET_free (rdir); 605 GNUNET_free (rdir);
607 return GNUNET_OK; 606 return GNUNET_OK;
608} 607}
@@ -649,37 +648,37 @@ GNUNET_DISK_directory_create_for_file (const char *filename)
649 */ 648 */
650ssize_t 649ssize_t
651GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle * h, void *result, 650GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle * h, void *result,
652 size_t len) 651 size_t len)
653{ 652{
654 if (h == NULL) 653 if (h == NULL)
655 { 654 {
656 errno = EINVAL; 655 errno = EINVAL;
657 return GNUNET_SYSERR; 656 return GNUNET_SYSERR;
658 } 657 }
659 658
660#ifdef MINGW 659#ifdef MINGW
661 DWORD bytesRead; 660 DWORD bytesRead;
662 661
663 if (h->type != GNUNET_PIPE) 662 if (h->type != GNUNET_PIPE)
663 {
664 if (!ReadFile (h->h, result, len, &bytesRead, NULL))
664 { 665 {
665 if (!ReadFile (h->h, result, len, &bytesRead, NULL)) 666 SetErrnoFromWinError (GetLastError ());
666 { 667 return GNUNET_SYSERR;
667 SetErrnoFromWinError (GetLastError ());
668 return GNUNET_SYSERR;
669 }
670 } 668 }
669 }
671 else 670 else
671 {
672 if (!ReadFile (h->h, result, len, NULL, h->oOverlapRead))
672 { 673 {
673 if (!ReadFile (h->h, result, len, NULL, h->oOverlapRead)) 674 if (GetLastError () != ERROR_IO_PENDING)
674 { 675 {
675 if (GetLastError () != ERROR_IO_PENDING) 676 SetErrnoFromWinError (GetLastError ());
676 { 677 return GNUNET_SYSERR;
677 SetErrnoFromWinError (GetLastError ()); 678 }
678 return GNUNET_SYSERR;
679 }
680 }
681 GetOverlappedResult (h->h, h->oOverlapRead, &bytesRead, TRUE);
682 } 679 }
680 GetOverlappedResult (h->h, h->oOverlapRead, &bytesRead, TRUE);
681 }
683 return bytesRead; 682 return bytesRead;
684#else 683#else
685 return read (h->fd, result, len); 684 return read (h->fd, result, len);
@@ -701,8 +700,7 @@ GNUNET_DISK_fn_read (const char *fn, void *result, size_t len)
701 struct GNUNET_DISK_FileHandle *fh; 700 struct GNUNET_DISK_FileHandle *fh;
702 ssize_t ret; 701 ssize_t ret;
703 702
704 fh = 703 fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE);
705 GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE);
706 if (!fh) 704 if (!fh)
707 return GNUNET_SYSERR; 705 return GNUNET_SYSERR;
708 ret = GNUNET_DISK_file_read (fh, result, len); 706 ret = GNUNET_DISK_file_read (fh, result, len);
@@ -721,46 +719,46 @@ GNUNET_DISK_fn_read (const char *fn, void *result, size_t len)
721 */ 719 */
722ssize_t 720ssize_t
723GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h, 721GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h,
724 const void *buffer, size_t n) 722 const void *buffer, size_t n)
725{ 723{
726 if (h == NULL) 724 if (h == NULL)
727 { 725 {
728 errno = EINVAL; 726 errno = EINVAL;
729 return GNUNET_SYSERR; 727 return GNUNET_SYSERR;
730 } 728 }
731 729
732#ifdef MINGW 730#ifdef MINGW
733 DWORD bytesWritten; 731 DWORD bytesWritten;
734 732
735 if (h->type != GNUNET_PIPE) 733 if (h->type != GNUNET_PIPE)
734 {
735 if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL))
736 { 736 {
737 if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL)) 737 SetErrnoFromWinError (GetLastError ());
738 { 738 return GNUNET_SYSERR;
739 SetErrnoFromWinError (GetLastError ());
740 return GNUNET_SYSERR;
741 }
742 } 739 }
740 }
743 else 741 else
744 { 742 {
745#if DEBUG_PIPE 743#if DEBUG_PIPE
746 LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to write\n"); 744 LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to write\n");
747#endif 745#endif
748 if (!WriteFile (h->h, buffer, n, NULL, h->oOverlapWrite)) 746 if (!WriteFile (h->h, buffer, n, NULL, h->oOverlapWrite))
749 { 747 {
750 if (GetLastError () != ERROR_IO_PENDING) 748 if (GetLastError () != ERROR_IO_PENDING)
751 { 749 {
752 SetErrnoFromWinError (GetLastError ()); 750 SetErrnoFromWinError (GetLastError ());
753#if DEBUG_PIPE 751#if DEBUG_PIPE
754 LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe\n"); 752 LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe\n");
755#endif 753#endif
756 return GNUNET_SYSERR; 754 return GNUNET_SYSERR;
757 } 755 }
758 } 756 }
759#if DEBUG_PIPE 757#if DEBUG_PIPE
760 LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n"); 758 LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n");
761#endif 759#endif
762 GetOverlappedResult (h->h, h->oOverlapWrite, &bytesWritten, TRUE); 760 GetOverlappedResult (h->h, h->oOverlapWrite, &bytesWritten, TRUE);
763 } 761 }
764 return bytesWritten; 762 return bytesWritten;
765#else 763#else
766 return write (h->fd, buffer, n); 764 return write (h->fd, buffer, n);
@@ -779,15 +777,14 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h,
779 */ 777 */
780ssize_t 778ssize_t
781GNUNET_DISK_fn_write (const char *fn, const void *buffer, size_t n, 779GNUNET_DISK_fn_write (const char *fn, const void *buffer, size_t n,
782 enum GNUNET_DISK_AccessPermissions mode) 780 enum GNUNET_DISK_AccessPermissions mode)
783{ 781{
784 struct GNUNET_DISK_FileHandle *fh; 782 struct GNUNET_DISK_FileHandle *fh;
785 ssize_t ret; 783 ssize_t ret;
786 784
787 fh = GNUNET_DISK_file_open (fn, 785 fh = GNUNET_DISK_file_open (fn,
788 GNUNET_DISK_OPEN_WRITE | 786 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE
789 GNUNET_DISK_OPEN_TRUNCATE | 787 | GNUNET_DISK_OPEN_CREATE, mode);
790 GNUNET_DISK_OPEN_CREATE, mode);
791 if (!fh) 788 if (!fh)
792 return GNUNET_SYSERR; 789 return GNUNET_SYSERR;
793 ret = GNUNET_DISK_file_write (fh, buffer, n); 790 ret = GNUNET_DISK_file_write (fh, buffer, n);
@@ -808,8 +805,8 @@ GNUNET_DISK_fn_write (const char *fn, const void *buffer, size_t n,
808 */ 805 */
809int 806int
810GNUNET_DISK_directory_scan (const char *dirName, 807GNUNET_DISK_directory_scan (const char *dirName,
811 GNUNET_FileNameCallback callback, 808 GNUNET_FileNameCallback callback,
812 void *callback_cls) 809 void *callback_cls)
813{ 810{
814 DIR *dinfo; 811 DIR *dinfo;
815 struct dirent *finfo; 812 struct dirent *finfo;
@@ -827,61 +824,61 @@ GNUNET_DISK_directory_scan (const char *dirName,
827 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR)) 824 while ((strlen (dname) > 0) && (dname[strlen (dname) - 1] == DIR_SEPARATOR))
828 dname[strlen (dname) - 1] = '\0'; 825 dname[strlen (dname) - 1] = '\0';
829 if (0 != STAT (dname, &istat)) 826 if (0 != STAT (dname, &istat))
830 { 827 {
831 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", dname); 828 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", dname);
832 GNUNET_free (dname); 829 GNUNET_free (dname);
833 return GNUNET_SYSERR; 830 return GNUNET_SYSERR;
834 } 831 }
835 if (!S_ISDIR (istat.st_mode)) 832 if (!S_ISDIR (istat.st_mode))
836 { 833 {
837 LOG (GNUNET_ERROR_TYPE_WARNING, 834 LOG (GNUNET_ERROR_TYPE_WARNING, _("Expected `%s' to be a directory!\n"),
838 _("Expected `%s' to be a directory!\n"), dirName); 835 dirName);
839 GNUNET_free (dname); 836 GNUNET_free (dname);
840 return GNUNET_SYSERR; 837 return GNUNET_SYSERR;
841 } 838 }
842 errno = 0; 839 errno = 0;
843 dinfo = OPENDIR (dname); 840 dinfo = OPENDIR (dname);
844 if ((errno == EACCES) || (dinfo == NULL)) 841 if ((errno == EACCES) || (dinfo == NULL))
845 { 842 {
846 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "opendir", dname); 843 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "opendir", dname);
847 if (dinfo != NULL) 844 if (dinfo != NULL)
848 closedir (dinfo); 845 closedir (dinfo);
849 GNUNET_free (dname); 846 GNUNET_free (dname);
850 return GNUNET_SYSERR; 847 return GNUNET_SYSERR;
851 } 848 }
852 name_len = 256; 849 name_len = 256;
853 n_size = strlen (dname) + name_len + 2; 850 n_size = strlen (dname) + name_len + 2;
854 name = GNUNET_malloc (n_size); 851 name = GNUNET_malloc (n_size);
855 while ((finfo = readdir (dinfo)) != NULL) 852 while ((finfo = readdir (dinfo)) != NULL)
853 {
854 if ((0 == strcmp (finfo->d_name, ".")) ||
855 (0 == strcmp (finfo->d_name, "..")))
856 continue;
857 if (callback != NULL)
856 { 858 {
857 if ((0 == strcmp (finfo->d_name, ".")) || 859 if (name_len < strlen (finfo->d_name))
858 (0 == strcmp (finfo->d_name, ".."))) 860 {
859 continue; 861 GNUNET_free (name);
860 if (callback != NULL) 862 name_len = strlen (finfo->d_name);
861 { 863 n_size = strlen (dname) + name_len + 2;
862 if (name_len < strlen (finfo->d_name)) 864 name = GNUNET_malloc (n_size);
863 { 865 }
864 GNUNET_free (name); 866 /* dname can end in "/" only if dname == "/";
865 name_len = strlen (finfo->d_name); 867 * if dname does not end in "/", we need to add
866 n_size = strlen (dname) + name_len + 2; 868 * a "/" (otherwise, we must not!) */
867 name = GNUNET_malloc (n_size); 869 GNUNET_snprintf (name, n_size, "%s%s%s", dname,
868 } 870 (strcmp (dname, DIR_SEPARATOR_STR) ==
869 /* dname can end in "/" only if dname == "/"; 871 0) ? "" : DIR_SEPARATOR_STR, finfo->d_name);
870 * if dname does not end in "/", we need to add 872 if (GNUNET_OK != callback (callback_cls, name))
871 * a "/" (otherwise, we must not!) */ 873 {
872 GNUNET_snprintf (name, n_size, "%s%s%s", dname, 874 closedir (dinfo);
873 (strcmp (dname, DIR_SEPARATOR_STR) == 875 GNUNET_free (name);
874 0) ? "" : DIR_SEPARATOR_STR, finfo->d_name); 876 GNUNET_free (dname);
875 if (GNUNET_OK != callback (callback_cls, name)) 877 return GNUNET_SYSERR;
876 { 878 }
877 closedir (dinfo);
878 GNUNET_free (name);
879 GNUNET_free (dname);
880 return GNUNET_SYSERR;
881 }
882 }
883 count++;
884 } 879 }
880 count++;
881 }
885 closedir (dinfo); 882 closedir (dinfo);
886 GNUNET_free (name); 883 GNUNET_free (name);
887 GNUNET_free (dname); 884 GNUNET_free (dname);
@@ -933,7 +930,7 @@ struct GNUNET_DISK_DirectoryIterator
933 */ 930 */
934static void 931static void
935directory_iterator_task (void *cls, 932directory_iterator_task (void *cls,
936 const struct GNUNET_SCHEDULER_TaskContext *tc) 933 const struct GNUNET_SCHEDULER_TaskContext *tc)
937{ 934{
938 struct GNUNET_DISK_DirectoryIterator *iter = cls; 935 struct GNUNET_DISK_DirectoryIterator *iter = cls;
939 char *name; 936 char *name;
@@ -958,35 +955,35 @@ directory_iterator_task (void *cls,
958 * GNUNET_SYSERR if abort was YES 955 * GNUNET_SYSERR if abort was YES
959 */ 956 */
960int 957int
961GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator 958GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator *iter,
962 *iter, int can) 959 int can)
963{ 960{
964 struct dirent *finfo; 961 struct dirent *finfo;
965 962
966 GNUNET_assert (iter->next_name == NULL); 963 GNUNET_assert (iter->next_name == NULL);
967 if (can == GNUNET_YES) 964 if (can == GNUNET_YES)
968 { 965 {
969 closedir (iter->directory); 966 closedir (iter->directory);
970 GNUNET_free (iter->dirname); 967 GNUNET_free (iter->dirname);
971 GNUNET_free (iter); 968 GNUNET_free (iter);
972 return GNUNET_SYSERR; 969 return GNUNET_SYSERR;
973 } 970 }
974 while (NULL != (finfo = readdir (iter->directory))) 971 while (NULL != (finfo = readdir (iter->directory)))
975 { 972 {
976 if ((0 == strcmp (finfo->d_name, ".")) || 973 if ((0 == strcmp (finfo->d_name, ".")) ||
977 (0 == strcmp (finfo->d_name, ".."))) 974 (0 == strcmp (finfo->d_name, "..")))
978 continue; 975 continue;
979 GNUNET_asprintf (&iter->next_name, "%s%s%s", iter->dirname, 976 GNUNET_asprintf (&iter->next_name, "%s%s%s", iter->dirname,
980 DIR_SEPARATOR_STR, finfo->d_name); 977 DIR_SEPARATOR_STR, finfo->d_name);
981 break; 978 break;
982 } 979 }
983 if (finfo == NULL) 980 if (finfo == NULL)
984 { 981 {
985 GNUNET_DISK_directory_iterator_next (iter, GNUNET_YES); 982 GNUNET_DISK_directory_iterator_next (iter, GNUNET_YES);
986 return GNUNET_NO; 983 return GNUNET_NO;
987 } 984 }
988 GNUNET_SCHEDULER_add_with_priority (iter->priority, 985 GNUNET_SCHEDULER_add_with_priority (iter->priority, &directory_iterator_task,
989 &directory_iterator_task, iter); 986 iter);
990 return GNUNET_YES; 987 return GNUNET_YES;
991} 988}
992 989
@@ -1004,9 +1001,9 @@ GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator
1004 */ 1001 */
1005void 1002void
1006GNUNET_DISK_directory_iterator_start (enum GNUNET_SCHEDULER_Priority prio, 1003GNUNET_DISK_directory_iterator_start (enum GNUNET_SCHEDULER_Priority prio,
1007 const char *dirName, 1004 const char *dirName,
1008 GNUNET_DISK_DirectoryIteratorCallback 1005 GNUNET_DISK_DirectoryIteratorCallback
1009 callback, void *callback_cls) 1006 callback, void *callback_cls)
1010{ 1007{
1011 struct GNUNET_DISK_DirectoryIterator *di; 1008 struct GNUNET_DISK_DirectoryIterator *di;
1012 1009
@@ -1015,11 +1012,11 @@ GNUNET_DISK_directory_iterator_start (enum GNUNET_SCHEDULER_Priority prio,
1015 di->callback_cls = callback_cls; 1012 di->callback_cls = callback_cls;
1016 di->directory = OPENDIR (dirName); 1013 di->directory = OPENDIR (dirName);
1017 if (di->directory == NULL) 1014 if (di->directory == NULL)
1018 { 1015 {
1019 GNUNET_free (di); 1016 GNUNET_free (di);
1020 callback (callback_cls, NULL, NULL, NULL); 1017 callback (callback_cls, NULL, NULL, NULL);
1021 return; 1018 return;
1022 } 1019 }
1023 di->dirname = GNUNET_strdup (dirName); 1020 di->dirname = GNUNET_strdup (dirName);
1024 di->priority = prio; 1021 di->priority = prio;
1025 GNUNET_DISK_directory_iterator_next (di, GNUNET_NO); 1022 GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
@@ -1056,7 +1053,7 @@ GNUNET_DISK_directory_remove (const char *fileName)
1056 struct stat istat; 1053 struct stat istat;
1057 1054
1058 if (0 != LSTAT (fileName, &istat)) 1055 if (0 != LSTAT (fileName, &istat))
1059 return GNUNET_NO; /* file may not exist... */ 1056 return GNUNET_NO; /* file may not exist... */
1060 CHMOD (fileName, S_IWUSR | S_IRUSR | S_IXUSR); 1057 CHMOD (fileName, S_IWUSR | S_IRUSR | S_IXUSR);
1061 if (UNLINK (fileName) == 0) 1058 if (UNLINK (fileName) == 0)
1062 return GNUNET_OK; 1059 return GNUNET_OK;
@@ -1065,18 +1062,18 @@ GNUNET_DISK_directory_remove (const char *fileName)
1065 * sticky /tmp directory may result in EPERM on BSD. 1062 * sticky /tmp directory may result in EPERM on BSD.
1066 * So we also explicitly check "isDirectory" */ 1063 * So we also explicitly check "isDirectory" */
1067 (GNUNET_YES != GNUNET_DISK_directory_test (fileName))) 1064 (GNUNET_YES != GNUNET_DISK_directory_test (fileName)))
1068 { 1065 {
1069 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", fileName); 1066 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", fileName);
1070 return GNUNET_SYSERR; 1067 return GNUNET_SYSERR;
1071 } 1068 }
1072 if (GNUNET_SYSERR == 1069 if (GNUNET_SYSERR ==
1073 GNUNET_DISK_directory_scan (fileName, &remove_helper, NULL)) 1070 GNUNET_DISK_directory_scan (fileName, &remove_helper, NULL))
1074 return GNUNET_SYSERR; 1071 return GNUNET_SYSERR;
1075 if (0 != RMDIR (fileName)) 1072 if (0 != RMDIR (fileName))
1076 { 1073 {
1077 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", fileName); 1074 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", fileName);
1078 return GNUNET_SYSERR; 1075 return GNUNET_SYSERR;
1079 } 1076 }
1080 return GNUNET_OK; 1077 return GNUNET_OK;
1081} 1078}
1082 1079
@@ -1102,34 +1099,34 @@ GNUNET_DISK_file_copy (const char *src, const char *dst)
1102 return GNUNET_SYSERR; 1099 return GNUNET_SYSERR;
1103 pos = 0; 1100 pos = 0;
1104 in = GNUNET_DISK_file_open (src, GNUNET_DISK_OPEN_READ, 1101 in = GNUNET_DISK_file_open (src, GNUNET_DISK_OPEN_READ,
1105 GNUNET_DISK_PERM_NONE); 1102 GNUNET_DISK_PERM_NONE);
1106 if (!in) 1103 if (!in)
1107 return GNUNET_SYSERR; 1104 return GNUNET_SYSERR;
1108 out = 1105 out =
1109 GNUNET_DISK_file_open (dst, 1106 GNUNET_DISK_file_open (dst,
1110 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | 1107 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE |
1111 GNUNET_DISK_OPEN_FAILIFEXISTS, 1108 GNUNET_DISK_OPEN_FAILIFEXISTS,
1112 GNUNET_DISK_PERM_USER_READ | 1109 GNUNET_DISK_PERM_USER_READ |
1113 GNUNET_DISK_PERM_USER_WRITE | 1110 GNUNET_DISK_PERM_USER_WRITE |
1114 GNUNET_DISK_PERM_GROUP_READ | 1111 GNUNET_DISK_PERM_GROUP_READ |
1115 GNUNET_DISK_PERM_GROUP_WRITE); 1112 GNUNET_DISK_PERM_GROUP_WRITE);
1116 if (!out) 1113 if (!out)
1117 { 1114 {
1118 GNUNET_DISK_file_close (in); 1115 GNUNET_DISK_file_close (in);
1119 return GNUNET_SYSERR; 1116 return GNUNET_SYSERR;
1120 } 1117 }
1121 buf = GNUNET_malloc (COPY_BLK_SIZE); 1118 buf = GNUNET_malloc (COPY_BLK_SIZE);
1122 while (pos < size) 1119 while (pos < size)
1123 { 1120 {
1124 len = COPY_BLK_SIZE; 1121 len = COPY_BLK_SIZE;
1125 if (len > size - pos) 1122 if (len > size - pos)
1126 len = size - pos; 1123 len = size - pos;
1127 if (len != GNUNET_DISK_file_read (in, buf, len)) 1124 if (len != GNUNET_DISK_file_read (in, buf, len))
1128 goto FAIL; 1125 goto FAIL;
1129 if (len != GNUNET_DISK_file_write (out, buf, len)) 1126 if (len != GNUNET_DISK_file_write (out, buf, len))
1130 goto FAIL; 1127 goto FAIL;
1131 pos += len; 1128 pos += len;
1132 } 1129 }
1133 GNUNET_free (buf); 1130 GNUNET_free (buf);
1134 GNUNET_DISK_file_close (in); 1131 GNUNET_DISK_file_close (in);
1135 GNUNET_DISK_file_close (out); 1132 GNUNET_DISK_file_close (out);
@@ -1154,17 +1151,17 @@ GNUNET_DISK_filename_canonicalize (char *fn)
1154 1151
1155 idx = fn; 1152 idx = fn;
1156 while (*idx) 1153 while (*idx)
1157 { 1154 {
1158 c = *idx; 1155 c = *idx;
1159
1160 if (c == '/' || c == '\\' || c == ':' || c == '*' || c == '?'
1161 || c == '"' || c == '<' || c == '>' || c == '|')
1162 {
1163 *idx = '_';
1164 }
1165 1156
1166 idx++; 1157 if (c == '/' || c == '\\' || c == ':' || c == '*' || c == '?' || c == '"' ||
1158 c == '<' || c == '>' || c == '|')
1159 {
1160 *idx = '_';
1167 } 1161 }
1162
1163 idx++;
1164 }
1168} 1165}
1169 1166
1170 1167
@@ -1184,12 +1181,12 @@ GNUNET_DISK_file_change_owner (const char *filename, const char *user)
1184 1181
1185 pws = getpwnam (user); 1182 pws = getpwnam (user);
1186 if (pws == NULL) 1183 if (pws == NULL)
1187 { 1184 {
1188 LOG (GNUNET_ERROR_TYPE_ERROR, 1185 LOG (GNUNET_ERROR_TYPE_ERROR,
1189 _("Cannot obtain information about user `%s': %s\n"), user, 1186 _("Cannot obtain information about user `%s': %s\n"), user,
1190 STRERROR (errno)); 1187 STRERROR (errno));
1191 return GNUNET_SYSERR; 1188 return GNUNET_SYSERR;
1192 } 1189 }
1193 if (0 != chown (filename, pws->pw_uid, pws->pw_gid)) 1190 if (0 != chown (filename, pws->pw_uid, pws->pw_gid))
1194 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "chown", filename); 1191 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "chown", filename);
1195#endif 1192#endif
@@ -1207,13 +1204,13 @@ GNUNET_DISK_file_change_owner (const char *filename, const char *user)
1207 */ 1204 */
1208int 1205int
1209GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, off_t lockStart, 1206GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, off_t lockStart,
1210 off_t lockEnd, int excl) 1207 off_t lockEnd, int excl)
1211{ 1208{
1212 if (fh == NULL) 1209 if (fh == NULL)
1213 { 1210 {
1214 errno = EINVAL; 1211 errno = EINVAL;
1215 return GNUNET_SYSERR; 1212 return GNUNET_SYSERR;
1216 } 1213 }
1217 1214
1218#ifndef MINGW 1215#ifndef MINGW
1219 struct flock fl; 1216 struct flock fl;
@@ -1232,13 +1229,12 @@ GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, off_t lockStart,
1232 o.Offset = lockStart; 1229 o.Offset = lockStart;
1233 1230
1234 if (!LockFileEx 1231 if (!LockFileEx
1235 (fh->h, 1232 (fh->h, (excl ? LOCKFILE_EXCLUSIVE_LOCK : 0) | LOCKFILE_FAIL_IMMEDIATELY,
1236 (excl ? LOCKFILE_EXCLUSIVE_LOCK : 0) | LOCKFILE_FAIL_IMMEDIATELY, 0, 1233 0, lockEnd - lockStart, 0, &o))
1237 lockEnd - lockStart, 0, &o)) 1234 {
1238 { 1235 SetErrnoFromWinError (GetLastError ());
1239 SetErrnoFromWinError (GetLastError ()); 1236 return GNUNET_SYSERR;
1240 return GNUNET_SYSERR; 1237 }
1241 }
1242 1238
1243 return GNUNET_OK; 1239 return GNUNET_OK;
1244#endif 1240#endif
@@ -1254,13 +1250,13 @@ GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, off_t lockStart,
1254 */ 1250 */
1255int 1251int
1256GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, off_t unlockStart, 1252GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, off_t unlockStart,
1257 off_t unlockEnd) 1253 off_t unlockEnd)
1258{ 1254{
1259 if (fh == NULL) 1255 if (fh == NULL)
1260 { 1256 {
1261 errno = EINVAL; 1257 errno = EINVAL;
1262 return GNUNET_SYSERR; 1258 return GNUNET_SYSERR;
1263 } 1259 }
1264 1260
1265#ifndef MINGW 1261#ifndef MINGW
1266 struct flock fl; 1262 struct flock fl;
@@ -1279,10 +1275,10 @@ GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, off_t unlockStart,
1279 o.Offset = unlockStart; 1275 o.Offset = unlockStart;
1280 1276
1281 if (!UnlockFileEx (fh->h, 0, unlockEnd - unlockStart, 0, &o)) 1277 if (!UnlockFileEx (fh->h, 0, unlockEnd - unlockStart, 0, &o))
1282 { 1278 {
1283 SetErrnoFromWinError (GetLastError ()); 1279 SetErrnoFromWinError (GetLastError ());
1284 return GNUNET_SYSERR; 1280 return GNUNET_SYSERR;
1285 } 1281 }
1286 1282
1287 return GNUNET_OK; 1283 return GNUNET_OK;
1288#endif 1284#endif
@@ -1303,7 +1299,7 @@ GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, off_t unlockStart,
1303 */ 1299 */
1304struct GNUNET_DISK_FileHandle * 1300struct GNUNET_DISK_FileHandle *
1305GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags, 1301GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
1306 enum GNUNET_DISK_AccessPermissions perm) 1302 enum GNUNET_DISK_AccessPermissions perm)
1307{ 1303{
1308 char *expfn; 1304 char *expfn;
1309 struct GNUNET_DISK_FileHandle *ret; 1305 struct GNUNET_DISK_FileHandle *ret;
@@ -1324,17 +1320,17 @@ GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
1324#ifndef MINGW 1320#ifndef MINGW
1325 mode = 0; 1321 mode = 0;
1326 if (GNUNET_DISK_OPEN_READWRITE == (flags & GNUNET_DISK_OPEN_READWRITE)) 1322 if (GNUNET_DISK_OPEN_READWRITE == (flags & GNUNET_DISK_OPEN_READWRITE))
1327 oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */ 1323 oflags = O_RDWR; /* note: O_RDWR is NOT always O_RDONLY | O_WRONLY */
1328 else if (flags & GNUNET_DISK_OPEN_READ) 1324 else if (flags & GNUNET_DISK_OPEN_READ)
1329 oflags = O_RDONLY; 1325 oflags = O_RDONLY;
1330 else if (flags & GNUNET_DISK_OPEN_WRITE) 1326 else if (flags & GNUNET_DISK_OPEN_WRITE)
1331 oflags = O_WRONLY; 1327 oflags = O_WRONLY;
1332 else 1328 else
1333 { 1329 {
1334 GNUNET_break (0); 1330 GNUNET_break (0);
1335 GNUNET_free (expfn); 1331 GNUNET_free (expfn);
1336 return NULL; 1332 return NULL;
1337 } 1333 }
1338 if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS) 1334 if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
1339 oflags |= (O_CREAT | O_EXCL); 1335 oflags |= (O_CREAT | O_EXCL);
1340 if (flags & GNUNET_DISK_OPEN_TRUNCATE) 1336 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
@@ -1342,22 +1338,22 @@ GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
1342 if (flags & GNUNET_DISK_OPEN_APPEND) 1338 if (flags & GNUNET_DISK_OPEN_APPEND)
1343 oflags |= O_APPEND; 1339 oflags |= O_APPEND;
1344 if (flags & GNUNET_DISK_OPEN_CREATE) 1340 if (flags & GNUNET_DISK_OPEN_CREATE)
1345 { 1341 {
1346 (void) GNUNET_DISK_directory_create_for_file (expfn); 1342 (void) GNUNET_DISK_directory_create_for_file (expfn);
1347 oflags |= O_CREAT; 1343 oflags |= O_CREAT;
1348 mode = translate_unix_perms (perm); 1344 mode = translate_unix_perms (perm);
1349 } 1345 }
1350 1346
1351 fd = open (expfn, oflags | O_LARGEFILE, mode); 1347 fd = open (expfn, oflags | O_LARGEFILE, mode);
1352 if (fd == -1) 1348 if (fd == -1)
1353 { 1349 {
1354 if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)) 1350 if (0 == (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))
1355 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", expfn); 1351 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", expfn);
1356 else 1352 else
1357 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "open", expfn); 1353 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "open", expfn);
1358 GNUNET_free (expfn); 1354 GNUNET_free (expfn);
1359 return NULL; 1355 return NULL;
1360 } 1356 }
1361#else 1357#else
1362 access = 0; 1358 access = 0;
1363 disp = OPEN_ALWAYS; 1359 disp = OPEN_ALWAYS;
@@ -1370,48 +1366,47 @@ GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
1370 access = FILE_WRITE_DATA; 1366 access = FILE_WRITE_DATA;
1371 1367
1372 if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS) 1368 if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
1373 { 1369 {
1374 disp = CREATE_NEW; 1370 disp = CREATE_NEW;
1375 } 1371 }
1376 else if (flags & GNUNET_DISK_OPEN_CREATE) 1372 else if (flags & GNUNET_DISK_OPEN_CREATE)
1377 { 1373 {
1378 (void) GNUNET_DISK_directory_create_for_file (expfn); 1374 (void) GNUNET_DISK_directory_create_for_file (expfn);
1379 if (flags & GNUNET_DISK_OPEN_TRUNCATE) 1375 if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1380 disp = CREATE_ALWAYS; 1376 disp = CREATE_ALWAYS;
1381 else 1377 else
1382 disp = OPEN_ALWAYS; 1378 disp = OPEN_ALWAYS;
1383 } 1379 }
1384 else if (flags & GNUNET_DISK_OPEN_TRUNCATE) 1380 else if (flags & GNUNET_DISK_OPEN_TRUNCATE)
1385 { 1381 {
1386 disp = TRUNCATE_EXISTING; 1382 disp = TRUNCATE_EXISTING;
1387 } 1383 }
1388 else 1384 else
1389 { 1385 {
1390 disp = OPEN_EXISTING; 1386 disp = OPEN_EXISTING;
1391 } 1387 }
1392 1388
1393 /* TODO: access priviledges? */ 1389 /* TODO: access priviledges? */
1394 h = CreateFile (expfn, access, 1390 h = CreateFile (expfn, access,
1395 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 1391 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1396 NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL); 1392 disp, FILE_ATTRIBUTE_NORMAL, NULL);
1397 if (h == INVALID_HANDLE_VALUE) 1393 if (h == INVALID_HANDLE_VALUE)
1394 {
1395 SetErrnoFromWinError (GetLastError ());
1396 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", expfn);
1397 GNUNET_free (expfn);
1398 return NULL;
1399 }
1400
1401 if (flags & GNUNET_DISK_OPEN_APPEND)
1402 if (SetFilePointer (h, 0, 0, FILE_END) == INVALID_SET_FILE_POINTER)
1398 { 1403 {
1399 SetErrnoFromWinError (GetLastError ()); 1404 SetErrnoFromWinError (GetLastError ());
1400 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", expfn); 1405 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "SetFilePointer", expfn);
1406 CloseHandle (h);
1401 GNUNET_free (expfn); 1407 GNUNET_free (expfn);
1402 return NULL; 1408 return NULL;
1403 } 1409 }
1404
1405 if (flags & GNUNET_DISK_OPEN_APPEND)
1406 if (SetFilePointer (h, 0, 0, FILE_END) == INVALID_SET_FILE_POINTER)
1407 {
1408 SetErrnoFromWinError (GetLastError ());
1409 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "SetFilePointer",
1410 expfn);
1411 CloseHandle (h);
1412 GNUNET_free (expfn);
1413 return NULL;
1414 }
1415#endif 1410#endif
1416 1411
1417 ret = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle)); 1412 ret = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle));
@@ -1435,28 +1430,28 @@ int
1435GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h) 1430GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h)
1436{ 1431{
1437 if (h == NULL) 1432 if (h == NULL)
1438 { 1433 {
1439 errno = EINVAL; 1434 errno = EINVAL;
1440 return GNUNET_SYSERR; 1435 return GNUNET_SYSERR;
1441 } 1436 }
1442 1437
1443#if MINGW 1438#if MINGW
1444 if (!CloseHandle (h->h)) 1439 if (!CloseHandle (h->h))
1445 { 1440 {
1446 SetErrnoFromWinError (GetLastError ()); 1441 SetErrnoFromWinError (GetLastError ());
1447 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "close"); 1442 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "close");
1448 GNUNET_free (h->oOverlapRead); 1443 GNUNET_free (h->oOverlapRead);
1449 GNUNET_free (h->oOverlapWrite); 1444 GNUNET_free (h->oOverlapWrite);
1450 GNUNET_free (h); 1445 GNUNET_free (h);
1451 return GNUNET_SYSERR; 1446 return GNUNET_SYSERR;
1452 } 1447 }
1453#else 1448#else
1454 if (close (h->fd) != 0) 1449 if (close (h->fd) != 0)
1455 { 1450 {
1456 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "close"); 1451 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "close");
1457 GNUNET_free (h); 1452 GNUNET_free (h);
1458 return GNUNET_SYSERR; 1453 return GNUNET_SYSERR;
1459 } 1454 }
1460#endif 1455#endif
1461 GNUNET_free (h); 1456 GNUNET_free (h);
1462 return GNUNET_OK; 1457 return GNUNET_OK;
@@ -1479,7 +1474,7 @@ GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h)
1479 */ 1474 */
1480char * 1475char *
1481GNUNET_DISK_get_home_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, 1476GNUNET_DISK_get_home_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
1482 const char *serviceName, ...) 1477 const char *serviceName, ...)
1483{ 1478{
1484 const char *c; 1479 const char *c;
1485 char *pfx; 1480 char *pfx;
@@ -1488,45 +1483,44 @@ GNUNET_DISK_get_home_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
1488 unsigned int needed; 1483 unsigned int needed;
1489 1484
1490 if (GNUNET_OK != 1485 if (GNUNET_OK !=
1491 GNUNET_CONFIGURATION_get_value_filename (cfg, serviceName, "HOME", 1486 GNUNET_CONFIGURATION_get_value_filename (cfg, serviceName, "HOME", &pfx))
1492 &pfx))
1493 return NULL; 1487 return NULL;
1494 if (pfx == NULL) 1488 if (pfx == NULL)
1495 { 1489 {
1496 LOG (GNUNET_ERROR_TYPE_WARNING, 1490 LOG (GNUNET_ERROR_TYPE_WARNING,
1497 _("No `%s' specified for service `%s' in configuration.\n"), 1491 _("No `%s' specified for service `%s' in configuration.\n"), "HOME",
1498 "HOME", serviceName); 1492 serviceName);
1499 return NULL; 1493 return NULL;
1500 } 1494 }
1501 needed = strlen (pfx) + 2; 1495 needed = strlen (pfx) + 2;
1502 if ((pfx[strlen (pfx) - 1] != '/') && (pfx[strlen (pfx) - 1] != '\\')) 1496 if ((pfx[strlen (pfx) - 1] != '/') && (pfx[strlen (pfx) - 1] != '\\'))
1503 needed++; 1497 needed++;
1504 va_start (ap, serviceName); 1498 va_start (ap, serviceName);
1505 while (1) 1499 while (1)
1506 { 1500 {
1507 c = va_arg (ap, const char *); 1501 c = va_arg (ap, const char *);
1508 1502
1509 if (c == NULL) 1503 if (c == NULL)
1510 break; 1504 break;
1511 needed += strlen (c); 1505 needed += strlen (c);
1512 if ((c[strlen (c) - 1] != '/') && (c[strlen (c) - 1] != '\\')) 1506 if ((c[strlen (c) - 1] != '/') && (c[strlen (c) - 1] != '\\'))
1513 needed++; 1507 needed++;
1514 } 1508 }
1515 va_end (ap); 1509 va_end (ap);
1516 ret = GNUNET_malloc (needed); 1510 ret = GNUNET_malloc (needed);
1517 strcpy (ret, pfx); 1511 strcpy (ret, pfx);
1518 GNUNET_free (pfx); 1512 GNUNET_free (pfx);
1519 va_start (ap, serviceName); 1513 va_start (ap, serviceName);
1520 while (1) 1514 while (1)
1521 { 1515 {
1522 c = va_arg (ap, const char *); 1516 c = va_arg (ap, const char *);
1523 1517
1524 if (c == NULL) 1518 if (c == NULL)
1525 break; 1519 break;
1526 if ((c[strlen (c) - 1] != '/') && (c[strlen (c) - 1] != '\\')) 1520 if ((c[strlen (c) - 1] != '/') && (c[strlen (c) - 1] != '\\'))
1527 strcat (ret, DIR_SEPARATOR_STR); 1521 strcat (ret, DIR_SEPARATOR_STR);
1528 strcat (ret, c); 1522 strcat (ret, c);
1529 } 1523 }
1530 va_end (ap); 1524 va_end (ap);
1531 if ((ret[strlen (ret) - 1] != '/') && (ret[strlen (ret) - 1] != '\\')) 1525 if ((ret[strlen (ret) - 1] != '/') && (ret[strlen (ret) - 1] != '\\'))
1532 (void) GNUNET_DISK_directory_create_for_file (ret); 1526 (void) GNUNET_DISK_directory_create_for_file (ret);
@@ -1575,56 +1569,56 @@ struct GNUNET_DISK_MapHandle
1575 */ 1569 */
1576void * 1570void *
1577GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h, 1571GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h,
1578 struct GNUNET_DISK_MapHandle **m, 1572 struct GNUNET_DISK_MapHandle **m,
1579 enum GNUNET_DISK_MapType access, size_t len) 1573 enum GNUNET_DISK_MapType access, size_t len)
1580{ 1574{
1581 if (h == NULL) 1575 if (h == NULL)
1582 { 1576 {
1583 errno = EINVAL; 1577 errno = EINVAL;
1584 return NULL; 1578 return NULL;
1585 } 1579 }
1586 1580
1587#ifdef MINGW 1581#ifdef MINGW
1588 DWORD mapAccess, protect; 1582 DWORD mapAccess, protect;
1589 1583
1590 if ((access & GNUNET_DISK_MAP_TYPE_READ) && 1584 if ((access & GNUNET_DISK_MAP_TYPE_READ) &&
1591 (access & GNUNET_DISK_MAP_TYPE_WRITE)) 1585 (access & GNUNET_DISK_MAP_TYPE_WRITE))
1592 { 1586 {
1593 protect = PAGE_READWRITE; 1587 protect = PAGE_READWRITE;
1594 mapAccess = FILE_MAP_ALL_ACCESS; 1588 mapAccess = FILE_MAP_ALL_ACCESS;
1595 } 1589 }
1596 else if (access & GNUNET_DISK_MAP_TYPE_READ) 1590 else if (access & GNUNET_DISK_MAP_TYPE_READ)
1597 { 1591 {
1598 protect = PAGE_READONLY; 1592 protect = PAGE_READONLY;
1599 mapAccess = FILE_MAP_READ; 1593 mapAccess = FILE_MAP_READ;
1600 } 1594 }
1601 else if (access & GNUNET_DISK_MAP_TYPE_WRITE) 1595 else if (access & GNUNET_DISK_MAP_TYPE_WRITE)
1602 { 1596 {
1603 protect = PAGE_READWRITE; 1597 protect = PAGE_READWRITE;
1604 mapAccess = FILE_MAP_WRITE; 1598 mapAccess = FILE_MAP_WRITE;
1605 } 1599 }
1606 else 1600 else
1607 { 1601 {
1608 GNUNET_break (0); 1602 GNUNET_break (0);
1609 return NULL; 1603 return NULL;
1610 } 1604 }
1611 1605
1612 *m = GNUNET_malloc (sizeof (struct GNUNET_DISK_MapHandle)); 1606 *m = GNUNET_malloc (sizeof (struct GNUNET_DISK_MapHandle));
1613 (*m)->h = CreateFileMapping (h->h, NULL, protect, 0, 0, NULL); 1607 (*m)->h = CreateFileMapping (h->h, NULL, protect, 0, 0, NULL);
1614 if ((*m)->h == INVALID_HANDLE_VALUE) 1608 if ((*m)->h == INVALID_HANDLE_VALUE)
1615 { 1609 {
1616 SetErrnoFromWinError (GetLastError ()); 1610 SetErrnoFromWinError (GetLastError ());
1617 GNUNET_free (*m); 1611 GNUNET_free (*m);
1618 return NULL; 1612 return NULL;
1619 } 1613 }
1620 1614
1621 (*m)->addr = MapViewOfFile ((*m)->h, mapAccess, 0, 0, len); 1615 (*m)->addr = MapViewOfFile ((*m)->h, mapAccess, 0, 0, len);
1622 if (!(*m)->addr) 1616 if (!(*m)->addr)
1623 { 1617 {
1624 SetErrnoFromWinError (GetLastError ()); 1618 SetErrnoFromWinError (GetLastError ());
1625 CloseHandle ((*m)->h); 1619 CloseHandle ((*m)->h);
1626 GNUNET_free (*m); 1620 GNUNET_free (*m);
1627 } 1621 }
1628 1622
1629 return (*m)->addr; 1623 return (*m)->addr;
1630#else 1624#else
@@ -1639,10 +1633,10 @@ GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h,
1639 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0); 1633 (*m)->addr = mmap (NULL, len, prot, MAP_SHARED, h->fd, 0);
1640 GNUNET_assert (NULL != (*m)->addr); 1634 GNUNET_assert (NULL != (*m)->addr);
1641 if (MAP_FAILED == (*m)->addr) 1635 if (MAP_FAILED == (*m)->addr)
1642 { 1636 {
1643 GNUNET_free (*m); 1637 GNUNET_free (*m);
1644 return NULL; 1638 return NULL;
1645 } 1639 }
1646 (*m)->len = len; 1640 (*m)->len = len;
1647 return (*m)->addr; 1641 return (*m)->addr;
1648#endif 1642#endif
@@ -1659,20 +1653,20 @@ GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h)
1659 int ret; 1653 int ret;
1660 1654
1661 if (h == NULL) 1655 if (h == NULL)
1662 { 1656 {
1663 errno = EINVAL; 1657 errno = EINVAL;
1664 return GNUNET_SYSERR; 1658 return GNUNET_SYSERR;
1665 } 1659 }
1666 1660
1667#ifdef MINGW 1661#ifdef MINGW
1668 ret = UnmapViewOfFile (h->addr) ? GNUNET_OK : GNUNET_SYSERR; 1662 ret = UnmapViewOfFile (h->addr) ? GNUNET_OK : GNUNET_SYSERR;
1669 if (ret != GNUNET_OK) 1663 if (ret != GNUNET_OK)
1670 SetErrnoFromWinError (GetLastError ()); 1664 SetErrnoFromWinError (GetLastError ());
1671 if (!CloseHandle (h->h) && (ret == GNUNET_OK)) 1665 if (!CloseHandle (h->h) && (ret == GNUNET_OK))
1672 { 1666 {
1673 ret = GNUNET_SYSERR; 1667 ret = GNUNET_SYSERR;
1674 SetErrnoFromWinError (GetLastError ()); 1668 SetErrnoFromWinError (GetLastError ());
1675 } 1669 }
1676#else 1670#else
1677 ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR; 1671 ret = munmap (h->addr, h->len) != -1 ? GNUNET_OK : GNUNET_SYSERR;
1678#endif 1672#endif
@@ -1690,10 +1684,10 @@ int
1690GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h) 1684GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h)
1691{ 1685{
1692 if (h == NULL) 1686 if (h == NULL)
1693 { 1687 {
1694 errno = EINVAL; 1688 errno = EINVAL;
1695 return GNUNET_SYSERR; 1689 return GNUNET_SYSERR;
1696 } 1690 }
1697 1691
1698#ifdef MINGW 1692#ifdef MINGW
1699 int ret; 1693 int ret;
@@ -1722,8 +1716,8 @@ GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h)
1722 unlike CreatePipe, which returns a bool for success or failure. */ 1716 unlike CreatePipe, which returns a bool for success or failure. */
1723static int 1717static int
1724create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, 1718create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
1725 LPSECURITY_ATTRIBUTES sa_ptr, DWORD psize, 1719 LPSECURITY_ATTRIBUTES sa_ptr, DWORD psize,
1726 DWORD dwReadMode, DWORD dwWriteMode) 1720 DWORD dwReadMode, DWORD dwWriteMode)
1727{ 1721{
1728 /* Default to error. */ 1722 /* Default to error. */
1729 *read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE; 1723 *read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE;
@@ -1740,103 +1734,103 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
1740 * Retrying will probably never be necessary, but we want 1734 * Retrying will probably never be necessary, but we want
1741 * to be as robust as possible. */ 1735 * to be as robust as possible. */
1742 while (1) 1736 while (1)
1743 { 1737 {
1744 static volatile LONG pipe_unique_id; 1738 static volatile LONG pipe_unique_id;
1745 1739
1746 snprintf (pipename, sizeof pipename, "\\\\.\\pipe\\gnunet-%d-%ld", 1740 snprintf (pipename, sizeof pipename, "\\\\.\\pipe\\gnunet-%d-%ld",
1747 getpid (), InterlockedIncrement ((LONG *) & pipe_unique_id)); 1741 getpid (), InterlockedIncrement ((LONG *) & pipe_unique_id));
1748#if DEBUG_PIPE 1742#if DEBUG_PIPE
1749 LOG (GNUNET_ERROR_TYPE_DEBUG, 1743 LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateNamedPipe: name = %s, size = %lu\n",
1750 "CreateNamedPipe: name = %s, size = %lu\n", pipename, psize); 1744 pipename, psize);
1751#endif 1745#endif
1752 /* Use CreateNamedPipe instead of CreatePipe, because the latter 1746 /* Use CreateNamedPipe instead of CreatePipe, because the latter
1753 * returns a write handle that does not permit FILE_READ_ATTRIBUTES 1747 * returns a write handle that does not permit FILE_READ_ATTRIBUTES
1754 * access, on versions of win32 earlier than WinXP SP2. 1748 * access, on versions of win32 earlier than WinXP SP2.
1755 * CreatePipe also stupidly creates a full duplex pipe, which is 1749 * CreatePipe also stupidly creates a full duplex pipe, which is
1756 * a waste, since only a single direction is actually used. 1750 * a waste, since only a single direction is actually used.
1757 * It's important to only allow a single instance, to ensure that 1751 * It's important to only allow a single instance, to ensure that
1758 * the pipe was not created earlier by some other process, even if 1752 * the pipe was not created earlier by some other process, even if
1759 * the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE 1753 * the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE
1760 * because that is only available for Win2k SP2 and WinXP. */ 1754 * because that is only available for Win2k SP2 and WinXP. */
1761 read_pipe = CreateNamedPipeA (pipename, PIPE_ACCESS_INBOUND | dwReadMode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, /* max instances */ 1755 read_pipe = CreateNamedPipeA (pipename, PIPE_ACCESS_INBOUND | dwReadMode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, /* max instances */
1762 psize, /* output buffer size */ 1756 psize, /* output buffer size */
1763 psize, /* input buffer size */ 1757 psize, /* input buffer size */
1764 NMPWAIT_USE_DEFAULT_WAIT, sa_ptr); 1758 NMPWAIT_USE_DEFAULT_WAIT, sa_ptr);
1765 1759
1766 if (read_pipe != INVALID_HANDLE_VALUE) 1760 if (read_pipe != INVALID_HANDLE_VALUE)
1767 { 1761 {
1768#if DEBUG_PIPE 1762#if DEBUG_PIPE
1769 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", read_pipe); 1763 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", read_pipe);
1770#endif 1764#endif
1771 break; 1765 break;
1772 } 1766 }
1773 1767
1774 DWORD err = GetLastError (); 1768 DWORD err = GetLastError ();
1775 1769
1776 switch (err) 1770 switch (err)
1777 { 1771 {
1778 case ERROR_PIPE_BUSY: 1772 case ERROR_PIPE_BUSY:
1779 /* The pipe is already open with compatible parameters. 1773 /* The pipe is already open with compatible parameters.
1780 * Pick a new name and retry. */ 1774 * Pick a new name and retry. */
1781#if DEBUG_PIPE 1775#if DEBUG_PIPE
1782 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe busy, retrying\n"); 1776 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe busy, retrying\n");
1783#endif 1777#endif
1784 continue; 1778 continue;
1785 case ERROR_ACCESS_DENIED: 1779 case ERROR_ACCESS_DENIED:
1786 /* The pipe is already open with incompatible parameters. 1780 /* The pipe is already open with incompatible parameters.
1787 * Pick a new name and retry. */ 1781 * Pick a new name and retry. */
1788#if DEBUG_PIPE 1782#if DEBUG_PIPE
1789 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe access denied, retrying\n"); 1783 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe access denied, retrying\n");
1790#endif 1784#endif
1791 continue; 1785 continue;
1792 case ERROR_CALL_NOT_IMPLEMENTED: 1786 case ERROR_CALL_NOT_IMPLEMENTED:
1793 /* We are on an older Win9x platform without named pipes. 1787 /* We are on an older Win9x platform without named pipes.
1794 * Return an anonymous pipe as the best approximation. */ 1788 * Return an anonymous pipe as the best approximation. */
1795#if DEBUG_PIPE 1789#if DEBUG_PIPE
1796 LOG (GNUNET_ERROR_TYPE_DEBUG, 1790 LOG (GNUNET_ERROR_TYPE_DEBUG,
1797 "CreateNamedPipe not implemented, resorting to " 1791 "CreateNamedPipe not implemented, resorting to "
1798 "CreatePipe: size = %lu\n", psize); 1792 "CreatePipe: size = %lu\n", psize);
1799#endif 1793#endif
1800 if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize)) 1794 if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize))
1801 { 1795 {
1802#if DEBUG_PIPE 1796#if DEBUG_PIPE
1803 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", 1797 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n",
1804 *read_pipe_ptr); 1798 *read_pipe_ptr);
1805 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", 1799 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n",
1806 *write_pipe_ptr); 1800 *write_pipe_ptr);
1807#endif 1801#endif
1808 return GNUNET_OK; 1802 return GNUNET_OK;
1809 } 1803 }
1810 err = GetLastError (); 1804 err = GetLastError ();
1811 LOG (GNUNET_ERROR_TYPE_ERROR, "CreatePipe failed: %d\n", err); 1805 LOG (GNUNET_ERROR_TYPE_ERROR, "CreatePipe failed: %d\n", err);
1812 return err; 1806 return err;
1813 default: 1807 default:
1814 LOG (GNUNET_ERROR_TYPE_ERROR, "CreateNamedPipe failed: %d\n", err); 1808 LOG (GNUNET_ERROR_TYPE_ERROR, "CreateNamedPipe failed: %d\n", err);
1815 return err; 1809 return err;
1816 }
1817 /* NOTREACHED */
1818 } 1810 }
1811 /* NOTREACHED */
1812 }
1819#if DEBUG_PIPE 1813#if DEBUG_PIPE
1820 LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile: name = %s\n", pipename); 1814 LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile: name = %s\n", pipename);
1821#endif 1815#endif
1822 1816
1823 /* Open the named pipe for writing. 1817 /* Open the named pipe for writing.
1824 * Be sure to permit FILE_READ_ATTRIBUTES access. */ 1818 * Be sure to permit FILE_READ_ATTRIBUTES access. */
1825 write_pipe = CreateFileA (pipename, GENERIC_WRITE | FILE_READ_ATTRIBUTES, 0, /* share mode */ 1819 write_pipe = CreateFileA (pipename, GENERIC_WRITE | FILE_READ_ATTRIBUTES, 0, /* share mode */
1826 sa_ptr, OPEN_EXISTING, dwWriteMode, /* flags and attributes */ 1820 sa_ptr, OPEN_EXISTING, dwWriteMode, /* flags and attributes */
1827 0); /* handle to template file */ 1821 0); /* handle to template file */
1828 1822
1829 if (write_pipe == INVALID_HANDLE_VALUE) 1823 if (write_pipe == INVALID_HANDLE_VALUE)
1830 { 1824 {
1831 /* Failure. */ 1825 /* Failure. */
1832 DWORD err = GetLastError (); 1826 DWORD err = GetLastError ();
1833 1827
1834#if DEBUG_PIPE 1828#if DEBUG_PIPE
1835 LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile failed: %d\n", err); 1829 LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile failed: %d\n", err);
1836#endif 1830#endif
1837 CloseHandle (read_pipe); 1831 CloseHandle (read_pipe);
1838 return err; 1832 return err;
1839 } 1833 }
1840#if DEBUG_PIPE 1834#if DEBUG_PIPE
1841 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", write_pipe); 1835 LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", write_pipe);
1842#endif 1836#endif
@@ -1863,7 +1857,7 @@ GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write)
1863 struct GNUNET_DISK_FileHandle *fds; 1857 struct GNUNET_DISK_FileHandle *fds;
1864 1858
1865 p = GNUNET_malloc (sizeof (struct GNUNET_DISK_PipeHandle) + 1859 p = GNUNET_malloc (sizeof (struct GNUNET_DISK_PipeHandle) +
1866 2 * sizeof (struct GNUNET_DISK_FileHandle)); 1860 2 * sizeof (struct GNUNET_DISK_FileHandle));
1867 fds = (struct GNUNET_DISK_FileHandle *) &p[1]; 1861 fds = (struct GNUNET_DISK_FileHandle *) &p[1];
1868 p->fd[0] = &fds[0]; 1862 p->fd[0] = &fds[0];
1869 p->fd[1] = &fds[1]; 1863 p->fd[1] = &fds[1];
@@ -1875,13 +1869,13 @@ GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write)
1875 1869
1876 ret = pipe (fd); 1870 ret = pipe (fd);
1877 if (ret == -1) 1871 if (ret == -1)
1878 { 1872 {
1879 eno = errno; 1873 eno = errno;
1880 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe"); 1874 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe");
1881 GNUNET_free (p); 1875 GNUNET_free (p);
1882 errno = eno; 1876 errno = eno;
1883 return NULL; 1877 return NULL;
1884 } 1878 }
1885 p->fd[0]->fd = fd[0]; 1879 p->fd[0]->fd = fd[0];
1886 p->fd[1]->fd = fd[1]; 1880 p->fd[1]->fd = fd[1];
1887 ret = 0; 1881 ret = 0;
@@ -1905,62 +1899,62 @@ GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write)
1905 if (0 > fcntl (fd[1], F_SETFD, flags)) 1899 if (0 > fcntl (fd[1], F_SETFD, flags))
1906 ret = -1; 1900 ret = -1;
1907 if (ret == -1) 1901 if (ret == -1)
1908 { 1902 {
1909 eno = errno; 1903 eno = errno;
1910 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fcntl"); 1904 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fcntl");
1911 GNUNET_break (0 == close (p->fd[0]->fd)); 1905 GNUNET_break (0 == close (p->fd[0]->fd));
1912 GNUNET_break (0 == close (p->fd[1]->fd)); 1906 GNUNET_break (0 == close (p->fd[1]->fd));
1913 GNUNET_free (p); 1907 GNUNET_free (p);
1914 errno = eno; 1908 errno = eno;
1915 return NULL; 1909 return NULL;
1916 } 1910 }
1917#else 1911#else
1918 BOOL ret; 1912 BOOL ret;
1919 HANDLE tmp_handle; 1913 HANDLE tmp_handle;
1920 1914
1921 ret = 1915 ret =
1922 create_selectable_pipe (&p->fd[0]->h, &p->fd[1]->h, NULL, 0, 1916 create_selectable_pipe (&p->fd[0]->h, &p->fd[1]->h, NULL, 0,
1923 FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED); 1917 FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED);
1924 if (!ret) 1918 if (!ret)
1925 { 1919 {
1926 GNUNET_free (p); 1920 GNUNET_free (p);
1927 SetErrnoFromWinError (GetLastError ()); 1921 SetErrnoFromWinError (GetLastError ());
1928 return NULL; 1922 return NULL;
1929 } 1923 }
1930 if (!DuplicateHandle 1924 if (!DuplicateHandle
1931 (GetCurrentProcess (), p->fd[0]->h, GetCurrentProcess (), &tmp_handle, 1925 (GetCurrentProcess (), p->fd[0]->h, GetCurrentProcess (), &tmp_handle, 0,
1932 0, inherit_read == GNUNET_YES ? TRUE : FALSE, DUPLICATE_SAME_ACCESS)) 1926 inherit_read == GNUNET_YES ? TRUE : FALSE, DUPLICATE_SAME_ACCESS))
1933 { 1927 {
1934 SetErrnoFromWinError (GetLastError ()); 1928 SetErrnoFromWinError (GetLastError ());
1935 CloseHandle (p->fd[0]->h); 1929 CloseHandle (p->fd[0]->h);
1936 CloseHandle (p->fd[1]->h); 1930 CloseHandle (p->fd[1]->h);
1937 GNUNET_free (p); 1931 GNUNET_free (p);
1938 return NULL; 1932 return NULL;
1939 } 1933 }
1940 CloseHandle (p->fd[0]->h); 1934 CloseHandle (p->fd[0]->h);
1941 p->fd[0]->h = tmp_handle; 1935 p->fd[0]->h = tmp_handle;
1942 1936
1943 if (!DuplicateHandle 1937 if (!DuplicateHandle
1944 (GetCurrentProcess (), p->fd[1]->h, GetCurrentProcess (), &tmp_handle, 1938 (GetCurrentProcess (), p->fd[1]->h, GetCurrentProcess (), &tmp_handle, 0,
1945 0, inherit_write == GNUNET_YES ? TRUE : FALSE, DUPLICATE_SAME_ACCESS)) 1939 inherit_write == GNUNET_YES ? TRUE : FALSE, DUPLICATE_SAME_ACCESS))
1946 { 1940 {
1947 SetErrnoFromWinError (GetLastError ()); 1941 SetErrnoFromWinError (GetLastError ());
1948 CloseHandle (p->fd[0]->h); 1942 CloseHandle (p->fd[0]->h);
1949 CloseHandle (p->fd[1]->h); 1943 CloseHandle (p->fd[1]->h);
1950 GNUNET_free (p); 1944 GNUNET_free (p);
1951 return NULL; 1945 return NULL;
1952 } 1946 }
1953 CloseHandle (p->fd[1]->h); 1947 CloseHandle (p->fd[1]->h);
1954 p->fd[1]->h = tmp_handle; 1948 p->fd[1]->h = tmp_handle;
1955 if (!blocking) 1949 if (!blocking)
1956 { 1950 {
1957 DWORD mode; 1951 DWORD mode;
1958 1952
1959 mode = PIPE_NOWAIT; 1953 mode = PIPE_NOWAIT;
1960 SetNamedPipeHandleState (p->fd[0]->h, &mode, NULL, NULL); 1954 SetNamedPipeHandleState (p->fd[0]->h, &mode, NULL, NULL);
1961 SetNamedPipeHandleState (p->fd[1]->h, &mode, NULL, NULL); 1955 SetNamedPipeHandleState (p->fd[1]->h, &mode, NULL, NULL);
1962 /* this always fails on Windows 95, so we don't care about error handling */ 1956 /* this always fails on Windows 95, so we don't care about error handling */
1963 } 1957 }
1964 p->fd[0]->type = GNUNET_PIPE; 1958 p->fd[0]->type = GNUNET_PIPE;
1965 p->fd[1]->type = GNUNET_PIPE; 1959 p->fd[1]->type = GNUNET_PIPE;
1966 1960
@@ -1989,51 +1983,51 @@ GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write)
1989 */ 1983 */
1990int 1984int
1991GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p, 1985GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p,
1992 enum GNUNET_DISK_PipeEnd end) 1986 enum GNUNET_DISK_PipeEnd end)
1993{ 1987{
1994 int ret = GNUNET_OK; 1988 int ret = GNUNET_OK;
1995 int save; 1989 int save;
1996 1990
1997#ifdef MINGW 1991#ifdef MINGW
1998 if (end == GNUNET_DISK_PIPE_END_READ) 1992 if (end == GNUNET_DISK_PIPE_END_READ)
1993 {
1994 if (!CloseHandle (p->fd[0]->h))
1999 { 1995 {
2000 if (!CloseHandle (p->fd[0]->h)) 1996 SetErrnoFromWinError (GetLastError ());
2001 { 1997 ret = GNUNET_SYSERR;
2002 SetErrnoFromWinError (GetLastError ());
2003 ret = GNUNET_SYSERR;
2004 }
2005 p->fd[0]->h = INVALID_HANDLE_VALUE;
2006 } 1998 }
1999 p->fd[0]->h = INVALID_HANDLE_VALUE;
2000 }
2007 else if (end == GNUNET_DISK_PIPE_END_WRITE) 2001 else if (end == GNUNET_DISK_PIPE_END_WRITE)
2002 {
2003 if (!CloseHandle (p->fd[1]->h))
2008 { 2004 {
2009 if (!CloseHandle (p->fd[1]->h)) 2005 SetErrnoFromWinError (GetLastError ());
2010 { 2006 ret = GNUNET_SYSERR;
2011 SetErrnoFromWinError (GetLastError ());
2012 ret = GNUNET_SYSERR;
2013 }
2014 p->fd[1]->h = INVALID_HANDLE_VALUE;
2015 } 2007 }
2008 p->fd[1]->h = INVALID_HANDLE_VALUE;
2009 }
2016 save = errno; 2010 save = errno;
2017#else 2011#else
2018 save = 0; 2012 save = 0;
2019 if (end == GNUNET_DISK_PIPE_END_READ) 2013 if (end == GNUNET_DISK_PIPE_END_READ)
2014 {
2015 if (0 != close (p->fd[0]->fd))
2020 { 2016 {
2021 if (0 != close (p->fd[0]->fd)) 2017 ret = GNUNET_SYSERR;
2022 { 2018 save = errno;
2023 ret = GNUNET_SYSERR;
2024 save = errno;
2025 }
2026 p->fd[0]->fd = -1;
2027 } 2019 }
2020 p->fd[0]->fd = -1;
2021 }
2028 else if (end == GNUNET_DISK_PIPE_END_WRITE) 2022 else if (end == GNUNET_DISK_PIPE_END_WRITE)
2023 {
2024 if (0 != close (p->fd[1]->fd))
2029 { 2025 {
2030 if (0 != close (p->fd[1]->fd)) 2026 ret = GNUNET_SYSERR;
2031 { 2027 save = errno;
2032 ret = GNUNET_SYSERR;
2033 save = errno;
2034 }
2035 p->fd[1]->fd = -1;
2036 } 2028 }
2029 p->fd[1]->fd = -1;
2030 }
2037#endif 2031#endif
2038 errno = save; 2032 errno = save;
2039 return ret; 2033 return ret;
@@ -2053,35 +2047,35 @@ GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p)
2053 2047
2054#ifdef MINGW 2048#ifdef MINGW
2055 if (!CloseHandle (p->fd[0]->h)) 2049 if (!CloseHandle (p->fd[0]->h))
2056 { 2050 {
2057 SetErrnoFromWinError (GetLastError ()); 2051 SetErrnoFromWinError (GetLastError ());
2058 ret = GNUNET_SYSERR; 2052 ret = GNUNET_SYSERR;
2059 } 2053 }
2060 if (!CloseHandle (p->fd[1]->h)) 2054 if (!CloseHandle (p->fd[1]->h))
2061 { 2055 {
2062 SetErrnoFromWinError (GetLastError ()); 2056 SetErrnoFromWinError (GetLastError ());
2063 ret = GNUNET_SYSERR; 2057 ret = GNUNET_SYSERR;
2064 } 2058 }
2065 save = errno; 2059 save = errno;
2066#else 2060#else
2067 save = 0; 2061 save = 0;
2068 if (p->fd[0]->fd != -1) 2062 if (p->fd[0]->fd != -1)
2063 {
2064 if (0 != close (p->fd[0]->fd))
2069 { 2065 {
2070 if (0 != close (p->fd[0]->fd)) 2066 ret = GNUNET_SYSERR;
2071 { 2067 save = errno;
2072 ret = GNUNET_SYSERR;
2073 save = errno;
2074 }
2075 } 2068 }
2069 }
2076 2070
2077 if (p->fd[1]->fd != -1) 2071 if (p->fd[1]->fd != -1)
2072 {
2073 if (0 != close (p->fd[1]->fd))
2078 { 2074 {
2079 if (0 != close (p->fd[1]->fd)) 2075 ret = GNUNET_SYSERR;
2080 { 2076 save = errno;
2081 ret = GNUNET_SYSERR;
2082 save = errno;
2083 }
2084 } 2077 }
2078 }
2085#endif 2079#endif
2086 GNUNET_free (p); 2080 GNUNET_free (p);
2087 errno = save; 2081 errno = save;
@@ -2098,7 +2092,7 @@ GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p)
2098 */ 2092 */
2099struct GNUNET_DISK_FileHandle * 2093struct GNUNET_DISK_FileHandle *
2100GNUNET_DISK_npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags, 2094GNUNET_DISK_npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
2101 enum GNUNET_DISK_AccessPermissions perm) 2095 enum GNUNET_DISK_AccessPermissions perm)
2102{ 2096{
2103#ifdef MINGW 2097#ifdef MINGW
2104 struct GNUNET_DISK_FileHandle *ret; 2098 struct GNUNET_DISK_FileHandle *ret;
@@ -2118,71 +2112,70 @@ GNUNET_DISK_npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
2118 openMode |= FILE_FLAG_FIRST_PIPE_INSTANCE; 2112 openMode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
2119 2113
2120 while (h == NULL) 2114 while (h == NULL)
2121 { 2115 {
2122 DWORD error_code; 2116 DWORD error_code;
2123 2117
2124 name = NULL; 2118 name = NULL;
2125 if (*fn != NULL) 2119 if (*fn != NULL)
2126 { 2120 {
2127 GNUNET_asprintf (&name, "\\\\.\\pipe\\%.246s", fn); 2121 GNUNET_asprintf (&name, "\\\\.\\pipe\\%.246s", fn);
2128#if DEBUG_NPIPE 2122#if DEBUG_NPIPE
2129 LOG (GNUNET_ERROR_TYPE_DEBUG, 2123 LOG (GNUNET_ERROR_TYPE_DEBUG,
2130 "Trying to create an instance of named pipe `%s'\n", name); 2124 "Trying to create an instance of named pipe `%s'\n", name);
2131#endif 2125#endif
2132 h = CreateNamedPipe (name, openMode | FILE_FLAG_OVERLAPPED, 2126 h = CreateNamedPipe (name, openMode | FILE_FLAG_OVERLAPPED,
2133 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 2127 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0,
2134 0, NULL); 2128 NULL);
2135 } 2129 }
2136 else 2130 else
2137 { 2131 {
2138 GNUNET_asprintf (fn, "\\\\.\\pipe\\gnunet-%llu", 2132 GNUNET_asprintf (fn, "\\\\.\\pipe\\gnunet-%llu",
2139 GNUNET_CRYPTO_random_u64 2133 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
2140 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX)); 2134 UINT64_MAX));
2141#if DEBUG_NPIPE 2135#if DEBUG_NPIPE
2142 LOG (GNUNET_ERROR_TYPE_DEBUG, 2136 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to create unique named pipe `%s'\n",
2143 "Trying to create unique named pipe `%s'\n", *fn); 2137 *fn);
2144#endif 2138#endif
2145 h = CreateNamedPipe (*fn, 2139 h = CreateNamedPipe (*fn,
2146 openMode | FILE_FLAG_OVERLAPPED | 2140 openMode | FILE_FLAG_OVERLAPPED |
2147 FILE_FLAG_FIRST_PIPE_INSTANCE, 2141 FILE_FLAG_FIRST_PIPE_INSTANCE,
2148 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 2142 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0,
2149 0, NULL); 2143 NULL);
2150 } 2144 }
2151 error_code = GetLastError (); 2145 error_code = GetLastError ();
2152 if (name) 2146 if (name)
2153 GNUNET_free (name); 2147 GNUNET_free (name);
2154 /* don't re-set name to NULL yet */ 2148 /* don't re-set name to NULL yet */
2155 if (h == INVALID_HANDLE_VALUE) 2149 if (h == INVALID_HANDLE_VALUE)
2156 { 2150 {
2157 SetErrnoFromWinError (error_code); 2151 SetErrnoFromWinError (error_code);
2158#if DEBUG_NPIPE 2152#if DEBUG_NPIPE
2159 LOG (GNUNET_ERROR_TYPE_DEBUG, 2153 LOG (GNUNET_ERROR_TYPE_DEBUG,
2160 "Pipe creation have failed because of %d, errno is %d\n", 2154 "Pipe creation have failed because of %d, errno is %d\n", error_code,
2161 error_code, errno); 2155 errno);
2162#endif 2156#endif
2163 if (name == NULL) 2157 if (name == NULL)
2164 { 2158 {
2165#if DEBUG_NPIPE 2159#if DEBUG_NPIPE
2166 LOG (GNUNET_ERROR_TYPE_DEBUG, 2160 LOG (GNUNET_ERROR_TYPE_DEBUG,
2167 "Pipe was to be unique, considering re-creation\n"); 2161 "Pipe was to be unique, considering re-creation\n");
2168#endif 2162#endif
2169 GNUNET_free (*fn); 2163 GNUNET_free (*fn);
2170 *fn = NULL; 2164 *fn = NULL;
2171 if (error_code != ERROR_ACCESS_DENIED 2165 if (error_code != ERROR_ACCESS_DENIED && error_code != ERROR_PIPE_BUSY)
2172 && error_code != ERROR_PIPE_BUSY) 2166 {
2173 { 2167 return NULL;
2174 return NULL; 2168 }
2175 }
2176#if DEBUG_NPIPE 2169#if DEBUG_NPIPE
2177 LOG (GNUNET_ERROR_TYPE_DEBUG, 2170 LOG (GNUNET_ERROR_TYPE_DEBUG,
2178 "Pipe name was not unique, trying again\n"); 2171 "Pipe name was not unique, trying again\n");
2179#endif 2172#endif
2180 h = NULL; 2173 h = NULL;
2181 } 2174 }
2182 else 2175 else
2183 return NULL; 2176 return NULL;
2184 }
2185 } 2177 }
2178 }
2186 errno = 0; 2179 errno = 0;
2187 2180
2188 ret = GNUNET_malloc (sizeof (*ret)); 2181 ret = GNUNET_malloc (sizeof (*ret));
@@ -2198,22 +2191,22 @@ GNUNET_DISK_npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
2198 return ret; 2191 return ret;
2199#else 2192#else
2200 if (*fn == NULL) 2193 if (*fn == NULL)
2194 {
2195 char dir[] = "/tmp/gnunet-pipe-XXXXXX";
2196
2197 if (mkdtemp (dir) == NULL)
2201 { 2198 {
2202 char dir[] = "/tmp/gnunet-pipe-XXXXXX"; 2199 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "mkdtemp");
2203 2200 return NULL;
2204 if (mkdtemp (dir) == NULL)
2205 {
2206 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "mkdtemp");
2207 return NULL;
2208 }
2209 GNUNET_asprintf (fn, "%s/child-control", dir);
2210 } 2201 }
2202 GNUNET_asprintf (fn, "%s/child-control", dir);
2203 }
2211 2204
2212 if (mkfifo (*fn, translate_unix_perms (perm)) == -1) 2205 if (mkfifo (*fn, translate_unix_perms (perm)) == -1)
2213 { 2206 {
2214 if ((errno != EEXIST) || (0 != (flags & GNUNET_DISK_OPEN_FAILIFEXISTS))) 2207 if ((errno != EEXIST) || (0 != (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)))
2215 return NULL; 2208 return NULL;
2216 } 2209 }
2217 2210
2218 flags = flags & (~GNUNET_DISK_OPEN_FAILIFEXISTS); 2211 flags = flags & (~GNUNET_DISK_OPEN_FAILIFEXISTS);
2219 return GNUNET_DISK_file_open (*fn, flags, perm); 2212 return GNUNET_DISK_file_open (*fn, flags, perm);
@@ -2231,7 +2224,7 @@ GNUNET_DISK_npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
2231 */ 2224 */
2232struct GNUNET_DISK_FileHandle * 2225struct GNUNET_DISK_FileHandle *
2233GNUNET_DISK_npipe_open (const char *fn, enum GNUNET_DISK_OpenFlags flags, 2226GNUNET_DISK_npipe_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
2234 enum GNUNET_DISK_AccessPermissions perm) 2227 enum GNUNET_DISK_AccessPermissions perm)
2235{ 2228{
2236#ifdef MINGW 2229#ifdef MINGW
2237 struct GNUNET_DISK_FileHandle *ret; 2230 struct GNUNET_DISK_FileHandle *ret;
@@ -2247,12 +2240,12 @@ GNUNET_DISK_npipe_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
2247 openMode = GENERIC_WRITE; 2240 openMode = GENERIC_WRITE;
2248 2241
2249 h = CreateFile (fn, openMode, 0, NULL, OPEN_EXISTING, 2242 h = CreateFile (fn, openMode, 0, NULL, OPEN_EXISTING,
2250 FILE_FLAG_OVERLAPPED | FILE_READ_ATTRIBUTES, NULL); 2243 FILE_FLAG_OVERLAPPED | FILE_READ_ATTRIBUTES, NULL);
2251 if (h == INVALID_HANDLE_VALUE) 2244 if (h == INVALID_HANDLE_VALUE)
2252 { 2245 {
2253 SetErrnoFromWinError (GetLastError ()); 2246 SetErrnoFromWinError (GetLastError ());
2254 return NULL; 2247 return NULL;
2255 } 2248 }
2256 2249
2257 ret = GNUNET_malloc (sizeof (*ret)); 2250 ret = GNUNET_malloc (sizeof (*ret));
2258 ret->h = h; 2251 ret->h = h;
@@ -2284,10 +2277,10 @@ GNUNET_DISK_npipe_close (struct GNUNET_DISK_FileHandle *pipe)
2284 2277
2285 ret = CloseHandle (pipe->h); 2278 ret = CloseHandle (pipe->h);
2286 if (!ret) 2279 if (!ret)
2287 { 2280 {
2288 SetErrnoFromWinError (GetLastError ()); 2281 SetErrnoFromWinError (GetLastError ());
2289 return GNUNET_SYSERR; 2282 return GNUNET_SYSERR;
2290 } 2283 }
2291 else 2284 else
2292 return GNUNET_OK; 2285 return GNUNET_OK;
2293#endif 2286#endif
@@ -2303,17 +2296,17 @@ GNUNET_DISK_npipe_close (struct GNUNET_DISK_FileHandle *pipe)
2303 */ 2296 */
2304const struct GNUNET_DISK_FileHandle * 2297const struct GNUNET_DISK_FileHandle *
2305GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, 2298GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p,
2306 enum GNUNET_DISK_PipeEnd n) 2299 enum GNUNET_DISK_PipeEnd n)
2307{ 2300{
2308 switch (n) 2301 switch (n)
2309 { 2302 {
2310 case GNUNET_DISK_PIPE_END_READ: 2303 case GNUNET_DISK_PIPE_END_READ:
2311 case GNUNET_DISK_PIPE_END_WRITE: 2304 case GNUNET_DISK_PIPE_END_WRITE:
2312 return p->fd[n]; 2305 return p->fd[n];
2313 default: 2306 default:
2314 GNUNET_break (0); 2307 GNUNET_break (0);
2315 return NULL; 2308 return NULL;
2316 } 2309 }
2317} 2310}
2318 2311
2319 2312
@@ -2327,7 +2320,7 @@ GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p,
2327 */ 2320 */
2328int 2321int
2329GNUNET_DISK_internal_file_handle_ (const struct GNUNET_DISK_FileHandle *fh, 2322GNUNET_DISK_internal_file_handle_ (const struct GNUNET_DISK_FileHandle *fh,
2330 void *dst, size_t dst_len) 2323 void *dst, size_t dst_len)
2331{ 2324{
2332#ifdef MINGW 2325#ifdef MINGW
2333 if (dst_len < sizeof (HANDLE)) 2326 if (dst_len < sizeof (HANDLE))