Writing to file causes zombie apocalypse
#1

Hello there! I've spent half a day today trying to debug single function (rewriting it would be faster I guess). The issue is this: I use fopen (tried with io_write, io_append and io_readwrite, no diffrence) to create/open a file. Then I use fwrite - and nothing happens.

I started with checking if file handle is correct - yes it is. File is created. I tried to use fputchar (with utf-8 set to true and false) - no diffrence. After few hours I tried some another combination - and somehow I managed to write to file. It seems that if I don't put fclose in the same function as rest, stuff gets weird. I'm completely baffled how it happens. Here's my completely first version of code for reference (with some debug), and the version that worked.
Version I wanted to work
pawn Код:
#define DEFAULT_LOG_FORMAT "ut/%04d.log"
//(...)
stock UT_SingleLog(player, const fmat[], va_args<>) {
    //If any type of logging enabled, do that, otherwise return true
    #if defined LOG_FILE || defined LOG_PRINT
   
    //@TODO:
    //Rethink the weight of all those function calls
    //Rethink the architecture of adding [UT] tag
    //Rethink my life

    //@TODO:
    //Rethink that value
    static
        contents[512];

    format(contents, sizeof contents, "[UT][Log]: %s", fmat);
    //Can I even reuse that? Kind of risky
    va_format(contents, sizeof contents, contents, va_start<2>);

    #if defined LOG_PRINT
    print(contents);
    #endif

    #if defined LOG_FILE
    //Conviniently use the format size (constant 4 cells wide number in _default_ log format which fits in place of %04d)
    new
        name[] = DEFAULT_LOG_FORMAT;

    if(!Iter_Contains(MockPlayerLog, player)) {
        format(name, sizeof name, DEFAULT_LOG_FORMAT, player);
        //Change to io_write if you want new log each tests run
        MockPlayerLog[player] = fopen(name, io_readwrite);
        if(!MockPlayerLog[player]) {
            perror("Couldn't open/create log file for player %d", player);
            return 0;
        }

        Iter_Add(MockPlayerLog, player);
    }
    fwrite(MockPlayerLog[player], contents);

    #endif
    #endif
    return 1;
}
Working version:
pawn Код:
stock UT_SingleLog(player, const fmat[], va_args<>) {
    #if defined LOG_FILE || defined LOG_PRINT
    static
        contents[512];

    format(contents, sizeof contents, "[UT][Log]: %s", fmat);
    contents[0] = EOS;
    va_format(contents, sizeof contents, contents, va_start<2>);

    #if defined LOG_PRINT
    print(contents);
    #endif

    #if defined LOG_FILE
    new
        name[] = DEFAULT_LOG_FORMAT;

    if(!Iter_Contains(MockPlayerLog, player)) {
        format(name, sizeof name, DEFAULT_LOG_FORMAT, player);
        //Change to io_write if you want new log each tests run
        MockPlayerLog[player] = fopen(name, io_readwrite);
        if(!MockPlayerLog[player]) {
            perror("Couldn't open/create log file for player %d", player);
            return 0;
        }
    }
    fwrite(MockPlayerLog[player], "Other string");
    fclose(MockPlayerLog[player]);

    #endif
    #endif
    return 1;
}
Before using fwrite, values were:
pawn Код:
content = "[UT][Log]: SCM"
MockPlayerLog[player] = 5117232
name = "ut/0007.log"
I desperately need ideas, thanks.
Reply
#2

Finally found it in lst file. If somehow your fclose is missing, then you can't write anything (I think it's some kind of runtime check, but error would be nicer).
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)