1/* 2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23#ifndef RLD 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <mach/mach.h> 28#include <sys/types.h> 29#include <sys/sysctl.h> 30#include "stuff/errors.h" 31#include "stuff/allocate.h" 32#include "stuff/macosx_deployment_target.h" 33 34/* last value passed to put_macosx_deployment_target() */ 35static char *command_line_macosx_deployment_target = NULL; 36 37/* 38 * put_macosx_deployment_target() is called with the command line argument to 39 * -macosx_version_min which the compiler uses to allow the user to asked for 40 * a particular macosx deployment target on the command-line to override the 41 * environment variable. This simply saves away the value requested. The 42 * string passed is not copied. If NULL is passed, it removes any previous 43 * setting. 44 */ 45__private_extern__ 46void 47put_macosx_deployment_target( 48char *target) 49{ 50 command_line_macosx_deployment_target = target; 51} 52 53/* 54 * get_macosx_deployment_target() sets the fields of the 55 * macosx_deployment_target struct passed to it based on the last 56 * command_line_macosx_deployment_target value set (if any) or the specified 57 * MACOSX_DEPLOYMENT_TARGET environment variable or the default which the 58 * the value the machine this is running on. The name field in the struct is 59 * always pointing to memory allocated here so it can be free()'ed when no 60 * longer needed. 61 */ 62__private_extern__ 63void 64get_macosx_deployment_target( 65struct macosx_deployment_target *value) 66{ 67 uint32_t ten, major, minor; 68 char *p, *q, *endp; 69 char osversion[32]; 70 size_t osversion_len; 71 static int osversion_name[2]; 72 73 /* 74 * Pick up the Mac OS X deployment target set by the command line 75 * or the environment variable if any. If that does not parse out 76 * use the default and generate a warning. We accept "10.x" or "10.x.y" 77 * where x and y are unsigned numbers. And x is non-zero. 78 */ 79 if(command_line_macosx_deployment_target != NULL) 80 p = command_line_macosx_deployment_target; 81 else 82 p = getenv("MACOSX_DEPLOYMENT_TARGET"); 83 if(p != NULL){ 84 ten = strtoul(p, &endp, 10); 85 if(*endp != '.') 86 goto use_default; 87 if(ten != 10) 88 goto use_default; 89 q = endp + 1; 90 major = strtoul(q, &endp, 10); 91 if(major == 0) 92 goto use_default; 93 if(*endp != '.' && *endp != '\0') 94 goto use_default; 95 if(*endp == '.'){ 96 q = endp + 1; 97 minor = strtoul(q, &endp, 10); 98 if(*endp != '\0') 99 goto use_default; 100 } 101 else{ 102 minor = 0; 103 } 104 value->major = major; 105 value->minor = minor; 106 value->name = allocate(strlen(p) + 1); 107 strcpy(value->name, p); 108 return; 109 } 110 111use_default: 112 /* 113 * The default value is the version of the running OS. 114 */ 115 osversion_name[0] = CTL_KERN; 116 osversion_name[1] = KERN_OSRELEASE; 117 osversion_len = sizeof(osversion) - 1; 118 if(sysctl(osversion_name, 2, osversion, &osversion_len, NULL, 0) == -1) 119 system_error("sysctl for kern.osversion failed"); 120 121 /* 122 * Now parse this out. It is expected to be of the form "x.y.z" where 123 * x, y and z are unsigned numbers. Where x-4 is the Mac OS X major 124 * version number, and y is the minor version number. We don't parse 125 * out the value of z. 126 */ 127 major = strtoul(osversion, &endp, 10); 128 if(*endp != '.') 129 goto bad_system_value; 130 if(major <= 4) 131 goto bad_system_value; 132 major = major - 4; 133 q = endp + 1; 134 minor = strtoul(q, &endp, 10); 135 if(*endp != '.') 136 goto bad_system_value; 137 138 value->major = major; 139 value->minor = minor; 140 value->name = allocate(32); 141 sprintf(value->name, "10.%u.%u", major, minor); 142 goto warn_if_bad_user_values; 143 144bad_system_value: 145 /* 146 * As a last resort we set the default to the highest known shipping 147 * system to date. 148 */ 149 value->major = 6; 150 value->minor = 0; 151 value->name = allocate(strlen("10.6") + 1); 152 strcpy(value->name, "10.6"); 153 warning("unknown value returned by sysctl() for kern.osrelease: %s " 154 "ignored (using %s)", osversion, value->name); 155 /* fall through to also warn about a possble bad user value */ 156 157warn_if_bad_user_values: 158 if(p != NULL){ 159 if(command_line_macosx_deployment_target != NULL) 160 warning("unknown -macosx_version_min parameter value: " 161 "%s ignored (using %s)", p, value->name); 162 else 163 warning("unknown MACOSX_DEPLOYMENT_TARGET environment " 164 "variable value: %s ignored (using %s)", p,value->name); 165 } 166} 167#endif /* !defined(RLD) */ 168