Пример #1
0
static void test_bigfprintf(abts_case *tc, void *data)
{
    apr_file_t *f;
    const char *fname = "data/testbigfprintf.dat";
    char *to_write;
    int i;

    apr_file_remove(fname, p);

    APR_ASSERT_SUCCESS(tc, "open test file",
                       apr_file_open(&f, fname,
                                     APR_CREATE|APR_WRITE,
                                     APR_UREAD|APR_UWRITE, p));
    

    to_write = malloc(HUGE_STRING_LEN + 3);

    for (i = 0; i < HUGE_STRING_LEN + 1; ++i)
        to_write[i] = 'A' + i%26;

    strcpy(to_write + HUGE_STRING_LEN, "42");

    i = apr_file_printf(f, "%s", to_write);
    ABTS_INT_EQUAL(tc, HUGE_STRING_LEN + 2, i);

    apr_file_close(f);

    file_contents_equal(tc, fname, to_write, HUGE_STRING_LEN + 2);

    free(to_write);
}
Пример #2
0
static void test_writev_full(abts_case *tc, void *data)
{
    apr_file_t *f;
    apr_size_t nbytes;
    struct iovec vec[5];
    const char *fname = "data/testwritev_full.txt";

    APR_ASSERT_SUCCESS(tc, "open file for writing",
                       apr_file_open(&f, fname, 
                                     APR_WRITE|APR_CREATE|APR_TRUNCATE, 
                                     APR_OS_DEFAULT, p));
    
    vec[0].iov_base = LINE1;
    vec[0].iov_len = strlen(LINE1);
    vec[1].iov_base = LINE2;
    vec[1].iov_len = strlen(LINE2);
    vec[2].iov_base = LINE1;
    vec[2].iov_len = strlen(LINE1);
    vec[3].iov_base = LINE1;
    vec[3].iov_len = strlen(LINE1);
    vec[4].iov_base = LINE2;
    vec[4].iov_len = strlen(LINE2);

    APR_ASSERT_SUCCESS(tc, "writev_full of size 5 to file",
                       apr_file_writev_full(f, vec, 5, &nbytes));

    ABTS_INT_EQUAL(tc, strlen(LINE1)*3 + strlen(LINE2)*2, nbytes);

    APR_ASSERT_SUCCESS(tc, "close for writing",
                       apr_file_close(f));

    file_contents_equal(tc, fname, LINE1 LINE2 LINE1 LINE1 LINE2, 
                        strlen(LINE1)*3 + strlen(LINE2)*2);

}
Пример #3
0
static void test_writev_buffered(abts_case *tc, void *data)
{
    apr_file_t *f;
    apr_size_t nbytes;
    struct iovec vec[2];
    const char *fname = "data/testwritev_buffered.dat";

    APR_ASSERT_SUCCESS(tc, "open file for writing",
                       apr_file_open(&f, fname,
                                     APR_WRITE | APR_CREATE | APR_TRUNCATE |
                                     APR_BUFFERED, APR_OS_DEFAULT, p));

    nbytes = strlen(TESTSTR);
    APR_ASSERT_SUCCESS(tc, "buffered write",
                       apr_file_write(f, TESTSTR, &nbytes));

    vec[0].iov_base = LINE1;
    vec[0].iov_len = strlen(LINE1);
    vec[1].iov_base = LINE2;
    vec[1].iov_len = strlen(LINE2);

    APR_ASSERT_SUCCESS(tc, "writev of size 2 to file",
                       apr_file_writev(f, vec, 2, &nbytes));

    APR_ASSERT_SUCCESS(tc, "close for writing",
                       apr_file_close(f));

    file_contents_equal(tc, fname, TESTSTR LINE1 LINE2,
                        strlen(TESTSTR) + strlen(LINE1) + strlen(LINE2));
}
Пример #4
0
static void test_writev_buffered(CuTest *tc)
{
    apr_status_t rv;
    apr_file_t *f;
    apr_size_t nbytes;
    struct iovec vec[2];
    const char *fname = "data/testwritev_buffered.dat";

    rv = apr_file_open(&f, fname,
                       APR_WRITE | APR_CREATE | APR_TRUNCATE |
                       APR_BUFFERED, APR_OS_DEFAULT, p);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);

    nbytes = strlen(TESTSTR);
    rv = apr_file_write(f, TESTSTR, &nbytes);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);

    vec[0].iov_base = LINE1;
    vec[0].iov_len = strlen(LINE1);
    vec[1].iov_base = LINE2;
    vec[1].iov_len = strlen(LINE2);

    rv = apr_file_writev(f, vec, 2, &nbytes);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);

    rv = apr_file_close(f);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);

    file_contents_equal(tc, fname, TESTSTR LINE1 LINE2,
                        strlen(TESTSTR) + strlen(LINE1) + strlen(LINE2));
}
Пример #5
0
static void test_puts(abts_case *tc, void *data)
{
    apr_file_t *f;
    const char *fname = "data/testputs.txt";

    APR_ASSERT_SUCCESS(tc, "open file for writing",
                       apr_file_open(&f, fname, 
                                     APR_WRITE|APR_CREATE|APR_TRUNCATE, 
                                     APR_OS_DEFAULT, p));
    
    APR_ASSERT_SUCCESS(tc, "write line to file", 
                       apr_file_puts(LINE1, f));
    APR_ASSERT_SUCCESS(tc, "write second line to file", 
                       apr_file_puts(LINE2, f));
    
    APR_ASSERT_SUCCESS(tc, "close for writing",
                       apr_file_close(f));

    file_contents_equal(tc, fname, LINE1 LINE2, strlen(LINE1 LINE2));
}
Пример #6
0
static void test_writev_buffered_seek(CuTest *tc)
{
    apr_file_t *f;
    apr_status_t rv;
    apr_off_t off = 0;
    struct iovec vec[3];
    apr_size_t nbytes = strlen(TESTSTR);
    char *str = apr_pcalloc(p, nbytes+1);
    const char *fname = "data/testwritev_buffered.dat";

    rv = apr_file_open(&f, fname,
                       APR_WRITE | APR_READ | APR_BUFFERED,
                       APR_OS_DEFAULT, p);

    rv = apr_file_read(f, str, &nbytes);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);
    CuAssertStrEquals(tc, TESTSTR, str);

    rv = apr_file_seek(f, APR_SET, &off);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);

    vec[0].iov_base = LINE1;
    vec[0].iov_len = strlen(LINE1);
    vec[1].iov_base = LINE2;
    vec[1].iov_len = strlen(LINE2);
    vec[2].iov_base = TESTSTR;
    vec[2].iov_len = strlen(TESTSTR);

    rv = apr_file_writev(f, vec, 3, &nbytes);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);

    rv = apr_file_close(f);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);

    file_contents_equal(tc, fname, LINE1 LINE2 TESTSTR,
                        strlen(LINE1) + strlen(LINE2) + strlen(TESTSTR));

    rv = apr_file_remove(fname, p);
    CuAssertIntEquals(tc, APR_SUCCESS, rv);
}
Пример #7
0
static void test_writev_buffered_seek(abts_case *tc, void *data)
{
    apr_file_t *f;
    apr_status_t rv;
    apr_off_t off = 0;
    struct iovec vec[3];
    apr_size_t nbytes = strlen(TESTSTR);
    char *str = apr_pcalloc(p, nbytes+1);
    const char *fname = "data/testwritev_buffered.dat";

    APR_ASSERT_SUCCESS(tc, "open file for writing",
                       apr_file_open(&f, fname,
                                     APR_FOPEN_WRITE | APR_FOPEN_READ | APR_FOPEN_BUFFERED,
                                     APR_OS_DEFAULT, p));

    rv = apr_file_read(f, str, &nbytes);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    ABTS_STR_EQUAL(tc, TESTSTR, str);
    APR_ASSERT_SUCCESS(tc, "buffered seek", apr_file_seek(f, APR_SET, &off));

    vec[0].iov_base = LINE1;
    vec[0].iov_len = strlen(LINE1);
    vec[1].iov_base = LINE2;
    vec[1].iov_len = strlen(LINE2);
    vec[2].iov_base = TESTSTR;
    vec[2].iov_len = strlen(TESTSTR);

    APR_ASSERT_SUCCESS(tc, "writev of size 2 to file",
                       apr_file_writev(f, vec, 3, &nbytes));

    APR_ASSERT_SUCCESS(tc, "close for writing",
                       apr_file_close(f));

    file_contents_equal(tc, fname, LINE1 LINE2 TESTSTR,
                        strlen(LINE1) + strlen(LINE2) + strlen(TESTSTR));

    APR_ASSERT_SUCCESS(tc, "remove file", apr_file_remove(fname, p));
}
Пример #8
0
static int sis_try_deduplicate(const char *rootdir, const char *fname)
{
	const char *p, *hash, *hashdir, *path, *hashes_dir, *hashes_path;
	struct stat st;
	ino_t inode;
	int ret;

	/* fname should be in <hash>-<guid> format */
	p = strchr(fname, '-');
	i_assert(p != NULL);

	hash = t_strdup_until(fname, p);
	hashdir = sis_get_dir(rootdir, hash);
	path = t_strdup_printf("%s/%s", hashdir, fname);

	hashes_dir = t_strconcat(hashdir, "/", HASH_DIR_NAME, NULL);
	hashes_path = t_strconcat(hashes_dir, "/", hash, NULL);
	if (link(path, hashes_path) == 0) {
		/* first file with this hash. we're done */
		return 0;
	}
	if (errno == ENOENT) {
		/* either path was already deleted or hashes dir
		   doesn't exist */
		if (mkdir(hashes_dir, 0700) < 0) {
			if (errno == EEXIST)
				return 0;
			i_error("mkdir(%s) failed: %m", hashes_dir);
			return -1;
		}
		/* try again */
		if (link(path, hashes_path) == 0 || errno == ENOENT)
			return 0;
	}
	if (errno != EEXIST) {
		i_error("link(%s, %s) failed: %m", path, hashes_path);
		return -1;
	}

	/* need to do a byte-by-byte comparison. but check first if someone
	   else already had deduplicated the file. */
	if (stat(path, &st) < 0) {
		if (errno == ENOENT) {
			/* just got deleted */
			return 0;
		}
		i_error("stat(%s) failed: %m", path);
		return -1;
	}
	if (st.st_nlink > 1) {
		/* already deduplicated */
		return 0;
	}

	ret = file_contents_equal(path, hashes_path, &inode);
	if (ret < 0) {
		if (errno == ENOENT) {
			/* either path or hashes_path was deleted. */
			return sis_try_deduplicate(rootdir, fname);
		}
		return -1;
	}
	if (ret > 0) {
		/* equal, replace with hard link */
		ret = hardlink_replace(hashes_path, path, inode);
		if (ret > 0)
			return 0;
		else if (ret < 0)
			return -1;
		/* too many hard links or inode changed */
	}

	/* replace hashes link with this  */
	return hardlink_replace(path, hashes_path, st.st_ino) < 0 ? -1 : 0;
}