Remove iflag argument to xs_write

xs_write with O_CREAT|O_EXCL causes problems over daemon restarts, since
it's not idempotent.
It turns out noone really needs the flags word at all, so get rid of it.
It's now as if everyone specified "O_CREAT".
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
This commit is contained in:
cl349@firebug.cl.cam.ac.uk committed 2005-09-19 14:34:30 +00:00
1 parent 265d719ce5
commit 7fd9bccce2
29 files changed
+137 -293

No files matched your search

+1 -1
View File
@@ -92,7 +92,7 @@ int xs_printf(struct xs_handle *h, const char *dir, const char *node,
if ((path == NULL) || (buf == NULL))
return 0;
ret = xs_write(h, path, buf, strlen(buf)+1, O_CREAT);
ret = xs_write(h, path, buf, strlen(buf)+1);
free(buf);
free(path);
+1 -1
View File
@@ -165,7 +165,7 @@ static int domain_create_tty(struct domain *dom)
success = asprintf(&path, "%s/tty", dom->conspath) != -1;
if (!success)
goto out;
success = xs_write(xs, path, slave, strlen(slave), O_CREAT);
success = xs_write(xs, path, slave, strlen(slave));
free(path);
if (!success)
goto out;
+4 -13
View File
@@ -116,8 +116,6 @@ static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
"Write data to a path.\n" \
" path [string] : xenstore path to write to\n." \
" data [string] : data to write.\n" \
" create [int] : create flag, default 0.\n" \
" excl [int] : exclusive flag, default 0.\n" \
"\n" \
"Returns None on success.\n" \
"Raises RuntimeError on error.\n" \
@@ -125,30 +123,23 @@ static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwd_spec[] = { "path", "data", "create", "excl", NULL };
static char *arg_spec = "ss#|ii";
static char *kwd_spec[] = { "path", "data", NULL };
static char *arg_spec = "ss#";
char *path = NULL;
char *data = NULL;
int data_n = 0;
int create = 0;
int excl = 0;
struct xs_handle *xh = xshandle(self);
PyObject *val = NULL;
int flags = 0;
int xsval = 0;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&path, &data, &data_n, &create, &excl))
&path, &data, &data_n))
goto exit;
if (create)
flags |= O_CREAT;
if (excl)
flags |= O_EXCL;
Py_BEGIN_ALLOW_THREADS
xsval = xs_write(xh, path, data, data_n, flags);
xsval = xs_write(xh, path, data, data_n);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
+5 -6
View File
@@ -255,7 +255,7 @@ class XenStore:
if x == "": continue
p = os.path.join(p, x)
if not self.exists(p):
self.getxs().write(p, "", create=True)
self.getxs().write(p, "")
def read(self, path):
try:
@@ -266,13 +266,12 @@ class XenStore:
else:
raise
def create(self, path, excl=False):
self.write(path, "", create=True, excl=excl)
def create(self, path):
self.write(path, "")
def write(self, path, data, create=True, excl=False):
self.mkdirs(path)
def write(self, path, data):
try:
self.getxs().write(path, data, create=create, excl=excl)
self.getxs().write(path, data)
except Exception, ex:
raise
+5 -8
View File
@@ -53,13 +53,11 @@ class xstransact:
ret.append(self._read(key))
return ret
def _write(self, key, data, create=True, excl=False):
def _write(self, key, data):
path = "%s/%s" % (self.path, key)
xshandle().write(path, data, create=create, excl=excl)
xshandle().write(path, data)
def write(self, *args, **opts):
create = opts.get('create') or True
excl = opts.get('excl') or False
if len(args) == 0:
raise TypeError
if isinstance(args[0], dict):
@@ -68,19 +66,18 @@ class xstransact:
raise TypeError
for key in d.keys():
try:
self._write(key, d[key], create, excl)
self._write(key, d[key])
except TypeError, msg:
raise TypeError('Writing %s: %s: %s' %
(key, str(d[key]), msg))
elif isinstance(args[0], list):
for l in args:
if not len(l) == 2:
raise TypeError
self._write(l[0], l[1], create, excl)
self._write(l[0], l[1])
elif len(args) % 2 == 0:
for i in range(len(args) / 2):
self._write(args[i * 2], args[i * 2 + 1], create, excl)
self._write(args[i * 2], args[i * 2 + 1])
else:
raise TypeError
+1 -1
View File
@@ -1,4 +1,4 @@
# Create an entry, read it.
write /test create contents
write /test contents
expect contents
read /test
+2 -2
View File
@@ -3,7 +3,7 @@ expect tool
dir /
# Create a file.
write /test create contents
write /test contents
# Directory shows it.
expect test
@@ -21,7 +21,7 @@ dir /
dir /dir
# Create a file, check it exists.
write /dir/test2 create contents2
write /dir/test2 contents2
expect test2
dir /dir
expect contents2
+6 -17
View File
@@ -1,31 +1,20 @@
# Write without create fails.
expect write failed: No such file or directory
write /test none contents
# Exclusive write succeeds
write /test excl contents
# Write succeeds
write /test contents
expect contents
read /test
# Exclusive write fails to overwrite.
expect write failed: File exists
write /test excl contents
# Non-exclusive overwrite succeeds.
write /test none contents2
# Overwrite succeeds.
write /test contents2
expect contents2
read /test
write /test create contents3
expect contents3
read /test
# Write should implicitly create directories
write /dir/test create contents
write /dir/test contents
expect test
dir /dir
expect contents
read /dir/test
write /dir/1/2/3/4 excl contents4
write /dir/1/2/3/4 contents4
expect test
expect 1
dir /dir
+2 -2
View File
@@ -4,7 +4,7 @@ expect rm failed: No such file or directory
rm /dir/test
# Create file and remove it
write /test excl contents
write /test contents
rm /test
# Create directory and remove it.
@@ -13,5 +13,5 @@ rm /dir
# Create directory, create file, remove all.
mkdir /dir
write /dir/test excl contents
write /dir/test contents
rm /dir
@@ -5,7 +5,7 @@ expect getperm failed: No such file or directory
getperm /dir/test
# Create file: inherits from root (0 READ)
write /test excl contents
write /test contents
expect 0 READ
getperm /test
setid 1
@@ -14,7 +14,7 @@ getperm /test
expect contents
read /test
expect write failed: Permission denied
write /test none contents
write /test contents
# Take away read access to file.
setid 0
@@ -25,7 +25,7 @@ getperm /test
expect read failed: Permission denied
read /test
expect write failed: Permission denied
write /test none contents
write /test contents
# Grant everyone write access to file.
setid 0
@@ -35,7 +35,7 @@ expect getperm failed: Permission denied
getperm /test
expect read failed: Permission denied
read /test
write /test none contents2
write /test contents2
setid 0
expect contents2
read /test
@@ -47,7 +47,7 @@ expect 0 READ/WRITE
getperm /test
expect contents2
read /test
write /test none contents3
write /test contents3
expect contents3
read /test
@@ -59,7 +59,7 @@ expect 1 NONE
getperm /test
expect contents3
read /test
write /test none contents4
write /test contents4
# User 2 can do nothing.
setid 2
@@ -70,7 +70,7 @@ getperm /test
expect read failed: Permission denied
read /test
expect write failed: Permission denied
write /test none contents4
write /test contents4
# Tools can always access things.
setid 0
@@ -78,4 +78,4 @@ expect 1 NONE
getperm /test
expect contents4
read /test
write /test none contents5
write /test contents5
+11 -19
View File
@@ -11,7 +11,7 @@ expect 0 READ
getperm /dir
dir /dir
expect write failed: Permission denied
write /dir/test create contents2
write /dir/test contents2
# Remove everyone's read access to directoy.
setid 0
@@ -22,7 +22,7 @@ dir /dir
expect read failed: Permission denied
read /dir/test create contents2
expect write failed: Permission denied
write /dir/test create contents2
write /dir/test contents2
# Grant everyone write access to directory.
setid 0
@@ -32,7 +32,7 @@ expect getperm failed: Permission denied
getperm /dir
expect dir failed: Permission denied
dir /dir
write /dir/test create contents
write /dir/test contents
setid 0
expect 1 WRITE
getperm /dir/test
@@ -47,7 +47,7 @@ expect 0 READ/WRITE
getperm /dir
expect test
dir /dir
write /dir/test2 create contents
write /dir/test2 contents
expect contents
read /dir/test2
setperm /dir/test2 1 NONE
@@ -60,7 +60,7 @@ getperm /dir
expect test
expect test2
dir /dir
write /dir/test3 create contents
write /dir/test3 contents
# User 2 can do nothing. Can't even tell if file exists.
setid 2
@@ -79,17 +79,9 @@ read /dir/test3
expect read failed: Permission denied
read /dir/test4
expect write failed: Permission denied
write /dir/test none contents
write /dir/test contents
expect write failed: Permission denied
write /dir/test create contents
expect write failed: Permission denied
write /dir/test excl contents
expect write failed: Permission denied
write /dir/test4 none contents
expect write failed: Permission denied
write /dir/test4 create contents
expect write failed: Permission denied
write /dir/test4 excl contents
write /dir/test4 contents
# Tools can always access things.
setid 0
@@ -99,13 +91,13 @@ expect test
expect test2
expect test3
dir /dir
write /dir/test4 create contents
write /dir/test4 contents
# Inherited by child.
mkdir /dir/subdir
expect 1 NONE
getperm /dir/subdir
write /dir/subfile excl contents
write /dir/subfile contents
expect 1 NONE
getperm /dir/subfile
@@ -114,12 +106,12 @@ setperm /dir/subdir 2 READ/WRITE
expect 2 READ/WRITE
getperm /dir/subdir
setid 3
write /dir/subdir/subfile excl contents
write /dir/subdir/subfile contents
expect 3 READ/WRITE
getperm /dir/subdir/subfile
# Inheritence works through multiple directories, too.
write /dir/subdir/1/2/3/4 excl contents
write /dir/subdir/1/2/3/4 contents
expect 3 READ/WRITE
getperm /dir/subdir/1/2/3/4
mkdir /dir/subdir/a/b/c/d
+18 -18
View File
@@ -1,8 +1,8 @@
# Watch something, write to it, check watch has fired.
write /test create contents
write /test contents
1 watch /test token
2 write /test create contents2
2 write /test contents2
expect 1:/test:token
1 waitwatch
1 ackwatch token
@@ -44,7 +44,7 @@ expect 1:/dir/newdir:token
# ignore watches while doing commands, should work.
watch /dir token
1 write /dir/test create contents
1 write /dir/test contents
expect contents
read /dir/test
expect /dir/test:token
@@ -56,7 +56,7 @@ close
1 watch /dir token1
3 watch /dir token3
2 watch /dir token2
write /dir/test create contents
write /dir/test contents
expect 3:/dir/test:token3
3 waitwatch
3 ackwatch token3
@@ -73,7 +73,7 @@ expect 1:/dir/test:token1
# If one dies (without acking), the other should still get ack.
1 watch /dir token1
2 watch /dir token2
write /dir/test create contents
write /dir/test contents
expect 2:/dir/test:token2
2 waitwatch
2 close
@@ -85,7 +85,7 @@ expect 1:/dir/test:token1
# If one dies (without reading at all), the other should still get ack.
1 watch /dir token1
2 watch /dir token2
write /dir/test create contents
write /dir/test contents
2 close
expect 1:/dir/test:token1
1 waitwatch
@@ -97,7 +97,7 @@ expect 1:/dir/test:token1
1 watch /dir token1
1 unwatch /dir token1
1 watch /dir token2
2 write /dir/test2 create contents
2 write /dir/test2 contents
expect 1:/dir/test2:token2
1 waitwatch
1 unwatch /dir token2
@@ -107,7 +107,7 @@ expect 1:/dir/test2:token2
# unwatch while watch pending. Other watcher still gets the event.
1 watch /dir token1
2 watch /dir token2
write /dir/test create contents
write /dir/test contents
2 unwatch /dir token2
expect 1:/dir/test:token1
1 waitwatch
@@ -117,17 +117,17 @@ expect 1:/dir/test:token1
# unwatch while watch pending. Should clear this so we get next event.
1 watch /dir token1
write /dir/test create contents
write /dir/test contents
1 unwatch /dir token1
1 watch /dir/test token2
write /dir/test none contents2
write /dir/test contents2
expect 1:/dir/test:token2
1 waitwatch
1 ackwatch token2
# check we only get notified once.
1 watch /test token
2 write /test create contents2
2 write /test contents2
expect 1:/test:token
1 waitwatch
1 ackwatch token
@@ -137,9 +137,9 @@ expect 1: waitwatch failed: Connection timed out
# watches are queued in order.
1 watch / token
2 write /test1 create contents
2 write /test2 create contents
2 write /test3 create contents
2 write /test1 contents
2 write /test2 contents
2 write /test3 contents
expect 1:/test1:token
1 waitwatch
1 ackwatch token
@@ -153,8 +153,8 @@ expect 1:/test3:token
# Creation of subpaths should be covered correctly.
1 watch / token
2 write /test/subnode create contents2
2 write /test/subnode/subnode create contents2
2 write /test/subnode contents2
2 write /test/subnode/subnode contents2
expect 1:/test/subnode:token
1 waitwatch
1 ackwatch token
@@ -167,7 +167,7 @@ expect 1: waitwatch failed: Connection timed out
# Watch event must have happened before we registered interest.
1 watch / token
2 write /test/subnode create contents2
2 write /test/subnode contents2
1 watch / token2 0
expect 1:/test/subnode:token
1 waitwatch
@@ -185,7 +185,7 @@ expect 1:/test/subnode:token
# Watch should not double-send after we ack, even if we did something in between.
1 watch /test2 token
2 write /test2/foo create contents2
2 write /test2/foo contents2
expect 1:/test2/foo:token
1 waitwatch
expect 1:contents2
@@ -1,7 +1,7 @@
# Test transaction timeouts. Take a second each.
mkdir /test
write /test/entry1 create contents
write /test/entry1 contents
# Transactions can take as long as the want...
start /test
+6 -6
View File
@@ -4,7 +4,7 @@ mkdir /test
# Simple transaction: create a file inside transaction.
1 start /test
1 write /test/entry1 create contents
1 write /test/entry1 contents
2 dir /test
expect 1:entry1
1 dir /test
@@ -16,14 +16,14 @@ rm /test/entry1
# Create a file and abort transaction.
1 start /test
1 write /test/entry1 create contents
1 write /test/entry1 contents
2 dir /test
expect 1:entry1
1 dir /test
1 abort
2 dir /test
write /test/entry1 create contents
write /test/entry1 contents
# Delete in transaction, commit
1 start /test
1 rm /test/entry1
@@ -34,7 +34,7 @@ expect 2:entry1
2 dir /test
# Delete in transaction, abort.
write /test/entry1 create contents
write /test/entry1 contents
1 start /test
1 rm /test/entry1
expect 2:entry1
@@ -84,8 +84,8 @@ expect 1:/test/dir/sub:token
# Multiple events from single transaction don't trigger assert
1 watch /test token
2 start /test
2 write /test/1 create contents
2 write /test/2 create contents
2 write /test/1 contents
2 write /test/2 contents
2 commit
expect 1:/test/1:token
1 waitwatch
+1 -1
View File
@@ -3,7 +3,7 @@
# Create a domain, write an entry.
expect handle is 1
introduce 1 100 7 /my/home
1 write /entry1 create contents
1 write /entry1 contents
expect entry1
expect tool
dir /
@@ -4,7 +4,7 @@
mkdir /home
expect handle is 1
introduce 1 100 7 /home
1 write entry1 create contents
1 write entry1 contents
expect contents
read /home/entry1
expect entry1
@@ -13,7 +13,7 @@ dir /home
# Place a watch using a relative path: expect relative answer.
1 mkdir foo
1 watch foo token
write /home/foo/bar create contents
write /home/foo/bar contents
expect 1:foo/bar:token
1 waitwatch
1 ackwatch token
+8 -8
View File
@@ -1,13 +1,13 @@
# Test watching from a domain.
# Watch something, write to it, check watch has fired.
write /test create contents
write /test contents
mkdir /dir
expect handle is 1
introduce 1 100 7 /my/home
1 watch /test token
write /test create contents2
write /test contents2
expect 1:/test:token
1 waitwatch
1 ackwatch token
@@ -19,10 +19,10 @@ release 1
expect handle is 1
introduce 1 100 7 /my/home
1 watch /dir token
write /dir/test create contents
1 write /dir/test2 create contents2
1 write /dir/test3 create contents3
1 write /dir/test4 create contents4
write /dir/test contents
1 write /dir/test2 contents2
1 write /dir/test3 contents3
1 write /dir/test4 contents4
expect 1:/dir/test:token
1 waitwatch
1 ackwatch token
@@ -35,7 +35,7 @@ introduce 1 100 7 /my/home
1 watch /dir token1
1 unwatch /dir token1
1 watch /dir token2
write /dir/test2 create contents
write /dir/test2 contents
expect 1:/dir/test2:token2
1 waitwatch
1 unwatch /dir token2
@@ -46,7 +46,7 @@ release 1
expect handle is 1
introduce 1 100 7 /my/home
1 watch /dir token1
write /dir/test2 create contents
write /dir/test2 contents
1 unwatch /dir token1
release 1
1 close
+4 -4
View File
@@ -1,6 +1,6 @@
# Test that read only connection can't alter store.
write /test create contents
write /test contents
readonly
expect test
@@ -20,9 +20,9 @@ abort
# These don't work
expect write failed: Read-only file system
write /test2 create contents
write /test2 contents
expect write failed: Read-only file system
write /test create contents
write /test contents
expect setperm failed: Read-only file system
setperm /test 100 NONE
expect setperm failed: Read-only file system
@@ -35,7 +35,7 @@ introduce 1 100 7 /home
# Check that watches work like normal.
watch / token
1 readwrite
1 write /test create contents
1 write /test contents
expect /test:token
waitwatch
ackwatch token
+3 -3
View File
@@ -13,10 +13,10 @@ mkdir /test/3
1 watch /test/1 token1
1 watch /test/2 token2
1 watch /test/3 token3
2 write /test/2 create contents2
2 write /test/2 contents2
expect 1:/test/2:token2
1 waitwatch
3 write /test/1 create contents1
4 write /test/3 create contents3
3 write /test/1 contents1
4 write /test/3 contents3
1 ackwatch token2
1 close
+5 -17
View File
@@ -12,13 +12,7 @@ dir /dir/file
expect *Permission denied
read /dir/file
expect *Permission denied
write /dir/file none value
expect *Permission denied
write /dir/file create value
expect *Permission denied
write /dir/file excl value
expect write failed: Invalid argument
write /dir/file crap value
write /dir/file value
expect *Permission denied
mkdir /dir/file
expect *Permission denied
@@ -30,7 +24,7 @@ getperm /dir/file
expect *Permission denied
setperm /dir/file 0 NONE
watch /dir/file token
1 write /dir/file create contents
1 write /dir/file contents
1 rm /dir/file
expect waitwatch failed: Connection timed out
waitwatch
@@ -50,7 +44,7 @@ introduce 2 100 7 /dir/file
# Now it exists
setid 0
write /dir/file create contents
write /dir/file contents
setid 1
expect *Permission denied
@@ -58,13 +52,7 @@ dir /dir/file
expect *Permission denied
read /dir/file
expect *Permission denied
write /dir/file none value
expect *Permission denied
write /dir/file create value
expect *Permission denied
write /dir/file excl value
expect write failed: Invalid argument
write /dir/file crap value
write /dir/file value
expect *Permission denied
mkdir /dir/file
expect *Permission denied
@@ -76,7 +64,7 @@ getperm /dir/file
expect *Permission denied
setperm /dir/file 0 NONE
watch /dir/file token
1 write /dir/file create contents
1 write /dir/file contents
1 rm /dir/file
expect waitwatch failed: Connection timed out
waitwatch
+10 -10
View File
@@ -1,10 +1,10 @@
# If we don't wait for an ack, we can crash daemon as it never expects to be
# sending out two replies on top of each other.
noackwrite /1 create 1
noackwrite /2 create 2
noackwrite /3 create 3
noackwrite /4 create 4
noackwrite /5 create 5
noackwrite /1 1
noackwrite /2 2
noackwrite /3 3
noackwrite /4 4
noackwrite /5 5
readack
readack
readack
@@ -13,11 +13,11 @@ readack
expect handle is 1
introduce 1 100 7 /my/home
1 noackwrite /1 create 1
1 noackwrite /2 create 2
1 noackwrite /3 create 3
1 noackwrite /4 create 4
1 noackwrite /5 create 5
1 noackwrite /1 1
1 noackwrite /2 2
1 noackwrite /3 3
1 noackwrite /4 4
1 noackwrite /5 5
1 readack
1 readack
1 readack
@@ -4,8 +4,8 @@ mkdir /test
watch /test token
1 start /test
# This will block on above
noackwrite /test/entry create contents
1 write /test/entry2 create contents
noackwrite /test/entry contents
1 write /test/entry2 contents
1 commit
readack
expect /test/entry2:token
+5 -29
View File
@@ -968,14 +968,12 @@ static bool node_exists(struct connection *conn, const char *node)
return lstat(node_dir(conn->transaction, node), &st) == 0;
}
/* path, flags, data... */
/* path, data... */
static void do_write(struct connection *conn, struct buffered_data *in)
{
unsigned int offset, datalen;
char *vec[2];
char *vec[1] = { NULL }; /* gcc4 + -W + -Werror fucks code. */
char *node, *tmppath;
enum xs_perm_type mode;
struct stat st;
/* Extra "strings" can be created by binary data. */
if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
@@ -992,26 +990,15 @@ static void do_write(struct connection *conn, struct buffered_data *in)
if (transaction_block(conn, node))
return;
offset = strlen(vec[0]) + strlen(vec[1]) + 2;
offset = strlen(vec[0]) + 1;
datalen = in->used - offset;
if (streq(vec[1], XS_WRITE_NONE))
mode = XS_PERM_WRITE;
else if (streq(vec[1], XS_WRITE_CREATE))
mode = XS_PERM_WRITE|XS_PERM_ENOENT_OK;
else if (streq(vec[1], XS_WRITE_CREATE_EXCL))
mode = XS_PERM_WRITE|XS_PERM_ENOENT_OK;
else {
send_error(conn, EINVAL);
return;
}
if (!check_node_perms(conn, node, mode)) {
if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_ENOENT_OK)) {
send_error(conn, errno);
return;
}
if (lstat(node_dir(conn->transaction, node), &st) != 0) {
if (!node_exists(conn, node)) {
char *dir;
/* Does not exist... */
@@ -1020,12 +1007,6 @@ static void do_write(struct connection *conn, struct buffered_data *in)
return;
}
/* Not going to create it? */
if (streq(vec[1], XS_WRITE_NONE)) {
send_error(conn, ENOENT);
return;
}
dir = tempdir(conn, node, in->buffer + offset, datalen);
if (!dir || !commit_dir(dir)) {
send_error(conn, errno);
@@ -1034,11 +1015,6 @@ static void do_write(struct connection *conn, struct buffered_data *in)
} else {
/* Exists... */
if (streq(vec[1], XS_WRITE_CREATE_EXCL)) {
send_error(conn, EEXIST);
return;
}
tmppath = tempfile(node_datafile(conn->transaction, node),
in->buffer + offset, datalen);
if (!tmppath) {
+5 -20
View File
@@ -326,32 +326,17 @@ void *xs_read(struct xs_handle *h, const char *path, unsigned int *len)
}
/* Write the value of a single file.
* Returns false on failure. createflags can be 0, O_CREAT, or O_CREAT|O_EXCL.
* Returns false on failure.
*/
bool xs_write(struct xs_handle *h, const char *path,
const void *data, unsigned int len, int createflags)
const void *data, unsigned int len)
{
const char *flags;
struct iovec iovec[3];
/* Format: Flags (as string), path, data. */
if (createflags == 0)
flags = XS_WRITE_NONE;
else if (createflags == O_CREAT)
flags = XS_WRITE_CREATE;
else if (createflags == (O_CREAT|O_EXCL))
flags = XS_WRITE_CREATE_EXCL;
else {
errno = EINVAL;
return false;
}
struct iovec iovec[2];
iovec[0].iov_base = (void *)path;
iovec[0].iov_len = strlen(path) + 1;
iovec[1].iov_base = (void *)flags;
iovec[1].iov_len = strlen(flags) + 1;
iovec[2].iov_base = (void *)data;
iovec[2].iov_len = len;
iovec[1].iov_base = (void *)data;
iovec[1].iov_len = len;
return xs_bool(xs_talkv(h, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
}
+2 -2
View File
@@ -53,10 +53,10 @@ char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num);
void *xs_read(struct xs_handle *h, const char *path, unsigned int *len);
/* Write the value of a single file.
* Returns false on failure. createflags can be 0, O_CREAT, or O_CREAT|O_EXCL.
* Returns false on failure.
*/
bool xs_write(struct xs_handle *h, const char *path, const void *data,
unsigned int len, int createflags);
unsigned int len);
/* Create a new directory.
* Returns false on failure, or success if it already exists.
+2 -7
View File
@@ -267,17 +267,12 @@ static void do_next_op(struct xs_handle *h, bool verbose)
free(xs_read(h, name, &num));
break;
case 2: {
int flags = random_flags(&state);
char *contents = talloc_asprintf(NULL, "%i",
get_randomness(&state));
unsigned int len = get_randomness(&state)%(strlen(contents)+1);
if (verbose)
printf("WRITE %s %s %.*s\n", name,
flags == O_CREAT ? "O_CREAT"
: flags == (O_CREAT|O_EXCL) ? "O_CREAT|O_EXCL"
: flags == 0 ? "0" : "CRAPFLAGS",
len, contents);
xs_write(h, name, contents, len, flags);
printf("WRITE %s %.*s\n", name, len, contents);
xs_write(h, name, contents, len);
break;
}
case 3:
+7 -49
View File
@@ -26,7 +26,7 @@ struct ops
void *(*read)(void *h, const char *path, unsigned int *len);
bool (*write)(void *h, const char *path, const void *data,
unsigned int len, int createflags);
unsigned int len);
bool (*mkdir)(void *h, const char *path);
@@ -333,40 +333,18 @@ static void make_dirs(const char *filename)
static bool file_write(struct file_ops_info *info,
const char *path, const void *data,
unsigned int len, int createflags)
unsigned int len)
{
char *filename = filename_to_data(path_to_name(info, path));
int fd;
/* Kernel isn't strict, but library is. */
if (createflags & ~(O_CREAT|O_EXCL)) {
errno = EINVAL;
return false;
}
if (!write_ok(info, path))
return false;
/* We regard it as existing if dir exists. */
if (strends(filename, ".DATA")) {
if (!createflags)
createflags = O_CREAT;
if (createflags & O_EXCL) {
errno = EEXIST;
return false;
}
}
if (createflags & O_CREAT)
make_dirs(parent_filename(filename));
fd = open(filename, createflags|O_TRUNC|O_WRONLY, 0600);
if (fd < 0) {
/* FIXME: Another hack. */
if (!(createflags & O_CREAT) && errno == EISDIR)
errno = EEXIST;
make_dirs(parent_filename(filename));
fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0600);
if (fd < 0)
return false;
}
if (write(fd, data, len) != (int)len)
barf_perror("Bad write to %s", filename);
@@ -846,20 +824,6 @@ static char *linearize_perms(struct xs_permissions *perms, unsigned int *size)
return ret;
}
static int random_flags(int *state)
{
switch (get_randomness(state) % 4) {
case 0:
return 0;
case 1:
return O_CREAT;
case 2:
return O_CREAT|O_EXCL;
default:
return get_randomness(state);
}
}
/* Do the next operation, return the results. */
static char *do_next_op(struct ops *ops, void *h, int state, bool verbose)
{
@@ -883,18 +847,12 @@ static char *do_next_op(struct ops *ops, void *h, int state, bool verbose)
ret = linearize_read(ops->read(h, name, &num), &num);
break;
case 2: {
int flags = random_flags(&state);
char *contents = talloc_asprintf(NULL, "%i",
get_randomness(&state));
unsigned int len = get_randomness(&state)%(strlen(contents)+1);
if (verbose)
printf("WRITE %s %s %.*s\n", name,
flags == O_CREAT ? "O_CREAT"
: flags == (O_CREAT|O_EXCL) ? "O_CREAT|O_EXCL"
: flags == 0 ? "0" : "CRAPFLAGS",
len, contents);
ret = bool_to_errstring(ops->write(h, name, contents, len,
flags));
printf("WRITE %s %.*s\n", name, len, contents);
ret = bool_to_errstring(ops->write(h, name, contents, len));
talloc_steal(ret, contents);
break;
}
+2 -2
View File
@@ -61,7 +61,7 @@ static void work(unsigned int cycles, unsigned int childnum)
barf_perror("%i: can't read %s iter %i",
childnum, file, i);
sprintf(tmp, "%i", atoi(contents) + 1);
if (!xs_write(h, file, tmp, strlen(tmp)+1, 0))
if (!xs_write(h, file, tmp, strlen(tmp)+1))
barf_perror("%i: can't write %s iter %i",
childnum, file, i);
@@ -91,7 +91,7 @@ static void create_dirs(struct xs_handle *h, const char *base, int togo)
if (togo == 0) {
sprintf(filename, "%s/count", base);
if (!xs_write(h, filename, "0", 2, O_EXCL|O_CREAT))
if (!xs_write(h, filename, "0", 1))
barf_perror("Writing to %s", filename);
return;
}
+8 -34
View File
@@ -192,7 +192,7 @@ static void __attribute__((noreturn)) usage(void)
"Reads commands from stdin, one per line:"
" dir <path>\n"
" read <path>\n"
" write <path> <flags> <value>...\n"
" write <path> <value>...\n"
" setid <id>\n"
" mkdir <path>\n"
" rm <path>\n"
@@ -213,7 +213,7 @@ static void __attribute__((noreturn)) usage(void)
" notimeout\n"
" readonly\n"
" readwrite\n"
" noackwrite <path> <flags> <value>...\n"
" noackwrite <path> <value>...\n"
" readack\n"
" dump\n");
}
@@ -348,48 +348,23 @@ static void do_read(unsigned int handle, char *path)
output("%.*s\n", len, value);
}
static void do_write(unsigned int handle, char *path, char *flags, char *data)
static void do_write(unsigned int handle, char *path, char *data)
{
int f;
if (streq(flags, "none"))
f = 0;
else if (streq(flags, "create"))
f = O_CREAT;
else if (streq(flags, "excl"))
f = O_CREAT | O_EXCL;
else if (streq(flags, "crap"))
f = 100;
else
barf("write flags 'none', 'create' or 'excl' only");
if (!xs_write(handles[handle], path, data, strlen(data), f))
if (!xs_write(handles[handle], path, data, strlen(data)))
failed(handle);
}
static void do_noackwrite(unsigned int handle,
char *path, const char *flags, char *data)
char *path, char *data)
{
struct xsd_sockmsg msg;
/* Format: Flags (as string), path, data. */
if (streq(flags, "none"))
flags = XS_WRITE_NONE;
else if (streq(flags, "create"))
flags = XS_WRITE_CREATE;
else if (streq(flags, "excl"))
flags = XS_WRITE_CREATE_EXCL;
else
barf("noackwrite flags 'none', 'create' or 'excl' only");
msg.len = strlen(path) + 1 + strlen(flags) + 1 + strlen(data);
msg.len = strlen(path) + 1 + strlen(data);
msg.type = XS_WRITE;
if (!write_all_choice(handles[handle]->fd, &msg, sizeof(msg)))
failed(handle);
if (!write_all_choice(handles[handle]->fd, path, strlen(path) + 1))
failed(handle);
if (!write_all_choice(handles[handle]->fd, flags, strlen(flags) + 1))
failed(handle);
if (!write_all_choice(handles[handle]->fd, data, strlen(data)))
failed(handle);
/* Do not wait for ack. */
@@ -778,8 +753,7 @@ static void do_command(unsigned int default_handle, char *line)
else if (streq(command, "read"))
do_read(handle, arg(line, 1));
else if (streq(command, "write"))
do_write(handle,
arg(line, 1), arg(line, 2), arg(line, 3));
do_write(handle, arg(line, 1), arg(line, 2));
else if (streq(command, "setid"))
do_setid(handle, arg(line, 1));
else if (streq(command, "mkdir"))
@@ -832,7 +806,7 @@ static void do_command(unsigned int default_handle, char *line)
xs_daemon_close(handles[handle]);
handles[handle] = NULL;
} else if (streq(command, "noackwrite"))
do_noackwrite(handle, arg(line,1), arg(line,2), arg(line,3));
do_noackwrite(handle, arg(line,1), arg(line,2));
else if (streq(command, "readack"))
do_readack(handle);
else
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.