Module Name:    src
Committed By:   jmmv
Date:           Tue Dec 22 13:36:57 UTC 2009

Modified Files:
        src/external/bsd/atf/dist/atf-c: dynstr.c fs.c io.c tc.c
Removed Files:
        src/external/bsd/atf/dist: ChangeLog ROADMAP
        src/external/bsd/atf/dist/tests/atf/atf-c: h_check.c h_macros.h
        src/external/bsd/atf/dist/tests/build: t_include_atf_c++_hpp.cpp
            t_include_atf_c_h.cpp
        src/external/bsd/atf/dist/tests/build/atf-c: t_include_check_h.c
            t_include_config_h.c t_include_dynstr_h.c t_include_env_h.c
            t_include_error_fwd_h.c t_include_error_h.c t_include_expand_h.c
            t_include_fs_h.c t_include_io_h.c t_include_list_h.c
            t_include_macros_h.c t_include_map_h.c t_include_object_h.c
            t_include_process_h.c t_include_sanity_h.c t_include_signals_h.c
            t_include_tc_h.c t_include_tcr_h.c t_include_text_h.c
            t_include_tp_h.c t_include_ui_h.c t_use_macros_h.c
        src/external/bsd/atf/dist/tests/build/atf-c++:
            t_include_application_hpp.cpp t_include_atffile_hpp.cpp
            t_include_check_hpp.cpp t_include_config_hpp.cpp
            t_include_env_hpp.cpp t_include_exceptions_hpp.cpp
            t_include_expand_hpp.cpp t_include_formats_hpp.cpp
            t_include_fs_hpp.cpp t_include_io_hpp.cpp t_include_macros_hpp.cpp
            t_include_parser_hpp.cpp t_include_process_hpp.cpp
            t_include_sanity_hpp.cpp t_include_signals_hpp.cpp
            t_include_tests_hpp.cpp t_include_text_hpp.cpp t_include_ui_hpp.cpp
            t_include_user_hpp.cpp t_include_utils_hpp.cpp t_use_macros_hpp.cpp

Log Message:
Merge atf 0.7.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r0 src/external/bsd/atf/dist/ChangeLog \
    src/external/bsd/atf/dist/ROADMAP
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/atf/dist/atf-c/dynstr.c \
    src/external/bsd/atf/dist/atf-c/fs.c src/external/bsd/atf/dist/atf-c/io.c \
    src/external/bsd/atf/dist/atf-c/tc.c
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/bsd/atf/dist/tests/atf/atf-c/h_check.c \
    src/external/bsd/atf/dist/tests/atf/atf-c/h_macros.h
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/bsd/atf/dist/tests/build/t_include_atf_c++_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/t_include_atf_c_h.cpp
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_check_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_config_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_dynstr_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_env_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_error_fwd_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_error_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_expand_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_fs_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_io_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_list_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_macros_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_map_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_object_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_process_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_sanity_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_signals_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_tc_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_tcr_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_text_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_tp_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_include_ui_h.c \
    src/external/bsd/atf/dist/tests/build/atf-c/t_use_macros_h.c
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_application_hpp.cpp 
\
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_atffile_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_check_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_config_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_env_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_exceptions_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_expand_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_formats_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_fs_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_io_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_macros_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_parser_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_process_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_sanity_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_signals_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_tests_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_text_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_ui_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_user_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_include_utils_hpp.cpp \
    src/external/bsd/atf/dist/tests/build/atf-c++/t_use_macros_hpp.cpp

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/atf/dist/atf-c/dynstr.c
diff -u src/external/bsd/atf/dist/atf-c/dynstr.c:1.2 src/external/bsd/atf/dist/atf-c/dynstr.c:1.3
--- src/external/bsd/atf/dist/atf-c/dynstr.c:1.2	Thu Feb 12 09:05:13 2009
+++ src/external/bsd/atf/dist/atf-c/dynstr.c	Tue Dec 22 13:36:56 2009
@@ -1,7 +1,7 @@
 /*
  * Automated Testing Framework (atf)
  *
- * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -126,13 +126,18 @@
     ad->m_data = (char *)malloc(sizeof(char));
     if (ad->m_data == NULL) {
         err = atf_no_memory_error();
-    } else {
-        ad->m_data[0] = '\0';
-        ad->m_datasize = 1;
-        ad->m_length = 0;
-        err = atf_no_error();
+        goto err_object;
     }
 
+    ad->m_data[0] = '\0';
+    ad->m_datasize = 1;
+    ad->m_length = 0;
+    err = atf_no_error();
+    goto out;
+
+err_object:
+    atf_object_fini(&ad->m_object);
+out:
     return err;
 }
 
@@ -146,31 +151,40 @@
     ad->m_datasize = strlen(fmt) + 1;
     ad->m_length = 0;
 
-    err = atf_no_error();
     do {
+        va_list ap2;
+        int ret;
+
         ad->m_datasize *= 2;
         ad->m_data = (char *)malloc(ad->m_datasize);
         if (ad->m_data == NULL) {
             err = atf_no_memory_error();
-        } else {
-            va_list ap2;
-            int ret;
-
-            va_copy(ap2, ap);
-            ret = vsnprintf(ad->m_data, ad->m_datasize, fmt, ap2);
-            va_end(ap2);
-            if (ret < 0) {
-                err = atf_libc_error(errno, "Cannot format string");
-            } else {
-                if ((size_t)ret >= ad->m_datasize) {
-                    free(ad->m_data);
-                    ad->m_data = NULL;
-                }
-                ad->m_length = ret;
-            }
+            goto err_object;
         }
-    } while (!atf_is_error(err) && ad->m_length >= ad->m_datasize);
 
+        va_copy(ap2, ap);
+        ret = vsnprintf(ad->m_data, ad->m_datasize, fmt, ap2);
+        va_end(ap2);
+        if (ret < 0) {
+            free(ad->m_data);
+            err = atf_libc_error(errno, "Cannot format string");
+            goto err_object;
+        }
+
+        INV(ret >= 0);
+        if ((size_t)ret >= ad->m_datasize) {
+            free(ad->m_data);
+            ad->m_data = NULL;
+        }
+        ad->m_length = ret;
+    } while (ad->m_length >= ad->m_datasize);
+
+    err = atf_no_error();
+    goto out;
+
+err_object:
+    atf_object_fini(&ad->m_object);
+out:
     POST(atf_is_error(err) || ad->m_data != NULL);
     return err;
 }
@@ -195,18 +209,28 @@
 
     atf_object_init(&ad->m_object);
 
+    if (memlen >= SIZE_MAX - 1) {
+        err = atf_no_memory_error();
+        goto err_object;
+    }
+
     ad->m_data = (char *)malloc(memlen + 1);
-    if (ad->m_data == NULL)
+    if (ad->m_data == NULL) {
         err = atf_no_memory_error();
-    else {
-        ad->m_datasize = memlen + 1;
-        memcpy(ad->m_data, mem, memlen);
-        ad->m_data[memlen] = '\0';
-        ad->m_length = strlen(ad->m_data);
-        INV(ad->m_length <= memlen);
-        err = atf_no_error();
+        goto err_object;
     }
 
+    ad->m_datasize = memlen + 1;
+    memcpy(ad->m_data, mem, memlen);
+    ad->m_data[memlen] = '\0';
+    ad->m_length = strlen(ad->m_data);
+    INV(ad->m_length <= memlen);
+    err = atf_no_error();
+    goto out;
+
+err_object:
+    atf_object_fini(&ad->m_object);
+out:
     return err;
 }
 
@@ -217,21 +241,27 @@
 
     atf_object_init(&ad->m_object);
 
-    if (len == SIZE_MAX)
+    if (len == SIZE_MAX) {
         err = atf_no_memory_error();
-    else {
-        ad->m_datasize = len + sizeof(char);
-        ad->m_data = (char *)malloc(ad->m_datasize);
-        if (ad->m_data == NULL) {
-            err = atf_no_memory_error();
-        } else {
-            memset(ad->m_data, ch, len);
-            ad->m_data[len] = '\0';
-            ad->m_length = len;
-            err = atf_no_error();
-        }
+        goto err_object;
+    }
+
+    ad->m_datasize = (len + 1) * sizeof(char);
+    ad->m_data = (char *)malloc(ad->m_datasize);
+    if (ad->m_data == NULL) {
+        err = atf_no_memory_error();
+        goto err_object;
     }
 
+    memset(ad->m_data, ch, len);
+    ad->m_data[len] = '\0';
+    ad->m_length = len;
+    err = atf_no_error();
+    goto out;
+
+err_object:
+    atf_object_fini(&ad->m_object);
+out:
     return err;
 }
 
Index: src/external/bsd/atf/dist/atf-c/fs.c
diff -u src/external/bsd/atf/dist/atf-c/fs.c:1.2 src/external/bsd/atf/dist/atf-c/fs.c:1.3
--- src/external/bsd/atf/dist/atf-c/fs.c:1.2	Thu Feb 12 09:05:13 2009
+++ src/external/bsd/atf/dist/atf-c/fs.c	Tue Dec 22 13:36:56 2009
@@ -1,7 +1,7 @@
 /*
  * Automated Testing Framework (atf)
  *
- * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,78 @@
 #include "atf-c/user.h"
 
 /* ---------------------------------------------------------------------
+ * Prototypes for auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static bool check_umask(const mode_t, const mode_t);
+static atf_error_t cleanup_aux(const atf_fs_path_t *, dev_t, bool);
+static atf_error_t cleanup_aux_dir(const char *, const atf_fs_stat_t *, bool);
+static atf_error_t copy_contents(const atf_fs_path_t *, char **);
+static mode_t current_umask(void);
+static atf_error_t do_mkdtemp(char *);
+static atf_error_t do_unmount(const atf_fs_path_t *);
+static atf_error_t normalize(atf_dynstr_t *, char *);
+static atf_error_t normalize_ap(atf_dynstr_t *, const char *, va_list);
+static void replace_contents(atf_fs_path_t *, const char *);
+static const char *stat_type_to_string(const int);
+
+/* ---------------------------------------------------------------------
+ * The "invalid_umask" error type.
+ * --------------------------------------------------------------------- */
+
+struct invalid_umask_error_data {
+    /* One of atf_fs_stat_*_type. */
+    int m_type;
+
+    /* The original path causing the error. */
+    /* XXX: Ideally this would be an atf_fs_path_t, but if we create it
+     * from the error constructor, we cannot delete the path later on.
+     * Can't remember why atf_error_new does not take a hook for
+     * deletion. */
+    char m_path[1024];
+
+    /* The umask that caused the error. */
+    mode_t m_umask;
+};
+typedef struct invalid_umask_error_data invalid_umask_error_data_t;
+
+static
+void
+invalid_umask_format(const atf_error_t err, char *buf, size_t buflen)
+{
+    const invalid_umask_error_data_t *data;
+
+    PRE(atf_error_is(err, "invalid_umask"));
+
+    data = atf_error_data(err);
+    snprintf(buf, buflen, "Could not create the temporary %s %s because "
+             "it will not have enough access rights due to the current "
+             "umask %05o", stat_type_to_string(data->m_type),
+             data->m_path, (unsigned int)data->m_umask);
+}
+
+static
+atf_error_t
+invalid_umask_error(const atf_fs_path_t *path, const int type,
+                    const mode_t failing_mask)
+{
+    atf_error_t err;
+    invalid_umask_error_data_t data;
+
+    data.m_type = type;
+
+    strncpy(data.m_path, atf_fs_path_cstring(path), sizeof(data.m_path));
+    data.m_path[sizeof(data.m_path) - 1] = '\0';
+
+    data.m_umask = failing_mask;
+
+    err = atf_error_new("invalid_umask", &data, sizeof(data),
+                        invalid_umask_format);
+
+    return err;
+}
+
+/* ---------------------------------------------------------------------
  * The "unknown_file_type" error type.
  * --------------------------------------------------------------------- */
 
@@ -96,11 +168,13 @@
  * Auxiliary functions.
  * --------------------------------------------------------------------- */
 
-static atf_error_t cleanup_aux(const atf_fs_path_t *, dev_t, bool);
-static atf_error_t cleanup_aux_dir(const char *, dev_t, bool);
-static atf_error_t do_unmount(const atf_fs_path_t *);
-static atf_error_t normalize(atf_dynstr_t *, char *);
-static atf_error_t normalize_ap(atf_dynstr_t *, const char *, va_list);
+static
+bool
+check_umask(const mode_t exp_mode, const mode_t min_mode)
+{
+    const mode_t actual_mode = (~current_umask() & exp_mode);
+    return (actual_mode & min_mode) == min_mode;
+}
 
 /* The erase parameter in this routine is to control nested mount points.
  * We want to descend into a mount point to unmount anything that is
@@ -120,7 +194,7 @@
         goto out;
 
     if (atf_fs_stat_get_type(&st) == atf_fs_stat_dir_type) {
-        err = cleanup_aux_dir(pstr, atf_fs_stat_get_device(&st),
+        err = cleanup_aux_dir(pstr, &st,
                               atf_fs_stat_get_device(&st) == parent_device);
         if (atf_is_error(err))
             goto out_st;
@@ -134,11 +208,7 @@
 
     if (erase) {
         if (atf_fs_stat_get_type(&st) == atf_fs_stat_dir_type) {
-            if (rmdir(pstr) == -1)
-                err = atf_libc_error(errno, "Cannot remove directory "
-                                     "%s", pstr);
-            else
-                INV(!atf_is_error(err));
+            err = atf_fs_rmdir(p);
         } else {
             if (unlink(pstr) == -1)
                 err = atf_libc_error(errno, "Cannot remove file %s", pstr);
@@ -155,12 +225,20 @@
 
 static
 atf_error_t
-cleanup_aux_dir(const char *pstr, dev_t this_device, bool erase)
+cleanup_aux_dir(const char *pstr, const atf_fs_stat_t *st, bool erase)
 {
     DIR *d;
     atf_error_t err;
     struct dirent *de;
 
+    if (erase && !(atf_fs_stat_get_mode(st) & S_IWUSR)) {
+        if (chmod(pstr, atf_fs_stat_get_mode(st) | S_IWUSR) == -1) {
+            err = atf_libc_error(errno, "Cannot grant write permissions "
+                                 "to %s", pstr);
+            goto out;
+        }
+    }
+
     d = opendir(pstr);
     if (d == NULL) {
         err = atf_libc_error(errno, "Cannot open directory %s", pstr);
@@ -175,7 +253,7 @@
         if (!atf_is_error(err)) {
             if (strcmp(de->d_name, ".") != 0 &&
                 strcmp(de->d_name, "..") != 0)
-                err = cleanup_aux(&p, this_device, erase);
+                err = cleanup_aux(&p, atf_fs_stat_get_device(st), erase);
 
             atf_fs_path_fini(&p);
         }
@@ -207,6 +285,15 @@
 }
 
 static
+mode_t
+current_umask(void)
+{
+    const mode_t current = umask(0);
+    (void)umask(current);
+    return current;
+}
+
+static
 atf_error_t
 do_mkdtemp(char *tmpl)
 {
@@ -274,12 +361,28 @@
          * also have to update /etc/mtab to match what we did.  It is
          * simpler to just leave the system-specific umount(8) tool deal
          * with it, at least for now. */
-        char *cmd;
+        atf_fs_path_t prog;
 
-        err = atf_text_format(&cmd, "umount '%s'", pastr);
+        /* TODO: Should have an atf_fs_find_in_path function or similar to
+         * avoid relying on the automatic path lookup of exec, which I'd
+         * like to get rid of. */
+        err = atf_fs_path_init_fmt(&prog, "umount");
         if (!atf_is_error(err)) {
-            err = atf_process_system(cmd);
-            free(cmd);
+            atf_process_status_t status;
+            const char *argv[3] = { "unmount", pastr, NULL };
+
+            err = atf_process_exec_array(&status, &prog, argv, NULL, NULL);
+            if (!atf_is_error(err)) {
+                if (!atf_process_status_exited(&status) ||
+                    atf_process_status_exitstatus(&status) != EXIT_SUCCESS) {
+                    /* XXX: This is the wrong error type. */
+                    err = atf_libc_error(EINVAL, "Failed to exec unmount");
+                }
+
+                atf_process_status_fini(&status);
+            }
+
+            atf_fs_path_fini(&prog);
         }
     }
 #endif
@@ -361,6 +464,36 @@
     INV(!atf_is_error(err));
 }
 
+static
+const char *
+stat_type_to_string(const int type)
+{
+    const char *str;
+
+    if (type == atf_fs_stat_blk_type)
+        str = "block device";
+    else if (type == atf_fs_stat_chr_type)
+        str = "character device";
+    else if (type == atf_fs_stat_dir_type)
+        str = "directory";
+    else if (type == atf_fs_stat_fifo_type)
+        str = "named pipe";
+    else if (type == atf_fs_stat_lnk_type)
+        str = "symbolic link";
+    else if (type == atf_fs_stat_reg_type)
+        str = "regular file";
+    else if (type == atf_fs_stat_sock_type)
+        str = "socket";
+    else if (type == atf_fs_stat_wht_type)
+        str = "whiteout";
+    else {
+        UNREACHABLE;
+        str = NULL;
+    }
+
+    return str;
+}
+
 /* ---------------------------------------------------------------------
  * The "atf_fs_path" type.
  * --------------------------------------------------------------------- */
@@ -420,10 +553,10 @@
 atf_error_t
 atf_fs_path_branch_path(const atf_fs_path_t *p, atf_fs_path_t *bp)
 {
-    const ssize_t endpos = atf_dynstr_rfind_ch(&p->m_data, '/');
+    const size_t endpos = atf_dynstr_rfind_ch(&p->m_data, '/');
     atf_error_t err;
 
-    if ((size_t)endpos == atf_dynstr_npos)
+    if (endpos == atf_dynstr_npos)
         err = atf_fs_path_init_fmt(bp, ".");
     else if (endpos == 0)
         err = atf_fs_path_init_fmt(bp, "/");
@@ -449,10 +582,10 @@
 atf_error_t
 atf_fs_path_leaf_name(const atf_fs_path_t *p, atf_dynstr_t *ln)
 {
-    ssize_t begpos = atf_dynstr_rfind_ch(&p->m_data, '/');
+    size_t begpos = atf_dynstr_rfind_ch(&p->m_data, '/');
     atf_error_t err;
 
-    if ((size_t)begpos == atf_dynstr_npos)
+    if (begpos == atf_dynstr_npos)
         begpos = 0;
     else
         begpos++;
@@ -640,6 +773,12 @@
     return st->m_sb.st_ino;
 }
 
+mode_t
+atf_fs_stat_get_mode(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & ~S_IFMT;
+}
+
 off_t
 atf_fs_stat_get_size(const atf_fs_stat_t *st)
 {
@@ -845,6 +984,11 @@
     atf_error_t err;
     char *buf;
 
+    if (!check_umask(S_IRWXU, S_IRWXU)) {
+        err = invalid_umask_error(p, atf_fs_stat_dir_type, current_umask());
+        goto out;
+    }
+
     err = copy_contents(p, &buf);
     if (atf_is_error(err))
         goto out;
@@ -869,6 +1013,11 @@
     char *buf;
     int fd;
 
+    if (!check_umask(S_IRWXU, S_IRWXU)) {
+        err = invalid_umask_error(p, atf_fs_stat_reg_type, current_umask());
+        goto out;
+    }
+
     err = copy_contents(p, &buf);
     if (atf_is_error(err))
         goto out;
@@ -888,6 +1037,26 @@
 }
 
 atf_error_t
+atf_fs_rmdir(const atf_fs_path_t *p)
+{
+    atf_error_t err;
+
+    if (rmdir(atf_fs_path_cstring(p))) {
+        if (errno == EEXIST) {
+            /* Some operating systems (e.g. OpenSolaris 200906) return
+             * EEXIST instead of ENOTEMPTY for non-empty directories.
+             * Homogenize the return value so that callers don't need
+             * to bother about differences in operating systems. */
+            errno = ENOTEMPTY;
+        }
+        err = atf_libc_error(errno, "Cannot remove directory");
+    } else
+        err = atf_no_error();
+
+    return err;
+}
+
+atf_error_t
 atf_fs_unlink(const atf_fs_path_t *p)
 {
     atf_error_t err;
Index: src/external/bsd/atf/dist/atf-c/io.c
diff -u src/external/bsd/atf/dist/atf-c/io.c:1.2 src/external/bsd/atf/dist/atf-c/io.c:1.3
--- src/external/bsd/atf/dist/atf-c/io.c:1.2	Thu Feb 12 09:05:13 2009
+++ src/external/bsd/atf/dist/atf-c/io.c	Tue Dec 22 13:36:56 2009
@@ -1,7 +1,7 @@
 /*
  * Automated Testing Framework (atf)
  *
- * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,24 +43,29 @@
 #include "atf-c/sanity.h"
 
 atf_error_t
-atf_io_readline(int fd, atf_dynstr_t *dest)
+atf_io_readline(int fd, atf_dynstr_t *dest, bool *eof)
 {
-    char ch[2];
+    char ch;
     ssize_t cnt;
     atf_error_t err;
 
-    ch[1] = '\0';
-    while ((cnt = read(fd, &ch[0], sizeof(ch[0]))) == sizeof(ch[0]) &&
-           ch[0] != '\n') {
-        atf_dynstr_append_fmt(dest, ch);
+    while ((cnt = read(fd, &ch, sizeof(ch))) == sizeof(ch) &&
+           ch != '\n') {
+        err = atf_dynstr_append_fmt(dest, "%c", ch);
+        if (atf_is_error(err))
+            goto out;
     }
 
-    if (cnt == -1)
+    if (cnt == -1) {
         err = atf_libc_error(errno, "Failed to read line from file "
                              "descriptor %d", fd);
-    else
-        err = atf_no_error();
+        goto out;
+    }
+
+    *eof = (cnt == 0);
+    err = atf_no_error();
 
+out:
     return err;
 }
 
@@ -80,6 +85,7 @@
                                  "descriptor %d", atf_dynstr_cstring(&str),
                                  fd);
         else {
+            INV(cnt >= 0);
             INV((size_t)cnt == atf_dynstr_length(&str));
             err = atf_no_error();
         }
Index: src/external/bsd/atf/dist/atf-c/tc.c
diff -u src/external/bsd/atf/dist/atf-c/tc.c:1.2 src/external/bsd/atf/dist/atf-c/tc.c:1.3
--- src/external/bsd/atf/dist/atf-c/tc.c:1.2	Tue Apr 14 15:41:11 2009
+++ src/external/bsd/atf/dist/atf-c/tc.c	Tue Dec 22 13:36:56 2009
@@ -1,7 +1,7 @@
 /*
  * Automated Testing Framework (atf)
  *
- * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,7 @@
 #include <unistd.h>
 
 #include "atf-c/config.h"
+#include "atf-c/defs.h"
 #include "atf-c/env.h"
 #include "atf-c/error.h"
 #include "atf-c/fs.h"
@@ -58,39 +59,46 @@
  * Auxiliary types and functions.
  * --------------------------------------------------------------------- */
 
+struct child_data {
+    const atf_tc_t *tc;
+    const atf_fs_path_t *workdir;
+};
+
 /* Parent-only stuff. */
 struct timeout_data;
 static atf_error_t body_parent(const atf_tc_t *, const atf_fs_path_t *,
-                               pid_t, atf_tcr_t *);
-static atf_error_t cleanup_parent(const atf_tc_t *, pid_t);
-static atf_error_t fork_body(const atf_tc_t *, const atf_fs_path_t *,
-                             atf_tcr_t *);
-static atf_error_t fork_cleanup(const atf_tc_t *, const atf_fs_path_t *);
+                               atf_process_child_t *, atf_tcr_t *);
+static atf_error_t cleanup_parent(const atf_tc_t *, atf_process_child_t *);
+static atf_error_t fork_body(const atf_tc_t *, int, int,
+                             const atf_fs_path_t *, atf_tcr_t *);
+static atf_error_t fork_cleanup(const atf_tc_t *, int, int,
+                                const atf_fs_path_t *);
 static atf_error_t get_tc_result(const atf_fs_path_t *, atf_tcr_t *);
-static atf_error_t program_timeout(pid_t, const atf_tc_t *,
-                                   struct timeout_data *);
+static atf_error_t program_timeout(const atf_process_child_t *,
+                                   const atf_tc_t *, struct timeout_data *);
 static void unprogram_timeout(struct timeout_data *);
 static void sigalrm_handler(int);
 
 /* Child-only stuff. */
-static void body_child(const atf_tc_t *, const atf_fs_path_t *)
-            ATF_DEFS_ATTRIBUTE_NORETURN;
+static void body_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
 static atf_error_t check_arch(const char *, void *);
 static atf_error_t check_config(const char *, void *);
 static atf_error_t check_machine(const char *, void *);
 static atf_error_t check_prog(const char *, void *);
 static atf_error_t check_prog_in_dir(const char *, void *);
 static atf_error_t check_requirements(const atf_tc_t *);
-static void cleanup_child(const atf_tc_t *, const atf_fs_path_t *)
-            ATF_DEFS_ATTRIBUTE_NORETURN;
+static void cleanup_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
 static void fail_internal(const char *, int, const char *, const char *,
                           const char *, va_list,
+                          void (*)(atf_dynstr_t *),
                           void (*)(const char *, ...));
 static void fatal_atf_error(const char *, atf_error_t)
             ATF_DEFS_ATTRIBUTE_NORETURN;
 static void fatal_libc_error(const char *, int)
             ATF_DEFS_ATTRIBUTE_NORETURN;
-static atf_error_t prepare_child(const atf_tc_t *, const atf_fs_path_t *);
+static atf_error_t prepare_child(const struct child_data *);
+static void tc_fail(atf_dynstr_t *) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void tc_fail_nonfatal(atf_dynstr_t *);
 static void write_tcr(const atf_tcr_t *);
 
 /* ---------------------------------------------------------------------
@@ -269,7 +277,7 @@
  * --------------------------------------------------------------------- */
 
 atf_error_t
-atf_tc_run(const atf_tc_t *tc, atf_tcr_t *tcr,
+atf_tc_run(const atf_tc_t *tc, atf_tcr_t *tcr, int fdout, int fderr,
            const atf_fs_path_t *workdirbase)
 {
     atf_error_t err, cleanuperr;
@@ -287,8 +295,8 @@
     if (atf_is_error(err))
         goto out_workdir;
 
-    err = fork_body(tc, &workdir, tcr);
-    cleanuperr = fork_cleanup(tc, &workdir);
+    err = fork_body(tc, fdout, fderr, &workdir, tcr);
+    cleanuperr = fork_cleanup(tc, fdout, fderr, &workdir);
     if (!atf_is_error(cleanuperr))
         (void)atf_fs_cleanup(&workdir);
     if (!atf_is_error(err))
@@ -328,7 +336,8 @@
 
 static
 atf_error_t
-program_timeout(pid_t pid, const atf_tc_t *tc, struct timeout_data *td)
+program_timeout(const atf_process_child_t *child, const atf_tc_t *tc,
+                struct timeout_data *td)
 {
     atf_error_t err;
     long timeout;
@@ -338,7 +347,7 @@
         goto out;
 
     if (timeout != 0) {
-        sigalrm_pid = pid;
+        sigalrm_pid = atf_process_child_pid(child);
         sigalrm_killed = false;
 
         err = atf_signal_programmer_init(&td->m_sigalrm, SIGALRM,
@@ -377,52 +386,62 @@
 
 static
 atf_error_t
-body_parent(const atf_tc_t *tc, const atf_fs_path_t *workdir, pid_t pid,
-            atf_tcr_t *tcr)
+body_parent(const atf_tc_t *tc, const atf_fs_path_t *workdir,
+            atf_process_child_t *child, atf_tcr_t *tcr)
 {
     atf_error_t err;
-    int state;
+    atf_process_status_t status;
     struct timeout_data td;
 
-    err = program_timeout(pid, tc, &td);
+    err = program_timeout(child, tc, &td);
     if (atf_is_error(err)) {
         char buf[4096];
 
         atf_error_format(err, buf, sizeof(buf));
         fprintf(stderr, "Error programming test case's timeout: %s", buf);
         atf_error_free(err);
-        killpg(pid, SIGKILL);
+        killpg(atf_process_child_pid(child), SIGKILL);
     }
 
-    if (waitpid(pid, &state, 0) == -1) {
-        if (errno == EINTR && sigalrm_killed)
+again:
+    err = atf_process_child_wait(child, &status);
+    if (atf_is_error(err)) {
+        if (atf_error_is(err, "libc") && atf_libc_error_code(err) == EINTR) {
+            atf_error_free(err);
+            goto again;
+        } else {
+            /* Propagate err */
+        }
+    } else {
+        if (sigalrm_killed)
             err = atf_tcr_init_reason_fmt(tcr, atf_tcr_failed_state,
                                           "Test case timed out after %s "
                                           "seconds",
                                           atf_tc_get_md_var(tc, "timeout"));
-        else
-            err = atf_libc_error(errno, "Error waiting for child process "
-                                 "%d", pid);
-    } else {
-        if (!WIFEXITED(state) || WEXITSTATUS(state) != EXIT_SUCCESS) {
-            if (WIFEXITED(state))
-                err = atf_tcr_init_reason_fmt(tcr, atf_tcr_failed_state,
-                                             "Test case did not exit cleanly; "
-                                             "exit status was %d",
-                                             WEXITSTATUS(state));
-            else if (WIFSIGNALED(state))
+        else {
+            if (atf_process_status_exited(&status)) {
+                const int exitstatus = atf_process_status_exitstatus(&status);
+                if (exitstatus == EXIT_SUCCESS)
+                    err = get_tc_result(workdir, tcr);
+                else
+                    err = atf_tcr_init_reason_fmt(tcr, atf_tcr_failed_state,
+                                                  "Test case exited with "
+                                                  "status %d", exitstatus);
+            } else if (atf_process_status_signaled(&status)) {
+                const int sig = atf_process_status_termsig(&status);
+                const bool wcore = atf_process_status_coredump(&status);
                 err = atf_tcr_init_reason_fmt(tcr, atf_tcr_failed_state,
-                                             "Test case did not exit cleanly: "
-                                             "%s%s",
-                                             strsignal(WTERMSIG(state)),
-                                             WCOREDUMP(state) ?
-                                               " (core dumped)" : "");
-            else
+                                              "Test case was signaled by "
+                                              "signal %d%s", sig,
+                                              wcore ? " (core dumped)" : "");
+            } else {
                 err = atf_tcr_init_reason_fmt(tcr, atf_tcr_failed_state,
-                                             "Test case did not exit cleanly; "
-                                             "state was %d", state);
-        } else
-            err = get_tc_result(workdir, tcr);
+                                              "Test case exited due to an "
+                                              "unexpected condition");
+            }
+        }
+
+        atf_process_status_fini(&status);
     }
 
     unprogram_timeout(&td);
@@ -432,71 +451,97 @@
 
 static
 atf_error_t
-cleanup_parent(const atf_tc_t *tc, pid_t pid)
+cleanup_parent(const atf_tc_t *tc, atf_process_child_t *child)
 {
     atf_error_t err;
-    int state;
+    atf_process_status_t status;
 
-    if (waitpid(pid, &state, 0) == -1) {
-        err = atf_libc_error(errno, "Error waiting for child process "
-                             "%d", pid);
+    err = atf_process_child_wait(child, &status);
+    if (atf_is_error(err))
         goto out;
-    }
 
-    if (!WIFEXITED(state) || WEXITSTATUS(state) != EXIT_SUCCESS)
+    if (!atf_process_status_exited(&status) ||
+        atf_process_status_exitstatus(&status) != EXIT_SUCCESS) {
         /* XXX Not really a libc error. */
         err = atf_libc_error(EINVAL, "Child process did not exit cleanly");
-    else
+    } else
         err = atf_no_error();
 
+    atf_process_status_fini(&status);
 out:
     return err;
 }
 
 static
 atf_error_t
-fork_body(const atf_tc_t *tc, const atf_fs_path_t *workdir, atf_tcr_t *tcr)
+fork_body(const atf_tc_t *tc, int fdout, int fderr,
+          const atf_fs_path_t *workdir, atf_tcr_t *tcr)
 {
     atf_error_t err;
-    pid_t pid;
+    atf_process_stream_t outsb, errsb;
+    atf_process_child_t child;
+    struct child_data data = {
+        tc,
+        workdir,
+    };
 
-    err = atf_process_fork(&pid);
+    err = atf_process_stream_init_redirect_fd(&outsb, fdout);
     if (atf_is_error(err))
         goto out;
 
-    if (pid == 0) {
-        body_child(tc, workdir);
-        UNREACHABLE;
-        abort();
-    } else {
-        err = body_parent(tc, workdir, pid, tcr);
-    }
+    err = atf_process_stream_init_redirect_fd(&errsb, fderr);
+    if (atf_is_error(err))
+        goto out_outsb;
+
+    err = atf_process_fork(&child, body_child, &outsb, &errsb, &data);
+    if (atf_is_error(err))
+        goto out_errsb;
+
+    err = body_parent(tc, workdir, &child, tcr);
 
+out_errsb:
+    atf_process_stream_fini(&errsb);
+out_outsb:
+    atf_process_stream_fini(&outsb);
 out:
     return err;
 }
 
 static
 atf_error_t
-fork_cleanup(const atf_tc_t *tc, const atf_fs_path_t *workdir)
+fork_cleanup(const atf_tc_t *tc, int fdout, int fderr,
+             const atf_fs_path_t *workdir)
 {
     atf_error_t err;
-    pid_t pid;
 
     if (tc->m_cleanup == NULL)
         err = atf_no_error();
     else {
-        err = atf_process_fork(&pid);
+        atf_process_stream_t outsb, errsb;
+        atf_process_child_t child;
+        struct child_data data = {
+            tc,
+            workdir,
+        };
+
+        err = atf_process_stream_init_redirect_fd(&outsb, fdout);
         if (atf_is_error(err))
             goto out;
 
-        if (pid == 0) {
-            cleanup_child(tc, workdir);
-            UNREACHABLE;
-            abort();
-        } else {
-            err = cleanup_parent(tc, pid);
-        }
+        err = atf_process_stream_init_redirect_fd(&errsb, fderr);
+        if (atf_is_error(err))
+            goto out_outsb;
+
+        err = atf_process_fork(&child, cleanup_child, &outsb, &errsb, &data);
+        if (atf_is_error(err))
+            goto out_errsb;
+
+        err = cleanup_parent(tc, &child);
+
+out_errsb:
+        atf_process_stream_fini(&errsb);
+out_outsb:
+        atf_process_stream_fini(&outsb);
     }
 
 out:
@@ -544,13 +589,13 @@
 
 static
 atf_error_t
-prepare_child(const atf_tc_t *tc, const atf_fs_path_t *workdir)
+prepare_child(const struct child_data *cd)
 {
     atf_error_t err;
     int i, ret;
 
-    current_tc = tc;
-    current_workdir = workdir;
+    current_tc = cd->tc;
+    current_workdir = cd->workdir;
     current_tc_fail_count = 0;
 
     ret = setpgid(getpid(), 0);
@@ -561,7 +606,7 @@
     for (i = 1; i <= atf_signals_last_signo; i++)
         atf_signal_reset(i);
 
-    err = atf_env_set("HOME", atf_fs_path_cstring(workdir));
+    err = atf_env_set("HOME", atf_fs_path_cstring(cd->workdir));
     if (atf_is_error(err))
         goto out;
 
@@ -601,9 +646,9 @@
     if (atf_is_error(err))
         goto out;
 
-    if (chdir(atf_fs_path_cstring(workdir)) == -1) {
+    if (chdir(atf_fs_path_cstring(cd->workdir)) == -1) {
         err = atf_libc_error(errno, "Cannot enter work directory '%s'",
-                             atf_fs_path_cstring(workdir));
+                             atf_fs_path_cstring(cd->workdir));
         goto out;
     }
 
@@ -615,19 +660,21 @@
 
 static
 void
-body_child(const atf_tc_t *tc, const atf_fs_path_t *workdir)
+body_child(void *v)
 {
+    const struct child_data *cd = v;
     atf_error_t err;
 
-    atf_disable_exit_checks();
+    atf_reset_exit_checks();
 
-    err = prepare_child(tc, workdir);
+    err = prepare_child(cd);
     if (atf_is_error(err))
         goto print_err;
-    err = check_requirements(tc);
+    err = check_requirements(cd->tc);
     if (atf_is_error(err))
         goto print_err;
-    tc->m_body(tc);
+
+    cd->tc->m_body(cd->tc);
 
     if (current_tc_fail_count == 0)
         atf_tc_pass();
@@ -636,7 +683,6 @@
                     current_tc_fail_count);
 
     UNREACHABLE;
-    abort();
 
 print_err:
     INV(atf_is_error(err));
@@ -650,7 +696,6 @@
     }
 
     UNREACHABLE;
-    abort();
 }
 
 static
@@ -704,8 +749,12 @@
         goto out;
 
     if (atf_fs_path_is_absolute(&p)) {
-        if (atf_is_error(atf_fs_eaccess(&p, atf_fs_access_x)))
+        err = atf_fs_eaccess(&p, atf_fs_access_x);
+        if (atf_is_error(err)) {
+            atf_error_free(err);
+            atf_fs_path_fini(&p);
             atf_tc_skip("The required program %s could not be found", prog);
+        }
     } else {
         const char *path = atf_env_get("PATH");
         struct prog_found_pair pf;
@@ -715,9 +764,12 @@
         if (atf_is_error(err))
             goto out_p;
 
-        if (strcmp(atf_fs_path_cstring(&bp), ".") != 0)
+        if (strcmp(atf_fs_path_cstring(&bp), ".") != 0) {
+            atf_fs_path_fini(&bp);
+            atf_fs_path_fini(&p);
             atf_tc_fail("Relative paths are not allowed when searching for "
                         "a program (%s)", prog);
+        }
 
         pf.prog = prog;
         pf.found = false;
@@ -725,9 +777,12 @@
         if (atf_is_error(err))
             goto out_bp;
 
-        if (!pf.found)
+        if (!pf.found) {
+            atf_fs_path_fini(&bp);
+            atf_fs_path_fini(&p);
             atf_tc_skip("The required program %s could not be found in "
                         "the PATH", prog);
+        }
 
 out_bp:
         atf_fs_path_fini(&bp);
@@ -755,8 +810,14 @@
         if (atf_is_error(err))
             goto out_p;
 
-        if (!atf_is_error(atf_fs_eaccess(&p, atf_fs_access_x)))
+        err = atf_fs_eaccess(&p, atf_fs_access_x);
+        if (!atf_is_error(err))
             pf->found = true;
+        else {
+            atf_error_free(err);
+            INV(!pf->found);
+            err = atf_no_error();
+        }
 
 out_p:
         atf_fs_path_fini(&p);
@@ -852,22 +913,22 @@
 
 static
 void
-cleanup_child(const atf_tc_t *tc, const atf_fs_path_t *workdir)
+cleanup_child(void *v)
 {
+    const struct child_data *cd = v;
     atf_error_t err;
 
-    atf_disable_exit_checks();
-
-    err = prepare_child(tc, workdir);
-    if (atf_is_error(err))
+    err = prepare_child(cd);
+    if (atf_is_error(err)) {
+        atf_reset_exit_checks();
         exit(EXIT_FAILURE);
-    else {
-        tc->m_cleanup(tc);
+    } else {
+        atf_reset_exit_checks();
+        cd->tc->m_cleanup(cd->tc);
         exit(EXIT_SUCCESS);
     }
 
     UNREACHABLE;
-    abort();
 }
 
 static
@@ -921,6 +982,39 @@
         fatal_atf_error("Cannot write test case results", err);
 
     close(fd);
+    atf_fs_path_fini(&tcrfile);
+}
+
+static
+void
+tc_fail(atf_dynstr_t *msg)
+{
+    atf_tcr_t tcr;
+    atf_error_t err;
+
+    PRE(current_tc != NULL);
+
+    err = atf_tcr_init_reason_fmt(&tcr, atf_tcr_failed_state, "%s",
+                                  atf_dynstr_cstring(msg));
+    if (atf_is_error(err))
+        abort();
+
+    write_tcr(&tcr);
+
+    atf_tcr_fini(&tcr);
+    atf_dynstr_fini(msg);
+
+    exit(EXIT_SUCCESS);
+}
+
+static
+void
+tc_fail_nonfatal(atf_dynstr_t *msg)
+{
+    fprintf(stderr, "%s\n", atf_dynstr_cstring(msg));
+    atf_dynstr_fini(msg);
+
+    current_tc_fail_count++;
 }
 
 void
@@ -965,7 +1059,7 @@
 
     va_start(ap, fmt);
     fail_internal(file, line, "Check failed", "*** ", fmt, ap,
-                  atf_tc_fail_nonfatal);
+                  tc_fail_nonfatal, atf_tc_fail_nonfatal);
     va_end(ap);
 }
 
@@ -974,9 +1068,11 @@
 {
     va_list ap;
 
+    atf_reset_exit_checks();
+
     va_start(ap, fmt);
     fail_internal(file, line, "Requirement failed", "", fmt, ap,
-                  atf_tc_fail);
+                  tc_fail, atf_tc_fail);
     va_end(ap);
 
     UNREACHABLE;
@@ -987,7 +1083,8 @@
 void
 fail_internal(const char *file, int line, const char *reason,
               const char *prefix, const char *fmt, va_list ap,
-              void (*failfunc)(const char *, ...))
+              void (*failfunc)(atf_dynstr_t *),
+              void (*backupfunc)(const char *, ...))
 {
     va_list ap2;
     atf_error_t err;
@@ -1007,13 +1104,13 @@
     }
 
     va_copy(ap2, ap);
-    failfunc("%s", atf_dynstr_cstring(&msg));
-    atf_dynstr_fini(&msg);
+    failfunc(&msg);
     return;
 
 backup:
+    atf_error_free(err);
     va_copy(ap2, ap);
-    failfunc(fmt, ap2);
+    backupfunc(fmt, ap2);
     va_end(ap2);
 }
 
@@ -1042,8 +1139,10 @@
     atf_error_t err;
 
     err = check_prog(prog, NULL);
-    if (atf_is_error(err))
+    if (atf_is_error(err)) {
+        atf_error_free(err);
         atf_tc_fail("atf_tc_require_prog failed"); /* XXX Correct? */
+    }
 }
 
 void

Reply via email to