Zjištění chyby při neúspěchu fwrite()

A. F.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #45 kdy: 30. 06. 2018, 22:39:28 »
A já mám právě problém v tom, že mi to žádnou chybu nevrátí. To je to co řeším.
Že došlo k chybě zjistíte tak, že otestujete výsledek volání fwrite(), zda je to FALSE nebo 0. Když funkce vrátí hodnotu větší než nula, opakujete její volání v cyklu a zapíšete další část.
A jak zjistím, jaká je to chyba?
« Poslední změna: 30. 06. 2018, 22:42:47 od andreaw.fean »


Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #46 kdy: 30. 06. 2018, 22:48:23 »
A jak zjistím, jaká je to chyba?
Zkusil bych error_get_last() nebo posix_get_last_error().

A. F.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #47 kdy: 30. 06. 2018, 22:51:35 »
A jak zjistím, jaká je to chyba?
Zkusil bych error_get_last() nebo posix_get_last_error().
To jsem zkoušel. To mi vrací success.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #48 kdy: 30. 06. 2018, 22:56:16 »
To jsem zkoušel. To mi vrací success.
Obě dvě? Voláte je až po té, co vám fwrite() vrátí false nebo 0? Bylo by lepší, kdybyste sem dal kód, který zkoušíte.

Lol Phirae

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #49 kdy: 30. 06. 2018, 22:56:58 »
A jak zjistím, jaká je to chyba?
Zkusil bych error_get_last() nebo posix_get_last_error().

Už ti tady asi 5x psali, že to nefunguje. Vyměň si tampón.  ;D ::)


Sten

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #50 kdy: 30. 06. 2018, 22:59:20 »
POSIXový write může vrátit 0 i v případě, že je požadován zápis nenulového počtu bajtů. A znamená to jen, že bylo zapsáno nula bajtů – není to chyba.

A ve kterém případě by se to mělo stát? POSIX také specifikuje, za jakých okolností je možné zapsat méně než požadovaný počet bajtů, a všechny při nezapsaní ani jednoho bajtu vrací -1 a nastavují errno.

A. F.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #51 kdy: 30. 06. 2018, 23:01:00 »
To jsem zkoušel. To mi vrací success.
Obě dvě? Voláte je až po té, co vám fwrite() vrátí false nebo 0? Bylo by lepší, kdybyste sem dal kód, který zkoušíte.
Máte ho hned v mém prvním příspěvku.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #52 kdy: 30. 06. 2018, 23:07:26 »
POSIX také specifikuje, za jakých okolností je možné zapsat méně než požadovaný počet bajtů
Kde to specifikuje?

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #53 kdy: 30. 06. 2018, 23:08:59 »
Máte ho hned v mém prvním příspěvku.
Ano, ale ten kód je špatně, tam netestujete, zda došlo k chybě. A nevolá se tam ani error_get_last() nebo posix_get_last_error().

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #54 kdy: 30. 06. 2018, 23:26:03 »
Radši vám ten opravený kód napíšu, jinak to bude na dlouho…

Kód: [Vybrat]
$tmpdir = sys_get_temp_dir();
$tmpname = tempnam($tmpdir, 'app-');
$handle = fopen($tmpname, 'a');
 
// velikost $s je obvykle 2096 bajtů
function write($handle, $s)
{
    $len = strlen($s);
    while ( $len > 0 )
    {
        $wrote = fwrite($handle, $s);

        if ( $wrote === false || $wrote == 0 )
        {
            var_dump(error_get_last());
            var_dump(posix_get_last_error());
            throw new RuntimeException('Zápis do souboru skončil chybou.');
        }

        $s = substr($s, $wrote)
        $len = strlen($s);
    }
}

A. F.

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #55 kdy: 30. 06. 2018, 23:36:16 »
Radši vám ten opravený kód napíšu, jinak to bude na dlouho…

Výsledek je stejný.

Lol Phirae

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #56 kdy: 01. 07. 2018, 01:10:56 »
 :)
 ;) ;)
 :D :D :D
 ;D ;D ;D ;D
 :P :P :P
 :-* :-*
 8)

Jens

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #57 kdy: 01. 07. 2018, 01:32:35 »
Kouknul jsem do zdrojáku PHP a fwrite nakonec vede na

Kód: [Vybrat]
    int bytes_written = write(data->fd, buf, count);
    if (bytes_written < 0) return 0;
    return (size_t) bytes_written;

tj. na https://linux.die.net/man/2/write

Když se koukneš na https://linux.die.net/man/3/explain_write tak bys asi rád znal hodnotu errno (errno.h), což by právě měla dělat posix_get_last_error() , jestli ta ale nevrací chybový kód, tak možná nezbyde než se smířit s "těžký život ve světě PHP".  ;)

Jens

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #58 kdy: 01. 07. 2018, 01:39:21 »
Ještě bych dodal, že errno mění kdejaká funkce z libc a i PHP samotné, takže hodnotu vrácenou z posix_get_last_error() bych si pro jistotu zapamatoval ihned po volání fwrite().

Re:Zjištění chyby při neúspěchu fwrite()
« Odpověď #59 kdy: 01. 07. 2018, 05:30:18 »
POSIXový write může vrátit 0 i v případě, že je požadován zápis nenulového počtu bajtů. A znamená to jen, že bylo zapsáno nula bajtů – není to chyba.

Citace
On success, the number of bytes written is returned (zero indicates nothing was written).  It is not an error if this number is smaller than the number of bytes requested; this may happen for example because the disk device was filled.  See also NOTES.

On error, -1 is returned, and errno is set appropriately.

Vrácení 0 by měl být výjimečný případ, ale počítá se mezi úspěšné výsledky volání. Nekonečnému cyklu zabrání to, že takový stav by byl jen dočasný, a v některém z příštích cyklů by write mělo něco zapsat nebo skončit chybou.

Zapsání nula bytes chyba je a OS by měl vrátit důvod, proč k tomu došlo. Podobné je to u interrupted by signal - pokud se aspoň jeden byte zapsal, vrací délku zapsaných dat, v opačném případě vrátí chybu EINTR. Návratová hodnota "nic se nepovedlo, ale neřeknu proč" není hodna implementace slušného OS. Jak jsem psal výše, něco takového by vedlo k busy loop a nesmyslnému aplikačnímu kódu. write() může skončit úspěšně i v případě předchozí chyby, proto tam ty chybové kódy jsou, aby se aplikace mohla rozhodnout, co má zkusit znovu a jak (EAGAIN, EINTR, ENOSPC).

Na druhé straně je třeba říct, že dokumentace (citace je z Linux man page, nikoliv POSIX specifikace) by mohla být napsaná jasněji, že jde o speciální případ prázdných dat (které můžou mít u speciálních file descriptors zvláštní význam - například EOF).