static OSErr FT_FSPathMakeRes( const UInt8* pathname, short* res ) { #if HAVE_FSREF OSErr err; FSRef ref; if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) return FT_Err_Cannot_Open_Resource; /* at present, no support for dfont format */ err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res ); if ( noErr == err ) return err; /* fallback to original resource-fork font */ *res = FSOpenResFile( &ref, fsRdPerm ); err = ResError(); #else OSErr err; FSSpec spec; if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) ) return FT_Err_Cannot_Open_Resource; /* at present, no support for dfont format without FSRef */ /* (see above), try original resource-fork font */ *res = FSpOpenResFile( &spec, fsRdPerm ); err = ResError(); #endif /* HAVE_FSREF */ return err; }
wxDirData::wxDirData(const wxString& dirname) : m_dirname(dirname) { m_ok = false; OSErr err; // throw away the trailing slashes size_t n = m_dirname.length(); wxCHECK_RET( n, _T("empty dir name in wxDir") ); while ( n > 0 && wxIsPathSeparator(m_dirname[--n]) ) ; m_dirname.Truncate(n + 1); #ifdef __DARWIN__ FSRef theRef; // get the FSRef associated with the POSIX path err = FSPathMakeRef((const UInt8 *) m_dirname.c_str(), &theRef, NULL); FSGetVRefNum(&theRef, &(m_CPB.hFileInfo.ioVRefNum)); err = FSGetNodeID( &theRef , &m_dirId , &m_isDir ) ; #else FSSpec fsspec ; wxMacFilename2FSSpec( m_dirname , &fsspec ) ; m_CPB.hFileInfo.ioVRefNum = fsspec.vRefNum ; err = FSpGetDirectoryID( &fsspec , &m_dirId , &m_isDir ) ; #endif //wxASSERT_MSG( (err == noErr) || (err == nsvErr) , wxT("Error accessing directory " + m_dirname)) ; if ( (err == noErr) || (err == nsvErr)) m_ok = true; else wxLogError(wxString(wxT("Error accessing directory ")) + m_dirname); m_CPB.hFileInfo.ioNamePtr = m_name ; m_index = 0 ; }
char* promptForFolder(const char *prompt, const char *defaultPath, char* folderPath, int folderPathLen) { char path[PATH_MAX]; OSStatus err; Boolean isDirectory; int len; FSRef ref; /* Display the prompt. */ if (prompt == NULL) prompt = "Please enter the path to a folder:"; printf("%s ", prompt); if (defaultPath != NULL) printf("[%s] ",defaultPath); fflush(stdout); /* Get user input, and trim trailing newlines. */ fgets(path,sizeof(path),stdin); for (len = strlen(path); len > 0 && path[len-1] == '\n';) path[--len] = 0; if (path[0] == 0) strcpy(path,defaultPath); /* Expand magic characters just like a shell (mostly so ~ will work) */ expandPathname(path); /* Convert the path into an FSRef, which is what the burn engine needs. */ err = FSPathMakeRef((const UInt8*)path,&ref,&isDirectory); if (err != noErr) { printf("Bad path. Aborting. (%d)\n", (int)err); exit(1); } if (!isDirectory) { printf("That's a file, not a directory! Aborting.\n"); exit(1); } return strncpy(folderPath, path, folderPathLen); }
bool isLink(const bfs::path& path) { if (isSymlink(path)) { return true; } #ifdef MACOSX // aliases appear as regular files if (isRegularFile(path)) { FSRef ref; if (FSPathMakeRef((const UInt8*)path.c_str(), &ref, NULL) == noErr) { Boolean isAlias = false, isFolder = false; if (FSIsAliasFile(&ref, &isAlias, &isFolder) == noErr) { return isAlias; } } } #endif return false; }
OSStatus FSPathMakeFSSpec(const UInt8 *path,FSSpec *spec,Boolean *isDirectory) /* can be NULL */ { OSStatus result; FSRef ref; /* check parameters */ require_action(NULL != spec, BadParameter, result = paramErr); /* convert the POSIX path to an FSRef */ result = FSPathMakeRef(path, &ref, isDirectory); require_noerr(result, FSPathMakeRef); /* and then convert the FSRef to an FSSpec */ result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL); require_noerr(result, FSGetCatalogInfo); FSGetCatalogInfo: FSPathMakeRef: BadParameter: return result; }
void CResourceFile::LoadFile( const std::string& fpath ) { FSRef fileRef; mResRefNum = -1; OSStatus resErr = FSPathMakeRef( (const UInt8*) fpath.c_str(), &fileRef, NULL ); if( resErr == noErr ) { mResRefNum = FSOpenResFile( &fileRef, fsRdPerm ); if( mResRefNum < 0 ) { fprintf( stderr, "Warning: No Mac resource fork to import.\n" ); resErr = fnfErr; } } else { fprintf( stderr, "Error: Error %d locating input file's resource fork.\n", (int)resErr ); mResRefNum = -1; } }
AudioFileReader::AudioFileReader(const char* filePath) : m_data(0) , m_dataSize(0) , m_filePath(filePath) , m_audioFileID(0) , m_extAudioFileRef(0) { FSRef fsref; OSStatus result = FSPathMakeRef((UInt8*)filePath, &fsref, 0); if (result != noErr) return; CFURLRef urlRef = CFURLCreateFromFSRef(0, &fsref); if (!urlRef) return; ExtAudioFileOpenURL(urlRef, &m_extAudioFileRef); if (urlRef) CFRelease(urlRef); }
/* Finish the current audio track. */ int PortBurn_EndTrack(void *handle) { PBHandle *h = (PBHandle *)handle; DRAudioTrackRef track; Boolean isDirectory; const char *filename; FSRef fsref; int index; if (!h) return pbErrNoHandle; if (!h->staging) return pbErrMustCallStartStaging; if (0 != PortBurn_EndStagingTrack(h->staging)) return pbErrCannotStageTrack; index = PortBurn_GetNumStagedTracks(h->staging); if (index <= 0) return pbErrCannotStageTrack; filename = PortBurn_GetStagedFilename(h->staging, index - 1); printf("Filename: '%s'\n", filename); h->err = FSPathMakeRef((const UInt8*)filename, &fsref, &isDirectory); if (h->err != noErr) return pbErrCannotAccessStagedFile; if (isDirectory) return pbErrCannotAccessStagedFile; track = DRAudioTrackCreate(&fsref); CFArrayAppendValue(h->trackArray, track); CFRelease(track); if (track) return pbSuccess; else return pbErrCannotUseStagedFileForBurning; }
BOOL TRASH_CanTrashFile(LPCWSTR wszPath) { char *unix_path; OSStatus status; FSRef ref; FSCatalogInfo catalogInfo; TRACE("(%s)\n", debugstr_w(wszPath)); if (!(unix_path = wine_get_unix_file_name(wszPath))) return FALSE; status = FSPathMakeRef((UInt8*)unix_path, &ref, NULL); heap_free(unix_path); if (status == noErr) status = FSGetCatalogInfo(&ref, kFSCatInfoVolume, &catalogInfo, NULL, NULL, NULL); if (status == noErr) status = FSFindFolder(catalogInfo.volume, kTrashFolderType, kCreateFolder, &ref); return (status == noErr); }
int wd_apple_resolve_alias(char *dst, char *src, size_t size) { FSRef fsPath; Boolean isDir, isAlias; strlcpy(dst, src, size); if(!wd_chroot) { if(FSPathMakeRef(src, &fsPath, NULL) != 0) return -1; if(FSIsAliasFile(&fsPath, &isAlias, &isDir) != 0) return -1; if(FSResolveAliasFile(&fsPath, true, &isDir, &isAlias) != 0) return -1; if(FSRefMakePath(&fsPath, dst, size) != 0) return -1; } return 1; }
std::unique_ptr<ImportFileHandle> QTImportPlugin::Open(const wxString & Filename) { OSErr err; FSRef inRef; Movie theMovie = NULL; Handle dataRef = NULL; OSType dataRefType = 0; short resID = 0; #if defined(__WXMAC__) err = wxMacPathToFSRef(Filename, &inRef); #else // LLL: This will not work for pathnames with Unicode characters...find // another method. err = FSPathMakeRef((UInt8 *)OSFILENAME(Filename), &inRef, NULL); #endif if (err != noErr) { return nullptr; } err = QTNewDataReferenceFromFSRef(&inRef, 0, &dataRef, &dataRefType); if (err != noErr) { return nullptr; } // instantiate the movie err = NewMovieFromDataRef(&theMovie, newMovieActive | newMovieDontAskUnresolvedDataRefs, &resID, dataRef, dataRefType); DisposeHandle(dataRef); if (err != noErr) { return nullptr; } return std::make_unique<QTImportFileHandle>(Filename, theMovie); }
static OSErr FT_FSPathMakeRes( const UInt8* pathname, ResFileRefNum* res ) { OSErr err; FSRef ref; if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) return FT_Err_Cannot_Open_Resource; /* at present, no support for dfont format */ err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res ); if ( noErr == err ) return err; /* fallback to original resource-fork font */ *res = FSOpenResFile( &ref, fsRdPerm ); err = ResError(); return err; }
/*AudioFile::AudioFile( shared_ptr<IStream> aStream ) : mStream( aStream ) { setup(); }*/ AudioFile::AudioFile( const std::string &aFilePath ) { #if defined( FLI_MAC ) FSRef fsref; OSStatus fileRefError = FSPathMakeRef( (const UInt8 *)aFilePath.c_str(), &fsref, NULL ); if( fileRefError ) { //handle error std::cout << "Input file not found" << std::endl; return; } OSStatus audioFileOpenError = AudioFileOpen(&fsref, fsRdPerm, 0, &mNativeFileRef); if( audioFileOpenError ) { //handle error std::cout << "AudioFileOpen failed" << std::endl; return; } loadHeader(); load(); #endif }
int main (int argc, const char *argv[]) { SInt32 fileID; FSRef ref, volRef; FSCatalogInfo volCatInfo; OSErr result; unsigned char pathName[255]; // Exit if anything more or less than two arguments are passed in if (argc != 3) { printf("Usage: %s <HFS ID> <volume mount point>\n", argv[0]); return 0; } result = FSPathMakeRef(argv[2], &volRef, NULL); if (result != noErr) { printf("Error %d\n", result); return 10; } result = FSGetCatalogInfo(&volRef, kFSCatInfoVolume, &volCatInfo, NULL, NULL, NULL); if (result != noErr) { printf("Error %d\n", result); return 10; } fileID = atoi(argv[1]); result = FSResolveFileIDRef(volCatInfo.volume, fileID, &ref); if (result != noErr) { printf("Error %d\n", result); return 10; } result = FSRefMakePath(&ref, pathName, sizeof(pathName)); if (result != noErr) { printf("Error %d\n", result); return 10; } printf("%s\n", pathName); return 0; }
static OSErr myFSCreateResFile(const char *path, OSType creator, OSType fileType, FSRef *outRef) { int fd = open(path, O_CREAT | O_WRONLY, 0666); if (fd == -1) { perror("opening destination:"); return bdNamErr; } close(fd); FSRef ref; OSErr err = FSPathMakeRef((const UInt8*)path, &ref, NULL); if (err != noErr) return err; HFSUniStr255 rname; FSGetResourceForkName(&rname); err = FSCreateResourceFork(&ref, rname.length, rname.unicode, 0); if (err != noErr) return err; FInfo finfo; err = FSGetFInfo(&ref, &finfo); if (err != noErr) return err; finfo.fdCreator = creator; finfo.fdType = fileType; err = FSSetFInfo(&ref, &finfo); if (err != noErr) return err; *outRef = ref; return noErr; }
/********** HELPER FUNCTIONS ***********/ static const char *GetSpecialPathName(const char *Path) { if(GetProductIsAppBundle(cur_info)) { FSRef Ref; HFSUniStr255 SpecialPathHFS; FSPathMakeRef(Path, &Ref, NULL); FSGetCatalogInfo(&Ref, kFSCatInfoNone, NULL, &SpecialPathHFS, NULL, NULL); CFStringRef cfs = CFStringCreateWithCharacters(kCFAllocatorDefault, SpecialPathHFS.unicode, SpecialPathHFS.length); CFStringGetCString(cfs, SpecialPath, 1024, kCFStringEncodingASCII); CFRelease(cfs); return SpecialPath; /*// Otherwise, it'll show /Users/joeshmo/Desktop. if(strstr(Path, DesktopName) != NULL) return DesktopName; else if(strstr(Path, DocumentsName) != NULL) return DocumentsName; else if(strstr(Path, ApplicationsName) != NULL) return ApplicationsName;*/ } return Path; }
//static pascal void LLFilePickerBase::doNavCallbackEvent(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void* callBackUD) { switch(callBackSelector) { case kNavCBStart: { LLFilePickerBase* picker = reinterpret_cast<LLFilePickerBase*>(callBackUD); if (picker->getFolder().empty()) break; OSStatus error = noErr; AEDesc theLocation = {typeNull, NULL}; FSSpec outFSSpec; //Convert string to a FSSpec FSRef myFSRef; const char* folder = picker->getFolder().c_str(); error = FSPathMakeRef ((UInt8*)folder, &myFSRef, NULL); if (error != noErr) break; error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL); if (error != noErr) break; error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation); if (error != noErr) break; error = NavCustomControl(callBackParms->context, kNavCtlSetLocation, (void*)&theLocation); } } }
static bool _q_isMacHidden(const QString &path) { OSErr err = noErr; FSRef fsRef; #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { err = FSPathMakeRefWithOptions(reinterpret_cast<const UInt8 *>(QFile::encodeName(QDir::cleanPath(path)).constData()), kFSPathMakeRefDoNotFollowLeafSymlink, &fsRef, 0); } else #endif { QFileInfo fi(path); FSRef parentRef; err = FSPathMakeRef(reinterpret_cast<const UInt8 *>(fi.absoluteDir().absolutePath().toUtf8().constData()), &parentRef, 0); if (err == noErr) { QString fileName = fi.fileName(); err = FSMakeFSRefUnicode(&parentRef, fileName.length(), reinterpret_cast<const UniChar *>(fileName.unicode()), kTextEncodingUnknown, &fsRef); } } if (err != noErr) return false; FSCatalogInfo catInfo; err = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catInfo, NULL, NULL, NULL); if (err != noErr) return false; FileInfo * const fileInfo = reinterpret_cast<FileInfo*>(&catInfo.finderInfo); bool result = (fileInfo->finderFlags & kIsInvisible); return result; }
static void show_macos_type(const char *filename) { int err; FSRef ref; FSCatalogInfo info; FInfo *finfo; err = FSPathMakeRef(filename, &ref, NULL); if (err == 0) { err = FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &info, NULL, NULL, NULL); } if (err == 0) { finfo = (FInfo *)(info.finderInfo); if (finfo->fdType != 0 || finfo->fdCreator != 0) { char typecode[5], creatorcode[5], s1[256], s2[256]; memcpy(typecode, &finfo->fdType, 4); typecode[4] = 0; format_ascii(typecode, s1); memcpy(creatorcode, &finfo->fdCreator, 4); creatorcode[4] = 0; format_ascii(creatorcode, s2); print_line(0, "Type code \"%s\", creator code \"%s\"", s1, s2); } else { print_line(0, "No type and creator code"); } } if (err) { print_line(0, "Type and creator code unknown (error %d)", err); } }
/* Return the file type for given pathname */ static OSType get_file_type_from_path( const UInt8* pathname ) { #if HAVE_FSREF FSRef ref; FSCatalogInfo info; if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) return ( OSType ) 0; if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info, NULL, NULL, NULL ) ) return ( OSType ) 0; return ((FInfo *)(info.finderInfo))->fdType; #else FSSpec spec; FInfo finfo; if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) ) return ( OSType ) 0; if ( noErr != FSpGetFInfo( &spec, &finfo ) ) return ( OSType ) 0; return finfo.fdType; #endif /* HAVE_FSREF */ }
static OSStatus FindCustomFolder (FSRef *folderRef, char *folderPath, const char *folderName) { OSStatus err; CFStringRef fstr; FSRef pref; UniChar buffer[PATH_MAX + 1]; char s[PATH_MAX + 1]; if (saveFolderPath == NULL) return (-1); err = CFStringGetCString(saveFolderPath, s, PATH_MAX, kCFStringEncodingUTF8) ? noErr : -1; if (err == noErr) err = FSPathMakeRef((unsigned char *) s, &pref, NULL); if (err) return (err); fstr = CFStringCreateWithCString(kCFAllocatorDefault, folderName, CFStringGetSystemEncoding()); CFStringGetCharacters(fstr, CFRangeMake(0, CFStringGetLength(fstr)), buffer); err = FSMakeFSRefUnicode(&pref, CFStringGetLength(fstr), buffer, kTextEncodingUnicodeDefault, folderRef); if (err == dirNFErr || err == fnfErr) { err = FSCreateDirectoryUnicode(&pref, CFStringGetLength(fstr), buffer, kFSCatInfoNone, NULL, folderRef, NULL, NULL); if (err == noErr) AddFolderIcon(folderRef, folderName); } if (err == noErr) err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX); CFRelease(fstr); return (err); }
void nglDataFilesObject::SetDragItemFlavorData(DragRef dragRef, DragItemRef& itemRef, FlavorType flavorType) { OSErr err = noErr; nglString file; std::list<DragItemRef>::iterator iRef = mItemRefs.begin(); for (std::list<nglString>::const_iterator i = GetFiles().begin(); i != GetFiles().end() && iRef != mItemRefs.end(); ++i, ++iRef) { if (itemRef == *iRef) { HFSFlavor hfsInfo; FSRef fileRef; int32 start = 0; int32 len = 1023; char str[1024]; memset(str, 0, 1024); i->Export(start, str, len, eUTF8); err = FSPathMakeRef((const UInt8*)str, &fileRef, NULL); NGL_ASSERT(!err); FSCatalogInfo catInfo; err = FSGetCatalogInfo(&fileRef, kFSCatInfoFinderInfo, &catInfo, NULL, &(hfsInfo.fileSpec), NULL); NGL_ASSERT(!err); FileInfo* finfo = (FileInfo*) &catInfo.finderInfo; hfsInfo.fdFlags = finfo->finderFlags; hfsInfo.fileType = finfo->fileType; hfsInfo.fileCreator = finfo->fileCreator; err = ::SetDragItemFlavorData(dragRef, itemRef, kDragFlavorTypeHFS, &hfsInfo, sizeof (hfsInfo), 0); NGL_ASSERT(!err); //NGL_OUT("Adding file to drag data, itemRef is %d: %s\n", itemRef, (*i).GetChars()); return; } } }
//static pascal void LLDirPicker::doNavCallbackEvent(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void* callBackUD) { switch(callBackSelector) { case kNavCBStart: { if (!sInstance.mFileName) break; OSStatus error = noErr; AEDesc theLocation = {typeNull, NULL}; FSSpec outFSSpec; //Convert string to a FSSpec FSRef myFSRef; const char* filename=sInstance.mFileName->c_str(); error = FSPathMakeRef ((UInt8*)filename, &myFSRef, NULL); if (error != noErr) break; error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL); if (error != noErr) break; error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation); if (error != noErr) break; error = NavCustomControl(callBackParms->context, kNavCtlSetLocation, (void*)&theLocation); } } }
bool path_to_fsspec(const char *p_filename, FSSpec* r_fsspec) { bool t_success; t_success = true; FSRef t_ref; if (t_success) { OSStatus t_status; t_status = FSPathMakeRef((const UInt8 *)p_filename, &t_ref, NULL); if (t_status != noErr) t_success = false; } if (t_success) { OSErr t_error; t_error = FSGetCatalogInfo(&t_ref, kFSCatInfoNone, NULL, NULL, r_fsspec, NULL); if (t_error != noErr) t_success = false; } return t_success; }
/* Given a pathname, fill in a file spec. */ static int file_spec_from_path( const char* pathname, FSSpec* spec ) { #if TARGET_API_MAC_CARBON OSErr e; FSRef ref; e = FSPathMakeRef( (UInt8 *)pathname, &ref, false /* not a directory */ ); if ( e == noErr ) e = FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, spec, NULL ); return ( e == noErr ) ? 0 : (-1); #else Str255 p_path; FT_ULong path_len; /* convert path to a pascal string */ path_len = ft_strlen( pathname ); if ( path_len > 255 ) return -1; p_path[0] = (unsigned char)path_len; ft_strncpy( (char*)p_path + 1, pathname, path_len ); if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr ) return -1; else return 0; #endif }
void filecontainer_doopen(t_filecontainer *x, t_symbol *arg) { t_atom a[4]; int err = 0; char filename[256]; short path; t_fourcc outtype = 0; t_fourcc type = 'cO0p'; #ifdef MAC_VERSION char *temppath; FSRef ref; Boolean isDir; FSCatalogInfo catalogInfo; #else // WIN_VERSION char temppath[512]; #endif char fullpath[512]; t_object *result = NULL; t_object *result2 = NULL; char **record = NULL; // sqlite records char **record2 = NULL; // sqlite records t_filehandle file_handle; t_ptr_size len = 0; char *blob; char sql[512]; if(!arg || !arg->s_name[0]) { if(open_dialog(filename, &path, &outtype, NULL, -1)) // Returns 0 if successful return; } else { t_fourcc typelist[1]; typelist[0] = 'cO0p'; strcpy(filename, arg->s_name); path = 0; locatefile_extended(filename, &path, &type, typelist, 0); } path_topotentialname(path, filename, fullpath, 0); #ifdef MAC_VERSION temppath = strchr(fullpath, ':'); temppath += 1; #else // WIN_VERSION path_nameconform(fullpath, temppath, PATH_STYLE_NATIVE_WIN, PATH_TYPE_ABSOLUTE); #endif x->name = gensym(temppath); // Create our temp folder for extracted files filecontainer_gettemppath(x); // Create the SQLite instance atom_setsym(&a[0], gensym("@rambased")); atom_setlong(&a[1], 0); atom_setsym(&a[2], gensym("@db")); atom_setsym(&a[3], x->name); x->sqlite = object_new_typed(CLASS_NOBOX, _sym_sqlite, 4, a); // Operate on the open DB if(x->sqlite) { object_method(x->sqlite, ps_starttransaction); object_method(x->sqlite, _sym_execstring, TABLEDEF_FILES, NULL); object_method(x->sqlite, _sym_execstring, TABLEDEF_ATTRS, NULL); object_method(x->sqlite, _sym_execstring, "UPDATE files SET valid = 1", NULL); object_method(x->sqlite, _sym_execstring, "SELECT file_id, filename, moddate FROM files", &result); while(record = (char **)object_method(result, _sym_nextrecord)) { // Here we check for the optional 'platform' attr for this file. // If a flag exists for the other platform, but not for the current platform, then we ignore this file. #ifdef MAC_VERSION sprintf(sql, "SELECT file_id_ext FROM attrs \ WHERE attr_name = 'platform' AND attr_value = 'windows' AND file_id_ext = %s ", record[0]); object_method(x->sqlite, _sym_execstring, sql, &result2); record2 = (char **)object_method(result2, _sym_nextrecord); if(record2) { sprintf(sql, "SELECT file_id_ext FROM attrs \ WHERE attr_name = 'platform' AND attr_value = 'mac' AND file_id_ext = %s ", record[0]); object_method(x->sqlite, _sym_execstring, sql, &result2); record2 = (char **)object_method(result2, _sym_nextrecord); if(!record2) { sprintf(sql, "UPDATE files SET valid = 0 WHERE file_id = %s ", record[0]); object_method(x->sqlite, _sym_execstring, sql, NULL); continue; } } #else // WIN_VERSION snprintf(sql, 512, "SELECT file_id_ext FROM attrs \ WHERE attr_name = 'platform' AND attr_value = 'mac' AND file_id_ext = %s ", record[0]); object_method(x->sqlite, _sym_execstring, sql, &result2); record2 = (char **)object_method(result2, _sym_nextrecord); if(record2) { snprintf(sql, 512, "SELECT file_id_ext FROM attrs \ WHERE attr_name = 'platform' AND attr_value = 'windows' AND file_id_ext = %s ", record[0]); object_method(x->sqlite, _sym_execstring, sql, &result2); record2 = (char **)object_method(result2, _sym_nextrecord); if(!record2) { snprintf(sql, 512, "UPDATE files SET valid = 0 WHERE file_id = %s ", record[0]); object_method(x->sqlite, _sym_execstring, sql, NULL); continue; } } #endif // At this point we have a file (record[0]), and we have determined that it is indeed a file we want to cache // So cache it to a new file in our temp path err = path_createsysfile(record[1], x->temp_path, type, &file_handle); if(err) { // Handle any errors that occur object_error((t_object *)x, "%s - error %d creating file", filename, err); } else { snprintf(sql, 512, "SELECT content FROM files WHERE file_id = %s", record[0]); object_method(x->sqlite, ps_getblob, sql, &blob, &len); err = sysfile_write(file_handle, &len, blob); if(err) { object_error((t_object *)x, "sysfile_write error (%d)", err); } } err = sysfile_seteof(file_handle, len); if(err) { object_error((t_object *)x, "%s - error %d setting EOF", filename, err); } sysfile_close(file_handle); // close file reference sysmem_freeptr(blob); blob = NULL; // Set the moddate #ifdef MAC_VERSION // FSCatalogInfo catalogInfo; // Boolean status; CFGregorianDate gdate; CFAbsoluteTime abstime; CFTimeZoneRef tz; UTCDateTime utc; sscanf(record[2], "%4ld-%02hd-%02hd %02hd:%02hd:%02lf", &gdate.year, (signed short*)&gdate.month, (signed short*)&gdate.day, (signed short*)&gdate.hour, (signed short*)&gdate.minute, &gdate.second); tz = CFTimeZoneCopySystem(); abstime = CFGregorianDateGetAbsoluteTime(gdate, tz); UCConvertCFAbsoluteTimeToUTCDateTime(abstime, &utc); catalogInfo.contentModDate = utc; strcpy(s_tempstr, x->temp_fullpath->s_name); temppath = strchr(s_tempstr, ':'); temppath++; strcat(temppath, "/"); strcat(temppath, record[1]); FSPathMakeRef((UInt8*)temppath, &ref, &isDir); err = FSSetCatalogInfo(&ref, kFSCatInfoContentMod, &catalogInfo); #else // WIN_VERSION char winpath[512]; HANDLE hFile; FILETIME fileTime; SYSTEMTIME systemTime; sscanf(record[2], "%4lu-%02lu-%02lu %02lu:%02lu:%02lu", &systemTime.wYear, &systemTime.wMonth, &systemTime.wDay, &systemTime.wHour, &systemTime.wMinute, &systemTime.wSecond); err = SystemTimeToFileTime(&systemTime, &fileTime); strcpy(s_tempstr, x->temp_fullpath->s_name); path_nameconform(s_tempstr, winpath, PATH_STYLE_NATIVE_WIN, PATH_TYPE_ABSOLUTE); strcat(winpath, "\\"); strcat(winpath, record[1]); hFile = CreateFile((LPCSTR)winpath , GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(hFile == INVALID_HANDLE_VALUE) { object_error((t_object *)x, "invalid handle value"); goto out; } err = SetFileTime(hFile, &fileTime, &fileTime, &fileTime); if(err == 0) { err = GetLastError(); object_error((t_object *)x, "Error setting date: %i", err); } CloseHandle(hFile); out: ; #endif } object_method(x->sqlite, ps_endtransaction); }
void ofQtVideoSaver::setup( int width , int height, string movieName){ w = width; h = height; fileName = (ofToDataPath(movieName)); //pszFlatFilename = flatFileName; initializeQuicktime(); /* Load the FSSpec structure to describe the receiving file. For a description of this and related calls see http://developer.apple.com/quicktime/icefloe/dispatch004.html. ================================================================ */ #ifdef TARGET_WIN32 //FILE * pFile = NULL; //pFile = fopen (fileName.c_str(),"w"); //fclose (pFile); char fileNameStr[255]; sprintf(fileNameStr, "%s", fileName.c_str()); osErr = NativePathNameToFSSpec (fileNameStr, &fsSpec, 0); #endif #ifdef TARGET_OSX /// kill a file and make a new one if needed: FILE * pFile; pFile = fopen (fileName.c_str(),"w"); fclose (pFile); Boolean isdir; osErr = FSPathMakeRef((const UInt8*)fileName.c_str(), &fsref, &isdir); osErr = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsSpec, NULL); #endif if (osErr && (osErr != fnfErr)) /* File-not-found error is ok */ { printf ("getting FSS spec failed %d\n", osErr); goto bail; } /* Step 1: Create a new, empty movie file and a movie that references that file (CreateMovieFile). ======================================================================== */ osErr = CreateMovieFile ( &fsSpec, /* FSSpec specifier */ FOUR_CHAR_CODE('TVOD'), /* file creator type, TVOD = QT player*/ smCurrentScript, /* movie script system to use */ createMovieFileDeleteCurFile /* movie file creation flags */ | createMovieFileDontCreateResFile, &sResRefNum, /* returned file ref num to data fork */ &movie /* returned handle to open empty movie*/ /* that references the created file */ ); if (osErr) { printf ("CreateMovieFile failed %d\n", osErr); goto bail; } /* Step 2: Add a new track to that movie (NewMovieTrack). ======================================================= */ track = NewMovieTrack ( movie, /* the movie to add track to */ ((long) w << 16), /* width of track in pixels (Fixed) */ FixRatio (h, 1), /* height of track in pixels (Fixed) */ kNoVolume /* default volume level */ ); osErr = GetMoviesError (); if (osErr) { printf ("NewMovieTrack failed %d\n", osErr); goto bail; } /* Step 3: Add a new media to that track (NewTrackMedia). ======================================================= */ media = NewTrackMedia ( track, /* the track to add the media to */ VideoMediaType, /* media type, e.g. SoundMediaType */ 600, /* num media time units that elapse/sec*/ NULL, /* ptr to file that holds media sampls*/ 0 /* type of ptr to media samples */ ); osErr = GetMoviesError (); if (osErr) { printf ("NewTrackMedia failed %d\n", osErr); goto bail; } /* Step 4: Add media samples to the media. ======================================== */ BeginMediaEdits (media); /* Inform the Movie Toolbox that we */ /* want to change the media samples */ /* referenced by a track's media. */ /* This opens the media container */ /* and makes it ready to receive */ /* and/or remove sample data. */ // Step 5: setup graphics port for qt movie and compression type --- /* Create a new offscreen graphics world that will hold the movie's drawing surface. draw_image() copies the image of IceFlow to this surface with varying amounts of transparency. ================================================================= */ MacSetRect (&rect, 0, 0, w, h); osErr = NewGWorld ( &pMovieGWorld, /* receives the new GWorld. */ 24, /* pixel depth in bits/pixel */ &rect, /* desired size of the GWorld. */ NULL, NULL, (GWorldFlags) 0 ); if (osErr != noErr) { printf ("NewGWorld 1 failed %d\n", osErr); goto bail; } /* Retrieve the pixel map associated with that graphics world and lock the pixel map in memory. GetMaxCompressionSize() and CompressImage() only operate on pixel maps, not graphics worlds. ===================================================================== */ pixMapHandle = GetGWorldPixMap (pMovieGWorld); if (pixMapHandle == NULL) { printf ("GetGWorldPixMap failed\n"); goto bail; } LockPixels (pixMapHandle); /* Get the maximum number of bytes required to hold an image having the specified characteristics compressed using the specified compressor. ==================================================================== */ osErr = GetMaxCompressionSize ( pixMapHandle, /* the pixel map to compress from. */ &rect, /* the image rectangle. */ 0, /* let ICM choose image bit depth. */ codecHighQuality, /* compression quality specifier. */ kRawCodecType, /* desired compression type */ // < set to RAW in case we set to a new compression type... (CompressorComponent) anyCodec, /* codec specifier. */ &lMaxCompressionSize /* receives max bytes needed for cmp. */ ); if (osErr != noErr) { printf ("GetMaxCompressionSize failed %d\n", osErr); goto bail; } /* Allocate a buffer to hold the compressed image data by creating a new handle. ===================================================================== */ hCompressedData = NewHandle (lMaxCompressionSize); if (hCompressedData == NULL) { printf ("NewHandle(%ld) failed\n", lMaxCompressionSize); goto bail; } /* Lock the handle and then dereference it to obtain a pointer to the data buffer because CompressImage() wants us to pass it a pointer, not a handle. ======================================================================= */ HLockHi (hCompressedData); pCompressedData = *hCompressedData; /* Create an image description object in memory of minimum size to pass to CompressImage(). CompressImage() will resize the memory as necessary so create it small here. ==================================================================== */ hImageDescription = (ImageDescriptionHandle) NewHandle (4); if (hImageDescription == NULL) { printf ("NewHandle(4) failed\n"); goto bail; } bSetupForRecordingMovie = true; return; bail: printf("got to bail somehows \n"); if (sResRefNum != 0) CloseMovieFile (sResRefNum); if (movie != NULL) DisposeMovie (movie); //ExitMovies (); /* Finalize Quicktime */ return; }
QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); if (file == BundleName) { #if !defined(QWS) && defined(Q_OS_MAC) QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath), kCFURLPOSIXPathStyle, true); if(CFDictionaryRef dict = CFBundleCopyInfoDictionaryForURL(url)) { if(CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) { if(CFGetTypeID(name) == CFStringGetTypeID()) return QCFString::toQString((CFStringRef)name); } } #endif return QString(); } else if (file == BaseName) { int slash = d->filePath.lastIndexOf(QLatin1Char('/')); if (slash != -1) return d->filePath.mid(slash + 1); } else if (file == PathName) { int slash = d->filePath.lastIndexOf(QLatin1Char('/')); if (slash == -1) return QLatin1String("."); else if (!slash) return QLatin1String("/"); return d->filePath.left(slash); } else if (file == AbsoluteName || file == AbsolutePathName) { QString ret; if (d->filePath.isEmpty() || !d->filePath.startsWith(QLatin1Char('/'))) ret = QDir::currentPath(); if (!d->filePath.isEmpty() && d->filePath != QLatin1String(".")) { if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) ret += QLatin1Char('/'); ret += d->filePath; } if (ret == QLatin1String("/")) return ret; bool isDir = ret.endsWith(QLatin1Char('/')); ret = QDir::cleanPath(ret); if (isDir) ret += QLatin1String("/"); if (file == AbsolutePathName) { int slash = ret.lastIndexOf(QLatin1Char('/')); if (slash == -1) return QDir::currentPath(); else if (!slash) return QLatin1String("/"); return ret.left(slash); } return ret; } else if (file == CanonicalName || file == CanonicalPathName) { if (!(fileFlags(ExistsFlag) & ExistsFlag)) return QString(); QString ret = QFSFileEnginePrivate::canonicalized(fileName(AbsoluteName)); if (!ret.isEmpty() && file == CanonicalPathName) { int slash = ret.lastIndexOf(QLatin1Char('/')); if (slash == -1) ret = QDir::currentPath(); else if (slash == 0) ret = QLatin1String("/"); ret = ret.left(slash); } return ret; } else if (file == LinkName) { if (d->isSymlink()) { #if defined(__GLIBC__) && !defined(PATH_MAX) #define PATH_CHUNK_SIZE 256 char *s = 0; int len = -1; int size = PATH_CHUNK_SIZE; while (1) { s = (char *) ::realloc(s, size); if (s == 0) { len = -1; break; } len = ::readlink(d->nativeFilePath.constData(), s, size); if (len < 0) { ::free(s); break; } if (len < size) { break; } size *= 2; } #else char s[PATH_MAX+1]; int len = readlink(d->nativeFilePath.constData(), s, PATH_MAX); #endif if (len > 0) { QString ret; if (S_ISDIR(d->st.st_mode) && s[0] != '/') { QDir parent(d->filePath); parent.cdUp(); ret = parent.path(); if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) ret += QLatin1Char('/'); } s[len] = '\0'; ret += QFile::decodeName(QByteArray(s)); #if defined(__GLIBC__) && !defined(PATH_MAX) ::free(s); #endif if (!ret.startsWith(QLatin1Char('/'))) { if (d->filePath.startsWith(QLatin1Char('/'))) { ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/'))) + QLatin1Char('/')); } else { ret.prepend(QDir::currentPath() + QLatin1Char('/')); } } ret = QDir::cleanPath(ret); if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) ret.chop(1); return ret; } } #if !defined(QWS) && defined(Q_OS_MAC) { FSRef fref; if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(), &fref, 0) == noErr) { Boolean isAlias, isFolder; if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) { AliasHandle alias; if (FSNewAlias(0, &fref, &alias) == noErr && alias) { CFStringRef cfstr; if (FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr) return QCFString::toQString(cfstr); } } } } #endif return QString(); } return d->filePath; }
/*! \reimp */ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const { Q_D(const QFSFileEngine); // Force a stat, so that we're guaranteed to get up-to-date results if (type & QAbstractFileEngine::FileFlag(QAbstractFileEngine::Refresh)) { d->tried_stat = 0; d->need_lstat = 1; } QAbstractFileEngine::FileFlags ret = 0; bool exists = d->doStat(); if (!exists && !d->isSymlink()) return ret; if (exists && (type & PermsMask)) { if (d->st.st_mode & S_IRUSR) ret |= ReadOwnerPerm; if (d->st.st_mode & S_IWUSR) ret |= WriteOwnerPerm; if (d->st.st_mode & S_IXUSR) ret |= ExeOwnerPerm; if (d->st.st_mode & S_IRUSR) ret |= ReadUserPerm; if (d->st.st_mode & S_IWUSR) ret |= WriteUserPerm; if (d->st.st_mode & S_IXUSR) ret |= ExeUserPerm; if (d->st.st_mode & S_IRGRP) ret |= ReadGroupPerm; if (d->st.st_mode & S_IWGRP) ret |= WriteGroupPerm; if (d->st.st_mode & S_IXGRP) ret |= ExeGroupPerm; if (d->st.st_mode & S_IROTH) ret |= ReadOtherPerm; if (d->st.st_mode & S_IWOTH) ret |= WriteOtherPerm; if (d->st.st_mode & S_IXOTH) ret |= ExeOtherPerm; } if (type & TypesMask) { #if !defined(QWS) && defined(Q_OS_MAC) bool foundAlias = false; { FSRef fref; if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(), &fref, NULL) == noErr) { Boolean isAlias, isFolder; if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr && isAlias) { foundAlias = true; ret |= LinkType; } } } if (!foundAlias) #endif { if ((type & LinkType) && d->isSymlink()) ret |= LinkType; if (exists && (d->st.st_mode & S_IFMT) == S_IFREG) ret |= FileType; else if (exists && (d->st.st_mode & S_IFMT) == S_IFDIR) ret |= DirectoryType; #if !defined(QWS) && defined(Q_OS_MAC) if((ret & DirectoryType) && (type & BundleType)) { QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath), kCFURLPOSIXPathStyle, true); UInt32 type, creator; if(CFBundleGetPackageInfoInDirectory(url, &type, &creator)) ret |= BundleType; } #endif } } if (type & FlagsMask) { ret |= LocalDiskFlag; if (exists) ret |= ExistsFlag; if (fileName(BaseName)[0] == QLatin1Char('.') #if !defined(QWS) && defined(Q_OS_MAC) || _q_isMacHidden(d->filePath) #endif ) ret |= HiddenFlag; if (d->filePath == QLatin1String("/")) ret |= RootFlag; } return ret; }
int process_spawn( process_t* proc ) { static char unescaped[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.:/\\"; int i, num_args; int size; #if FOUNDATION_PLATFORM_WINDOWS wchar_t* wcmdline; wchar_t* wwd; char* cmdline = 0; #endif if( !proc ) return PROCESS_INVALID_ARGS; proc->code = PROCESS_INVALID_ARGS; if( !string_length( proc->path ) ) return proc->code; //Always escape path on Windows platforms #if FOUNDATION_PLATFORM_POSIX if( string_find_first_not_of( proc->path, unescaped, 0 ) != STRING_NPOS ) #endif { if( proc->path[0] != '"' ) proc->path = string_prepend( proc->path, "\"" ); if( proc->path[ string_length( proc->path ) - 1 ] != '"' ) proc->path = string_append( proc->path, "\"" ); } size = array_size( proc->args ); for( i = 0, num_args = 0; i < size; ++i ) { char* arg = proc->args[i]; if( !string_length( arg ) ) continue; ++num_args; if( string_find_first_not_of( arg, unescaped, 0 ) != STRING_NPOS ) { if( arg[0] != '"' ) { //Check if we need to escape " characters unsigned int pos = string_find( arg, '"', 0 ); while( pos != STRING_NPOS ) { if( arg[ pos - 1 ] != '\\' ) { char* escarg = string_substr( arg, 0, pos ); char* left = string_substr( arg, pos, STRING_NPOS ); escarg = string_append( escarg, "\\" ); escarg = string_append( escarg, left ); string_deallocate( left ); string_deallocate( arg ); arg = escarg; } pos = string_find( arg, '"', pos + 2 ); } arg = string_prepend( arg, "\"" ); arg = string_append( arg, "\"" ); proc->args[i] = arg; } } } #if FOUNDATION_PLATFORM_WINDOWS # ifndef SEE_MASK_NOASYNC # define SEE_MASK_NOASYNC 0x00000100 # endif if( !( proc->flags & PROCESS_WINDOWS_USE_SHELLEXECUTE ) ) //Don't prepend exe path to parameters if using ShellExecute cmdline = string_clone( proc->path ); //Build command line string for( i = 0; i < size; ++i ) { char* arg = proc->args[i]; if( !string_length( arg ) ) continue; if( cmdline ) cmdline = string_append( cmdline, " " ); cmdline = string_append( cmdline, arg ); } if( !string_length( proc->wd ) ) proc->wd = string_clone( environment_current_working_directory() ); wcmdline = wstring_allocate_from_string( cmdline, 0 ); wwd = wstring_allocate_from_string( proc->wd, 0 ); if( proc->flags & PROCESS_WINDOWS_USE_SHELLEXECUTE ) { SHELLEXECUTEINFOW sei; wchar_t* wverb; wchar_t* wpath; wverb = ( proc->verb && string_length( proc->verb ) ) ? wstring_allocate_from_string( proc->verb, 0 ) : 0; wpath = wstring_allocate_from_string( proc->path, 0 ); ZeroMemory( &sei, sizeof( sei ) ); sei.cbSize = sizeof(SHELLEXECUTEINFOW); sei.hwnd = 0; sei.fMask = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS; sei.lpVerb = wverb; sei.lpFile = wpath; sei.lpParameters = wcmdline; sei.lpDirectory = wwd; sei.nShow = SW_SHOWNORMAL; if( !( proc->flags & PROCESS_CONSOLE ) ) sei.fMask |= SEE_MASK_NO_CONSOLE; if( proc->flags & PROCESS_STDSTREAMS ) log_warnf( 0, WARNING_UNSUPPORTED, "Unable to redirect standard in/out through pipes when using ShellExecute for process spawning" ); log_debugf( 0, "Spawn process (ShellExecute): %s %s", proc->path, cmdline ); if( !ShellExecuteExW( &sei ) ) { log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to spawn process (ShellExecute) for executable '%s': %s", proc->path, system_error_message( GetLastError() ) ); } else { proc->hp = sei.hProcess; proc->ht = 0; proc->code = 0; } wstring_deallocate( wverb ); wstring_deallocate( wpath ); } else { STARTUPINFOW si; PROCESS_INFORMATION pi; BOOL inherit_handles = FALSE; memset( &si, 0, sizeof( si ) ); memset( &pi, 0, sizeof( pi ) ); si.cb = sizeof( si ); if( proc->flags & PROCESS_STDSTREAMS ) { proc->pipeout = pipe_allocate(); proc->pipein = pipe_allocate(); si.dwFlags |= STARTF_USESTDHANDLES; si.hStdOutput = pipe_write_handle( proc->pipeout ); si.hStdError = pipe_write_handle( proc->pipeout ); si.hStdInput = pipe_read_handle( proc->pipein ); //Don't inherit wrong ends of pipes SetHandleInformation( pipe_read_handle( proc->pipeout ), HANDLE_FLAG_INHERIT, 0 ); SetHandleInformation( pipe_write_handle( proc->pipein ), HANDLE_FLAG_INHERIT, 0 ); inherit_handles = TRUE; } log_debugf( 0, "Spawn process (CreateProcess): %s %s", proc->path, cmdline ); if( !CreateProcessW( 0/*wpath*/, wcmdline, 0, 0, inherit_handles, ( proc->flags & PROCESS_CONSOLE ) ? CREATE_NEW_CONSOLE : 0, 0, wwd, &si, &pi ) ) { log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to spawn process (CreateProcess) for executable '%s': %s", proc->path, system_error_message( GetLastError() ) ); stream_deallocate( proc->pipeout ); stream_deallocate( proc->pipein ); proc->pipeout = 0; proc->pipein = 0; } else { proc->hp = pi.hProcess; proc->ht = pi.hThread; proc->code = 0; } if( proc->pipeout ) pipe_close_write( proc->pipeout ); if( proc->pipein ) pipe_close_read( proc->pipein ); } wstring_deallocate( wcmdline ); wstring_deallocate( wwd ); string_deallocate( cmdline ); if( proc->code < 0 ) return proc->code; //Error #endif #if FOUNDATION_PLATFORM_MACOSX if( proc->flags & PROCESS_OSX_USE_OPENAPPLICATION ) { proc->pid = 0; LSApplicationParameters params; ProcessSerialNumber psn; FSRef* fsref = memory_allocate( 0, sizeof( FSRef ), 0, MEMORY_TEMPORARY | MEMORY_ZERO_INITIALIZED ); memset( ¶ms, 0, sizeof( LSApplicationParameters ) ); memset( &psn, 0, sizeof( ProcessSerialNumber ) ); char* pathstripped = string_strip( string_clone( proc->path ), "\"" ); OSStatus status = 0; status = FSPathMakeRef( (uint8_t*)pathstripped, fsref, 0 ); if( status < 0 ) { pathstripped = string_append( pathstripped, ".app" ); status = FSPathMakeRef( (uint8_t*)pathstripped, fsref, 0 ); } CFStringRef* args = 0; for( i = 0, size = array_size( proc->args ); i < size; ++i ) //App gets executable path automatically, don't include array_push( args, CFStringCreateWithCString( 0, proc->args[i], kCFStringEncodingUTF8 ) ); CFArrayRef argvref = CFArrayCreate( 0, (const void**)args, (CFIndex)array_size( args ), 0 ); params.flags = kLSLaunchDefaults; params.application = fsref; params.argv = argvref; log_debugf( 0, "Spawn process (LSOpenApplication): %s", pathstripped ); status = LSOpenApplication( ¶ms, &psn ); if( status != 0 ) { proc->code = status; log_warnf( 0, WARNING_BAD_DATA, "Unable to spawn process for executable '%s': %s", proc->path, system_error_message( status ) ); } CFRelease( argvref ); for( i = 0, size = array_size( args ); i < size; ++i ) CFRelease( args[i] ); memory_deallocate( fsref ); string_deallocate( pathstripped ); if( status == 0 ) { pid_t pid = 0; GetProcessPID( &psn, &pid ); proc->pid = pid; //Always "detached" with LSOpenApplication, not a child process at all //Setup a kqueue to watch when process terminates so we can emulate a wait proc->kq = kqueue(); if( proc->kq < 0 ) { log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to create kqueue for process watch: %s (%d)", proc->kq, system_error_message( proc->kq ) ); proc->kq = 0; } else { struct kevent changes; EV_SET( &changes, (pid_t)pid, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, 0 ); int ret = kevent( proc->kq, &changes, 1, &changes, 1, 0 ); if( ret != 1 ) { log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to setup kqueue for process watch, failed to add event to kqueue (%d)", ret ); close( proc->kq ); proc->kq = 0; } } } goto exit; } #endif #if FOUNDATION_PLATFORM_POSIX //Insert executable arg at start and null ptr at end int argc = array_size( proc->args ) + 1; array_grow( proc->args, 2 ); for( int arg = argc - 1; arg > 0; --arg ) proc->args[arg] = proc->args[arg-1]; proc->args[0] = string_clone( proc->path ); proc->args[argc] = 0; if( proc->flags & PROCESS_STDSTREAMS ) { proc->pipeout = pipe_allocate(); proc->pipein = pipe_allocate(); } proc->pid = 0; pid_t pid = fork(); if( pid == 0 ) { //Child if( string_length( proc->wd ) ) { log_debugf( 0, "Spawned child process, setting working directory to %s", proc->wd ); environment_set_current_working_directory( proc->wd ); } log_debugf( 0, "Child process executing: %s", proc->path ); if( proc->flags & PROCESS_STDSTREAMS ) { pipe_close_read( proc->pipeout ); dup2( pipe_write_fd( proc->pipeout ), STDOUT_FILENO ); pipe_close_write( proc->pipein ); dup2( pipe_read_fd( proc->pipein ), STDIN_FILENO ); } int code = execv( proc->path, proc->args ); if( code < 0 ) //Will always be true since this point will never be reached if execve() is successful log_warnf( 0, WARNING_BAD_DATA, "Child process failed execve() : %s : %s", proc->path, system_error_message( errno ) ); //Error process_exit( -1 ); } if( pid > 0 ) { log_debugf( 0, "Child process forked, pid %d", pid ); proc->pid = pid; if( proc->pipeout ) pipe_close_write( proc->pipeout ); if( proc->pipein ) pipe_close_read( proc->pipein ); if( proc->flags & PROCESS_DETACHED ) { int cstatus = 0; pid_t err = waitpid( pid, &cstatus, WNOHANG ); if( err == 0 ) { //TODO: Ugly wait to make sure process spawned correctly thread_sleep( 500 ); err = waitpid( pid, &cstatus, WNOHANG ); } if( err > 0 ) { //Process exited, check code proc->code = (int)((char)WEXITSTATUS( cstatus )); log_debugf( 0, "Child process returned: %d", proc->code ); return proc->code; } } } else { //Error proc->code = errno; log_warnf( 0, WARNING_BAD_DATA, "Unable to spawn process: %s : %s", proc->path, system_error_message( proc->code ) ); if( proc->pipeout ) stream_deallocate( proc->pipeout ); if( proc->pipein ) stream_deallocate( proc->pipein ); proc->pipeout = 0; proc->pipein = 0; return proc->code; } #endif #if !FOUNDATION_PLATFORM_WINDOWS && !FOUNDATION_PLATFORM_POSIX FOUNDATION_ASSERT_FAIL( "Process spawning not supported on platform" ); #endif #if FOUNDATION_PLATFORM_MACOSX exit: #endif if( proc->flags & PROCESS_DETACHED ) return PROCESS_STILL_ACTIVE; return process_wait( proc ); }