diff options
Diffstat (limited to 'src/util/disk.c')
-rw-r--r-- | src/util/disk.c | 106 |
1 files changed, 31 insertions, 75 deletions
diff --git a/src/util/disk.c b/src/util/disk.c index b6b458f..cba0d44 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -40,10 +40,6 @@ #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) -#define DEBUG_NPIPE GNUNET_EXTRA_LOGGING - -#define DEBUG_PIPE GNUNET_EXTRA_LOGGING - /** * Block size for IO for copying files. */ @@ -112,9 +108,22 @@ struct GetFileSizeData * GNUNET_YES if symbolic links should be included. */ int include_sym_links; + + /** + * GNUNET_YES if mode is file-only (return total == -1 for directories). + */ + int single_file_mode; }; +#ifndef MINGW +/** + * Translate GNUnet-internal permission bitmap to UNIX file + * access permission bitmap. + * + * @param perm file permissions, GNUnet style + * @return file permissions, UNIX style + */ static int translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm) { @@ -142,6 +151,7 @@ translate_unix_perms (enum GNUNET_DISK_AccessPermissions perm) return mode; } +#endif /** @@ -166,16 +176,21 @@ getSizeRec (void *cls, const char *fn) #ifdef HAVE_STAT64 if (0 != STAT64 (fn, &buf)) { - LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat64", fn); + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat64", fn); return GNUNET_SYSERR; } #else if (0 != STAT (fn, &buf)) { - LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", fn); + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat", fn); return GNUNET_SYSERR; } #endif + if ((S_ISDIR (buf.st_mode)) && (gfsd->single_file_mode == GNUNET_YES)) + { + errno = EISDIR; + return GNUNET_SYSERR; + } if ((!S_ISLNK (buf.st_mode)) || (gfsd->include_sym_links == GNUNET_YES)) gfsd->total += buf.st_size; if ((S_ISDIR (buf.st_mode)) && (0 == ACCESS (fn, X_OK)) && @@ -255,7 +270,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset, } #ifdef MINGW - LARGE_INTEGER li, new_pos; + LARGE_INTEGER li; + LARGE_INTEGER new_pos; BOOL b; static DWORD t[] = {[GNUNET_DISK_SEEK_SET] = FILE_BEGIN, @@ -290,11 +306,13 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle * h, OFF_T offset, * of all sizes of files in the directory) * @param includeSymLinks should symbolic links be * included? + * @param singleFileMode GNUNET_YES to only get size of one file + * and return GNUNET_SYSERR for directories. * @return GNUNET_SYSERR on error, GNUNET_OK on success */ int GNUNET_DISK_file_size (const char *filename, uint64_t * size, - int includeSymLinks) + int includeSymLinks, int singleFileMode) { struct GetFileSizeData gfsd; int ret; @@ -302,6 +320,7 @@ GNUNET_DISK_file_size (const char *filename, uint64_t * size, GNUNET_assert (size != NULL); gfsd.total = 0; gfsd.include_sym_links = includeSymLinks; + gfsd.single_file_mode = singleFileMode; ret = getSizeRec (&gfsd, filename); *size = gfsd.total; return ret; @@ -719,27 +738,18 @@ GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle * h, void *result, } else { -#if DEBUG_PIPE - LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to read\n"); -#endif if (!ReadFile (h->h, result, len, &bytesRead, h->oOverlapRead)) { if (GetLastError () != ERROR_IO_PENDING) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error reading from pipe: %u\n", GetLastError ()); -#endif SetErrnoFromWinError (GetLastError ()); return GNUNET_SYSERR; } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n"); -#endif GetOverlappedResult (h->h, h->oOverlapRead, &bytesRead, TRUE); } -#if DEBUG_PIPE - LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes\n", bytesRead); -#endif + LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes from pipe\n", bytesRead); } return bytesRead; #else @@ -781,33 +791,24 @@ GNUNET_DISK_file_read_non_blocking (const struct GNUNET_DISK_FileHandle * h, } else { -#if DEBUG_PIPE - LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe, trying to read\n"); -#endif if (!ReadFile (h->h, result, len, &bytesRead, h->oOverlapRead)) { if (GetLastError () != ERROR_IO_PENDING) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error reading from pipe: %u\n", GetLastError ()); -#endif SetErrnoFromWinError (GetLastError ()); return GNUNET_SYSERR; } else { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "ReadFile() queued a read, cancelling\n"); -#endif CancelIo (h->h); errno = EAGAIN; return GNUNET_SYSERR; } } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes\n", bytesRead); -#endif } return bytesRead; #else @@ -880,31 +881,23 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h, } else { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to write %u bytes\n", n); -#endif if (!WriteFile (h->h, buffer, n, &bytesWritten, h->oOverlapWrite)) { if (GetLastError () != ERROR_IO_PENDING) { SetErrnoFromWinError (GetLastError ()); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n", GetLastError ()); -#endif return GNUNET_SYSERR; } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n"); -#endif if (!GetOverlappedResult (h->h, h->oOverlapWrite, &bytesWritten, TRUE)) { SetErrnoFromWinError (GetLastError ()); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error getting overlapped result while writing to pipe: %u\n", GetLastError ()); -#endif return GNUNET_SYSERR; } } @@ -913,35 +906,27 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h, DWORD ovr; if (!GetOverlappedResult (h->h, h->oOverlapWrite, &ovr, TRUE)) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error getting control overlapped result while writing to pipe: %u\n", GetLastError ()); -#endif } else { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes (ovr says %u), picking the greatest\n", bytesWritten, ovr); -#endif } } if (bytesWritten == 0) { if (n > 0) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes, returning -1 with EAGAIN\n", bytesWritten); -#endif errno = EAGAIN; return GNUNET_SYSERR; } } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytesWritten); -#endif } return bytesWritten; #else @@ -970,37 +955,27 @@ GNUNET_DISK_file_write_blocking (const struct GNUNET_DISK_FileHandle * h, #ifdef MINGW DWORD bytesWritten; /* We do a non-overlapped write, which is as blocking as it gets */ -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Writing %u bytes\n", n); -#endif if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL)) { SetErrnoFromWinError (GetLastError ()); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n", GetLastError ()); -#endif return GNUNET_SYSERR; } if (bytesWritten == 0 && n > 0) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for pipe to clean\n"); -#endif WaitForSingleObject (h->h, INFINITE); if (!WriteFile (h->h, buffer, n, &bytesWritten, NULL)) { SetErrnoFromWinError (GetLastError ()); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n", GetLastError ()); -#endif return GNUNET_SYSERR; } } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytesWritten); -#endif return bytesWritten; #else int flags; @@ -1350,7 +1325,7 @@ GNUNET_DISK_file_copy (const char *src, const char *dst) struct GNUNET_DISK_FileHandle *in; struct GNUNET_DISK_FileHandle *out; - if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES)) + if (GNUNET_OK != GNUNET_DISK_file_size (src, &size, GNUNET_YES, GNUNET_YES)) return GNUNET_SYSERR; pos = 0; in = GNUNET_DISK_file_open (src, GNUNET_DISK_OPEN_READ, @@ -2008,10 +1983,8 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, snprintf (pipename, sizeof pipename, "\\\\.\\pipe\\gnunet-%d-%ld", getpid (), InterlockedIncrement ((LONG *) & pipe_unique_id)); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateNamedPipe: name = %s, size = %lu\n", pipename, psize); -#endif /* Use CreateNamedPipe instead of CreatePipe, because the latter * returns a write handle that does not permit FILE_READ_ATTRIBUTES * access, on versions of win32 earlier than WinXP SP2. @@ -2028,9 +2001,7 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, if (read_pipe != INVALID_HANDLE_VALUE) { -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", read_pipe); -#endif break; } @@ -2041,33 +2012,24 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, case ERROR_PIPE_BUSY: /* The pipe is already open with compatible parameters. * Pick a new name and retry. */ -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe busy, retrying\n"); -#endif continue; case ERROR_ACCESS_DENIED: /* The pipe is already open with incompatible parameters. * Pick a new name and retry. */ -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe access denied, retrying\n"); -#endif continue; case ERROR_CALL_NOT_IMPLEMENTED: /* We are on an older Win9x platform without named pipes. * Return an anonymous pipe as the best approximation. */ -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateNamedPipe not implemented, resorting to " "CreatePipe: size = %lu\n", psize); -#endif if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize)) { -#if DEBUG_PIPE - LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p\n", - *read_pipe_ptr); - LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", + LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe read handle = %p, write handle = %p\n", + *read_pipe_ptr, *write_pipe_ptr); -#endif return GNUNET_OK; } err = GetLastError (); @@ -2079,9 +2041,7 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, } /* NOTREACHED */ } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile: name = %s\n", pipename); -#endif /* Open the named pipe for writing. * Be sure to permit FILE_READ_ATTRIBUTES access. */ @@ -2094,15 +2054,11 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr, /* Failure. */ DWORD err = GetLastError (); -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "CreateFile failed: %d\n", err); -#endif CloseHandle (read_pipe); return err; } -#if DEBUG_PIPE LOG (GNUNET_ERROR_TYPE_DEBUG, "pipe write handle = %p\n", write_pipe); -#endif /* Success. */ *read_pipe_ptr = read_pipe; *write_pipe_ptr = write_pipe; |