char *realpath(const char *file_name, char *resolved_name, size_t resolv_buffer_length) { long lRet; wchar_t szFile[_MAX_PATH + 1]; wchar_t szRet[_MAX_PATH + 1]; wchar_t *wresult; char *result = NULL; if (_plibc_utf8_mode == 1) { lRet = plibc_conv_to_win_pathwconv(file_name, szFile, _MAX_PATH ); if (lRet != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return NULL; } wresult = _wfullpath(szRet, szFile, MAX_PATH); SetErrnoFromWinError(GetLastError()); if (wresult) wchartostr (szRet, &result, CP_UTF8); return result; } else { lRet = plibc_conv_to_win_path(file_name, (char *) szFile, _MAX_PATH ); if (lRet != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return NULL; } result = _fullpath(resolved_name, (char *) szFile, resolv_buffer_length); SetErrnoFromWinError(GetLastError()); return result; } }
/** * @brief Unmap files from memory * @author Cygwin team * @author Nils Durner */ int _win_munmap(void *start, size_t length) { unsigned uiIndex; if (UnmapViewOfFile(start)) { BOOL success = TRUE; errno = 0; /* Release mapping handle */ WaitForSingleObject(hMappingsLock, INFINITE); for(uiIndex = 0; uiIndex <= uiMappingsCount; uiIndex++) { if (pMappings[uiIndex].pStart == start) { DWORD error; error = NO_ERROR; if (!CloseHandle(pMappings[uiIndex].hMapping)) { success = FALSE; error = GetLastError(); } if (!CloseHandle(pMappings[uiIndex].hFile)) { success = FALSE; error = GetLastError(); } if (error != NO_ERROR) SetErrnoFromWinError(error); pMappings[uiIndex].pStart = NULL; pMappings[uiIndex].hMapping = NULL; pMappings[uiIndex].hFile = NULL; break; } } ReleaseMutex(hMappingsLock); return success ? 0 : MAP_FAILED; } else { SetErrnoFromWinError(GetLastError()); return MAP_FAILED; } }
/** * Make a FIFO special file * @todo use mode */ int _win_mkfifo(const char *path, mode_t mode) { HANDLE ret; SECURITY_ATTRIBUTES sec; ZeroMemory(&sec, sizeof(sec)); sec.nLength = sizeof(sec); sec.bInheritHandle = TRUE; ret = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 0, 0, 0, &sec); if (ret == INVALID_HANDLE_VALUE) { SetErrnoFromWinError(GetLastError()); return -1; } else { errno = 0; __win_SetHandleType((DWORD) ret, PIPE_HANDLE); return 0; } }
/** * @brief Get status information on a file */ int __win_stat(const char *path, struct stat *buffer, int iDeref) { char szFile[_MAX_PATH + 1]; long lRet; if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* Remove trailing slash */ lRet = strlen(szFile) - 1; if (szFile[lRet] == '\\') { szFile[lRet] = 0; } /* Dereference symlinks */ if (iDeref) { if (__win_deref(szFile) == -1 && errno != EINVAL) return -1; } /* stat sets errno */ return stat(szFile, buffer); }
DWORD WINAPI __win_Read(TReadWriteInfo *pInfo) { int iRet; if (__win_GetHandleType(pInfo->fildes) == FD_HANDLE) { _setmode(pInfo->fildes, _O_BINARY); errno = 0; iRet = _read(pInfo->fildes, pInfo->buf, pInfo->nbyte); free(pInfo); return iRet; } else { DWORD dwRead; errno = 0; if (!ReadFile((HANDLE) pInfo->fildes, pInfo->buf, pInfo->nbyte, &dwRead, NULL)) { free(pInfo); SetErrnoFromWinError(GetLastError()); return -1; } else { free(pInfo); return dwRead; } } }
int _win_msync(void *start, size_t length, int flags) { unsigned uiIndex; /* Can't have sync and async at the same time */ if ((flags & MS_SYNC) && (flags & MS_ASYNC)) { errno = EINVAL; return -1; } /* Not sure what to make of it. It's either the default, or unsupported */ if (flags & MS_INVALIDATE) { errno = ENOSYS; return -1; } if (FlushViewOfFile (start, length)) { BOOL success = TRUE; errno = 0; if (flags & MS_SYNC) { /* Flush to the file */ WaitForSingleObject(hMappingsLock, INFINITE); for(uiIndex = 0; uiIndex <= uiMappingsCount; uiIndex++) { if (pMappings[uiIndex].pStart == start) { success = FlushFileBuffers (pMappings[uiIndex].hFile); SetErrnoFromWinError(GetLastError()); break; } } ReleaseMutex(hMappingsLock); } return success ? 0 : -1; } else { SetErrnoFromWinError(GetLastError()); return -1; } }
/** * @brief Writes data to a stream */ size_t _win_fwrite(const void *buffer, size_t size, size_t count, FILE *stream) { DWORD dwWritten; WriteFile((HANDLE) _get_osfhandle(_fileno(stream)), buffer, size, &dwWritten, NULL); SetErrnoFromWinError(GetLastError()); return dwWritten; }
/** * @brief Synchronize changes to a file */ int fsync(int fildes) { if (!FlushFileBuffers((HANDLE) _get_osfhandle(fildes))) { SetErrnoFromWinError(GetLastError()); return -1; } else { errno = 0; return 0; } }
/** * @brief Get status information on a file */ int __win_stat64(const char *path, struct stat64 *buffer, int iDeref) { char szFile[_MAX_PATH + 1]; long lRet; if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* Remove trailing slash */ lRet = strlen(szFile) - 1; if (szFile[lRet] == '\\') { szFile[lRet] = 0; } /* Dereference symlinks */ if (iDeref) { if (__win_deref(szFile) == -1 && errno != EINVAL) return -1; } if (!_plibc_stat64) { /* not supported under Windows 9x */ struct stat theStat; int iRet; iRet = __win_stat(path, &theStat, iDeref); buffer->st_dev = theStat.st_dev; buffer->st_ino = theStat.st_ino; buffer->st_mode = theStat.st_mode; buffer->st_nlink = theStat.st_nlink; buffer->st_uid = theStat.st_uid; buffer->st_gid = theStat.st_gid; buffer->st_rdev = theStat.st_rdev; buffer->st_size = (theStat.st_size > LONG_MAX) ? LONG_MAX : theStat.st_size; buffer->st_atime = (theStat.st_atime > LONG_MAX) ? LONG_MAX : theStat.st_atime; buffer->st_mtime = (theStat.st_mtime > LONG_MAX) ? LONG_MAX : theStat.st_mtime; buffer->st_ctime = (theStat.st_ctime > LONG_MAX) ? LONG_MAX : theStat.st_ctime; return iRet; } else /* stat sets errno */ return _plibc_stat64(szFile, buffer); }
/** * @brief Delete a file * If filename is a link, the link itself it removed. */ int _win_unlink(const char *filename) { char szFile[_MAX_PATH + 1]; long lRet; if ((lRet = plibc_conv_to_win_path_ex(filename, szFile, 0)) != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* unlink sets errno */ return unlink(szFile); }
/** * @brief Determine file-access permission. */ int _win_access( const char *path, int mode ) { char szFile[_MAX_PATH + 1]; long lRet; mode &= 6; if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* access sets errno */ return access(szFile, mode); }
char *_win_bindtextdomain(const char *domainname, const char *dirname) { #ifdef HAVE_LIBINTL char szDirname[_MAX_PATH + 1]; int i; if ((i = plibc_conv_to_win_path(dirname, szDirname)) != ERROR_SUCCESS) { SetErrnoFromWinError(i); return NULL; } return bindtextdomain(domainname, szDirname); #else errno = ENOSYS; return NULL; #endif }
/** * Create a pipe for reading and writing */ int _win_pipe(int *phandles) { /* To get non-blocking pipes we could use CreateNamedPipe here. But it isn't implemented under Win9x. */ if (!CreatePipe((HANDLE *) &phandles[0],(HANDLE *) &phandles[1], NULL, 0)) { SetErrnoFromWinError(GetLastError()); return -1; } else { errno = 0; __win_SetHandleType((DWORD) phandles[0], PIPE_HANDLE); __win_SetHandleType((DWORD) phandles[1], PIPE_HANDLE); return 0; } }
int _win_close(int fd) { THandleType theType; int ret; theType = __win_GetHandleType((DWORD) fd); switch(theType) { case SOCKET_HANDLE: ret = closesocket(fd); if (ret == SOCKET_ERROR) SetErrnoFromWinsockError(WSAGetLastError()); break; case PIPE_HANDLE: if (!CloseHandle((HANDLE) fd)) { SetErrnoFromWinError(GetLastError()); ret = -1; } else ret = 0; break; case FD_HANDLE: ret = close(fd); break; case UNKNOWN_HANDLE: ret = -1; errno = EBADF; SetLastError(ERROR_INVALID_HANDLE); __plibc_panic(5, "Cannot close() unknown handle\n"); break; } if (theType != UNKNOWN_HANDLE) { __win_DiscardHandleBlockingMode(fd); __win_DiscardHandleType(fd); } return ret; }
/** * @brief Delete a file * If filename is a link, the link itself it removed. */ int _win_unlink(const char *filename) { wchar_t szFile[_MAX_PATH + 1]; long lRet; if (plibc_utf8_mode() == 1) lRet = plibc_conv_to_win_pathwconv_ex(filename, szFile, 0); else lRet = plibc_conv_to_win_path_ex(filename, (char *) szFile, 0); if (lRet != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* unlink sets errno */ if (plibc_utf8_mode() == 1) return _wunlink(szFile); else return unlink((char *) szFile); }
/** * @brief Set errno according to a HRESULT (COM error code) */ void SetErrnoFromHRESULT(HRESULT hRes) { switch(hRes) { case NOERROR: errno = 0; break; case E_UNEXPECTED: case E_FAIL: case S_FALSE: errno = ESTALE; case E_NOTIMPL: errno = ENOSYS; break; case E_OUTOFMEMORY: errno = ENOMEM; break; case E_INVALIDARG: case E_NOINTERFACE: errno = EINVAL; break; case E_POINTER: case E_ABORT: errno = EFAULT; break; case E_HANDLE: errno = EBADF; break; case E_ACCESSDENIED: errno = EACCES; break; case E_PENDING: errno = EBUSY; break; default: SetErrnoFromWinError(HRESULT_CODE(hRes)); } }
/** * Change the file-permission settings. */ int _win_chmod(const char *filename, int pmode) { wchar_t szFile[_MAX_PATH + 1]; long lRet; pmode &= (_S_IREAD | _S_IWRITE); if (_plibc_utf8_mode == 1) lRet = plibc_conv_to_win_pathwconv(filename, szFile, _MAX_PATH); else lRet = plibc_conv_to_win_path(filename, (char *) szFile, _MAX_PATH); if (lRet != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return -1; } /* chmod sets errno */ if (_plibc_utf8_mode == 1) return _wchmod(szFile, pmode); else return chmod((char *) szFile, pmode); }
char *_win_bindtextdomain(const char *domainname, const char *dirname) { #ifdef HAVE_LIBINTL char szDirname[_MAX_PATH + 1]; int i; if ((i = plibc_conv_to_win_path(dirname, szDirname, _MAX_PATH)) != ERROR_SUCCESS) { SetErrnoFromWinError(i); return NULL; } /* There is nothing we could do: libintl will internally call CRT with * szDirname, so we can't convert it to UTF-8, and can't convince * libintl to use wide-character functions either. * So only call BINDTEXTDOMAIN() with ASCII/CP*-encoded dirnames. */ return bindtextdomain(domainname, szDirname); #else errno = ENOSYS; return NULL; #endif }
/** * @brief map files into memory * @author Cygwin team * @author Nils Durner */ void *_win_mmap(void *start, size_t len, int access, int flags, int fd, unsigned long long off) { DWORD protect, high, low, access_param; HANDLE h, hFile; SECURITY_ATTRIBUTES sec_none; void *base; BOOL bFound = FALSE; unsigned int uiIndex; errno = 0; switch(access) { case PROT_WRITE: protect = PAGE_READWRITE; access_param = FILE_MAP_WRITE; break; case PROT_READ: protect = PAGE_READONLY; access_param = FILE_MAP_READ; break; default: protect = PAGE_WRITECOPY; access_param = FILE_MAP_COPY; break; } sec_none.nLength = sizeof(SECURITY_ATTRIBUTES); sec_none.bInheritHandle = TRUE; sec_none.lpSecurityDescriptor = NULL; hFile = (HANDLE) _get_osfhandle(fd); h = CreateFileMapping(hFile, &sec_none, protect, 0, 0, NULL); if (! h) { SetErrnoFromWinError(GetLastError()); return MAP_FAILED; } high = off >> 32; low = off & ULONG_MAX; base = NULL; /* If a non-zero start is given, try mapping using the given address first. If it fails and flags is not MAP_FIXED, try again with NULL address. */ if (start) base = MapViewOfFileEx(h, access_param, high, low, len, start); if (!base && !(flags & MAP_FIXED)) base = MapViewOfFileEx(h, access_param, high, low, len, NULL); if (!base || ((flags & MAP_FIXED) && base != start)) { if (!base) SetErrnoFromWinError(GetLastError()); else errno = EINVAL; CloseHandle(h); return MAP_FAILED; } /* Save mapping handle */ WaitForSingleObject(hMappingsLock, INFINITE); for(uiIndex = 0; uiIndex <= uiMappingsCount; uiIndex++) { if (pMappings[uiIndex].pStart == base) { bFound = 1; break; } } if (! bFound) { int inserted = 0; HANDLE hOwnFile; if (!DuplicateHandle (GetCurrentProcess (), hFile, GetCurrentProcess (), &hOwnFile, 0, FALSE, DUPLICATE_SAME_ACCESS)) { ReleaseMutex(hMappingsLock); SetErrnoFromWinError(GetLastError()); CloseHandle(h); return MAP_FAILED; } uiIndex = 0; while(!inserted) { if (pMappings[uiIndex].pStart == NULL) { pMappings[uiIndex].pStart = base; pMappings[uiIndex].hMapping = h; pMappings[uiIndex].hFile = hOwnFile; inserted = 1; } if (uiIndex == uiMappingsCount) { uiMappingsCount++; pMappings = (TMapping *) realloc(pMappings, (uiMappingsCount + 1) * sizeof(TMapping)); pMappings[uiMappingsCount].pStart = NULL; } uiIndex++; } } ReleaseMutex(hMappingsLock); return base; }
/** * Complete filename (a la shell) from abbrevition. * @param fil the name of the file, may contain ~/ or * be relative to the current directory * @returns the full file name, * NULL is returned on error */ static char * expandFileName(const char * fil) { char buffer[512]; char * fn; #ifndef MINGW char * fm; const char *fil_ptr; #else long lRet; #endif if (fil == NULL) return NULL; #ifndef MINGW if (fil[0] == DIR_SEPARATOR) { /* absolute path, just copy */ return STRDUP(fil); } if (fil[0] == '~') { fm = getenv("HOME"); if (fm == NULL) { /* keep it symbolic to show error to user! */ fm = "$HOME"; } /* do not copy '~' */ fil_ptr = fil + 1; /* skip over dir seperator to be consistent */ if (fil_ptr[0] == DIR_SEPARATOR) fil_ptr++; } else { fil_ptr = fil; if (getcwd(buffer, 512) != NULL) fm = buffer; else fm = "$PWD"; } fn = MALLOC(strlen(fm) + 1 + strlen(fil_ptr) + 1); sprintf(fn, "%s/%s", fm, fil_ptr); #else fn = MALLOC(MAX_PATH + 1); if ((lRet = conv_to_win_path(fil, buffer)) != ERROR_SUCCESS) { SetErrnoFromWinError(lRet); return NULL; } /* is the path relative? */ if ((strncmp(buffer + 1, ":\\", 2) != 0) && (strncmp(buffer, "\\\\", 2) != 0)) { char szCurDir[MAX_PATH + 1]; lRet = GetCurrentDirectory(MAX_PATH + 1, szCurDir); if (lRet + strlen(fn) + 1 > (_MAX_PATH + 1)) { SetErrnoFromWinError(ERROR_BUFFER_OVERFLOW); return NULL; } sprintf(fn, "%s\\%s", szCurDir, buffer); } else { strcpy(fn, buffer); } #endif return fn; }
/** * Win32 select() will only work with sockets, so we roll our own * implementation here. * - If you supply only sockets, this simply passes through to winsock select(). * - If you supply file handles, there is no way to distinguish between * ready for read/write or OOB, so any set in which the handle is found will * be marked as ready. * - If you supply a mixture of handles and sockets, the system will interleave * calls between select() and WaitForMultipleObjects(). The time slicing may * cause this function call to take up to 100 ms longer than you specified. * - Pipes are not checked for writability or errors (errno = ENOSYS) */ int _win_select(int max_fd, fd_set * rfds, fd_set * wfds, fd_set * efds, const struct timeval *tv) { DWORD ms_total, limit; HANDLE handles[MAXIMUM_WAIT_OBJECTS], hPipes[MAXIMUM_WAIT_OBJECTS]; int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS]; int n_handles, i, iPipes; fd_set sock_read, sock_write, sock_except; fd_set aread, awrite, aexcept; int sock_max_fd; struct timeval tvslice; int retcode; #define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set)) n_handles = 0; sock_max_fd = -1; iPipes = 0; /* calculate how long we need to wait in milliseconds */ if(tv == NULL) ms_total = INFINITE; else { ms_total = tv->tv_sec * 1000; ms_total += tv->tv_usec / 1000; } /* select() may be used as a portable way to sleep */ if (!(rfds || wfds || efds)) { Sleep(ms_total); return 0; } FD_ZERO(&sock_read); FD_ZERO(&sock_write); FD_ZERO(&sock_except); /* build an array of handles for non-sockets */ for(i = 0; i < max_fd; i++) { if(SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) { unsigned long ulVal; if (__win_GetHandleType((DWORD) i) == SOCKET_HANDLE) { /* socket */ if(SAFE_FD_ISSET(i, rfds)) FD_SET(i, &sock_read); if(SAFE_FD_ISSET(i, wfds)) FD_SET(i, &sock_write); if(SAFE_FD_ISSET(i, efds)) FD_SET(i, &sock_except); if(i > sock_max_fd) sock_max_fd = i; } else { if (__win_GetHandleType((DWORD) i) == PIPE_HANDLE) hPipes[iPipes++] = (HANDLE) i; /* Pipe */ else { handles[n_handles] = (HANDLE) _get_osfhandle(i); if ((DWORD) handles[n_handles] == 0xffffffff) handles[n_handles] = (HANDLE) i; handle_slot_to_fd[n_handles] = i; n_handles++; } } } } /* multiplex between winsock select() and waiting on the handles */ FD_ZERO(&aread); FD_ZERO(&awrite); FD_ZERO(&aexcept); limit = GetTickCount() + ms_total; do { retcode = 0; if(sock_max_fd >= 0) { /* overwrite the zero'd sets here; the select call * will clear those that are not active */ aread = sock_read; awrite = sock_write; aexcept = sock_except; tvslice.tv_sec = 0; tvslice.tv_usec = 100000; if ((retcode = select(sock_max_fd + 1, &aread, &awrite, &aexcept, &tvslice)) == SOCKET_ERROR) { SetErrnoFromWinsockError(WSAGetLastError()); if (errno == ENOTSOCK) errno = EBADF; return retcode; } } if(n_handles > 0) { /* check handles */ DWORD wret; wret = MsgWaitForMultipleObjects(n_handles, handles, FALSE, retcode > 0 ? 0 : 100, QS_ALLEVENTS); if(wret == WAIT_TIMEOUT) { /* set retcode to 0; this is the default. * select() may have set it to something else, * in which case we leave it alone, so this branch * does nothing */ ; } else if(wret == WAIT_FAILED) { SetErrnoFromWinError(GetLastError()); return -1; } else { for(i = 0; i < n_handles; i++) { if(WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0)) { if(SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) { FD_SET(handle_slot_to_fd[i], &aread); } if(SAFE_FD_ISSET(handle_slot_to_fd[i], wfds)) FD_SET(handle_slot_to_fd[i], &awrite); if(SAFE_FD_ISSET(handle_slot_to_fd[i], efds)) FD_SET(handle_slot_to_fd[i], &aexcept); retcode++; } } } } /* Poll Pipes */ for(i = 0; i < iPipes; i++) { DWORD dwBytes; if(SAFE_FD_ISSET(hPipes[i], rfds)) { if (! PeekNamedPipe(hPipes[i], NULL, 0, NULL, &dwBytes, NULL)) { retcode = -1; SetErrnoFromWinError(GetLastError()); } else if (dwBytes) { FD_SET((int) hPipes[i], &aread); retcode++; } } else if (SAFE_FD_ISSET(hPipes[i], wfds) || SAFE_FD_ISSET(hPipes[i], efds)) { errno = ENOSYS; return -1; /* Not implemented */ } } /* Check for closed sockets */ for(i = 0; i < sock_max_fd; i++) { if(SAFE_FD_ISSET(i, &sock_read)) { struct sockaddr addr; int len; if (getpeername(i, &addr, &len) == SOCKET_ERROR) { int err, len; len = sizeof(err); if (getsockopt(i, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == 0 && err == WSAENOTCONN) { if (! SAFE_FD_ISSET(i, &aread)) { FD_SET(i, &aread); retcode++; } } } } } } while(retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit)); if(rfds) *rfds = aread; if(wfds) *wfds = awrite; if(efds) *efds = aexcept; return retcode; }
/** * Complete filename (a la shell) from abbrevition. * @param fil the name of the file, may contain ~/ or * be relative to the current directory * @returns the full file name, * NULL is returned on error */ char * GNUNET_STRINGS_filename_expand (const char *fil) { char *buffer; #ifndef MINGW size_t len; size_t n; char *fm; const char *fil_ptr; #else char *fn; long lRet; #endif if (fil == NULL) return NULL; #ifndef MINGW if (fil[0] == DIR_SEPARATOR) /* absolute path, just copy */ return GNUNET_strdup (fil); if (fil[0] == '~') { fm = getenv ("HOME"); if (fm == NULL) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failed to expand `$HOME': environment variable `HOME' not set")); return NULL; } fm = GNUNET_strdup (fm); /* do not copy '~' */ fil_ptr = fil + 1; /* skip over dir seperator to be consistent */ if (fil_ptr[0] == DIR_SEPARATOR) fil_ptr++; } else { /* relative path */ fil_ptr = fil; len = 512; fm = NULL; while (1) { buffer = GNUNET_malloc (len); if (getcwd (buffer, len) != NULL) { fm = buffer; break; } if ((errno == ERANGE) && (len < 1024 * 1024 * 4)) { len *= 2; GNUNET_free (buffer); continue; } GNUNET_free (buffer); break; } if (fm == NULL) { LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "getcwd"); buffer = getenv ("PWD"); /* alternative */ if (buffer != NULL) fm = GNUNET_strdup (buffer); } if (fm == NULL) fm = GNUNET_strdup ("./"); /* give up */ } n = strlen (fm) + 1 + strlen (fil_ptr) + 1; buffer = GNUNET_malloc (n); GNUNET_snprintf (buffer, n, "%s%s%s", fm, (fm[strlen (fm) - 1] == DIR_SEPARATOR) ? "" : DIR_SEPARATOR_STR, fil_ptr); GNUNET_free (fm); return buffer; #else fn = GNUNET_malloc (MAX_PATH + 1); if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS) { SetErrnoFromWinError (lRet); LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path"); return NULL; } /* is the path relative? */ if ((strncmp (fn + 1, ":\\", 2) != 0) && (strncmp (fn, "\\\\", 2) != 0)) { char szCurDir[MAX_PATH + 1]; lRet = GetCurrentDirectory (MAX_PATH + 1, szCurDir); if (lRet + strlen (fn) + 1 > (MAX_PATH + 1)) { SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW); LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory"); return NULL; } buffer = GNUNET_malloc (MAX_PATH + 1); GNUNET_snprintf (buffer, MAX_PATH + 1, "%s\\%s", szCurDir, fn); GNUNET_free (fn); fn = buffer; } return fn; #endif }