 04527412e3
			
		
	
	04527412e3
	
	
	
		
			
			The pseudo keyword 'fallthrough' is defined such that case statement blocks must end with any of these keywords: * break; * fallthrough; * continue; * goto <label>; * return [expression]; * * gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes The macro is defined either as __attribute__((__fallthrough__)) or as do {} while (0) /* fallthrough */ not including the semicolon. This change implements the Linux kernel style and updates several locations where "/*fallthrough*/ and /* FALLTHROUGH */ were not previously replaced. Externally imported code such as libedit, libtommath and sqlite are restored to their unaltered state. Change-Id: I69db8167b0d5884f55d96d72de3059a0235a1ba3
		
			
				
	
	
		
			279 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			279 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /***********************************************************************
 | |
|  * Copyright (c) 2009, Secure Endpoints Inc.
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions
 | |
|  * are met:
 | |
|  *
 | |
|  * - Redistributions of source code must retain the above copyright
 | |
|  *   notice, this list of conditions and the following disclaimer.
 | |
|  *
 | |
|  * - Redistributions in binary form must reproduce the above copyright
 | |
|  *   notice, this list of conditions and the following disclaimer in
 | |
|  *   the documentation and/or other materials provided with the
 | |
|  *   distribution.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
|  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | |
|  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | |
|  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 | |
|  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | |
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | |
|  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | |
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | |
|  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
|  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 | |
|  * OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  *
 | |
|  **********************************************************************/
 | |
| #include <config.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdarg.h>
 | |
| #include <direct.h>
 | |
| #include <errno.h>
 | |
| #include <io.h>
 | |
| #include <fcntl.h>
 | |
| #include <sys/stat.h>
 | |
| #include <string.h>
 | |
| #include "dirent.h"
 | |
| 
 | |
| /* Note that we create a known directory structure in a subdirectory
 | |
|    of the current directory to run our tests. */
 | |
| 
 | |
| #define TESTDIR "dirent-test-dir"
 | |
| 
 | |
| const char * dir_entries[] = {
 | |
|     "A",
 | |
|     "B",
 | |
|     "C",
 | |
|     "CAA",
 | |
|     "CAAA",
 | |
|     "CABBBB",
 | |
|     "CAABBB.txt",
 | |
|     "A filename with spaces"
 | |
| };
 | |
| 
 | |
| const char * entries_begin_with_C[] = {
 | |
|     "C",
 | |
|     "CAA",
 | |
|     "CAAA",
 | |
|     "CABBBB",
 | |
|     "CAABBB.txt"
 | |
| };
 | |
| 
 | |
| const char * entries_end_with_A[] = {
 | |
|     "A",
 | |
|     "CAA",
 | |
|     "CAAA"
 | |
| };
 | |
| 
 | |
| const int n_dir_entries = sizeof(dir_entries)/sizeof(dir_entries[0]);
 | |
| 
 | |
| int teardown_test(void);
 | |
| 
 | |
| void fail_test(const char * reason, ...)
 | |
| {
 | |
|     va_list args;
 | |
| 
 | |
|     va_start(args, reason);
 | |
|     vfprintf(stderr, reason, args);
 | |
|     va_end(args);
 | |
| 
 | |
|     fprintf(stderr, " : errno = %d (%s)\n", errno, strerror(errno));
 | |
|     teardown_test();
 | |
|     abort();
 | |
| }
 | |
| 
 | |
| void fail_test_nf(const char * format, ...)
 | |
| {
 | |
|     va_list args;
 | |
| 
 | |
|     fprintf(stderr, "FAIL:");
 | |
| 
 | |
|     va_start(args, format);
 | |
|     vfprintf(stderr, format, args);
 | |
|     va_end(args);
 | |
| 
 | |
|     fprintf(stderr, " : errno = %d (%s)\n", errno, strerror(errno));
 | |
| }
 | |
| 
 | |
| int touch(const char * filename)
 | |
| {
 | |
|     int fd;
 | |
| 
 | |
|     fd = _open(filename, _O_CREAT, _S_IREAD| _S_IWRITE);
 | |
| 
 | |
|     if (fd == -1)
 | |
|         return -1;
 | |
| 
 | |
|     return _close(fd);
 | |
| }
 | |
| 
 | |
| int setup_test(void)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     fprintf(stderr, "Creating test directory %s ...\n", TESTDIR);
 | |
| 
 | |
|     if (_mkdir(TESTDIR))
 | |
|         fail_test("Can't create test directory \"" TESTDIR "\"");
 | |
| 
 | |
|     if (_chdir(TESTDIR))
 | |
|         fail_test("Can't change to test directory");
 | |
| 
 | |
|     for (i=0; i < n_dir_entries; i++) {
 | |
|         if (touch(dir_entries[i]))
 | |
|             fail_test("Can't create test file '%s'", dir_entries[i]);
 | |
|     }
 | |
| 
 | |
|     fprintf(stderr, "Done with test setup.\n");
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int teardown_test(void)
 | |
| {
 | |
|     char dirname[_MAX_PATH];
 | |
|     size_t len;
 | |
|     int i;
 | |
| 
 | |
|     printf ("Begin cleanup...\n");
 | |
| 
 | |
|     if (_getcwd(dirname, sizeof(dirname)/sizeof(char)) != NULL &&
 | |
| 
 | |
|         (len = strlen(dirname)) > sizeof(TESTDIR)/sizeof(char) &&
 | |
| 
 | |
|         strcmp(dirname + len + 1 - sizeof(TESTDIR)/sizeof(char), TESTDIR) == 0) {
 | |
| 
 | |
|         fallthrough;
 | |
| 
 | |
|     } else {
 | |
|         /* did we create the directory? */
 | |
| 
 | |
|         if (!_rmdir( TESTDIR )) {
 | |
|             fprintf(stderr, "Removed test directory\n");
 | |
|             return 0;
 | |
|         } else {
 | |
|             if (errno == ENOTEMPTY) {
 | |
|                 if (_chdir(TESTDIR)) {
 | |
|                     fprintf(stderr, "Can't change to test directory. Aborting cleanup.\n");
 | |
|                     return -1;
 | |
|                 } else {
 | |
|                     fallthrough;
 | |
|                 }
 | |
|             } else {
 | |
|                 return -1;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     fprintf(stderr, "Cleaning up test directory %s ...\n", TESTDIR);
 | |
| 
 | |
|     for (i=0; i < n_dir_entries; i++) {
 | |
|         if (_unlink(dir_entries[i])) {
 | |
|             /* if the test setup failed, we expect this to happen for
 | |
|                at least some files */
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (_chdir("..")) {
 | |
|         fprintf(stderr, "Can't escape test directory. Giving in.\n");
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     if (_rmdir( TESTDIR )) {
 | |
|         fprintf(stderr, "Can't remove test directory.\n");
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     printf("Cleaned up test directory\n");
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int check_list(const char * filespec, const char ** list, int n, int expect_dot_and_dotdot)
 | |
| {
 | |
|     DIR * d;
 | |
|     struct dirent * e;
 | |
|     int n_found = 0;
 | |
|     int i;
 | |
|     int rv = 0;
 | |
|     int retry = 1;
 | |
| 
 | |
|     d = opendir(filespec);
 | |
|     if (d == NULL) {
 | |
|         fail_test_nf("opendir failed for [%s]", filespec);
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     printf("Checking filespec [%s]... ", filespec);
 | |
| 
 | |
|  retry:
 | |
|     while ((e = readdir(d)) != NULL) {
 | |
|         n_found ++;
 | |
| 
 | |
|         if (expect_dot_and_dotdot &&
 | |
|             (strcmp(e->d_name, ".") == 0 ||
 | |
|              strcmp(e->d_name, "..") == 0))
 | |
|             continue;
 | |
| 
 | |
|         for (i=0; i < n; i++) {
 | |
|             if (strcmp(list[i], e->d_name) == 0)
 | |
|                 break;
 | |
|         }
 | |
| 
 | |
|         if (i == n) {
 | |
|             fail_test_nf("Found unexpected entry [%s]", e->d_name);
 | |
|             rv = -1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (n_found != n) {
 | |
|         fail_test_nf("Unexpected number of entries [%d].  Expected %d", n_found, n);
 | |
|         rv = -1;
 | |
|     }
 | |
| 
 | |
|     if (retry) {
 | |
|         retry = 0;
 | |
|         n_found = 0;
 | |
| 
 | |
|         rewinddir(d);
 | |
|         goto retry;
 | |
|     }
 | |
| 
 | |
|     if (closedir(d)) {
 | |
|         fail_test_nf("closedir() failed");
 | |
|     }
 | |
| 
 | |
|     printf("done\n");
 | |
| 
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| int run_tests()
 | |
| {
 | |
|     /* assumes that the test directory has been set up and we have
 | |
|        changed into the test directory. */
 | |
| 
 | |
|     check_list("*", dir_entries, n_dir_entries + 2, 1);
 | |
|     check_list("*.*", dir_entries, n_dir_entries + 2, 1);
 | |
|     check_list("C*", entries_begin_with_C, sizeof(entries_begin_with_C)/sizeof(entries_begin_with_C[0]), 0);
 | |
|     check_list("*A", entries_end_with_A, sizeof(entries_end_with_A)/sizeof(entries_end_with_A[0]), 0);
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int main(int argc, char ** argv)
 | |
| {
 | |
|     if (setup_test())
 | |
|         return 1;
 | |
| 
 | |
|     run_tests();
 | |
| 
 | |
|     teardown_test();
 | |
| 
 | |
|     return 0;
 | |
| }
 |