software "engineering"
2006-12-28 22:11:37.391365+00 by
Dan Lyke
7 comments
Why does every OS or shell that isn't Un*x think that it's a good idea to have separate sorts of handles or descriptors for sockets versus streams versus files? Even those that are based on an underlying Un*x architecture? What part of the object oriented notion of "reading and writing are common operations so we should be able to do them on base objects" that the designers of Un*x and BSD sockets understood is wrong in the eyes of the developers of Mac OS/X and Windows?
[ related topics:
Microsoft Open Source Software Engineering Macintosh
]
comments in ascending chronological order (reverse):
#Comment Re: made: 2006-12-29 00:15:40.856328+00 by:
markd
I'm a bit confused - bsd sockets, pipes, and regular file descriptors are as interchangable on OSX as on
other unix-like systems. Mach ports are a different story, of course, since they're message queues and
not byte streams.
#Comment Re: made: 2006-12-29 00:24:07.228453+00 by:
Dan Lyke
But there's no strongly documented way to incorporate them into, say, a Carbon run loop or any of the Core Foundation stuff. There's the possibility that using the "create from native" call of CFSockets will work, but no indication that if that works now it'll work in future releases.
So I'm down to another select()
loop in a separate thread.
(Actually, for this case for now the process can work synchronously, so I can just do a straight select()
loop, but it sure would be nice if CFStreams had a "convert from POSIX socket" call or something similar.)
It's like Windows: Yes, there is the Winsock API that looks a lot like BSD sockets, but don't try to use 'em with read()
and write()
, they won't do what you want, and once you start using the native Windows APIs there are separate functions for every single variant of what you're reading and writing.
#Comment Re: made: 2006-12-29 00:28:05.329174+00 by:
Dan Lyke
Okay, I should elaborate a little bit:
I'm forking another process. I want to be able to read stdout
and stderr
from that other process. Trivial under POSIX, which is where I implemented my test code. Doable under Windows if I use the Windows API calls to do it (haven't done it in half a decade, but did it way back then). Don't see a way to integrate that into a regular Carbon run loop without jumping through huge contortions, either through Core Foundation functions or by taking my POSIX code and moving the select()
code over to something that'll get callbacks from the run loop.
#Comment Re: made: 2006-12-29 15:23:30.26592+00 by:
markd
[edit history]
I've got a whole chapter on that in Advanced Mac OS X Programming, oddly enough :-) The create from
native works, and has been recommended by Apple DTS, so it should keep on working (I'm revving the
book for a class in April, so I'll triple-check that stuff on Leopard sooner rather than later and let you
know)
NSFileHandle, if you can use NeXTstep/Cocoa, has file handles with standard in/out/err/devnull that can
be used asynchronously. Plus with NSTask, reading and writing from the forked process is straightforward
synchronously or asynchronously. Shoot, if you don't mind blocking the event loop, go ahead and use
pipe() and fork().
But I don't see how this is very different than any API that takes over the event loop. Even with Qt (which
runs on the presumably well-engineered platforms) you'd have to jump through hoops to be able to use
file descriptors without potentially blocking the UI. If you don't mind the main thread being blocked while
you read()/write(), you're welcome to do so even in Carbon-Land.
#Comment Re: made: 2006-12-29 15:25:25.809672+00 by:
markd
[edit history]
And yeah, the whole CFRunLoop thing, and most of CoreFoundation for that matter, is pretty grody. I
appreciate the design decisions over time that led to them, but I don't enjoy using them. I try to keep
either to Cloud-Cocoa-Land, or down in POSIXville.
#Comment Re: made: 2006-12-30 02:15:28.912598+00 by:
concept14
You're assuming Windows had designers.
#Comment Re: made: 2006-12-30 22:52:20.468354+00 by:
Dan Lyke
The difference is that on the Un*x frameworks I've used, they all assume that you'll want to be attaching events to the select(...)
events on handles expressed as int
s, so there's never been a problem mixing and matching with various other aspects of the POSIX API and whatever their run loop is.
When I'm home again I'll see if the book by you that I have is that one, and if not I'll get it.
On Windows & design: Sometimes the designers are evolutionary processes...