All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
To: "Michael Kerrisk (man-pages)"
	<mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Paul Pluzhnikov
	<ppluzhnikov-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: linux-man <linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	libc-alpha <libc-alpha-9JcytcrH/bA+uJoB2kUjGw@public.gmane.org>
Subject: Re: Revised fmemopen(3) man page
Date: Fri, 11 Mar 2016 11:15:13 +0700	[thread overview]
Message-ID: <56E24651.8060807@linaro.org> (raw)
In-Reply-To: <56DFA46F.1050509-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

I am not the most qualified person to correct syntactic issues or
grammar, but regarding the contents it covers current functionalities
and previous bugs as I would expect, thanks!

On 09-03-2016 11:19, Michael Kerrisk (man-pages) wrote:
> Hello Adhemerval
> 
> Since you recently did a reimplementation of fmemopen() (which
> Paul reminded me of) I've similarly just now done a major rework
> of the man page. Might you (or Paul, feel free to also chin in!),
> be willing to take a look at the text below and let me know if 
> anything needs fixing?
> 
> Thanks,
> 
> Michael
> 
> NAME
>        fmemopen -  open memory as stream
> 
> SYNOPSIS
>        #include <stdio.h>
> 
>        FILE *fmemopen(void *buf, size_t size, const char *mode);
> 
>    Feature    Test    Macro   Requirements   for   glibc   (see   fea‐
>    ture_test_macros(7)):
> 
>        fmemopen():
>            Since glibc 2.10:
>                _POSIX_C_SOURCE >= 200809L
>            Before glibc 2.10:
>                _GNU_SOURCE
> 
> DESCRIPTION
>        The fmemopen() function opens a stream that permits the  access
>        specified  by  mode.   The stream allows I/O to be performed on
>        the string or memory buffer pointed to by buf.
> 
>        The mode argument specifies the semantics of I/O on the stream,
>        and is one of the following:
> 
>        r       The stream is opened for reading.
> 
>        w       The stream is opened for writing.
> 
>        a       Append; open the stream for writing, with the file ini‐
>                tial position set to the first null byte.
> 
>        r+      Open the stream for reading and writing.
> 
>        w+      Open the stream for reading and  writing.   The  buffer
>                contents  are  truncated  (i.e.,  '\0' is placed in the
>                first byte of the buffer).
> 
>        a+      Append; open the stream for reading and  writing,  with
>                the file initial position set to the first null byte.
> 
>        The  stream  maintains  the  notion  of a current position, the
>        location where the next I/O operation will be  performed.   The
>        current  position  is implicitly updated by I/O operations.  It
>        can be explicitly updated using fseek(3), and determined  using
>        ftell(3).  In all modes other than append, the initial position
>        is set to the start of the buffer.  In append mode, if no  null
>        byte  is  found within the buffer, then the initial position is
>        size+1.
> 
>        If buf is specified as NULL, then fmemopen() allocates a buffer
>        of size bytes.  This is useful for an application that wants to
>        write data to a temporary buffer and then read it  back  again.
>        The  initial  position  is set to the start of the buffer.  The
>        buffer is automatically freed when the stream is closed.   Note
>        that the caller has no way to obtain a pointer to the temporary
>        buffer allocated by this call (but see open_memstream(3)).
> 
>        If buf is not NULL, then it should point  to  a  buffer  of  at
>        least len bytes allocated by the caller.
> 
>        When  a  stream  that  has  been  opened for writing is flushed
>        (fflush(3)) or closed (fclose(3)), a null byte  is  written  at
>        the  end  of  the  buffer if there is space.  The caller should
>        ensure that an extra byte is available in the buffer (and  that
>        size counts that byte) to allow for this.
> 
>        In a stream opened for reading, null bytes ('\0') in the buffer
>        do not cause read operations to return an  end-of-file  indica‐
>        tion.   A  read  from the buffer will indicate end-of-file only
>        when the file current position advances  size  bytes  past  the
>        start of the buffer.
> 
>        Write operations take place either at the current position (for
>        modes other than append), or at the current size of the  stream
>        (for append modes).
> 
>        Attempts  to write more than size bytes to the buffer result in
>        an error.  By default, such errors  will  be  visible  (by  the
>        absence  of  data) only when the stdio buffer is flushed.  Dis‐
>        abling buffering with the  following  call  may  be  useful  to
>        detect errors at the time of an output operation:
> 
>            setbuf(stream, NULL);
> 
>        Alternatively,  the  caller can explicitly set buf as the stdio
>        stream buffer, at the same time informing stdio of the buffer's
>        size, using:
> 
>            setbuffer(stream, buf, size);
> 
> RETURN VALUE
>        Upon  successful completion, fmemopen() returns a FILE pointer.
>        Otherwise, NULL is returned and errno is set  to  indicate  the
>        error.
> 
> VERSIONS
>        fmemopen() was already available in glibc 1.0.x.
> 
> ATTRIBUTES
>        For  an  explanation  of  the  terms  used in this section, see
>        attributes(7).
> 
>        ┌────────────┬───────────────┬─────────┐
>        │Interface   │ Attribute     │ Value   │
>        ├────────────┼───────────────┼─────────┤
>        │fmemopen(), │ Thread safety │ MT-Safe │
>        └────────────┴───────────────┴─────────┘
> 
> CONFORMING TO
>        POSIX.1-2008.  This function is not specified in  POSIX.1-2001,
>        and is not widely available on other systems.
> 
>        POSIX.1-2008 specifies that 'b' in mode shall be ignored.  How‐
>        ever, Technical Corrigendum 1 adjusts  the  standard  to  allow
>        implementation-specific  treatment  for this case, thus permit‐
>        ting the glibc treatment of 'b'.
> 
> NOTES
>        There is no file descriptor associated  with  the  file  stream
>        returned by this function (i.e., fileno(3) will return an error
>        if called on the returned stream).
> 
>        With version 2.22, binary mode (see below)  was  removed,  many
>        longstanding  bugs  in  the  implementation  of fmemopen() were
>        fixed, and a new versioned symbol was created for  this  inter‐
>        face.
> 
>    Binary mode
>        From  version  2.9  to 2.21, the glibc implementation of fmemo‐
>        pen() supported a "binary" mode, enabled by specifying the let‐
>        ter  'b' as the second character in mode.  In this mode, writes
>        don't implicitly add a  terminating  null  byte,  and  fseek(3)
>        SEEK_END  is relative to the end of the buffer (i.e., the value
>        specified by the size argument), rather than the current string
>        length.
> 
>        An  API  bug  afflicted  the  implementation of binary mode: to
>        specify binary mode, the 'b' must be the  second  character  in
>        mode.   Thus,  for  example,  "wb+" has the desired effect, but
>        "w+b" does not.  This is inconsistent  with  the  treatment  of
>        mode by fopen(3).
> 
>        Binary  mode was removed in glibc 2.22; a 'b' specified in mode
>        has no effect.
> 
> BUGS
>        In versions of glibc before 2.22, if size is specified as zero,
>        fmemopen()  fails with the error EINVAL.  It would be more con‐
>        sistent if this case successfully created a  stream  that  then
>        returned  end  of  file  on the first attempt at reading; since
>        version 2.22, the glibc implementation provides that behavior.
> 
>        In versions of glibc before 2.22, specifying append  mode  ("a"
>        or "a+") for fmemopen() sets the initial buffer position to the
>        first null byte, but (if the file offset is reset to a location
>        other  than  the  end  of the stream) does not force subsequent
>        writes to append at the end of the stream.  This bug  is  fixed
>        in glibc 2.22.
> 
>        In versions of glibc before 2.22, if the mode argument to fmem‐
>        open() specifies append ("a" or "a+"), and  the  size  argument
>        does  not  cover  a  null  byte  in  buf,  then,  according  to
>        POSIX.1-2008, the initial buffer position should be set to  the
>        next  byte  after the end of the buffer.  However, in this case
>        the glibc fmemopen() sets the buffer position to -1.  This  bug
>        is fixed in glibc 2.22.
> 
>        In  versions of glibc before 2.22, when a call to fseek(3) with
>        a whence value of SEEK_END was performed on a stream created by
>        fmemopen(),  the  offset  was subtracted from the end-of-stream
>        position, instead of being added.  This bug is fixed  in  glibc
>        2.22.
> 
>        The glibc 2.9 addition of "binary" mode for fmemopen() silently
>        changed the ABI: previously, fmemopen() ignored 'b' in mode.
> 
> EXAMPLE
>        The program below uses fmemopen() to open an input buffer,  and
>        open_memstream(3)  to  open  a dynamically sized output buffer.
>        The program scans its input string (taken  from  the  program's
>        first  command-line  argument) reading integers, and writes the
>        squares of these integers to the output buffer.  An example  of
>        the output produced by this program is the following:
> 
>            $ ./a.out '1 23 43'
>            size=11; ptr=1 529 1849
> 
>    Program source
> 
>        #define _GNU_SOURCE
>        #include <string.h>
>        #include <stdio.h>
>        #include <stdlib.h>
> 
>        #define handle_error(msg) \
>            do { perror(msg); exit(EXIT_FAILURE); } while (0)
> 
>        int
>        main(int argc, char *argv[])
>        {
>            FILE *out, *in;
>            int v, s;
>            size_t size;
>            char *ptr;
> 
>            if (argc != 2) {
>                fprintf(stderr, "Usage: %s '<num>...'\n", argv[0]);
>                exit(EXIT_FAILURE);
>            }
> 
>            in = fmemopen(argv[1], strlen(argv[1]), "r");
>            if (in == NULL)
>                handle_error("fmemopen");
> 
>            out = open_memstream(&ptr, &size);
>            if (out == NULL)
>                handle_error("open_memstream");
> 
>            for (;;) {
>                s = fscanf(in, "%d", &v);
>                if (s <= 0)
>                    break;
> 
>                s = fprintf(out, "%d ", v * v);
>                if (s == -1)
>                    handle_error("fprintf");
>            }
> 
>            fclose(in);
>            fclose(out);
> 
>            printf("size=%zu; ptr=%s\n", size, ptr);
> 
>            free(ptr);
>            exit(EXIT_SUCCESS);
>        }
> 
> SEE ALSO
>        fopen(3), fopencookie(3), open_memstream(3)
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2016-03-11  4:15 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-09  4:19 Revised fmemopen(3) man page Michael Kerrisk (man-pages)
     [not found] ` <56DFA46F.1050509-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-03-11  4:15   ` Adhemerval Zanella [this message]
2016-03-11 16:33     ` Michael Kerrisk (man-pages)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56E24651.8060807@linaro.org \
    --to=adhemerval.zanella-qsej5fyqhm4dnm+yrofe0a@public.gmane.org \
    --cc=libc-alpha-9JcytcrH/bA+uJoB2kUjGw@public.gmane.org \
    --cc=linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=ppluzhnikov-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.