PHYSFS - Zawsze zwraca false

0

Cześć, chciałem pobawić się z PHYSFS, jednak próba zakończyła się ciągłym zwracaniem false/0.. o co może chodzic? Zawsze zwraca NO FILE.

#include <iostream>
#include <stdio.h>
#include <physfs.h>

int main(int argc, char* argv[])
{
    PHYSFS_init(argv[0]);
    PHYSFS_permitSymbolicLinks(1);

    const std::string path = PHYSFS_getBaseDir() + std::string("test.log");
    std::cout << path << std::endl;
    if (!PHYSFS_exists(path.c_str())) {
        std::cout << "NO FILE" << std::endl;
    }

    PHYSFS_deinit();
    getchar();
}
2

Jaką ścieżkę wyświetla Ci to std::cout << path?

0

Poprawną, jak wklepie w eksplorator windows to otwiera plik, zresztą jaką ścieżkę bym nie wpisał zawsze zwraca to samo..

C:\Users\TEST\source\repos\ConsoleApplication2\Debug\test.log
1

Obsługa błędów jest ważną częścią porgrmowania!
Popraw tak, uruchom i wróć z informacją co zostało wypisane na strumieniu błędów:

#include <iostream>
#include <stdio.h>
#include <physfs.h>

int main(int argc, char* argv[])
{
    if (!PHYSFS_init(argv[0])) {
        std::cerr << "init: " << PHYSFS_getLastError() << '\n';
        return 1;
    }
    PHYSFS_permitSymbolicLinks(1);

    const std::string path = PHYSFS_getBaseDir() + std::string("test.log");
    std::cout << path << std::endl;
    if (!PHYSFS_exists(path.c_str())) {
        std::cerr << "NO FILE: " << PHYSFS_getLastError() << std::endl;
    }

    if (!PHYSFS_deinit()) {
        std::cerr << "deinit: " << PHYSFS_getLastError() << '\n';
        return 2;
    }
    getchar();
    return 0;
}

Jeszcze taka uwaga: jak masz pytania dotyczącej mniej znanej biblioteki, to dawaj też linki do jej opisu, żebyśmy nie musieli googlać niepotrzebnie.
Ci co pracują już dłużej w branży zwykle potrafią wydłubać z dokumentacji to co najważniejsze, więc mogą ci pomóc nawet nie znając biblioteki.
Ja wydłubałem to:

0

O, nie wiedziałem o tym, tu już coś podaje // odpalenie przez administratora też nic nie daje

NO FILE: filename is illegal or insecure
3

Ta biblioteka nie lubi Windowsa.
Problemem jest to (ty wpadasz w linię 27 z cytatu):
https://github.com/icculus/physfs/blob/69a742878745c38c9e9f2fc08e6407d2819d64f4/src/physfs.c#L959-L960

/*
 * Make a platform-independent path string sane. Doesn't actually check the
 *  file hierarchy, it just cleans up the string.
 *  (dst) must be a buffer at least as big as (src), as this is where the
 *  cleaned up string is deposited.
 * If there are illegal bits in the path (".." entries, etc) then we
 *  return zero and (dst) is undefined. Non-zero if the path was sanitized.
 */
static int sanitizePlatformIndependentPath(const char *src, char *dst)
{
    char *prev;
    char ch;

    while (*src == '/')  /* skip initial '/' chars... */
        src++;

    /* Make sure the entire string isn't "." or ".." */
    if ((strcmp(src, ".") == 0) || (strcmp(src, "..") == 0))
        BAIL(PHYSFS_ERR_BAD_FILENAME, 0);

    prev = dst;
    do
    {
        ch = *(src++);

        if ((ch == ':') || (ch == '\\'))  /* illegal chars in a physfs path. */
            BAIL(PHYSFS_ERR_BAD_FILENAME, 0);

Ergo popraw ścieżkę tak by była Unixowa.

1

To wydaje mi się, że nie przepuszcza

if ((ch == ':') || (ch == '\\'))  /* illegal chars in a physfs path. */
            BAIL(PHYSFS_ERR_BAD_FILENAME, 0);

Edit: O.. Na górze nawet widzę to samo :D Usunąć ten post, czy jak?

0

W sumie jak patrze jeszcze na to:

storm. napisał(a):

Poprawną, jak wklepie w eksplorator windows to otwiera plik, zresztą jaką ścieżkę bym nie wpisał zawsze zwraca to samo..

C:\Users\TEST\source\repos\ConsoleApplication2\Debug\test.log

To to jest bug w bibliotece. Skoro nie wolno użyć : i \ to biblioteka nie powinna zwracać ścieżki, która zawiera te znaki.

0
MarekR22 napisał(a):

W sumie jak patrze jeszcze na to:

storm. napisał(a):

Poprawną, jak wklepie w eksplorator windows to otwiera plik, zresztą jaką ścieżkę bym nie wpisał zawsze zwraca to samo..

C:\Users\TEST\source\repos\ConsoleApplication2\Debug\test.log

To to jest bug w bibliotece. Skoro nie wolno użyć : i \ to biblioteka nie powinna zwracać ścieżki, która zawiera te znaki.

Użycie "%appdata%/test.txt" też nie działa (nie ma błędu, program się zamyka), to o jakiej ścieżce mówicie, da się to jeszcze bardziej zmienić?..

0

A jeszcze jedno, weź skopiuj tą bibliotekę do debug u siebie, a następnie uruchom swoją apkę i zdebuguj tą bibliotekę, żeby się upewnić jaka ścieżka dochodzi do wskazanej funkcji.
Może sie okazać, że nie masz kontroli z kodu nad argumentem src dla tej funkcji, a problemem są inne dane wejściowe.
Myśmy tylko zlokalizowali skąd leci ten błąd i jaka jest jego natura, a nie wiemy na pewno, że src to jest dokładnie co przekazałeś do PHYSFS_exists

Edit: Ok sprawdziłem to w kodzie, to jet ta ścieżka:

0

PHYSFS_getBaseDir jest ustawiana na podstawie argumentu: PHYSFS_init.
Co dokładnie tam trafia?

Zależnie jak uruchamiasz tą aplikację, to argv[0] będzie zawierać co innego.
Np uruchomienie z linii poleceń z katalogu, w którym znajduje się plik powoduje, że ten argument zawiera tylko nazwę pliku wykonalnego.

natomiast uruchomienie z exploratora powoduje, że argv[0] zawiera pełną bezwzględną ścieżkę pliku wykonalnego.

Żeby to obejść można zrobić to (używając C++17 filesystem):

#include <iostream>
#include <filesystem>

std::string normalizeArg(const char* arg0)
{
    return std::filesystem::relative(arg0).lexically_normal().generic_string();
}

int main(int argc, char* argv[])
{
    if (!PHYSFS_init(normalizeArg(argv[0]).c_str())) {
        std::cerr << "init: " << PHYSFS_getLastError() << '\n';
        return 1;
    }
    ...

1 użytkowników online, w tym zalogowanych: 0, gości: 1