Re: fread multiple files
Re: fread multiple files
- Subject: Re: fread multiple files
- From: Terry Lambert <email@hidden>
- Date: Sat, 26 Sep 2009 09:18:08 -0700
On Sep 25, 2009, at 11:07 PM, Steve Checkoway <email@hidden> wrote:
On Sep 25, 2009, at 4:24 PM, Terry Lambert wrote:
We don't support all of POSIX RT. The option set that that's in is
actially AIO, which is a subset of RT, and we don't se
_POSIX_ASYNCHRONOUS_IO in <unistd.h> because we don't support one
of the option flags to aio_fsync() in a POSIX compliant way.
So this seems like a case where relying on the version test macros
in unistd.h as a method of determining the usability of a function
rather than a link test is incorrect.
Except you can't run partial test sets when running the conformance
tests, so it's impossible to know without the feature test macros
whether or not the behaviour of the interface, to the extent it is
implemented, is in fact POSIX compliant.
And, indeed, I know for a fact that it is not; however, I also happen
to know that, to the extent he would be using it as a replacement for
read in the use model he's reported to us, it'd work well enough for
him.
Just glancing through the list for the first time, I see
_POSIX_SPAWN is defined as -1 but I thought posix_spawn() was
supported.
That feature test macro is defined that way for two reasons, even
though Apple makes extensive use of posix_spawn() practically
everywhere {v}fork()/execve() was used in prior OS releases:
1) the gcc compiler is broken in that it can't handle a non-variable
containing prototype using the "restrict" keyword interior to an array
declaration, so it's not possible to implement the prototype in a
completely compliant way.
2) we wanted some "bake time" before everyone and their dog jumped in
and started using it, and not advertising it was the best way to let
us change its behaviour in future releases, without breaking too many
people.
The following works for me, at least. It seems like the only sure
way to check if something will work is to write test code trying it
since one cannot rely on the version test macros nor on link tests.
In retrospect, this is obvious.
#include <spawn.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
extern char **environ;
int main( int argc, char *argv[] )
{
if( argc < 2 )
return 1;
pid_t pid;
int status;
int ret = posix_spawnp( &pid, argv[1], NULL, NULL, argv+1,
environ );
if( ret != 0 )
{
errno = ret; // lazy
perror( "posix_spawn" );
return 1;
}
ret = waitpid( pid, &status, 0 );
if( ret == -1 )
{
perror( "waitpid" );
return 2;
}
if( WIFEXITED(status) )
printf( "Exited normally with status %d\n",
WEXITSTATUS(status) );
else if( WIFSIGNALED(status) )
printf( "Terminated due to signal %d\n", WTERMSIG
(status) );
else
puts( "Something else" );
return 0;
}
You did the "errno = ret;"... a lazier programmer might not have done
that, and if they didn't, and their program was multiththreaded,
they'd maybe see one thing that we already know we have to fix about
the implementation to make it more strictly compliant (i.e. it
sometimes smashes errno, but not for all errors). Like I said, it
needs some "bake time".
Likewise, it'd be possible to use per-thread current working
directories to implement the HPC interfaces openat(), etc.. You'd
actually not want to use them mostly, since per-thread current working
directories are vastly superior to those interfaces for most uses to
which they are put (e.g. virtual hosting and cgi sandboxing in web
servers, etc.), they are just hard to implement in a lot of OSs, so
people hacked around it by using up a bunch if fds as directory
handles instead (hint: consider any OS without a 1:1 threading model).
But if we implemented the HPC library functions before they were
actually standardized, people started depending on some quirk of the
draft standard, and that was later eliminated by the standards
committee, people who implemented to our version would be in trouble
over portability, and we'd be in trouble over standards compliance. So
rather than implement a bunch of _np versions of largely inferior
standards track interfaces, we don't implement them, and we point
people who ask for them at per thread current working directories
instead.
Of course, standards committees may not catch their mistakes; lchown
(), for example, was standardized as returning an errno of EOPNOTSUPP
for an FS implementation not supporting changing ownership of
symlinks; that's "operation not supported on socket", as opposed to
the correct errno value, which would have been ENOTSUP, "not
supported". And that's totally side-stepping the questionable utility
of an lchown() in a standard which omits lchmod(), or the questionable
utility of a function it would be a completly standards compliantl
implementation of to just always set errno EOPNOTSUPP.
But depending on them making such a mistake all the time would be a
mistake.
So there are, and probably always will be, interfaces which are "use
at your own risk", which you will be able to find without the benefit
of an OS contract about their adherence to standards (and an implied
contract to not change unless the standard changes). If you want your
code to be portable, you won't use them even if you are clever and
find them without the feature test macros. Or, as in this case, you'll
make a conscious trade-off between a potential loss of portability vs.
greatly increased performance, and hopefully bracket your code with
derived #ifdef's rather than direct #ifdef's.
-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden