#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <atf-c.h>
ATF_TC_WITHOUT_HEAD(test_preexisting);
ATF_TC_BODY(test_preexisting, tc)
{
char buf[512];
char buf2[512];
char str[] = "Test writing some stuff";
char str2[] = "AAAAAAAAA";
char str3[] = "AAAA writing some stuff";
FILE *fp;
size_t nofw, nofr;
int rc;
fp = fmemopen(buf, sizeof(buf), "w");
ATF_REQUIRE(fp != NULL);
nofw = fwrite(str, 1, sizeof(str), fp);
ATF_REQUIRE(nofw == sizeof(str));
rc = fclose(fp);
ATF_REQUIRE(rc == 0);
fp = fmemopen(buf, sizeof(buf), "r");
ATF_REQUIRE(fp != NULL);
bzero(buf2, sizeof(buf2));
nofr = fread(buf2, 1, sizeof(buf2), fp);
ATF_REQUIRE(nofr == sizeof(buf2));
ATF_REQUIRE(strcmp(str, buf2) == 0);
rc = fclose(fp);
ATF_REQUIRE(rc == 0);
fp = fmemopen(str, 4, "w");
ATF_REQUIRE(fp != NULL);
nofw = fwrite(str2, 1, sizeof(str2), fp);
ATF_REQUIRE(nofw == 4);
rc = fclose(fp);
ATF_REQUIRE(rc == 0);
ATF_REQUIRE(strcmp(str, str3) == 0);
}
ATF_TC_WITHOUT_HEAD(test_autoalloc);
ATF_TC_BODY(test_autoalloc, tc)
{
FILE *fp;
long pos;
size_t nofw, i;
int rc;
fp = fmemopen(NULL, 512, "w+");
ATF_REQUIRE(fp != NULL);
for (i = 0; i < 512; i++) {
nofw = fwrite("a", 1, 1, fp);
ATF_REQUIRE(nofw == 1);
}
pos = ftell(fp);
ATF_REQUIRE(pos == 512);
nofw = fwrite("a", 1, 1, fp);
ATF_REQUIRE(nofw == 0);
rc = fclose(fp);
ATF_REQUIRE(rc == 0);
fp = fmemopen(NULL, 512, "r");
ATF_REQUIRE(fp == NULL);
ATF_REQUIRE(errno == EINVAL);
fp = fmemopen(NULL, 512, "w");
ATF_REQUIRE(fp == NULL);
ATF_REQUIRE(errno == EINVAL);
}
ATF_TC_WITHOUT_HEAD(test_data_length);
ATF_TC_BODY(test_data_length, tc)
{
FILE *fp;
char buf[512] = {'\0'};
char str[] = "Test data length. ";
char str2[] = "Do we have two sentences?";
char str3[sizeof(str) + sizeof(str2) -1];
long pos;
size_t nofw, nofr;
int rc;
fp = fmemopen(buf, sizeof(buf), "w+");
ATF_REQUIRE(fp != NULL);
nofw = fwrite(str, 1, sizeof(str), fp);
ATF_REQUIRE(nofw == sizeof(str));
rc = fseek(fp, 0, SEEK_END);
ATF_REQUIRE(rc == 0);
pos = ftell(fp);
ATF_REQUIRE(pos == sizeof(str));
rc = fclose(fp);
ATF_REQUIRE(rc == 0);
fp = fmemopen(buf, sizeof(buf), "a+");
ATF_REQUIRE(fp != NULL);
nofw = fwrite(str2, 1, sizeof(str2), fp);
ATF_REQUIRE(nofw == sizeof(str2));
rc = fseek(fp, 0, SEEK_SET);
ATF_REQUIRE(rc == 0);
pos = ftell(fp);
ATF_REQUIRE(pos == 0);
nofr = fread(str3, 1, sizeof(buf), fp);
ATF_REQUIRE(nofr == sizeof(str3));
ATF_REQUIRE(strncmp(str3, str, sizeof(str) - 1) == 0);
ATF_REQUIRE(strncmp(str3 + sizeof(str) - 1, str2, sizeof(str2)) == 0);
rc = fclose(fp);
ATF_REQUIRE(rc == 0);
}
ATF_TC_WITHOUT_HEAD(test_binary);
ATF_TC_BODY(test_binary, tc)
{
FILE *fp;
char buf[20];
char str[] = "Test";
size_t nofw;
int rc, i;
memset(buf, 'A', sizeof(buf));
fp = fmemopen(buf, sizeof(buf), "w+b");
ATF_REQUIRE(fp != NULL);
nofw = fwrite(str, 1, strlen(str), fp);
ATF_REQUIRE(nofw == strlen(str));
for (i = 0; i < sizeof(buf); i++)
ATF_REQUIRE(buf[i] != '\0');
rc = fclose(fp);
ATF_REQUIRE(rc == 0);
}
ATF_TC_WITHOUT_HEAD(test_append_binary_pos);
ATF_TC_BODY(test_append_binary_pos, tc)
{
FILE *fp;
fp = fmemopen(NULL, 16, "ab+");
ATF_REQUIRE(fp != NULL);
ATF_REQUIRE(ftell(fp) == 0L);
fclose(fp);
char buf[] = "Hello";
fp = fmemopen(buf, sizeof(buf), "ab+");
ATF_REQUIRE(fp != NULL);
ATF_REQUIRE(ftell(fp) == strlen(buf));
fclose(fp);
}
ATF_TC_WITHOUT_HEAD(test_size_0);
ATF_TC_BODY(test_size_0, tc)
{
FILE *fp;
fp = fmemopen(NULL, 0, "r+");
ATF_REQUIRE(fp == NULL);
ATF_REQUIRE(errno == EINVAL);
}
ATF_TC_WITHOUT_HEAD(test_rdonly_wronly);
ATF_TC_BODY(test_rdonly_wronly, tc)
{
FILE *fp;
char buf[16];
char buf_orig[16] = "input data";
char buf_write[16] = "write";
size_t sz;
memcpy(buf, buf_orig, sizeof(buf));
fp = fmemopen(buf, sizeof(buf), "r");
ATF_REQUIRE(fp != NULL);
sz = fwrite(buf_write, 1, strlen(buf_write), fp);
ATF_REQUIRE(sz == 0);
ATF_REQUIRE(errno == EBADF);
ATF_REQUIRE(memcmp(buf, buf_orig, sizeof(buf)) == 0);
fclose(fp);
fp = fmemopen(buf_orig, sizeof(buf), "w");
ATF_REQUIRE(fp != NULL);
sz = fread(buf, sizeof(buf), 1, fp);
ATF_REQUIRE(sz == 0);
ATF_REQUIRE(errno == EBADF);
fclose(fp);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, test_autoalloc);
ATF_TP_ADD_TC(tp, test_preexisting);
ATF_TP_ADD_TC(tp, test_data_length);
ATF_TP_ADD_TC(tp, test_binary);
ATF_TP_ADD_TC(tp, test_append_binary_pos);
ATF_TP_ADD_TC(tp, test_size_0);
ATF_TP_ADD_TC(tp, test_rdonly_wronly);
return (atf_no_error());
}