From: "Daniel Cegiełka" <daniel.cegielka@gmail.com>
To: musl@lists.openwall.com
Subject: Re: funopen() from BSD
Date: Sat, 29 Sep 2012 00:34:37 +0200 [thread overview]
Message-ID: <CAPLrYETAny1acOdPc4SZi5HmYaDMUgBU+J4JE_1pek-3vrjPEg@mail.gmail.com> (raw)
In-Reply-To: <20120928213501.GI254@brightrain.aerifal.cx>
[-- Attachment #1: Type: text/plain, Size: 1548 bytes --]
2012/9/28 Rich Felker <dalias@aerifal.cx>:
> A few general comments...
>
> 1. musl does not support 32-bit file offsets. All of the 32/64
> distinction stuff can be removed. off_t is always 64-bit.
I noticed, but I left it for sure. Already cleaned...
> 2. The original documentation states that the read/write functions can
> call setvbuf on the file to change its buffer. This imposes a huge
> restriction on the implementation that's not acceptable to musl. If
> that's part of the API, maybe we can look for some kind of workaround
> to block attempts to mess with the buffer, but it's hard since legal
> buffering changes (i.e. first action after open) should not be
> blocked.
>
> 3. flockfile/funlockfile are not musl functions, they're POSIX. Since
> funopen isn't part of plain ISO C, it's allowable to call them from
> funopen stuff, but it's going to impose unnecessary locking. The
> locking operations you want are FLOCK() and FUNLOCK() macros in
> stdio_impl.h.
Corrected.
And how to fix this piece of code:
if ((fp = __sfp()) == NULL) return NULL;
if ((c = (funcookie *)malloc(sizeof *c)) == NULL) {
__sfp_lock_acquire ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
__sfp_lock_release ();
return NULL;
}
Did I find in musl some equivalent for these functions?
I'm sending a new (clean) version.
Daniel
> I don't see any reason why funopen can't go in, but a little bit of
> motivation for why it's needed would be nice since it is mildly messy.
>
> Rich
[-- Attachment #2: funopen.c --]
[-- Type: text/x-csrc, Size: 2691 bytes --]
/* Copyright (C) 2007 Eric Blake
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
#include <stdio.h>
#include <errno.h>
#include "stdio_impl.h"
#define __SRD 0x0004 /* OK to read */
#define __SWR 0x0008 /* OK to write */
#define __SRW 0x0010 /* open for reading & writing */
typedef int (*funread)(void *_cookie, char *_buf, int _n);
typedef int (*funwrite)(void *_cookie, const char *_buf, int _n);
typedef off_t (*funseek)(void *_cookie, off_t _off, int _whence);
typedef int (*funclose)(void *_cookie);
typedef struct funcookie {
void *cookie;
funread readfn;
funwrite writefn;
funseek seekfn;
funclose closefn;
} funcookie;
static int funreader(void *cookie, char *buf, int n),
{
int result;
funcookie *c = (funcookie *)cookie;
errno = 0;
if ((result = c->readfn(c->cookie, buf, n)) < 0 && errno) return 0;
return result;
}
static int funwriter(void *cookie, const char *buf, int n)
{
int result;
funcookie *c = (funcookie *)cookie;
errno = 0;
if ((result = c->writefn(c->cookie, buf, n)) < 0 && errno) return 0;
return result;
}
static off_t funseeker(void *cookie, off_t off, int whence)
{
funcookie *c = (funcookie *)cookie;
off64_t result;
errno = 0;
if ((result = c->seekfn(c->cookie, (off_t)off, whence)) < 0 && errno) return 0;
return result;
}
static int funcloser(void *cookie)
{
int result = 0;
funcookie *c = (funcookie *)cookie;
if (c->closefn) {
errno = 0;
if ((result = c->closefn(c->cookie)) < 0 && errno) return 0;
}
free(c); /* check it in newlib src to be shure */
return result;
}
FILE *funopen(const void *cookie, funread readfn, funwrite writefn,
funseek seekfn, funclose closefn)
{
FILE *fp;
funcookie *c;
if (!readfn && !writefn) {
errno = EINVAL;
return NULL;
}
if ((fp = __sfp()) == NULL) return NULL;
if ((c = (funcookie *)malloc(sizeof *c)) == NULL) {
__sfp_lock_acquire ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
__sfp_lock_release ();
return NULL;
}
FLOCK(fp);
fp->_file = -1;
c->cookie = (void *)cookie; /* cast away const */
fp->_cookie = c;
if (readfn) {
c->readfn = readfn;
fp->_read = funreader;
if (writefn) {
fp->_flags = __SRW;
c->writefn = writefn;
fp->_write = funwriter;
}
else {
fp->_flags = __SRD;
c->writefn = NULL;
fp->_write = NULL;
}
}
else {
fp->_flags = __SWR;
c->writefn = writefn;
fp->_write = funwriter;
c->readfn = NULL;
fp->_read = NULL;
}
c->seekfn = seekfn;
fp->_seek = seekfn ? funseeker : NULL;
c->closefn = closefn;
fp->_close = funcloser;
FUNLOCK(fp);
return fp;
}
prev parent reply other threads:[~2012-09-28 22:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-28 21:01 Daniel Cegiełka
2012-09-28 21:35 ` Rich Felker
2012-09-28 22:34 ` Daniel Cegiełka [this message]
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=CAPLrYETAny1acOdPc4SZi5HmYaDMUgBU+J4JE_1pek-3vrjPEg@mail.gmail.com \
--to=daniel.cegielka@gmail.com \
--cc=musl@lists.openwall.com \
/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.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).