Changeset 308 for trunk/launch/launch/main.c
- Timestamp:
- 10/30/06 10:36:56 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/launch/launch/main.c
r305 r308 21 21 #include <unistd.h> 22 22 #include <sys/stat.h> 23 #include <mach-o/fat.h> 24 #include <mach-o/arch.h> 25 #include <mach-o/loader.h> 23 26 #include <Carbon/Carbon.h> 24 27 #include <CoreServices/CoreServices.h> … … 648 651 CFRelease(typeStr); 649 652 return buffer; 653 } 654 655 // based on Apple's "CheckExecutableArchitecture" sample code 656 657 #define MAX_HEADER_BYTES 512 658 659 void swapHeader(uint8_t *bytes, ssize_t length) { 660 for (ssize_t i = 0 ; i < length ; i += 4) 661 *(uint32_t *)(bytes + i) = OSSwapInt32(*(uint32_t *)(bytes + i)); 662 } 663 664 void printExecutableArchitectures(CFURLRef url, bool printOnFailure) { 665 uint8_t path[PATH_MAX]; 666 if (printOnFailure) 667 printf("\tarchitecture: "); 668 669 if (!CFURLGetFileSystemRepresentation(url, true, path, PATH_MAX)) { 670 if (printOnFailure) printf("(can't get executable)\n"); 671 return; 672 } 673 674 int fd = open((const char *)path, O_RDONLY, 0777); 675 if (fd <= 0) { 676 if (printOnFailure) printf("(can't read)\n"); 677 return; 678 } 679 680 uint8_t bytes[MAX_HEADER_BYTES]; 681 ssize_t length = read(fd, bytes, MAX_HEADER_BYTES); 682 close(fd); 683 684 if (length < sizeof(struct mach_header_64)) { 685 if (printOnFailure) printf("(can't read Mach-O header)\n"); 686 return; 687 } 688 689 // Look for any of the six magic numbers relevant to Mach-O executables, and swap the header if necessary. 690 uint32_t num_fat = 0, magic = *((uint32_t *)bytes); 691 uint32_t max_fat = (length - sizeof(struct fat_header)) / sizeof(struct fat_arch); 692 struct fat_arch one_fat = {0}, *fat; 693 if (MH_MAGIC == magic || MH_CIGAM == magic) { 694 struct mach_header *mh = (struct mach_header *)bytes; 695 if (MH_CIGAM == magic) swapHeader(bytes, length); 696 one_fat.cputype = mh->cputype; 697 one_fat.cpusubtype = mh->cpusubtype; 698 fat = &one_fat; 699 num_fat = 1; 700 } else if (MH_MAGIC_64 == magic || MH_CIGAM_64 == magic) { 701 struct mach_header_64 *mh = (struct mach_header_64 *)bytes; 702 if (MH_CIGAM_64 == magic) swapHeader(bytes, length); 703 one_fat.cputype = mh->cputype; 704 one_fat.cpusubtype = mh->cpusubtype; 705 fat = &one_fat; 706 num_fat = 1; 707 } else if (FAT_MAGIC == magic || FAT_CIGAM == magic) { 708 fat = (struct fat_arch *)(bytes + sizeof(struct fat_header)); 709 if (FAT_CIGAM == magic) swapHeader(bytes, length); 710 num_fat = ((struct fat_header *)bytes)->nfat_arch; 711 if (num_fat > max_fat) num_fat = max_fat; 712 } 713 714 if (num_fat == 0) { 715 if (printOnFailure) printf("(none found)\n"); 716 return; 717 } 718 719 if (!printOnFailure) 720 printf("\tarchitecture: "); 721 722 for (int i = 0 ; i < num_fat ; i++) { 723 if (i != 0) printf(", "); 724 const NXArchInfo *arch = NXGetArchInfoFromCpuType(fat[i].cputype, fat[i].cpusubtype); 725 if (arch == NULL) { 726 printf("unknown (cputype %d, subtype %d)", fat[i].cputype, fat[i].cpusubtype); 727 continue; 728 } 729 printf(arch->description); 730 } 731 printf("\n"); 650 732 } 651 733 … … 761 843 intVersion = CFBundleGetVersionNumber(bundle); 762 844 } 845 CFURLRef executable = CFBundleCopyExecutableURL(bundle); 846 if (executable != NULL) { 847 printExecutableArchitectures(executable, true); 848 CFRelease(executable); 849 } 763 850 CFRelease(bundle); 764 851 } … … 767 854 CFRelease(bundleID); 768 855 } 769 } else if (haveFSRef) { 770 // try to get a version if we can, but don't complain if we can't 771 SInt16 resFork = FSOpenResFile(&fsr, fsRdPerm); 772 if (ResError() == noErr) { 773 VersRecHndl vers = (VersRecHndl)Get1Resource('vers', 1); 774 if (ResError() == noErr && vers != NULL) { 775 version = CFStringCreateWithPascalString(NULL, vers[0]->shortVersion, CFStringGetSystemEncoding()); // XXX use country code instead? 776 intVersion = ((NumVersionVariant)vers[0]->numericVersion).whole; 856 } else { 857 printExecutableArchitectures(url, false); 858 if (haveFSRef) { 859 // try to get a version if we can, but don't complain if we can't 860 SInt16 resFork = FSOpenResFile(&fsr, fsRdPerm); 861 if (ResError() == noErr) { 862 VersRecHndl vers = (VersRecHndl)Get1Resource('vers', 1); 863 if (ResError() == noErr && vers != NULL) { 864 version = CFStringCreateWithPascalString(NULL, vers[0]->shortVersion, CFStringGetSystemEncoding()); // XXX use country code instead? 865 intVersion = ((NumVersionVariant)vers[0]->numericVersion).whole; 866 } 777 867 } 868 CloseResFile(resFork); 778 869 } 779 CloseResFile(resFork);780 870 } 781 871 782 872 if (version != NULL) { 783 873 printf("\tversion: %s", utf8StringFromCFStringRef(version));
Note:
See TracChangeset
for help on using the changeset viewer.