Fix append mode and expand regress.  I've added an append flag to
the state but we could just as easily store the open flag instead.

 - todd

Index: lib/libc/stdio/fmemopen.c
===================================================================
RCS file: /cvs/src/lib/libc/stdio/fmemopen.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 fmemopen.c
--- lib/libc/stdio/fmemopen.c   14 Aug 2020 12:00:33 -0000      1.4
+++ lib/libc/stdio/fmemopen.c   14 Aug 2020 15:28:09 -0000
@@ -30,6 +30,7 @@ struct state {
        size_t           size;          /* allocated size */
        size_t           len;           /* length of the data */
        int              update;        /* open for update */
+       int              append;        /* open for append */
 };
 
 static int
@@ -51,6 +52,9 @@ fmemopen_write(void *v, const char *b, i
        struct state    *st = v;
        int             i;
 
+       if (st->append)
+               st->pos = st->len;
+
        for (i = 0; i < l && i + st->pos < st->size; i++)
                st->string[st->pos + i] = b[i];
        st->pos += i;
@@ -147,6 +151,7 @@ fmemopen(void *buf, size_t size, const c
        st->len = (oflags & O_TRUNC) ? 0 : size;
        st->size = size;
        st->update = oflags & O_RDWR;
+       st->append = oflags & O_APPEND;
 
        if (buf == NULL) {
                if ((st->string = malloc(size)) == NULL) {
@@ -173,7 +178,7 @@ fmemopen(void *buf, size_t size, const c
 
        fp->_flags = (short)flags;
        fp->_file = -1;
-       fp->_cookie = (void *)st;
+       fp->_cookie = st;
        fp->_read = (flags & __SWR) ? NULL : fmemopen_read;
        fp->_write = (flags & __SRD) ? NULL : fmemopen_write;
        fp->_seek = fmemopen_seek;

Index: regress/lib/libc/fmemopen/fmemopentest.c
===================================================================
RCS file: /cvs/src/regress/lib/libc/fmemopen/fmemopentest.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 fmemopentest.c
--- regress/lib/libc/fmemopen/fmemopentest.c    28 Mar 2013 09:35:58 -0000      
1.3
+++ regress/lib/libc/fmemopen/fmemopentest.c    15 Aug 2020 01:02:47 -0000
@@ -70,7 +70,7 @@ simpletest(void)
 }
 
 int
-updatetest(void)
+appendtest(const char *mode)
 {
        FILE    *s1;
        char     string[] = "hello\0 test number 2";
@@ -78,35 +78,44 @@ updatetest(void)
        size_t   len;
        int      failures = 0;
 
-       s1 = fmemopen(string, 19, "a+");
+       s1 = fmemopen(string, 19, mode);
        if (s1 == NULL)
                return (1);
 
+       fseek(s1, 0, SEEK_SET);
+       if (ftell(s1) != 0) {
+               warnx("failed seek test [%s] (4)", mode);
+               failures++;
+       }
+
+       /* write should append even though seek position is 0 */
        len = fwrite(" world", 1, 6, s1);
        if (len != 6) {
-               warnx("failed write test (4)");
+               warnx("failed write test [%s] (5)", mode);
                failures++;
        }
 
-       fseek(s1, 0, SEEK_SET);
-       if (ftell(s1) != 0) {
-               warnx("failed seek test (5)");
+       if (ftell(s1) != strlen("hello world")) {
+               warnx("failed seek test [%s] (6)", mode);
                failures++;
        }
 
-       len = fread(buffer, 1, sizeof(buffer) - 1, s1);
-       if (strncmp(string, buffer, len)) {
-               warnx("failed compare test (6)");
-               failures++;
+       if (mode[1] == '+') {
+               fseek(s1, 0, SEEK_SET);
+               len = fread(buffer, 1, sizeof(buffer) - 1, s1);
+               if (len == 0 || strncmp(string, buffer, len)) {
+                       warnx("failed compare test [%s] (7)", mode);
+                       failures++;
+               }
        }
 
        if (strcmp(string, "hello world")) {
-               warnx("failed compare test (7)");
+               warnx("failed compare test [%s] (8)", mode);
                failures++;
        }
 
        if (strcmp(string + strlen(string) + 1, "number 2")) {
-               warnx("failed compare test (8)");
+               warnx("failed compare test [%s] (9)", mode);
                failures++;
        }
 
@@ -114,7 +123,46 @@ updatetest(void)
 }
 
 int
-writetest(void)
+updatetest(void)
+{
+       FILE    *s1;
+       char     string[] = "bah, what a day";
+       char     buffer[256];
+       size_t   len;
+       int      failures = 0;
+
+       s1 = fmemopen(string, 19, "r+");
+       if (s1 == NULL)
+               return (1);
+
+       if (ftell(s1) != 0) {
+               warnx("failed seek test (10)");
+               failures++;
+       }
+
+       len = fwrite("oh frabjous", 1, 11, s1);
+       if (len != 11) {
+               warnx("failed write test (11)");
+               failures++;
+       }
+
+       fseek(s1, 0, SEEK_SET);
+       len = fread(buffer, 1, sizeof(buffer) - 1, s1);
+       if (len == 0 || strncmp(string, buffer, len)) {
+               warnx("failed compare test (12)");
+               failures++;
+       }
+
+       if (strcmp(string, "oh frabjous day")) {
+               warnx("failed compare test (13)");
+               failures++;
+       }
+
+       return (failures);
+}
+
+int
+writetest(const char *mode)
 {
        FILE    *s1;
        char     string[] = "super test number 3";
@@ -124,36 +172,36 @@ writetest(void)
 
        slen = strlen(string) + 1;
 
-       s1 = fmemopen(string, slen, "w");
+       s1 = fmemopen(string, slen, mode);
        if (s1 == NULL)
                return (1);
 
        len = fwrite("short", 1, 5, s1);
        if (len != strlen("short")) {
-               warnx("failed write test (9)");
+               warnx("failed write test [%s] (14)", mode);
                failures++;
        }
        fclose(s1);
 
        s1 = fmemopen(string, slen, "r");
        if (s1 == NULL) {
-               warnx("failed open test (10)");
+               warnx("failed open test [%s] (15)", mode);
                failures++;
        }
 
        len = fread(buffer, 1, sizeof(buffer) - 1, s1);
-       if (strncmp(string, buffer, len)) {
-               warnx("failed compare test (11)");
+       if (len == 0 || strncmp(string, buffer, len)) {
+               warnx("failed compare test [%s] (16)", mode);
                failures++;
        }
 
        if (strcmp(string, "short")) {
-               warnx("failed compare test (12)");
+               warnx("failed compare test [%s] (17)", mode);
                failures++;
        }
 
        if (strcmp(string + strlen(string) + 1, "test number 3")) {
-               warnx("failed compare test (13)");
+               warnx("failed compare test [%s] (18)", mode);
                failures++;
        }
 
@@ -175,23 +223,23 @@ seektest(void)
                return (1);
 
        if (fseek(s1, 8, SEEK_SET) != 0) {
-               warnx("failed to fseek. (14)");
+               warnx("failed to fseek. (19)");
                failures++;
        }
 
        if (ftell(s1) != 8) {
-               warnx("failed seek test. (15)");
+               warnx("failed seek test. (20)");
                failures++;
        }
 
        /* Try to seek backward */
        if (fseek(s1, -1, SEEK_CUR) != 0) {
-               warnx("failed to fseek. (16)");
+               warnx("failed to fseek. (21)");
                failures++;
        }
 
        if (ftell(s1) != 7) {
-               warnx("failed seeking backward. (17)");
+               warnx("failed seeking backward. (22)");
                failures++;
        }
 
@@ -204,8 +252,11 @@ main(void)
        int      failures = 0;
 
        failures += simpletest();
+       failures += appendtest("a");
+       failures += appendtest("a+");
        failures += updatetest();
-       failures += writetest();
+       failures += writetest("w");
+       failures += writetest("w+");
        failures += seektest();
 
        return (failures);

Reply via email to