ccan: update to latest version, which includes more take() checks.

And add the missing unit test from my previous update.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-12-17 14:33:18 +10:30 committed by Christian Decker
parent c4ffec57b4
commit 8e7c8a18df
6 changed files with 159 additions and 2 deletions

View File

@ -1,3 +1,3 @@
CCAN imported from http://ccodearchive.net.
CCAN version: init-2455-gd3d2242b
CCAN version: init-2456-g9d2d2c49

View File

@ -0,0 +1,98 @@
#include <ccan/pipecmd/pipecmd.h>
/* Include the C files directly. */
#include <ccan/pipecmd/pipecmd.c>
#include <ccan/tap/tap.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
pid_t child;
int fd, oldfd, status;
char buf[5] = "test";
char template[] = "/tmp/run-preserve.XXXXXX";
/* We call ourselves, to test pipe. */
if (argc == 2) {
if (strcmp(argv[1], "out") == 0) {
if (write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf))
exit(2);
} else if (strcmp(argv[1], "in") == 0) {
if (read(STDIN_FILENO, buf, sizeof(buf)) != sizeof(buf))
exit(3);
if (memcmp(buf, "test", sizeof(buf)) != 0)
exit(4);
} else if (strcmp(argv[1], "err") == 0) {
if (write(STDERR_FILENO, buf, sizeof(buf)) != sizeof(buf))
exit(5);
} else
abort();
exit(0);
}
/* This is how many tests you plan to run */
plan_tests(25);
/* Preserve stdin test. */
fd = mkstemp(template);
ok1(write(fd, buf, sizeof(buf)) == sizeof(buf));
ok1(fd >= 0);
ok1(dup2(fd, STDIN_FILENO) == STDIN_FILENO);
ok1(lseek(STDIN_FILENO, 0, SEEK_SET) == 0);
child = pipecmd(&pipecmd_preserve, NULL, NULL, argv[0], "in", NULL);
if (!ok1(child > 0))
exit(1);
ok1(waitpid(child, &status, 0) == child);
ok1(WIFEXITED(status));
ok1(WEXITSTATUS(status) == 0);
close(STDIN_FILENO);
/* Preserve stdout test */
fd = open(template, O_WRONLY|O_TRUNC);
ok1(fd >= 0);
oldfd = dup(STDOUT_FILENO);
/* Can't use OK after this, since we mug stdout */
if (dup2(fd, STDOUT_FILENO) != STDOUT_FILENO)
exit(1);
child = pipecmd(NULL, &pipecmd_preserve, NULL, argv[0], "out", NULL);
if (child == -1)
exit(1);
/* Restore stdout */
dup2(oldfd, STDOUT_FILENO);
close(oldfd);
ok1(waitpid(child, &status, 0) == child);
ok1(WIFEXITED(status));
ok1(WEXITSTATUS(status) == 0);
fd = open(template, O_RDONLY);
ok1(read(fd, buf, sizeof(buf)) == sizeof(buf));
ok1(close(fd) == 0);
ok1(memcmp(buf, "test", sizeof(buf)) == 0);
/* Preserve stderr test. */
fd = open(template, O_WRONLY|O_TRUNC);
ok1(fd >= 0);
oldfd = dup(STDERR_FILENO);
ok1(dup2(fd, STDERR_FILENO) == STDERR_FILENO);
child = pipecmd(NULL, NULL, &pipecmd_preserve, argv[0], "err", NULL);
if (!ok1(child > 0))
exit(1);
/* Restore stderr. */
ok1(dup2(oldfd, STDERR_FILENO));
ok1(waitpid(child, &status, 0) == child);
ok1(WIFEXITED(status));
ok1(WEXITSTATUS(status) == 0);
close(oldfd);
fd = open(template, O_RDONLY);
ok1(read(fd, buf, sizeof(buf)) == sizeof(buf));
ok1(close(fd) == 0);
ok1(memcmp(buf, "test", sizeof(buf)) == 0);
unlink(template);
/* This exits depending on whether all tests passed */
return exit_status();
}

View File

@ -385,6 +385,8 @@ static void del_tree(struct tal_hdr *t, const tal_t *orig, int saved_errno)
{
struct prop_hdr **prop, *p, *next;
assert(!taken(from_tal_hdr(t)));
/* Already being destroyed? Don't loop. */
if (unlikely(get_destroying_bit(t->parent_child)))
return;
@ -710,6 +712,10 @@ bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear)
/* Fix up linked list pointers. */
t->list.next->prev = t->list.prev->next = &t->list;
/* Copy take() property. */
if (taken(from_tal_hdr(old_t)))
take(from_tal_hdr(t));
/* Fix up child property's parent pointer. */
child = find_property(t, CHILDREN);
if (child) {

View File

@ -106,6 +106,9 @@ void *tal_free(const tal_t *p);
* This returns true on success (and may move *@p), or false on failure.
* On success, tal_count() of *@p will be @count.
*
* Note: if *p is take(), it will still be take() upon return, even if it
* has been moved.
*
* Example:
* tal_resize(&p, 100);
*/

View File

@ -0,0 +1,44 @@
#include <ccan/tal/tal.h>
#include <ccan/tal/tal.c>
#include <ccan/tap/tap.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
int status;
char *p;
plan_tests(4);
/* Test direct free. */
switch (fork()) {
case 0:
tal_free(take(tal(NULL, char)));
exit(2);
case -1:
exit(1);
default:
wait(&status);
ok1(WIFSIGNALED(status));
ok1(WTERMSIG(status) == SIGABRT);
}
/* Test indirect free. */
switch (fork()) {
case 0:
p = tal(NULL, char);
take(tal(p, char));
tal_free(p);
exit(2);
case -1:
exit(1);
default:
wait(&status);
ok1(WIFSIGNALED(status));
ok1(WTERMSIG(status) == SIGABRT);
}
return exit_status();
}

View File

@ -6,7 +6,7 @@ int main(void)
{
char *parent, *c;
plan_tests(21);
plan_tests(22);
/* We can take NULL. */
ok1(take(NULL) == NULL);
@ -44,6 +44,12 @@ int main(void)
tal_free(c);
ok1(tal_first(parent) == NULL);
/* tal_resize should return a taken pointer. */
c = take(tal_arr(parent, char, 5));
tal_resize(&c, 100);
ok1(taken(c));
tal_free(c);
tal_free(parent);
ok1(!taken_any());