void OBSBasic::on_actionRemoveSceneCollection_triggered()
{
	std::string newName;
	std::string newPath;

	std::string oldFile = config_get_string(App()->GlobalConfig(),
			"Basic", "SceneCollectionFile");
	std::string oldName = config_get_string(App()->GlobalConfig(),
			"Basic", "SceneCollection");

	auto cb = [&](const char *name, const char *filePath)
	{
		if (strcmp(oldName.c_str(), name) != 0) {
			newName = name;
			newPath = filePath;
			return false;
		}

		return true;
	};

	EnumSceneCollections(cb);

	/* this should never be true due to menu item being grayed out */
	if (newPath.empty())
		return;

	QString text = QTStr("ConfirmRemove.Text");
	text.replace("$1", QT_UTF8(oldName.c_str()));

	QMessageBox::StandardButton button = QMessageBox::question(this,
			QTStr("ConfirmRemove.Title"), text);
	if (button == QMessageBox::No)
		return;

	char path[512];
	int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
	if (ret <= 0) {
		blog(LOG_WARNING, "Failed to get scene collection config path");
		return;
	}

	oldFile.insert(0, path);
	oldFile += ".json";
	os_unlink(oldFile.c_str());

	Load(newPath.c_str());
	RefreshSceneCollections();

	const char *newFile = config_get_string(App()->GlobalConfig(),
			"Basic", "SceneCollectionFile");

	blog(LOG_INFO, "Removed scene collection '%s' (%s.json), "
			"switched to '%s' (%s.json)",
			oldName.c_str(), oldFile.c_str(),
			newName.c_str(), newFile);
	blog(LOG_INFO, "------------------------------------------------");

	UpdateTitleBar();
}
Exemplo n.º 2
0
static void dag_clean(struct dag * slf){

    int i, silent, rv;
    struct pkg * pk;
    char ** packages = slf->pkgs->keys(slf->pkgs);
    
    if(packages){

        silent = global_get_bool("-quiet");
        
        for(i = 0; packages[i]; i++){
            pk = get_pkg_from_name(slf, packages[i]);
            if(pk->o_file && is_file(pk->o_file)){
                if(! silent){
                    printf("rm: %s\n", pk->o_file);
                }
                rv = os_unlink(pk->o_file);
                if(rv){
                    perror(pk->o_file);
                    panic("failed to delete file", __FILE__, __LINE__);
                }
            }
        }       
    }
};
Exemplo n.º 3
0
Arquivo: file.c Projeto: krzycz/nvml
/*
 * util_file_create -- create a new memory pool file
 */
int
util_file_create(const char *path, size_t size, size_t minsize)
{
	LOG(3, "path \"%s\" size %zu minsize %zu", path, size, minsize);

	ASSERTne(size, 0);

	if (size < minsize) {
		ERR("size %zu smaller than %zu", size, minsize);
		errno = EINVAL;
		return -1;
	}

	if (((os_off_t)size) < 0) {
		ERR("invalid size (%zu) for os_off_t", size);
		errno = EFBIG;
		return -1;
	}

	int fd;
	int mode;
	int flags = O_RDWR | O_CREAT | O_EXCL;
#ifndef _WIN32
	mode = 0;
#else
	mode = S_IWRITE | S_IREAD;
	flags |= O_BINARY;
#endif

	/*
	 * Create file without any permission. It will be granted once
	 * initialization completes.
	 */
	if ((fd = os_open(path, flags, mode)) < 0) {
		ERR("!open \"%s\"", path);
		return -1;
	}

	if ((errno = os_posix_fallocate(fd, 0, (os_off_t)size)) != 0) {
		ERR("!posix_fallocate \"%s\", %zu", path, size);
		goto err;
	}

	/* for windows we can't flock until after we fallocate */
	if (os_flock(fd, OS_LOCK_EX | OS_LOCK_NB) < 0) {
		ERR("!flock \"%s\"", path);
		goto err;
	}

	return fd;

err:
	LOG(4, "error clean up");
	int oerrno = errno;
	if (fd != -1)
		(void) os_close(fd);
	os_unlink(path);
	errno = oerrno;
	return -1;
}
Exemplo n.º 4
0
int state_uninit(void)
{
    int err;

    state = &main_state;

    if (state->write_ram_buf && !state->ram_buf_rm) {
        err = os_write_ram_buf(state->ram_buf_fname);
        if (err) {
            printf("Failed to write RAM buffer\n");
            return err;
        }
    }

    if (state->write_state) {
        if (sandbox_write_state(state, state->state_fname)) {
            printf("Failed to write sandbox state\n");
            return -1;
        }
    }

    /* Delete this at the last moment so as not to upset gdb too much */
    if (state->jumped_fname)
        os_unlink(state->jumped_fname);

    if (state->state_fdt)
        os_free(state->state_fdt);
    memset(state, '\0', sizeof(*state));

    return 0;
}
Exemplo n.º 5
0
GPublic void file_remove(String_t szFileName)
{
    if (szFileName != NULL)
    {
        os_unlink(szFileName);
    }
}
Exemplo n.º 6
0
static void dag_unlink_test(struct dag * slf, char * tstamp){
    
    // test package should be last package of slf->sorted
    int i, fail;
    for(i = 0; slf->sorted[i]; i++);

    struct pkg * pk;
    pk = slf->sorted[i-1];

    // we can assume all is fine if this is ok
    if( starts_with( pk->name, tstamp) ){

        fail = os_unlink(pk->c_file);
        if(fail){
            perror(pk->c_file);
            panic(NULL, __FILE__, __LINE__);
        }

        fail = os_unlink(pk->o_file);
        if(fail){
            perror(pk->o_file);
            panic(NULL, __FILE__, __LINE__);
        }
    }

    const char * testdir[2];
    testdir[0] = global_get_str("-src");
    testdir[1] = tstamp;

    char * testpath = path_join_len(testdir, 2);
    fail = os_rmdir(testpath);
    if(fail){
        perror(testpath);
        panic(NULL,__FILE__,__LINE__);
    }

    free(testpath);

    if(is_file(global_get_str("-testbin"))){
        fail = os_unlink(global_get_str("-testbin"));
        if(fail){
            perror(global_get_str("-testbin"));
            panic(NULL,__FILE__,__LINE__);
        }
    }
};
Exemplo n.º 7
0
bool os_quick_write_utf8_file_safe(const char *path, const char *str,
		size_t len, bool marker, const char *temp_ext,
		const char *backup_ext)
{
	struct dstr backup_path = {0};
	struct dstr temp_path = {0};
	bool success = false;

	if (!temp_ext || !*temp_ext) {
		blog(LOG_ERROR, "os_quick_write_utf8_file_safe: invalid "
		                "temporary extension specified");
		return false;
	}

	dstr_copy(&temp_path, path);
	if (*temp_ext != '.')
		dstr_cat(&temp_path, ".");
	dstr_cat(&temp_path, temp_ext);

	if (!os_quick_write_utf8_file(temp_path.array, str, len, marker)) {
		goto cleanup;
	}

	if (backup_ext && *backup_ext) {
		dstr_copy(&backup_path, path);
		if (*backup_ext != '.')
			dstr_cat(&backup_path, ".");
		dstr_cat(&backup_path, backup_ext);

		os_unlink(backup_path.array);
		os_rename(path, backup_path.array);

		dstr_free(&backup_path);
	} else {
		os_unlink(path);
	}

	os_rename(temp_path.array, path);
	success = true;

cleanup:
	dstr_free(&backup_path);
	dstr_free(&temp_path);
	return success;
}
Exemplo n.º 8
0
/*
 * ut_unlink -- an unlink that cannot return -1
 */
int
ut_unlink(const char *file, int line, const char *func, const char *path)
{
	int retval = os_unlink(path);

	if (retval != 0)
		ut_fatal(file, line, func, "!unlink: %s", path);

	return retval;
}
Exemplo n.º 9
0
static inline void replace_file(const char *src_base_path,
		const char *dst_base_path, const char *file)
{
	char *src_path = get_path(src_base_path, file);
	char *dst_path = get_path(dst_base_path, file);

	if (src_path && dst_path) {
		os_unlink(dst_path);
		os_rename(src_path, dst_path);
	}

	bfree(dst_path);
	bfree(src_path);
}
Exemplo n.º 10
0
static void copy_local_to_cache(struct update_info *info, const char *file)
{
	char *local_file_path = get_path(info->local, file);
	char *cache_file_path = get_path(info->cache, file);
	char *temp_file_path  = get_path(info->temp,  file);

	os_copyfile(local_file_path, temp_file_path);
	os_unlink(cache_file_path);
	os_rename(temp_file_path, cache_file_path);

	bfree(local_file_path);
	bfree(cache_file_path);
	bfree(temp_file_path);
}
void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir)
{
	char profilePath[512];
	char basePath[512];

	int ret = GetConfigPath(basePath, 512, "obs-studio/basic/profiles");
	if (ret <= 0) {
		blog(LOG_WARNING, "Failed to get profiles config path");
		return;
	}

	ret = snprintf(profilePath, 512, "%s/%s/*", basePath, profileDir);
	if (ret <= 0) {
		blog(LOG_WARNING, "Failed to get path for profile dir '%s'",
				profileDir);
		return;
	}

	os_glob_t *glob;
	if (os_glob(profilePath, 0, &glob) != 0) {
		blog(LOG_WARNING, "Failed to glob profile dir '%s'",
				profileDir);
		return;
	}

	for (size_t i = 0; i < glob->gl_pathc; i++) {
		const char *filePath = glob->gl_pathv[i].path;

		if (glob->gl_pathv[i].directory)
			continue;

		os_unlink(filePath);
	}

	os_globfree(glob);

	ret = snprintf(profilePath, 512, "%s/%s", basePath, profileDir);
	if (ret <= 0) {
		blog(LOG_WARNING, "Failed to get path for profile dir '%s'",
				profileDir);
		return;
	}

	os_rmdir(profilePath);

	blog(LOG_INFO, "------------------------------------------------");
	blog(LOG_INFO, "Removed profile '%s' (%s)",
			profileName, profileDir);
	blog(LOG_INFO, "------------------------------------------------");
}
Exemplo n.º 12
0
int main(int argc, char *argv[])
{
	struct sandbox_state *state;
	gd_t data;
	int ret;

	ret = state_init();
	if (ret)
		goto err;

	state = state_get_current();
	if (os_parse_args(state, argc, argv))
		return 1;

	ret = sandbox_read_state(state, state->state_fname);
	if (ret)
		goto err;

	/* Remove old memory file if required */
	if (state->ram_buf_rm && state->ram_buf_fname)
		os_unlink(state->ram_buf_fname);

	memset(&data, '\0', sizeof(data));
	gd = &data;
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
	gd->malloc_base = CONFIG_MALLOC_F_ADDR;
#endif
	setup_ram_buf(state);

	/* Do pre- and post-relocation init */
	board_init_f(0);

	board_init_r(gd->new_gd, 0);

	/* NOTREACHED - board_init_r() does not return */
	return 0;

err:
	printf("Error %d\n", ret);
	return 1;
}
Exemplo n.º 13
0
Arquivo: file.c Projeto: krzycz/nvml
/*
 * util_unlink -- unlinks a file or zeroes a device dax
 */
int
util_unlink(const char *path)
{
	LOG(3, "path \"%s\"", path);

	enum file_type type = util_file_get_type(path);
	if (type < 0)
		return -1;

	if (type == TYPE_DEVDAX) {
		return util_file_zero(path, 0, DEVICE_DAX_ZERO_LEN);
	} else {
#ifdef _WIN32
		/* on Windows we can not unlink Read-Only files */
		if (os_chmod(path, S_IREAD | S_IWRITE) == -1) {
			ERR("!chmod \"%s\"", path);
			return -1;
		}
#endif
		return os_unlink(path);
	}
}
void OBSBasic::on_actionRenameSceneCollection_triggered()
{
	std::string name;
	std::string file;

	std::string oldFile = config_get_string(App()->GlobalConfig(),
			"Basic", "SceneCollectionFile");
	const char *oldName = config_get_string(App()->GlobalConfig(),
			"Basic", "SceneCollection");

	bool success = GetSceneCollectionName(this, name, file, oldName);
	if (!success)
		return;

	config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection",
			name.c_str());
	config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile",
			file.c_str());
	SaveProjectNow();

	char path[512];
	int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
	if (ret <= 0) {
		blog(LOG_WARNING, "Failed to get scene collection config path");
		return;
	}

	oldFile.insert(0, path);
	oldFile += ".json";
	os_unlink(oldFile.c_str());

	blog(LOG_INFO, "------------------------------------------------");
	blog(LOG_INFO, "Renamed scene collection to '%s' (%s.json)",
			name.c_str(), file.c_str());
	blog(LOG_INFO, "------------------------------------------------");

	UpdateTitleBar();
	RefreshSceneCollections();
}
Exemplo n.º 15
0
Arquivo: pmem.c Projeto: ldorau/nvml
static inline
#endif
void *
pmem_map_fileU(const char *path, size_t len, int flags,
	mode_t mode, size_t *mapped_lenp, int *is_pmemp)
{
	LOG(3, "path \"%s\" size %zu flags %x mode %o mapped_lenp %p "
		"is_pmemp %p", path, len, flags, mode, mapped_lenp, is_pmemp);

	int oerrno;
	int fd;
	int open_flags = O_RDWR;
	int delete_on_err = 0;
	int file_type = util_file_get_type(path);
#ifdef _WIN32
	open_flags |= O_BINARY;
#endif

	if (file_type == OTHER_ERROR)
		return NULL;

	if (flags & ~(PMEM_FILE_ALL_FLAGS)) {
		ERR("invalid flag specified %x", flags);
		errno = EINVAL;
		return NULL;
	}

	if (file_type == TYPE_DEVDAX) {
		if (flags & ~(PMEM_DAX_VALID_FLAGS)) {
			ERR("flag unsupported for Device DAX %x", flags);
			errno = EINVAL;
			return NULL;
		} else {
			/* we are ignoring all of the flags */
			flags = 0;
			ssize_t actual_len = util_file_get_size(path);
			if (actual_len < 0) {
				ERR("unable to read Device DAX size");
				errno = EINVAL;
				return NULL;
			}
			if (len != 0 && len != (size_t)actual_len) {
				ERR("Device DAX length must be either 0 or "
					"the exact size of the device: %zu",
					actual_len);
				errno = EINVAL;
				return NULL;
			}
			len = 0;
		}
	}

	if (flags & PMEM_FILE_CREATE) {
		if ((os_off_t)len < 0) {
			ERR("invalid file length %zu", len);
			errno = EINVAL;
			return NULL;
		}
		open_flags |= O_CREAT;
	}

	if (flags & PMEM_FILE_EXCL)
		open_flags |= O_EXCL;

	if ((len != 0) && !(flags & PMEM_FILE_CREATE)) {
		ERR("non-zero 'len' not allowed without PMEM_FILE_CREATE");
		errno = EINVAL;
		return NULL;
	}

	if ((len == 0) && (flags & PMEM_FILE_CREATE)) {
		ERR("zero 'len' not allowed with PMEM_FILE_CREATE");
		errno = EINVAL;
		return NULL;
	}

	if ((flags & PMEM_FILE_TMPFILE) && !(flags & PMEM_FILE_CREATE)) {
		ERR("PMEM_FILE_TMPFILE not allowed without PMEM_FILE_CREATE");
		errno = EINVAL;
		return NULL;
	}

	if (flags & PMEM_FILE_TMPFILE) {
		if ((fd = util_tmpfile(path,
					OS_DIR_SEP_STR"pmem.XXXXXX",
					open_flags & O_EXCL)) < 0) {
			LOG(2, "failed to create temporary file at \"%s\"",
				path);
			return NULL;
		}
	} else {
		if ((fd = os_open(path, open_flags, mode)) < 0) {
			ERR("!open %s", path);
			return NULL;
		}
		if ((flags & PMEM_FILE_CREATE) && (flags & PMEM_FILE_EXCL))
			delete_on_err = 1;
	}

	if (flags & PMEM_FILE_CREATE) {
		/*
		 * Always set length of file to 'len'.
		 * (May either extend or truncate existing file.)
		 */
		if (os_ftruncate(fd, (os_off_t)len) != 0) {
			ERR("!ftruncate");
			goto err;
		}
		if ((flags & PMEM_FILE_SPARSE) == 0) {
			if ((errno = os_posix_fallocate(fd, 0,
							(os_off_t)len)) != 0) {
				ERR("!posix_fallocate");
				goto err;
			}
		}
	} else {
		ssize_t actual_size = util_file_get_size(path);
		if (actual_size < 0) {
			ERR("stat %s: negative size", path);
			errno = EINVAL;
			goto err;
		}

		len = (size_t)actual_size;
	}

	void *addr = pmem_map_register(fd, len, path, file_type == TYPE_DEVDAX);
	if (addr == NULL)
		goto err;

	if (mapped_lenp != NULL)
		*mapped_lenp = len;

	if (is_pmemp != NULL)
		*is_pmemp = pmem_is_pmem(addr, len);

	LOG(3, "returning %p", addr);

	VALGRIND_REGISTER_PMEM_MAPPING(addr, len);
	VALGRIND_REGISTER_PMEM_FILE(fd, addr, len, 0);

	(void) os_close(fd);

	return addr;
err:
	oerrno = errno;
	(void) os_close(fd);
	if (delete_on_err)
		(void) os_unlink(path);
	errno = oerrno;
	return NULL;
}
Exemplo n.º 16
0
// Create test directory.
inline int dir_setup(const char *testdir)
{
	int ret;

#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 3
	if ((ret = __os_mkdir(NULL, testdir, 0755)) != 0) {
#else
	if ((ret = mkdir(testdir, 0755)) != 0) {
#endif
		fprintf(stderr,
		    "dir_setup: Creating directory %s: %s\n", 
		    testdir, db_strerror(ret));
		return (1);
	}
	return (0);
}

inline int os_unlink(const char *path)
{
#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 7
	return (__os_unlink(NULL, path));
#else
	return (__os_unlink(NULL, path, 0));
#endif
}

#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 4
#define	OS_EXISTS(a, b, c)	__os_exists(a, b, c)
#else
#define	OS_EXISTS(a, b, c)	__os_exists(b, c)
#endif

// Remove contents in specified directory recursively(in DB versions earlier 
// than 4.6, don't recursively), and optionally remove the directory itself.
int rmdir_rcsv(const char *dir, bool keep_this_dir)
{
	int cnt, i, isdir, ret;
	char buf[1024], **names;

	ret = 0;

	/* If the directory doesn't exist, we're done. */
	if (OS_EXISTS(NULL, dir, &isdir) != 0)
		return (0);

	/* Get a list of the directory contents. */
#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 6
	if ((ret = __os_dirlist(NULL, dir, 1, &names, &cnt)) != 0)
		return (ret);
#else
	if ((ret = __os_dirlist(NULL, dir, &names, &cnt)) != 0)
		return (ret);
#endif
	/* Go through the file name list, remove each file in the list */
	for (i = 0; i < cnt; ++i) {
		(void)snprintf(buf, sizeof(buf),
		    "%s%c%s", dir, PATH_SEPARATOR[0], names[i]);
		if ((ret = OS_EXISTS(NULL, buf, &isdir)) != 0)
			goto file_err;
		if (!isdir && (ret = os_unlink(buf)) != 0) {
file_err:		fprintf(stderr, 
			    "os_unlink: Error unlinking file: %s: %s\n",
			    buf, db_strerror(ret));
			break;
		}
		if (isdir && rmdir_rcsv(buf, false) != 0)
			goto file_err;
	}

	__os_dirfree(NULL, names, cnt);

	/*
	 * If we removed the contents of the directory and we don't want to
	 * keep this directory, remove the directory itself.
	 */
	if (i == cnt && !keep_this_dir && (ret = rmdir(dir)) != 0)
		fprintf(stderr,
		    "rmdir_rcsv(%s): %s\n", dir, db_strerror(errno));
	return (ret);
} // rmdir_rcsv
Exemplo n.º 17
0
static int do_ut_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	printf("%s: Testing commands\n", __func__);
	run_command("env default -f -a", 0);

	/* run a single command */
	run_command("setenv single 1", 0);
	assert(!strcmp("1", getenv("single")));

	/* make sure that compound statements work */
#ifdef CONFIG_SYS_HUSH_PARSER
	run_command("if test -n ${single} ; then setenv check 1; fi", 0);
	assert(!strcmp("1", getenv("check")));
	run_command("setenv check", 0);
#endif

	/* commands separated by ; */
	run_command_list("setenv list 1; setenv list ${list}1", -1, 0);
	assert(!strcmp("11", getenv("list")));

	/* commands separated by \n */
	run_command_list("setenv list 1\n setenv list ${list}1", -1, 0);
	assert(!strcmp("11", getenv("list")));

	/* command followed by \n and nothing else */
	run_command_list("setenv list 1${list}\n", -1, 0);
	assert(!strcmp("111", getenv("list")));

	/* three commands in a row */
	run_command_list("setenv list 1\n setenv list ${list}2; "
		"setenv list ${list}3", -1, 0);
	assert(!strcmp("123", getenv("list")));

	/* a command string with \0 in it. Stuff after \0 should be ignored */
	run_command("setenv list", 0);
	run_command_list(test_cmd, sizeof(test_cmd), 0);
	assert(!strcmp("123", getenv("list")));

	/*
	 * a command list where we limit execution to only the first command
	 * using the length parameter.
	 */
	run_command_list("setenv list 1\n setenv list ${list}2; "
		"setenv list ${list}3", strlen("setenv list 1"), 0);
	assert(!strcmp("1", getenv("list")));

	assert(run_command("false", 0) == 1);
	assert(run_command("echo", 0) == 0);
	assert(run_command_list("false", -1, 0) == 1);
	assert(run_command_list("echo", -1, 0) == 0);

#ifdef CONFIG_SYS_HUSH_PARSER
	/* Test the 'test' command */

#define HUSH_TEST(name, expr, expected_result) \
	run_command("if test " expr " ; then " \
			"setenv " #name "_" #expected_result " y; else " \
			"setenv " #name "_" #expected_result " n; fi", 0); \
	assert(!strcmp(#expected_result, getenv(#name "_" #expected_result))); \
	setenv(#name "_" #expected_result, NULL);

	/* Basic operators */
	HUSH_TEST(streq, "aaa = aaa", y);
	HUSH_TEST(streq, "aaa = bbb", n);

	HUSH_TEST(strneq, "aaa != bbb", y);
	HUSH_TEST(strneq, "aaa != aaa", n);

	HUSH_TEST(strlt, "aaa < bbb", y);
	HUSH_TEST(strlt, "bbb < aaa", n);

	HUSH_TEST(strgt, "bbb > aaa", y);
	HUSH_TEST(strgt, "aaa > bbb", n);

	HUSH_TEST(eq, "123 -eq 123", y);
	HUSH_TEST(eq, "123 -eq 456", n);

	HUSH_TEST(ne, "123 -ne 456", y);
	HUSH_TEST(ne, "123 -ne 123", n);

	HUSH_TEST(lt, "123 -lt 456", y);
	HUSH_TEST(lt_eq, "123 -lt 123", n);
	HUSH_TEST(lt, "456 -lt 123", n);

	HUSH_TEST(le, "123 -le 456", y);
	HUSH_TEST(le_eq, "123 -le 123", y);
	HUSH_TEST(le, "456 -le 123", n);

	HUSH_TEST(gt, "456 -gt 123", y);
	HUSH_TEST(gt_eq, "123 -gt 123", n);
	HUSH_TEST(gt, "123 -gt 456", n);

	HUSH_TEST(ge, "456 -ge 123", y);
	HUSH_TEST(ge_eq, "123 -ge 123", y);
	HUSH_TEST(ge, "123 -ge 456", n);

	HUSH_TEST(z, "-z \"\"", y);
	HUSH_TEST(z, "-z \"aaa\"", n);

	HUSH_TEST(n, "-n \"aaa\"", y);
	HUSH_TEST(n, "-n \"\"", n);

	/* Inversion of simple tests */
	HUSH_TEST(streq_inv, "! aaa = aaa", n);
	HUSH_TEST(streq_inv, "! aaa = bbb", y);

	HUSH_TEST(streq_inv_inv, "! ! aaa = aaa", y);
	HUSH_TEST(streq_inv_inv, "! ! aaa = bbb", n);

	/* Binary operators */
	HUSH_TEST(or_0_0, "aaa != aaa -o bbb != bbb", n);
	HUSH_TEST(or_0_1, "aaa != aaa -o bbb = bbb", y);
	HUSH_TEST(or_1_0, "aaa = aaa -o bbb != bbb", y);
	HUSH_TEST(or_1_1, "aaa = aaa -o bbb = bbb", y);

	HUSH_TEST(and_0_0, "aaa != aaa -a bbb != bbb", n);
	HUSH_TEST(and_0_1, "aaa != aaa -a bbb = bbb", n);
	HUSH_TEST(and_1_0, "aaa = aaa -a bbb != bbb", n);
	HUSH_TEST(and_1_1, "aaa = aaa -a bbb = bbb", y);

	/* Inversion within binary operators */
	HUSH_TEST(or_0_0_inv, "! aaa != aaa -o ! bbb != bbb", y);
	HUSH_TEST(or_0_1_inv, "! aaa != aaa -o ! bbb = bbb", y);
	HUSH_TEST(or_1_0_inv, "! aaa = aaa -o ! bbb != bbb", y);
	HUSH_TEST(or_1_1_inv, "! aaa = aaa -o ! bbb = bbb", n);

	HUSH_TEST(or_0_0_inv_inv, "! ! aaa != aaa -o ! ! bbb != bbb", n);
	HUSH_TEST(or_0_1_inv_inv, "! ! aaa != aaa -o ! ! bbb = bbb", y);
	HUSH_TEST(or_1_0_inv_inv, "! ! aaa = aaa -o ! ! bbb != bbb", y);
	HUSH_TEST(or_1_1_inv_inv, "! ! aaa = aaa -o ! ! bbb = bbb", y);

	setenv("ut_var_nonexistent", NULL);
	setenv("ut_var_exists", "1");
	HUSH_TEST(z_varexp_quoted, "-z \"$ut_var_nonexistent\"", y);
	HUSH_TEST(z_varexp_quoted, "-z \"$ut_var_exists\"", n);
	setenv("ut_var_exists", NULL);

	run_command("setenv ut_var_space \" \"", 0);
	assert(!strcmp(getenv("ut_var_space"), " "));
	run_command("setenv ut_var_test $ut_var_space", 0);
	assert(!getenv("ut_var_test"));
	run_command("setenv ut_var_test \"$ut_var_space\"", 0);
	assert(!strcmp(getenv("ut_var_test"), " "));
	run_command("setenv ut_var_test \" 1${ut_var_space}${ut_var_space} 2 \"", 0);
	assert(!strcmp(getenv("ut_var_test"), " 1   2 "));
	setenv("ut_var_space", NULL);
	setenv("ut_var_test", NULL);

#ifdef CONFIG_SANDBOX
	/* File existence */
	HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", n);
	run_command("sb save hostfs - creating_this_file_breaks_uboot_unit_test 0 1", 0);
	HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", y);
	/* Perhaps this could be replaced by an "rm" shell command one day */
	assert(!os_unlink("creating_this_file_breaks_uboot_unit_test"));
	HUSH_TEST(e, "-e hostfs - creating_this_file_breaks_uboot_unit_test", n);
#endif
#endif

	printf("%s: Everything went swimmingly\n", __func__);
	return 0;
}