<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2003/XInclude" type="topic" id="file-system" xml:lang="cs">

  <info>
    <link type="guide" xref="index#specific-how-tos"/>

    <credit type="author copyright">
      <name>Philip Withnall</name>
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
      <years>2015</years>
    </credit>

    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>

    <desc>Jak přistupovat k souborovému systému</desc>
  </info>

  <title>Přístup k souborovému systému</title>

  <synopsis>
    <title>Shrnutí</title>

    <p>Při přístupu k souborovému systému byste měli mít na paměti několik negativních návrhových vzorů. Tento článek předpokládá znalost standardních API <link href="https://developer.gnome.org/gio/stable/GFile.html"><code>GFile</code></link>, <link href="https://developer.gnome.org/gio/stable/GInputStream.html"><code>GInputStream</code></link> a <link href="https://developer.gnome.org/gio/stable/GOutputStream.html"><code>GOutputStream</code></link>.</p>

    <list>
      <item><p>Pro přístup k souborům používejte asynchronní V/V. (<link xref="#asynchronous-io"/>)</p></item>
      <item><p>Vždy používejte vhodné funkce k vytvoření názvů souborů a cest. (<link xref="#file-path-construction"/>)</p></item>
      <item><p>Než použijete cestu k souboru, ověřte, že se nachází v očekávané složce. (<link xref="#path-validation-and-sandboxing"/>)</p></item>
      <item><p>Používejte povinné profily pro řízení přístupu, aby se zaručily omezení v přístupu k souborům. (<link xref="#path-validation-and-sandboxing"/>)</p></item>
    </list>
  </synopsis>

  <section id="asynchronous-io">
    <title>Asynchronní V/V</title>

    <p>Většina V/V operací by měla být prováděna asynchronně. Což znamená bez blokování <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html">hlavního kontextu GLib</link>. Toho lze dosáhnout důsledným používáním variant <code>*_async()</code> a <code>*_finish()</code> jednotlivých V/V funkcí.</p>

    <example>
      <p>Například použijte <link href="https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-async"><code>g_input_stream_read_async()</code></link> a ne <link href="https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read"><code>g_input_stream_read()</code></link>.</p>
    </example>

    <p>Synchronní V/V operace blokují hlavní smyčku, což znamená, že ostatní události, jako je vstup od uživatele, příchozí síťový paket, vypršení časového limitu a zpětné volání při nečinnosti, nejsou obsluhovány, dokud nedojde k návratu z blokující funkce.</p>

    <p>Synchronní V/V je přijatelný za určitých okolností, kdy náklady na plánování asynchronní operace převýší cenu místního synchronního V/V v Linuxu. Například provedení drobného čtení z místního souborového systému nebo z virtuálního souborového systému, jako je <file>/proc</file>. Při takovém čtení by měly být použity raději nízkoúrovňové funkce <code>g_open()</code>, <code>read()</code> a <code>g_close()</code> místo GIO.</p>

    <p>Soubory v uživatelově domovské složce se <em>nepočítají</em> jako místní, protože mohou být na síťovém souborovém systému.</p>

    <p>Upozorňujeme, že alternativa – běh synchronního V/V v odděleném vlákně – je silně nedoporučován. Více informací viz <link xref="threading#when-to-use-threading">pokyny k vláknům</link>.</p>
  </section>

  <section id="file-path-construction">
    <title>Sestavení cesty k souboru</title>

    <p>Názvy souborů a cesty nejsou běžné řetězce: na některých systémech mohou používat jiné kódování znaků, než UTF-8, zatímco u normálních řetězců je v GLib vždy zaručeno použití UTF-8. Z tohoto důvodu by pro sestavení a zpracování názvů souborů a cest měly používat speciální funkce. (Moderní linuxové systémy povětšinou pro kódování názvů souborů jednotně používají UTF-8, takže to v praxi není problém, ale tyto funkce by měly být přesto používány kvůli kompatibilitě s jinými systéme, jako jsou Windows používající v názvech souborů UTF-16.)</p>

    <example>
      <p>Například cesta k souboru by se měla sestavit pomocí <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-build-filename"><code>g_build_filename()</code></link> namísto běžného <link href="https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strconcat"><code>g_strconcat()</code></link>.</p>
    </example>

    <p>Když se to dělá takto, je v kódu jasnější, co se tím míní a také se tím zamezí zdvojení oddělovačů cest a vrácená cesta je kanonická (i když ne nutně absolutně).</p>

    <example>
      <p>Jiným příkladem by mohlo být rozložení cesty pomocí <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-basename"><code>g_path_get_basename()</code></link> a <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-dirname"><code>g_path_get_dirname()</code></link> namísto běžného <link href="https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strrstr"><code>g_strrstr()</code></link> nebo jiných ručních vyhledávacích funkcí.</p>
    </example>
  </section>

  <section id="path-validation-and-sandboxing">
    <title>Ověřování cest a pískoviště</title>

    <p>Když název souboru nebo cesta pochází z externího vstupu, jako je webová stránka nebo uživatelský vstup, měly by být ověřeny, aby se zajistilo, že jejich vložení do cesty nevytvoří jen tak nějakou cestu. Například, když je název souboru sestavován z řetězce <file>~/</file> plus uživatelského vstupu a uživatel zadá <file>../../etc/passwd</file>, mohl by (potenciálně) získat přístup k citlivým informacím o účtech, v závislosti na tom, pod jakým účtem program běží a co dělá s daty načtenými ze sestavené cesty.</p>

    <p>Tomu se dá předejít ověřováním sestavené cesty před tím, než ji použijete, pomocí funkce <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-resolve-relative-path"><code>g_file_resolve_relative_path()</code></link>, která převede relativní cesty na absolutní a následně ověří, že cesta je pod danou kořenovou složku pískoviště příslušejícího operaci. Například, když kód stahuje soubor, mohl by pomocí <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-has-parent"><code>g_file_has_parent()</code></link> ověřovat, že jsou všechny cesty pod <file>~/Downloads</file>.</p>

    <p>Jako druhou linii obrany by všechny projekty, které přistupují k souborovému systému, měly zvážit poskytnutí povinného profilu pro řízení přístupu za použití systému jako jsou <link href="http://apparmor.net/">AppArmor</link> nebo <link href="http://selinuxproject.org/">SELinux</link>, čímž se omezí složky a soubory, které lze číst a zapisovat do nich.</p>
  </section>
</page>
