Search code examples
macosmacos-carbonstdio

Replacing Carbon file functions with stdio.h functions


I'm attempting to convert an old chunk of code containing the obsolete Carbon functions FSWrite, FSRead, etc. One experiment we want to try is replacing these with their POSIX equivalents, the functions defined in stdio.h, e.g. replacing FSRead() with fread(). But I'm not sure what to do about the first arg given to the Carbon functions:

SetFPos(gFormatRecord->dataFork, fsFromStart, 0);

gFormatRecord is a pointer to a FormatRecord. Is the dataFork just a plain regular unixy file handle suitable to shove into fread(), fprintf() and such? (I don't know much about file "forks" in any case.)

(This is a follow-up to my earlier question, On a Mac, where are FSRead, FSWrite, SetFPos et al defined, and should I even be using them?)


Solution

  • From gFormatRecord->dataFork, it sounds like you're trying to write a Photoshop plugin. That's not going to work so well.

    Photoshop (and presumably most Mac Adobe software) is full of a lot of Carbon code, which was designed to be largely identical to existing 8.5 APIs while also being API/ABI compatible with OS X (I don't know if/when CFM Carbon support was dropped).

    According to the documentation, you're supposed to use FSSetForkPosition() instead, which probably ends up being the same function call in the end. You almost certainly can't use fseek()/fsetpos()/fseeko(), which expect a FILE *, while a Carbon file handle appears to be a SInt16 according to my header (the webdocs say it's a FSIORefNum). [1]

    Also note that fopen() and friends are not POSIX; they're standard C. The POSIX functions are generally the same without the leading f, except for seek which is lseek(). [2] The POSIX "file handle" is a file descriptor, which is just an int.

    Now, if you're incredibly lucky, a FSIORefNum will just be a file descriptor which you can pass to read()/write()/lseek(). But this is ultimately for little benefit; if Photoshop's still built on Carbon, what's the point?


    Footnotes!

    1. It's not impossible that fseek() special-cases pointers to the zero page, but I don't think they'd pollute libc with that.)
    2. On Linux/x86, you'll need to #define __FILE_OFFSET_BITS 64 or so to get largefile support, which is easy to forget. Shame it's not easy to do so universally...