Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Nov 2000 06:53:09 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        marcel@cup.hp.com (Marcel Moolenaar)
Cc:        bright@wintelcom.net (Alfred Perlstein), marcs@znep.com (Marc Slemko), eischen@vigrid.com (Daniel Eischen), arch@FreeBSD.ORG
Subject:   Re: Modifying FILE to add lock
Message-ID:  <200011300653.XAA07381@usr08.primenet.com>
In-Reply-To: <3A258696.EAD7BD7A@cup.hp.com> from "Marcel Moolenaar" at Nov 29, 2000 05:43:34 PM

next in thread | previous in thread | raw e-mail | index | archive | help
> > I've never ever looked at the contents of struct FILE except to
> > research how stdio works.  Why do we need to care about the
> > contents of struct FILE (or DIR)?  We have funopen do deal with
> > creating our own special streams, what's the point of digging
> > into struct FILE?
> 
> The fact that you (and I) can't see the point, doesn't mean there is no
> point. Ignoring the fact that maybe there's a point somehow or somewhere
> is far more worse than reaching general consensus that there likely is
> no point at all.
> 
> Modula has some weird architecture and OS dependencies, IIRC. It doesn't
> hurt to check it out before we commit the change.

There are a number of programs which traditionally need to
be able to access the contents of the FILE buffers directly,
particularly with regard to things like "unget", and so on.

Mostly, these are mixed-mode programs, which do things like
bounce in and out of raw mode, or set cbreak, or modify the
value of vmin or vtime, and wish to act properly on already
typed ahead on ungetc()'ed characters that have been buffered.

It would be terrifically useful, for example, for getpass()
to use this to permit scripting of the creation of user
accounts (as one example).  That it does not work that way
means you have to resort to "pw" (a perl abomination) to get
the job done right.

Historically, things like EMACS and simulations that like to
implement command "intertia" (no command in the timeout window
means the previous command is in effect) tend to directly
manipulate buffered input contents.

There is at least one "curses"-like library of which I'm
aware that actually manipulates buffered output contents to
remove redundant output (e.g. "don't draw X there, if you
are going to draw Y there immediately afterward).  It's very
useful for slow links for things like text editors, where I
can delete a character, insert another, and end up with only
a single character being redrawn once, instead of to the end
of the line from the deletion/insertion point needing to be
rendered twice.

There are also programs which move stdin/out/err around to
effect certain features, without telling the program about
it (screen used to be one, so that it could support session
detach and reattach).

Suffice it to say that not everyone uses the macros, and
those who do, tend to not want to recompile the world.

You might consider using the old "debugging malloc" trick,
of allocating one structure, but referring to another, and
reference your "hidden" lock at a negative offset.  This
would let you pass around FILE objects that were allocated
larger than they were supposed to be, and reference locks
at a negative offset.  This would require some simple pointer
math on allocation, and would ensure binary backward compatability
with old programs and the new libc, without requiring a version
bump at all. 

If you use this trick, be wary of "#pragma pack()" in scope,
since unlike the kernel MUTEX() trick, the relative location
of the start of the shadow structure will end up moving around,
if you aren't explicit.

struct foo {
	whatever;
	whatever;
	...
};

struct foo_with_lock {
	LOCK	alfreds_new_lock;
	struct foo internal_foo;
};

Pass around:

struct foo *foop = &(foo_with_lockp->internal_foo);

Reference the lock with:

CVT_TO_LOCKED(struct foo_with_lock, foop)->alfreds_new_lock

#define CVT_TO_LOCKED(x,y)	\
	(void *)(((char *)(y)) - (int)&(((x *)0)->internal_foo))

I would probably force the packing around the declaration in the
header file.

					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011300653.XAA07381>