github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/cmd/libsnap-confine-private/cleanup-funcs-test.c (about)

     1  /*
     2   * Copyright (C) 2015 Canonical Ltd
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License version 3 as
     6   * published by the Free Software Foundation.
     7   *
     8   * This program is distributed in the hope that it will be useful,
     9   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11   * GNU General Public License for more details.
    12   *
    13   * You should have received a copy of the GNU General Public License
    14   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15   *
    16   */
    17  
    18  #include "cleanup-funcs.h"
    19  #include "cleanup-funcs.c"
    20  
    21  #include <glib.h>
    22  #include <glib/gstdio.h>
    23  
    24  #include <fcntl.h>
    25  #include <sys/types.h>
    26  #include <sys/stat.h>
    27  #include <sys/timerfd.h>
    28  
    29  static int called = 0;
    30  
    31  static void cleanup_fn(int *ptr)
    32  {
    33  	called = 1;
    34  }
    35  
    36  // Test that cleanup functions are applied as expected
    37  static void test_cleanup_sanity(void)
    38  {
    39  	{
    40  		int test SC_CLEANUP(cleanup_fn);
    41  		test = 0;
    42  		test++;
    43  	}
    44  	g_assert_cmpint(called, ==, 1);
    45  }
    46  
    47  static void test_cleanup_string(void)
    48  {
    49  	/* It is safe to use with a NULL pointer to a string. */
    50  	sc_cleanup_string(NULL);
    51  
    52  	/* It is safe to use with a NULL string. */
    53  	char *str = NULL;
    54  	sc_cleanup_string(&str);
    55  
    56  	/* It is safe to use with a non-NULL string. */
    57  	str = malloc(1);
    58  	g_assert_nonnull(str);
    59  	sc_cleanup_string(&str);
    60  	g_assert_null(str);
    61  }
    62  
    63  static void test_cleanup_file(void)
    64  {
    65  	/* It is safe to use with a NULL pointer to a FILE. */
    66  	sc_cleanup_file(NULL);
    67  
    68  	/* It is safe to use with a NULL FILE. */
    69  	FILE *f = NULL;
    70  	sc_cleanup_file(&f);
    71  
    72  	/* It is safe to use with a non-NULL FILE. */
    73  	f = fmemopen(NULL, 10, "rt");
    74  	g_assert_nonnull(f);
    75  	sc_cleanup_file(&f);
    76  	g_assert_null(f);
    77  }
    78  
    79  static void test_cleanup_endmntent(void)
    80  {
    81  	/* It is safe to use with a NULL pointer to a FILE. */
    82  	sc_cleanup_endmntent(NULL);
    83  
    84  	/* It is safe to use with a NULL FILE. */
    85  	FILE *f = NULL;
    86  	sc_cleanup_endmntent(&f);
    87  
    88  	/* It is safe to use with a non-NULL FILE. */
    89  	GError *err = NULL;
    90  	char *mock_fstab = NULL;
    91  	gint mock_fstab_fd =
    92  	    g_file_open_tmp("s-c-test-fstab-mock.XXXXXX", &mock_fstab, &err);
    93  	g_assert_no_error(err);
    94  	g_assert_cmpint(mock_fstab_fd, >=, 0);
    95  	g_assert_true(g_close(mock_fstab_fd, NULL));
    96  	/* XXX: not strictly needed as the test only calls setmntent */
    97  	const char *mock_fstab_data = "/dev/foo / ext4 defaults 0 1";
    98  	g_assert_true(g_file_set_contents
    99  		      (mock_fstab, mock_fstab_data, -1, NULL));
   100  
   101  	f = setmntent(mock_fstab, "rt");
   102  	g_assert_nonnull(f);
   103  	sc_cleanup_endmntent(&f);
   104  	g_assert_null(f);
   105  
   106  	g_remove(mock_fstab);
   107  
   108  	g_free(mock_fstab);
   109  }
   110  
   111  static void test_cleanup_closedir(void)
   112  {
   113  	/* It is safe to use with a NULL pointer to a DIR. */
   114  	sc_cleanup_closedir(NULL);
   115  
   116  	/* It is safe to use with a NULL DIR. */
   117  	DIR *d = NULL;
   118  	sc_cleanup_closedir(&d);
   119  
   120  	/* It is safe to use with a non-NULL DIR. */
   121  	d = opendir(".");
   122  	g_assert_nonnull(d);
   123  	sc_cleanup_closedir(&d);
   124  	g_assert_null(d);
   125  }
   126  
   127  static void test_cleanup_close(void)
   128  {
   129  	/* It is safe to use with a NULL pointer to an int. */
   130  	sc_cleanup_close(NULL);
   131  
   132  	/* It is safe to use with a -1 file descriptor. */
   133  	int fd = -1;
   134  	sc_cleanup_close(&fd);
   135  
   136  	/* It is safe to use with a non-invalid file descriptor. */
   137  	/* Timerfd is a simple to use and widely available object that can be
   138  	 * created and closed without interacting with the filesystem. */
   139  	fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
   140  	g_assert_cmpint(fd, !=, -1);
   141  	sc_cleanup_close(&fd);
   142  	g_assert_cmpint(fd, ==, -1);
   143  }
   144  
   145  static void __attribute__((constructor)) init(void)
   146  {
   147  	g_test_add_func("/cleanup/sanity", test_cleanup_sanity);
   148  	g_test_add_func("/cleanup/string", test_cleanup_string);
   149  	g_test_add_func("/cleanup/file", test_cleanup_file);
   150  	g_test_add_func("/cleanup/endmntent", test_cleanup_endmntent);
   151  	g_test_add_func("/cleanup/closedir", test_cleanup_closedir);
   152  	g_test_add_func("/cleanup/close", test_cleanup_close);
   153  }