mailing list of musl libc
 help / color / mirror / code / Atom feed
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;
}

      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).