/usr/share/doc/cockpit/guide/cockpit-file.html is in cockpit-doc 164-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>cockpit.js: File Access</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="index.html" title="Cockpit Guide">
<link rel="up" href="api-base1.html" title="API: base1">
<link rel="prev" href="cockpit-dbus.html" title="cockpit.js: DBus Client">
<link rel="next" href="cockpit-http.html" title="cockpit.js: HTTP Client">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2"><tr valign="middle">
<td><a accesskey="p" href="cockpit-dbus.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
<td><a accesskey="u" href="api-base1.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">Cockpit Guide</th>
<td><a accesskey="n" href="cockpit-http.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
</tr></table>
<div class="refentry">
<a name="cockpit-file"></a><div class="titlepage"></div>
<div class="refnamediv"><table width="100%"><tr>
<td valign="top">
<h2>cockpit.js: File Access</h2>
<p>cockpit.js: File Access — Reading, writing, and watching files.</p>
</td>
<td valign="top" align="right"></td>
</tr></table></div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
<p>The <code class="code">cockpit.file</code> API lets you read, write, and watch regular files in their entirety.
It cannot efficiently do random access in a big file or read non-regular files such as
<code class="code">/dev/random</code>.
</p>
<pre class="programlisting">
file = cockpit.file(path,
{ syntax: syntax_object,
binary: boolean,
max_read_size: int,
superuser: string,
host: string
})
promise = file.read()
promise
.done(function (content, tag) { ... })
.fail(function (error) { ... })
promise = file.replace(content, [ expected_tag ])
promise
.done(function (new_tag) { ... })
.fail(function (error) { ... })
promise = file.modify(callback, [ initial_content, initial_tag ]
promise
.done(function (new_content, new_tag) { ... })
.fail(function (error) { ... })
file.watch(function (content, tag, [error]) { })
file.close()
</pre>
</div>
<div class="refsection">
<a name="cockpit-file-simple"></a><h2>Simple reading and writing</h2>
<p>You can read a file with code like this:</p>
<pre class="programlisting">
cockpit.file("/path/to/file").read()
.done(function (content, tag) {
...
})
.fail(function (error) {
...
});
</pre>
<p>The <code class="code">read()</code> method returns a
<a class="ulink" href="https://www.promisejs.org/" target="_top">promise</a>.</p>
<p>When successful, the promise will be resolved with the content of the
file. Unless you specify options to change this (see below), the file
is assumed to be text in the UTF-8 encoding, and <code class="code">content</code>
will be a string.</p>
<p>The tag that is passed to the <code class="code">done()</code> callback is a short
string that is associated with the file and changes whenever the
content of the file changes. It is meant to be used with <code class="code">replace()</code>.</p>
<p>It is not an error when the file does not exist. In this case, the
<code class="code">done()</code> callback will be called with a <code class="code">null</code>
value for <code class="code">content</code> and <code class="code">tag</code> is <code class="code">"-"</code>.</p>
<p>The <code class="code">superuser</code> and <code class="code">host</code> options can be used the same way
as described in the <a class="link" href="cockpit-channels.html#cockpit-channels-channel" title="cockpit.channel()">cockpit.channel()</a>
to provide a different access level to the file.</p>
<p>You can use the <code class="code">max_read_size</code> option to limit
the amount of data that is read. If the file is larger than the
given limit, no data is read and the channel is closed with
problem code <code class="code">too-large</code>. The default limit is 16 MiB.</p>
<p>To write to a file, use code like this:
</p>
<pre class="programlisting">
cockpit.file("/path/to/file").replace("my new content\n")
.done(function (tag) {
...
})
.fail(function (error) {
...
});
</pre>
<p>
</p>
<p>The <code class="code">replace()</code> method returns a
<a class="ulink" href="https://www.promisejs.org/" target="_top">promise</a>.</p>
<p>When the promise is resolved, the file has been atomically replaced
(via the <code class="code">rename()</code> syscall) with the new content. As with
<code class="code">read()</code>, by default the new content is a string and will
be written to the file as UTF-8. The returned tag corresponds to the
new content of the file.</p>
<p>When the promise is rejected because of an error, the file or its meta
data has not been changed in any way.</p>
<p>As a special case, passing the value <code class="code">null</code> to
<code class="code">replace()</code> will remove the file.</p>
<p>The <code class="code">replace()</code> method can also check for conflicting
changes to a file. You can pass a tag (as returned by
<code class="code">read()</code> or <code class="code">replace()</code>) to
<code class="code">replace()</code>, and the file will only be replaced if it still
has the given tag. If the tag of the file has changed,
<code class="code">replace()</code> will fail with an error object that has
<code class="code">error.problem == "change-conflict"</code>. See
<code class="code">modify()</code> below for a convenient way to achieve
transactional updates to a file.</p>
</div>
<div class="refsection">
<a name="cockpit-file-format"></a><h2>File format</h2>
<p>By default, a file is assumed to be text encoded in UTF-8, and the
<code class="code">read()</code> and <code class="code">replace()</code> functions use strings to
represent the content.</p>
<p>By specifying the <code class="code">syntax.parser()</code> and
<code class="code">syntax.stringify()</code> options, you can cause
<code class="code">read()</code> to parse the content before passing it back to
you, and <code class="code">replace()</code> to unparse it before writing.</p>
<p>The main idea is to be able to write <code class="code">{ syntax: JSON }</code>, of
course, but you can easily pass in individual functions or make your
own parser/unparser object:
</p>
<pre class="programlisting">
cockpit.file("/path/to/file.json", { syntax: JSON })
var syntax_object = {
parse: my_parser,
stringify: my_unparser
};
cockpit.file("/path/to/file", { syntax: syntax_object })
</pre>
<p>
Any exceptions thrown by the <code class="code">parse()</code> and
<code class="code">stringify()</code> functions are caught and reported as read or
write errors.</p>
<p>The <code class="code">null</code> value that is used to represent the content of a
non-existing file (see "Simple reading and writing", above) is not
passed through the <code class="code">parse()</code> and <code class="code">stringify()</code>
functions.</p>
</div>
<div class="refsection">
<a name="cockpit-file-binary"></a><h2>Binary files</h2>
<p>By default the content of the file is assumed to be text encoded as
UTF-8 and it can not contain zero bytes. The content is represented
as a JavaScript string with <code class="code">read()</code>,
<code class="code">replace()</code>, etc. By setting the <code class="code">binary</code> option
to true when creating the proxy, no assumptions are placed on the
content, and it is represented as a <code class="code">Uint8Array</code> in
JavaScript.</p>
</div>
<div class="refsection">
<a name="cockpit-file-atomic"></a><h2>Atomic modifications</h2>
<p>Use <code class="code">modify()</code> to modify the content of the file safely. A
call to <code class="code">modify()</code> will read the content of the file, call
<code class="code">callback</code> on the content, and then replace the content of
the file with the return value of the callback.</p>
<p>The <code class="code">modify()</code> method uses the <code class="code">read()</code> and
<code class="code">replace()</code> methods internally in the obvious way. Thus,
the <code class="code">syntax.parse()</code> and <code class="code">syntax.stringify()</code>
options work as expected, <code class="code">null</code> represents a non-existing
file, and the watch callbacks are fired.</p>
<p>It will do this one or more times, until no other conflicting changes
have been made to the file between reading and replacing it.</p>
<p>The callback is called like this
</p>
<pre class="programlisting">
new_content = callback (old_content)
</pre>
<p>
The callback is allowed to mutate <code class="code">old_content</code>, but note
that this will also mutate the objects that are passed to the watch
callbacks. Returning <code class="code">undefined</code> from the proxy is the
same as returning <code class="code">old_content</code>.</p>
<p>The <code class="code">modify()</code> method returns a
<a class="ulink" href="https://www.promisejs.org/" target="_top">promise</a>.</p>
<p>The promise will be resolved with the new content and its tag, like so
</p>
<pre class="programlisting">
function shout(old_content) {
return old_content.toUpperCase();
}
cockpit.file("/path/to/file").modify(shout)
.done(function (content, tag) {
...
})
.fail(function (error) {
...
});
</pre>
<p>
If you have cached the last content and tag results of the
<code class="code">read()</code> or <code class="code">modify()</code> method, or the last
values passed to a watch callback, you can pass them to
<code class="code">modify()</code> as the second and third argument. In this case,
<code class="code">modify()</code> will skip the initial read and start with the
given values.</p>
</div>
<div class="refsection">
<a name="cockpit-file-notify"></a><h2>Change notifications</h2>
<p>Calling <code class="code">watch()</code> will start monitoring the file for
external changes.
</p>
<pre class="programlisting">
handle = file.watch(callback);
</pre>
<p>
Whenever a change occurs, the <code class="code">callback()</code> is called with
the new content and tag of the file. This might happen because of
external changes, but also as part of calls to <code class="code">read()</code>,
<code class="code">replace()</code>, and <code class="code">modify()</code>.</p>
<p>When a read error occurs, the <code class="code">callback()</code> is called with
an error as a third argument. Write errors are not reported via the watch callback.</p>
<p>Calling <code class="code">watch()</code> will also automatically call
<code class="code">read()</code> to get the initial content of the file.</p>
<p>Thus, you normally don't need to call <code class="code">read()</code> at all when
using <code class="code">watch()</code>.</p>
<p>To free the resources used for monitoring, call <code class="code">handle.remove()</code>.</p>
</div>
<div class="refsection">
<a name="cockpit-file-path"></a><h2>file.path</h2>
<p>A string containing the path that was passed to the <code class="code">cockpit.file()</code>
method.</p>
</div>
<div class="refsection">
<a name="cockpit-file-close"></a><h2>Closing</h2>
<p>Call the <code class="code">close()</code> method on a file proxy to cancel all
ongoing operations, such as reading, writing, and monitoring. The
proxy should not be used after closing it.</p>
</div>
</div>
<div class="footer"><hr></div>
</body>
</html>
|