tony@tui.marcam.dsir.govt.nz (Tony Cooper) (05/06/91)
UNIX programs under A/UX cannot use MacOS files stored on a HFS filesystem because there is no UNIX driver for the HFS filesystem. But there is a simple way to do this in a crude sort of way. Also this method has the possibilities of allowing MacOS programs to use pipes (ie you can feed the output from a MacOS program straight to the input of another MacOS program without creating an intermediate file). The method uses a feature of UNIX that doesn't seem to be widely known. So I thought that people would find it instructive (and hopefully stimulating) if I showed how easy it is. The method uses named pipes which can be created using the mknod command. Suppose you create two called /dev/stdin and /dev/stdout. Then you can do a unix command such as sort < /dev/stdin > /dev/stdout. Nothing happens until some process send data to /dev/stdin and some process tries to read from /dev/stdout. What you can then do is run a MacOS program to send data to /dev/stdin and to read from /dev/stdout. Since it is a MacOS program it can use files on the HFS filesystem. Thus you can sort a HFS file using a UNIX sort program. With a little imagination and some MacOS programming you can do far more sophisticated things. Also you can do things like running BinHex on a MacOS file and sending the output to /dev/stdout (or any named pipe) and run Unstuffit to unstuff the file /dev/stdout. That way BinHex sends data to a pipe and Unstuffit reads from that pipe. That could be quite nifty if it worked. (But the problem is that when BinHex tries to send data to /dev/stdout it sees /dev/stdout as an existing file and deletes it before making a new copy. This deletes the pipe which stops the whole process from working). Here is a simple demo of the process. I can't program under MacOS very well so I've made the demo as simple as I can and just a stdin demo. Even so, the MacOS program does not work properly. You have to run it from Commandshell for it to work. Double clicking makes it crash. Start by doing /etc/mknod /dev/stdin p (or make it /tmp/pipe or whatever). Compile the MacOS program using the cc compiler or otherwise. Use the makefile in /mac/src/examples to do see how to do this. Call the program MacStdin. Make sure you are running Commandshell and type in cat < /dev/stdin > /tmp/myfile From Commandshell run MacStdin. Choose a file using the file dialog. Hey presto that MacOS file will be operated on by the UNIX cat command. I hope the process is understandable from this brief posting. I hope it inspires someone to write a more useful MacOS utility to do it in general. I can help with the UNIX side of things if you like. Cheers Tony Cooper sramtrc@albert.dsir.govt.nz Here's the MacOS program to read a HFS file and send it to /dev/stdin. #include <mac/types.h> #include <mac/packages.h> #include <mac/quickdraw.h> #include <mac/osutils.h> #include <mac/files.h> #include <mac/errors.h> #include <mac/strings.h> #include <sys/types.h> #include <sys/errno.h> #include <strings.h> #include <fcntl.h> #include <stdio.h> main() { Point where; short refNum, numTypes; SFReply reply; SFTypeList typeList; char *prompt = ""; OSErr err; char buffer[512]; long bufSize; void MultiFinder(); int fd; MultiFinder(20); /* initialise the MacOS stuff */ where.h = 50; where.v = 50; numTypes = -1; sfgetfile(where, prompt, nil, numTypes, typeList, nil, &reply); if(!reply.good) ExitToShell(); fd = open("/dev/stdin", O_GLOBAL|O_WRONLY); if (fd > 0) { if ((err = FSOpen(reply.fName, reply.vRefNum, &refNum)) == noErr) { do { bufSize = 512; (void)FSRead(refNum, &bufSize, buffer); (void)write(fd, buffer, bufSize); } while (bufSize > 0); (void)FSClose(refNum); (void)close(fd); } } ExitToShell(); } void MultiFinder(sleep) short sleep; { EventRecord theEvent; static int firstTime = 1; if (firstTime == 1) { /* initialize everything */ InitGraf(&qd.thePort); InitWindows(); InitFonts(); InitMenus(); InitDialogs(nil); InitCursor(); FlushEvents(everyEvent, 0); firstTime = 0; } (void) WaitNextEvent(everyEvent, &theEvent, sleep, 0); } Here is the MacStdin.r file: #include "types.r" resource 'SIZE' (-1,"Size Resource") { dontSaveScreen, ignoreSuspendResumeEvents, enableOptionSwitch, cannotBackground, notMultiFinderAware, backgroundAndForeground, dontGetFrontClicks, ignoreChildDiedEvents, is32BitCompatible, reserved, reserved, reserved, reserved, reserved, reserved, reserved, 64*1024, /* preferred memory size */ 64*1024 /* minimum memory size */ };