gen/FreeBSD/readpassphrase.c freebsd lib/libc/gen/readpassphrase.c 1f19a8fc755a14865a5a5b67d5fa895c4b7cf622
gen/FreeBSD/readpassphrase.3 freebsd lib/libc/gen/readpassphrase.3 e0a2d4f15ed9e93fcb62544ed65f7a98e2339c3b
gen/FreeBSD/times.3 freebsd lib/libc/gen/times.3 5b882020081a138285227631c46a406c08e17bc8
+gen/FreeBSD/timespec_get.c freebsd lib/libc/gen/timespec_get.c 7cbaa4254c0f10f7c00014ce9591ca60abfa57fb
+gen/FreeBSD/timespec_get.3 freebsd lib/libc/gen/timespec_get.3 7cbaa4254c0f10f7c00014ce9591ca60abfa57fb
gen/FreeBSD/ttyname.3 freebsd lib/libc/gen/ttyname.3 84be924362c6e5f469564d418c928c5b1b4a2457
gen/FreeBSD/ttyslot.c freebsd lib/libc/gen/ttyslot.c 898928e8d0a0bab201c1ef232e01cafa27322dae
gen/FreeBSD/unvis.c freebsd contrib/libc-vis/unvis.c 9e3e4b88576d01efe1f56469cac79e116bb62c67
gen/FreeBSD/vis.3 freebsd contrib/libc-vis/unvis.3 9e3e4b88576d01efe1f56469cac79e116bb62c67
gen/FreeBSD/vis.h freebsd contrib/libc-vis/unvis.3 9e3e4b88576d01efe1f56469cac79e116bb62c67
gen/NetBSD/rbtree.3 netbsd share/man/man3/rbtree.3 a6d78d4a28be21d6006d3c609f31967c0e536779
+gen/directory.3 freebsd lib/libc/gen/directory.3 7cbaa4254c0f10f7c00014ce9591ca60abfa57fb
gen/fts.c openbsd gen/fts.c 9936a0e983044822375a0d5cdebec20c3623866c
include/glob.h freebsd include/glob.h ececcb3d95a00665500a1f799a118fc4eaf6750b
include/readpassphrase.h freebsd include/readpassphrase.h e0a2d4f15ed9e93fcb62544ed65f7a98e2339c3b
stdtime/FreeBSD/tzfile.5 freebsd contrib/tzcode/stdtime/tzfile.5 000663e80955a044c229f9274011b828a788ee4b
string/FreeBSD/bcmp.3 freebsd lib/libc/string/bcmp.3 408f4a1ab49f89368c80edb4485895658fc81598
string/FreeBSD/memcmp.3 freebsd lib/libc/string/memcmp.3 3eb0ea4663f0ae19c4983e80963a121463224508
+string/FreeBSD/rpmatch.c freebsd lib/libc/locale/rpmatch.c 8919cfa0b0054509fb3e01f3b22e140645bc6407
+string/FreeBSD/rpmatch.3 freebsd lib/libc/locale/rpmatch.3 8919cfa0b0054509fb3e01f3b22e140645bc6407
string/FreeBSD/strcpy.3 freebsd lib/libc/string/strcpy.3 cfc3df2b8f708ce8494d9d556e3472a5c8c21b8a
string/FreeBSD/strlcpy.3 freebsd lib/libc/string/strlcpy.3 e3c83e4556db162d5b54833d2e9974a1152394eb
string/FreeBSD/strpbrk.3 freebsd lib/libc/string/strpbrk.3 5b882020081a138285227631c46a406c08e17bc8
gen/FreeBSD/scandir_b.c freebsd lib/libc/gen/scandir_b.c 0127b103f27578fc7f9cc3389b299f221deb1d4c
gen/FreeBSD/seekdir.c freebsd lib/libc/gen/seekdir.c 74c1506b3359ee725c9031331908b717460830dc
gen/FreeBSD/telldir.c freebsd lib/libc/gen/telldir.c 74c1506b3359ee725c9031331908b717460830dc
+net/inet_ntop.c freebsd lib/libc/inet/inet_ntop.c f0171d33b464dee5ac308f1d13ede2ddd9d030a7
name = Libc_darwin;
productName = libdarwin;
};
+ E47E980E22150EAD006E312E /* Libc */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = E47E981122150EAD006E312E /* Build configuration list for PBXAggregateTarget "Libc" */;
+ buildPhases = (
+ );
+ dependencies = (
+ E47E981722150F0A006E312E /* PBXTargetDependency */,
+ E47E981922150F2C006E312E /* PBXTargetDependency */,
+ E47E981B22150F2F006E312E /* PBXTargetDependency */,
+ E47E981D22150F32006E312E /* PBXTargetDependency */,
+ );
+ name = Libc;
+ productName = Libc;
+ };
+ E47E981222150EBB006E312E /* Libc_driverkit */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = E47E981322150EBB006E312E /* Build configuration list for PBXAggregateTarget "Libc_driverkit" */;
+ buildPhases = (
+ );
+ dependencies = (
+ E47E981F22150F3C006E312E /* PBXTargetDependency */,
+ );
+ name = Libc_driverkit;
+ productName = Libc_driverkit;
+ };
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
3FD4D48E1472F4B200075CCE /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
4B075C8E208BE9F200FD4F23 /* variant_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 926F73991E03E8D6001E049D /* variant_private.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B0899BC2046258F001360A4 /* cleanup.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B0899B920460FAC001360A4 /* cleanup.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 4B09323421C9C08F006063D6 /* mach_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B09323321C9C088006063D6 /* mach_utils.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B20DB4D202B81A4005C2327 /* bsd.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA6E56A202ACF7A00F38D3A /* bsd.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B20DB50202B81A4005C2327 /* err.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA6E563202AC0C200F38D3A /* err.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B20DB51202B81A4005C2327 /* errno.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA6E55B202AB1F100F38D3A /* errno.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B2C64A915519BC800342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
4B2C64AA15519BCB00342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
4B2C64BA1551B03700342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B450FFB211A56DD0029AF5D /* ctl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B450FFA211A56DC0029AF5D /* ctl.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 4B450FFD211A56EC0029AF5D /* ctl.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B450FFC211A56EC0029AF5D /* ctl.c */; };
4B4E643F2069E94A00C4D8D5 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2C50E41F8453FA005DA2B6 /* internal.h */; };
4B69E81320800D47008D13D2 /* libdarwin_init.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B69E81220800BE9008D13D2 /* libdarwin_init.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B6CFC042065B9FF0022DBAD /* mach.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B6CFC032065B9FF0022DBAD /* mach.c */; };
4B6D181D206DEFBD00C00E37 /* mach_exception.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6D181C206DEFBD00C00E37 /* mach_exception.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B6D181F206DF1E200C00E37 /* exception.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B6D181E206DF1E200C00E37 /* exception.c */; };
4B782979208926A80070E1FF /* api.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B782978208926A70070E1FF /* api.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 4B8A6F3221C99ACC00D00D67 /* linker_set.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8A6F3121C99A0E00D00D67 /* linker_set.h */; settings = {ATTRIBUTES = (Private, ); }; };
4BA6E55F202AB35900F38D3A /* string.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA6E55E202AB35900F38D3A /* string.c */; };
4BA6E562202AC06300F38D3A /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA6E561202AC06300F38D3A /* err.c */; };
4BA6E566202AC94800F38D3A /* stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA6E565202AC94800F38D3A /* stdlib.c */; };
4BA6E569202ACDAA00F38D3A /* stdio.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA6E568202ACDAA00F38D3A /* stdio.c */; };
4BA6E56C202AD02900F38D3A /* bsd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA6E56B202AD02900F38D3A /* bsd.c */; };
- 4BCC350F20659AD500A4CBAA /* mach_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCC350E20659AD500A4CBAA /* mach_utils.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 4BCC350F20659AD500A4CBAA /* linker_set.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCC350E20659AD500A4CBAA /* linker_set.h */; settings = {ATTRIBUTES = (Private, ); }; };
63D4060613DDEDF10094DD56 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; };
63D4060813DDEDFF0094DD56 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; };
63D4060A13DDEEA20094DD56 /* stpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060913DDEEA10094DD56 /* stpncpy.c */; };
63D4060E13DDF26A0094DD56 /* strcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060C13DDF26A0094DD56 /* strcat.c */; };
63D4061013DDF4340094DD56 /* strncat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060F13DDF4340094DD56 /* strncat.c */; };
63D4061113DDF4340094DD56 /* strncat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060F13DDF4340094DD56 /* strncat.c */; };
+ 7756338822F3B539002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756338922F3B53A002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756338A22F3B53B002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756338B22F3B546002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756338C22F3B549002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756338D22F3B54A002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756338E22F3B54A002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756338F22F3B54B002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756339022F3B54E002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 7756339122F3B550002F1707 /* rpmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 7711D82422F37DB600E7296B /* rpmatch.c */; };
+ 922D0C0A21BFA1530072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C0B21BFA19A0072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C0C21BFA19A0072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C0D21BFA19B0072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C0E21BFA1A10072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C0F21BFA1A20072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C1021BFA1A30072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C1121BFA1A30072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C1221BFA1A40072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
+ 922D0C1321BFA1A40072834D /* timespec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = 922D0C0921BFA1530072834D /* timespec_get.c */; };
926F73981E03E8C4001E049D /* variant.c in Sources */ = {isa = PBXBuildFile; fileRef = 926F73971E03E8C4001E049D /* variant.c */; };
92767C841E0A7E2700AB9C76 /* init.c in Sources */ = {isa = PBXBuildFile; fileRef = 92767C821E0A7E2100AB9C76 /* init.c */; };
928841361EA75555001064D1 /* dirstat_collection.c in Sources */ = {isa = PBXBuildFile; fileRef = 928841341EA7554D001064D1 /* dirstat_collection.c */; };
remoteGlobalIDString = C95B7ED9138F3C55004311DA;
remoteInfo = Variant_DarwinExtsn;
};
- C0E345E51C58323000E749C2 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = C9B53597138D9A690028D27C /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = C0E343831C582ECB00E749C2;
- remoteInfo = libc_static;
- };
C925D2001518FA5D003D315B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C9B53597138D9A690028D27C /* Project object */;
remoteGlobalIDString = C95B7ED9138F3C55004311DA;
remoteInfo = Variant_DarwinExtsn;
};
- C925D2021518FEBE003D315B /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = C9B53597138D9A690028D27C /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = C97A6F1E1517AF53005E1998;
- remoteInfo = libc_eOS.a;
- };
- C942130813901709004BA536 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = C9B53597138D9A690028D27C /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = C942102D13900C8A004BA536;
- remoteInfo = libc.a;
- };
C95B817C138F3F72004311DA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C9B53597138D9A690028D27C /* Project object */;
remoteGlobalIDString = C9258093138E2D3100B3107C;
remoteInfo = NetBSD;
};
+ E47E981622150F0A006E312E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C9D9432E138DB73300FB7ACC;
+ remoteInfo = libsystem_c.dylib;
+ };
+ E47E981822150F2C006E312E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C942102D13900C8A004BA536;
+ remoteInfo = libc_dyld;
+ };
+ E47E981A22150F2F006E312E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C0E343831C582ECB00E749C2;
+ remoteInfo = libc_static;
+ };
+ E47E981C22150F32006E312E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C97A6F1E1517AF53005E1998;
+ remoteInfo = libc_eOS.a;
+ };
+ E47E981E22150F3C006E312E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C9D9432E138DB73300FB7ACC;
+ remoteInfo = libsystem_c.dylib;
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
3FD14572171D42B300B7BAF5 /* bcopy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = "<group>"; };
3FF283231A4764240098AD2C /* sim-compat-symlink.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "sim-compat-symlink.sh"; sourceTree = "<group>"; };
4B0899B920460FAC001360A4 /* cleanup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cleanup.h; sourceTree = "<group>"; };
+ 4B09323321C9C088006063D6 /* mach_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_utils.h; sourceTree = "<group>"; };
4B151E0B1F8574B400F3F52F /* style.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = style.3; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.man; };
4B2C50E41F8453FA005DA2B6 /* internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
4B2C64A215519BAF00342BFA /* assumes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = assumes.c; path = os/assumes.c; sourceTree = "<group>"; };
4B2C64AB15519C3400342BFA /* assumes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = assumes.h; path = os/assumes.h; sourceTree = "<group>"; };
+ 4B450FFA211A56DC0029AF5D /* ctl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ctl.h; sourceTree = "<group>"; };
+ 4B450FFC211A56EC0029AF5D /* ctl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ctl.c; sourceTree = "<group>"; };
4B69E81220800BE9008D13D2 /* libdarwin_init.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libdarwin_init.h; sourceTree = "<group>"; };
4B6CFC032065B9FF0022DBAD /* mach.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mach.c; sourceTree = "<group>"; };
4B6D181C206DEFBD00C00E37 /* mach_exception.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mach_exception.h; sourceTree = "<group>"; };
4B6D181E206DF1E200C00E37 /* exception.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = exception.c; sourceTree = "<group>"; };
4B782978208926A70070E1FF /* api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = api.h; path = os/api.h; sourceTree = "<group>"; };
+ 4B8A6F3121C99A0E00D00D67 /* linker_set.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = linker_set.h; path = os/linker_set.h; sourceTree = "<group>"; };
4BA6E55B202AB1F100F38D3A /* errno.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = errno.h; sourceTree = "<group>"; };
4BA6E55D202AB31100F38D3A /* string.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = string.h; sourceTree = "<group>"; };
4BA6E55E202AB35900F38D3A /* string.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = string.c; sourceTree = "<group>"; };
4BA6E568202ACDAA00F38D3A /* stdio.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stdio.c; sourceTree = "<group>"; };
4BA6E56A202ACF7A00F38D3A /* bsd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bsd.h; sourceTree = "<group>"; };
4BA6E56B202AD02900F38D3A /* bsd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bsd.c; sourceTree = "<group>"; };
- 4BCC350E20659AD500A4CBAA /* mach_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_utils.h; sourceTree = "<group>"; };
+ 4BCC350E20659AD500A4CBAA /* linker_set.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = linker_set.h; path = ../../os/linker_set.h; sourceTree = "<group>"; };
63D4060513DDEDF10094DD56 /* stpcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stpcpy.c; sourceTree = "<group>"; };
63D4060913DDEEA10094DD56 /* stpncpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stpncpy.c; sourceTree = "<group>"; };
63D4060C13DDF26A0094DD56 /* strcat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strcat.c; sourceTree = "<group>"; };
63D4060F13DDF4340094DD56 /* strncat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strncat.c; sourceTree = "<group>"; };
+ 7711D82422F37DB600E7296B /* rpmatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rpmatch.c; sourceTree = "<group>"; };
+ 7711D82622F3A52400E7296B /* rpmatch.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = rpmatch.3; sourceTree = "<group>"; };
+ 922D0C0821BFA1520072834D /* timespec_get.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = timespec_get.3; sourceTree = "<group>"; };
+ 922D0C0921BFA1530072834D /* timespec_get.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = timespec_get.c; sourceTree = "<group>"; };
926F73921E03E2A3001E049D /* libsystem_darwin.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_darwin.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
926F73971E03E8C4001E049D /* variant.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = variant.c; sourceTree = "<group>"; };
926F73991E03E8D6001E049D /* variant_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = variant_private.h; path = os/variant_private.h; sourceTree = "<group>"; };
C9FACC591ACDBA54009F33F1 /* Makefile.inc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.pascal; name = Makefile.inc; path = Platforms/appletvos/Makefile.inc; sourceTree = SOURCE_ROOT; };
E40EA6C01EAA8F9300B2FA36 /* _strings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _strings.h; sourceTree = "<group>"; };
E41BEA97178E72E100E348BB /* Libc.order */ = {isa = PBXFileReference; lastKnownFileType = text; path = Libc.order; sourceTree = "<group>"; };
+ E464104B224C5EA2001B23EF /* __wctype.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = __wctype.h; sourceTree = "<group>"; };
+ E464104C224C5F19001B23EF /* _ctype.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _ctype.h; sourceTree = "<group>"; };
E4A877A6174D82FB000DBB55 /* alias.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = alias.list; sourceTree = "<group>"; };
+ E4EDB7262227DF25006A8322 /* Makefile.inc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.pascal; path = Makefile.inc; sourceTree = "<group>"; };
FC2ED60E157D4BE70098EC69 /* inet_ntop.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet_ntop.c; sourceTree = "<group>"; };
FC2ED60F157D4BE70098EC69 /* inet_pton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet_pton.c; sourceTree = "<group>"; };
FC2ED623157D4DA90098EC69 /* inet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inet.h; sourceTree = "<group>"; };
children = (
4BA6E56A202ACF7A00F38D3A /* bsd.h */,
4B0899B920460FAC001360A4 /* cleanup.h */,
+ 4B450FFA211A56DC0029AF5D /* ctl.h */,
4BA6E563202AC0C200F38D3A /* err.h */,
4BA6E55B202AB1F100F38D3A /* errno.h */,
4B6D181C206DEFBD00C00E37 /* mach_exception.h */,
- 4BCC350E20659AD500A4CBAA /* mach_utils.h */,
+ 4B09323321C9C088006063D6 /* mach_utils.h */,
+ 4BCC350E20659AD500A4CBAA /* linker_set.h */,
4BA6E567202ACAFA00F38D3A /* stdio.h */,
4BA6E564202AC43700F38D3A /* stdlib.h */,
4BA6E55D202AB31100F38D3A /* string.h */,
isa = PBXGroup;
children = (
4B782978208926A70070E1FF /* api.h */,
+ 4B8A6F3121C99A0E00D00D67 /* linker_set.h */,
926F73991E03E8D6001E049D /* variant_private.h */,
2DF67CE7184F9CD000B83A3D /* debug_private.h */,
2DF67CDD184F9CBE00B83A3D /* debug_private.c */,
9280EA171E59BC8A007A6F58 /* AppleInternalVariant.plist */,
4B2C50E41F8453FA005DA2B6 /* internal.h */,
4BA6E56B202AD02900F38D3A /* bsd.c */,
+ 4B450FFC211A56EC0029AF5D /* ctl.c */,
4B6D181E206DF1E200C00E37 /* exception.c */,
4BA6E561202AC06300F38D3A /* err.c */,
4B6CFC032065B9FF0022DBAD /* mach.c */,
C9B5379E138D9E990028D27C /* time.c */,
C9B537A0138D9E990028D27C /* times.3 */,
C9B537A2138D9E990028D27C /* times.c */,
+ 922D0C0821BFA1520072834D /* timespec_get.3 */,
+ 922D0C0921BFA1530072834D /* timespec_get.c */,
C9B537A3138D9E990028D27C /* timezone.3 */,
C9B537A4138D9E990028D27C /* timezone.c */,
C9B537A5138D9E990028D27C /* ttyname.3 */,
C9B5384F138D9E990028D27C /* include */ = {
isa = PBXGroup;
children = (
+ E464104B224C5EA2001B23EF /* __wctype.h */,
+ E464104C224C5F19001B23EF /* _ctype.h */,
3006CB0E20BF7482003C5C79 /* _stdio.h */,
C9B53850138D9E990028D27C /* _locale.h */,
FC60BAD016555A4A00033196 /* _types */,
isa = PBXGroup;
children = (
C975E22B1A12ECA00093B345 /* appletv */,
+ E4EDB7252227DF25006A8322 /* driverkit */,
C9B53A46138D9E990028D27C /* iphoneos */,
C9B53A48138D9E990028D27C /* macosx */,
C9A288A61ACDBA95004A33A7 /* watchos */,
C9B53D0B138D9E9A0028D27C /* memset.3 */,
C9B53D0E138D9E9A0028D27C /* rindex.3 */,
C9B53D10138D9E9A0028D27C /* rindex.c */,
+ 7711D82622F3A52400E7296B /* rpmatch.3 */,
+ 7711D82422F37DB600E7296B /* rpmatch.c */,
C9B53D13138D9E9A0028D27C /* strcasecmp.3 */,
C9B53D15138D9E9A0028D27C /* strcasecmp.c */,
C9B53D17138D9E9A0028D27C /* strcasestr.c */,
path = xcodescripts;
sourceTree = "<group>";
};
+ E4EDB7252227DF25006A8322 /* driverkit */ = {
+ isa = PBXGroup;
+ children = (
+ E4EDB7262227DF25006A8322 /* Makefile.inc */,
+ );
+ path = driverkit;
+ sourceTree = "<group>";
+ };
FC60BAD016555A4A00033196 /* _types */ = {
isa = PBXGroup;
children = (
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 4B450FFB211A56DD0029AF5D /* ctl.h in Headers */,
+ 4B782979208926A80070E1FF /* api.h in Headers */,
4B6D181D206DEFBD00C00E37 /* mach_exception.h in Headers */,
4B20DB4D202B81A4005C2327 /* bsd.h in Headers */,
4B20DB50202B81A4005C2327 /* err.h in Headers */,
4B20DB51202B81A4005C2327 /* errno.h in Headers */,
4B20DB52202B81A4005C2327 /* stdio.h in Headers */,
4B0899BC2046258F001360A4 /* cleanup.h in Headers */,
- 4BCC350F20659AD500A4CBAA /* mach_utils.h in Headers */,
+ 4BCC350F20659AD500A4CBAA /* linker_set.h in Headers */,
4B20DB53202B81A4005C2327 /* stdlib.h in Headers */,
+ 4B8A6F3221C99ACC00D00D67 /* linker_set.h in Headers */,
+ 4B09323421C9C08F006063D6 /* mach_utils.h in Headers */,
4B69E81320800D47008D13D2 /* libdarwin_init.h in Headers */,
- 4B782979208926A80070E1FF /* api.h in Headers */,
4B20DB54202B81A4005C2327 /* string.h in Headers */,
4B075C8E208BE9F200FD4F23 /* variant_private.h in Headers */,
4B4E643F2069E94A00C4D8D5 /* internal.h in Headers */,
C9EB326D138F74D20075BB52 /* PBXTargetDependency */,
C9EB3515138F771F0075BB52 /* PBXTargetDependency */,
3F51211716C318EB00AFB431 /* PBXTargetDependency */,
- C942130913901709004BA536 /* PBXTargetDependency */,
- C0E345E61C58323000E749C2 /* PBXTargetDependency */,
- C925D2031518FEBE003D315B /* PBXTargetDependency */,
);
name = libsystem_c.dylib;
productName = Libc;
928F25D01BEACED7007B13C7 = {
CreatedOnToolsVersion = 7.1;
};
+ E47E980E22150EAD006E312E = {
+ CreatedOnToolsVersion = 11.0;
+ };
+ E47E981222150EBB006E312E = {
+ CreatedOnToolsVersion = 11.0;
+ };
};
};
buildConfigurationList = C9B5359A138D9A690028D27C /* Build configuration list for PBXProject "Libc" */;
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
+ English,
en,
);
mainGroup = C9B53595138D9A690028D27C;
projectDirPath = "";
projectRoot = "";
targets = (
+ E47E980E22150EAD006E312E /* Libc */,
+ 926F739D1E046E55001E049D /* Libc_darwin */,
+ E47E981222150EBB006E312E /* Libc_driverkit */,
+ 925E7FE619E8945900AC7889 /* Libc_tests */,
C9D9432E138DB73300FB7ACC /* libsystem_c.dylib */,
C942102D13900C8A004BA536 /* libc_dyld */,
C0E343831C582ECB00E749C2 /* libc_static */,
C9EB2FC9138F6D880075BB52 /* Variant_Legacy */,
C9EB326F138F75580075BB52 /* Variant_Inode32 */,
3F51206A16C3174300AFB431 /* FortifySource */,
- 925E7FE619E8945900AC7889 /* Libc_tests */,
- 928F25D01BEACED7007B13C7 /* darwintests */,
- 926F739D1E046E55001E049D /* Libc_darwin */,
926F73911E03E2A3001E049D /* libsystem_darwin.dylib */,
+ 928F25D01BEACED7007B13C7 /* darwintests */,
);
};
/* End PBXProject section */
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/bin/bash -e -x";
- shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"\n";
+ shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
+ showEnvVarsInLog = 0;
};
3F51206B16C3174300AFB431 /* Generate libc-features.h */ = {
isa = PBXShellScriptBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/bin/bash -e -x";
shellScript = "mkdir -p ${TAPI_PUBLIC_HEADER_PATH}";
+ showEnvVarsInLog = 0;
};
3FF283291A4764370098AD2C /* Simulator Build Compat Symlink */ = {
isa = PBXShellScriptBuildPhase;
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/bash;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
+ showEnvVarsInLog = 0;
};
9280EA241E5A5D6F007A6F58 /* Copy AppleFooVariant.plists */ = {
isa = PBXShellScriptBuildPhase;
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\" /bin/ln -sf libc_dyld.a ${DSTROOT}${INSTALL_PATH}/libc.a";
+ showEnvVarsInLog = 0;
};
C0E3438E1C582ECB00E749C2 /* Build Link List */ = {
isa = PBXShellScriptBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
+ showEnvVarsInLog = 0;
};
C0E3438F1C582ECB00E749C2 /* Generate libc-features.h */ = {
isa = PBXShellScriptBuildPhase;
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
C0E345E41C5830C200E749C2 /* Symlink libc.a to a loaderd path */ = {
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\" /bin/ln -sf ../../../../${INSTALL_PATH}/libc.a ${DSTROOT}/usr/local/lib/loaderd/libc.a";
+ showEnvVarsInLog = 0;
};
C9194B4B140E3A7100BE0C3A /* Build Link Lists */ = {
isa = PBXShellScriptBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
+ showEnvVarsInLog = 0;
};
C93D6152143D321000EB9023 /* Sanitise Headers (rdar://problem/10241868) */ = {
isa = PBXShellScriptBuildPhase;
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
C942135B13905EB9004BA536 /* Install Manpages */ = {
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
C95B8185138F52B0004311DA /* Generate libc-features.h */ = {
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
C95B842B138F53DB004311DA /* Generate libc-features.h */ = {
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
C965CBF3143BBFF7003912CE /* Remove deps.c */ = {
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
};
C9766152138ECA3800741512 /* Patch Headers */ = {
isa = PBXShellScriptBuildPhase;
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
C976616D138EF15900741512 /* Generate libc-features.h */ = {
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
C9950E6B1390D2DC009863B6 /* Install Headers */ = {
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
+ showEnvVarsInLog = 0;
};
C9BD3C3C138F189200B389FD /* Generate libc-features.h */ = {
isa = PBXShellScriptBuildPhase;
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
C9EB3270138F75580075BB52 /* Generate libc-features.h */ = {
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDK_SYSTEM_FRAMEWORK_HEADERS}\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
926F73981E03E8C4001E049D /* variant.c in Sources */,
4BA6E566202AC94800F38D3A /* stdlib.c in Sources */,
92D763E01EA6DA3A001467FC /* dirstat.c in Sources */,
+ 4B450FFD211A56EC0029AF5D /* ctl.c in Sources */,
4BA6E569202ACDAA00F38D3A /* stdio.c in Sources */,
4B6D181F206DF1E200C00E37 /* exception.c in Sources */,
92767C841E0A7E2700AB9C76 /* init.c in Sources */,
C0E344DF1C582ECB00E749C2 /* ftell.c in Sources */,
C0E344E01C582ECB00E749C2 /* funopen.c in Sources */,
C0E344E11C582ECB00E749C2 /* fvwrite.c in Sources */,
+ 922D0C0C21BFA19A0072834D /* timespec_get.c in Sources */,
C0E344E21C582ECB00E749C2 /* fwalk.c in Sources */,
C0E344E31C582ECB00E749C2 /* fwide.c in Sources */,
C0E344E41C582ECB00E749C2 /* fwprintf.c in Sources */,
C0E3451D1C582ECB00E749C2 /* wprintf.c in Sources */,
C0E3451E1C582ECB00E749C2 /* wscanf.c in Sources */,
C0E3451F1C582ECB00E749C2 /* wsetup.c in Sources */,
+ 7756338922F3B53A002F1707 /* rpmatch.c in Sources */,
C0E345201C582ECB00E749C2 /* a64l.c in Sources */,
C0E345211C582ECB00E749C2 /* _Exit_.c in Sources */,
C0E345221C582ECB00E749C2 /* abort.c in Sources */,
C9257FD4138E1CC000B3107C /* makebuf.c in Sources */,
C9257FD5138E1CC000B3107C /* mktemp.c in Sources */,
C9257FD6138E1CC000B3107C /* perror.c in Sources */,
+ 7756338B22F3B546002F1707 /* rpmatch.c in Sources */,
C9257FD7138E1CC000B3107C /* printf-pos.c in Sources */,
C9257FD8138E1CC000B3107C /* printf.c in Sources */,
C9257FD9138E1CC000B3107C /* putc.c in Sources */,
C9421022138F2661004BA536 /* machdep_ldisd.c in Sources */,
C9421023138F2661004BA536 /* machdep_ldisdd.c in Sources */,
C9421024138F2661004BA536 /* machdep_ldisQ.c in Sources */,
+ 922D0C0A21BFA1530072834D /* timespec_get.c in Sources */,
C9421025138F2661004BA536 /* machdep_ldisx.c in Sources */,
C95B7ED7138F3BEA004311DA /* rune.c in Sources */,
C9EB2FC1138F6BB00075BB52 /* merge_b.c in Sources */,
C94210D213900C8A004BA536 /* sleep.c in Sources */,
C94210D313900C8A004BA536 /* srand48.c in Sources */,
C94210D413900C8A004BA536 /* stringlist.c in Sources */,
+ 922D0C0B21BFA19A0072834D /* timespec_get.c in Sources */,
C94210D513900C8A004BA536 /* sysconf.c in Sources */,
C94210D613900C8A004BA536 /* sysctl.c in Sources */,
C94210D713900C8A004BA536 /* sysctlbyname.c in Sources */,
C94212B813900C8A004BA536 /* pack.c in Sources */,
C94212B913900C8A004BA536 /* parse.c in Sources */,
C94212BA13900C8A004BA536 /* unpack.c in Sources */,
+ 7756338822F3B539002F1707 /* rpmatch.c in Sources */,
C94212BB13900C8A004BA536 /* unparse.c in Sources */,
C94212C613900C8A004BA536 /* scandir_b.c in Sources */,
63D4060813DDEDFF0094DD56 /* stpcpy.c in Sources */,
C95B7EF6138F3C55004311DA /* bt_close.c in Sources */,
C95B7EF7138F3C55004311DA /* bt_conv.c in Sources */,
C95B7EF8138F3C55004311DA /* bt_debug.c in Sources */,
+ 7756338D22F3B54A002F1707 /* rpmatch.c in Sources */,
C95B7EF9138F3C55004311DA /* bt_delete.c in Sources */,
C95B7EFA138F3C55004311DA /* bt_get.c in Sources */,
C95B7EFB138F3C55004311DA /* bt_open.c in Sources */,
C95B80D3138F3C55004311DA /* setenv.c in Sources */,
C95B80D4138F3C55004311DA /* strhash.c in Sources */,
C95B80D5138F3C55004311DA /* strtoimax.c in Sources */,
+ 922D0C1021BFA1A30072834D /* timespec_get.c in Sources */,
C95B80D6138F3C55004311DA /* strtol.c in Sources */,
C95B80D7138F3C55004311DA /* strtoll.c in Sources */,
C95B80D8138F3C55004311DA /* strtoq.c in Sources */,
C95B81A1138F52B0004311DA /* bt_close.c in Sources */,
C95B81A2138F52B0004311DA /* bt_conv.c in Sources */,
C95B81A3138F52B0004311DA /* bt_debug.c in Sources */,
+ 7756338E22F3B54A002F1707 /* rpmatch.c in Sources */,
C95B81A4138F52B0004311DA /* bt_delete.c in Sources */,
C95B81A5138F52B0004311DA /* bt_get.c in Sources */,
C95B81A6138F52B0004311DA /* bt_open.c in Sources */,
C95B837E138F52B0004311DA /* setenv.c in Sources */,
C95B837F138F52B0004311DA /* strhash.c in Sources */,
C95B8380138F52B0004311DA /* strtoimax.c in Sources */,
+ 922D0C1121BFA1A30072834D /* timespec_get.c in Sources */,
C95B8381138F52B0004311DA /* strtol.c in Sources */,
C95B8382138F52B0004311DA /* strtoll.c in Sources */,
C95B8383138F52B0004311DA /* strtoq.c in Sources */,
C95B8447138F53DB004311DA /* bt_close.c in Sources */,
C95B8448138F53DB004311DA /* bt_conv.c in Sources */,
C95B8449138F53DB004311DA /* bt_debug.c in Sources */,
+ 7756338F22F3B54B002F1707 /* rpmatch.c in Sources */,
C95B844A138F53DB004311DA /* bt_delete.c in Sources */,
C95B844B138F53DB004311DA /* bt_get.c in Sources */,
C95B844C138F53DB004311DA /* bt_open.c in Sources */,
C95B8624138F53DB004311DA /* setenv.c in Sources */,
C95B8625138F53DB004311DA /* strhash.c in Sources */,
C95B8626138F53DB004311DA /* strtoimax.c in Sources */,
+ 922D0C1221BFA1A40072834D /* timespec_get.c in Sources */,
C95B8627138F53DB004311DA /* strtol.c in Sources */,
C95B8628138F53DB004311DA /* strtoll.c in Sources */,
C95B8629138F53DB004311DA /* strtoq.c in Sources */,
C97A70AC1517AF53005E1998 /* mbrune.c in Sources */,
C97A70AD1517AF53005E1998 /* runedepreciated.c in Sources */,
C97A70AE1517AF53005E1998 /* setinvalidrune.c in Sources */,
+ 7756338A22F3B53B002F1707 /* rpmatch.c in Sources */,
C97A70AF1517AF53005E1998 /* xlocale.c in Sources */,
C97A70B01517AF53005E1998 /* addr2ascii.c in Sources */,
C97A70B11517AF53005E1998 /* ascii2addr.c in Sources */,
C97A70D91517AF53005E1998 /* stpncpy_chk.c in Sources */,
C97A70DA1517AF53005E1998 /* strcat_chk.c in Sources */,
C97A70DB1517AF53005E1998 /* strcpy_chk.c in Sources */,
+ 922D0C0D21BFA19B0072834D /* timespec_get.c in Sources */,
3FA8F3251643AB8100D37078 /* strlcat_chk.c in Sources */,
3FA8F3261643AB8100D37078 /* strlcpy_chk.c in Sources */,
C97A70DC1517AF53005E1998 /* strncat_chk.c in Sources */,
C9765ECB138EC61900741512 /* bt_close.c in Sources */,
C9765ECC138EC61900741512 /* bt_conv.c in Sources */,
C9765ECD138EC61900741512 /* bt_debug.c in Sources */,
+ 7756338C22F3B549002F1707 /* rpmatch.c in Sources */,
C9765ECE138EC61900741512 /* bt_delete.c in Sources */,
C9765ECF138EC61900741512 /* bt_get.c in Sources */,
C9765ED0138EC61900741512 /* bt_open.c in Sources */,
C97660A8138EC61A00741512 /* setenv.c in Sources */,
C97660A9138EC61A00741512 /* strhash.c in Sources */,
C97660AA138EC61A00741512 /* strtoimax.c in Sources */,
+ 922D0C1321BFA1A40072834D /* timespec_get.c in Sources */,
C97660AB138EC61A00741512 /* strtol.c in Sources */,
C97660AC138EC61A00741512 /* strtoll.c in Sources */,
C97660AD138EC61A00741512 /* strtoq.c in Sources */,
C9EB31A2138F6D880075BB52 /* atof.c in Sources */,
C9EB31A3138F6D880075BB52 /* atoi.c in Sources */,
C9EB31A4138F6D880075BB52 /* atol.c in Sources */,
+ 922D0C0F21BFA1A20072834D /* timespec_get.c in Sources */,
C9EB31A5138F6D880075BB52 /* atoll.c in Sources */,
C9EB31A6138F6D880075BB52 /* bsearch.c in Sources */,
C9EB31A7138F6D880075BB52 /* div.c in Sources */,
C9EB31DD138F6D880075BB52 /* strptime.c in Sources */,
C9EB31DE138F6D880075BB52 /* time32.c in Sources */,
C9EB31DF138F6D880075BB52 /* timelocal.c in Sources */,
+ 7756339022F3B54E002F1707 /* rpmatch.c in Sources */,
C9EB31E0138F6D880075BB52 /* getdate.c in Sources */,
C9EB31E1138F6D880075BB52 /* timezone_unix03.c in Sources */,
C9EB31EA138F6D880075BB52 /* memmem.c in Sources */,
C9EB3449138F75580075BB52 /* atof.c in Sources */,
C9EB344A138F75580075BB52 /* atoi.c in Sources */,
C9EB344B138F75580075BB52 /* atol.c in Sources */,
+ 922D0C0E21BFA1A10072834D /* timespec_get.c in Sources */,
C9EB344C138F75580075BB52 /* atoll.c in Sources */,
C9EB344D138F75580075BB52 /* bsearch.c in Sources */,
C9EB344E138F75580075BB52 /* div.c in Sources */,
C9EB3484138F75580075BB52 /* strptime.c in Sources */,
C9EB3485138F75580075BB52 /* time32.c in Sources */,
C9EB3486138F75580075BB52 /* timelocal.c in Sources */,
+ 7756339122F3B550002F1707 /* rpmatch.c in Sources */,
C9EB3487138F75580075BB52 /* getdate.c in Sources */,
C9EB3488138F75580075BB52 /* timezone_unix03.c in Sources */,
C9EB3491138F75580075BB52 /* memmem.c in Sources */,
target = C95B7ED9138F3C55004311DA /* Variant_DarwinExtsn */;
targetProxy = C0E3438D1C582ECB00E749C2 /* PBXContainerItemProxy */;
};
- C0E345E61C58323000E749C2 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = C0E343831C582ECB00E749C2 /* libc_static */;
- targetProxy = C0E345E51C58323000E749C2 /* PBXContainerItemProxy */;
- };
C925D2011518FA5D003D315B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = C95B7ED9138F3C55004311DA /* Variant_DarwinExtsn */;
targetProxy = C925D2001518FA5D003D315B /* PBXContainerItemProxy */;
};
- C925D2031518FEBE003D315B /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = C97A6F1E1517AF53005E1998 /* libc_eOS.a */;
- targetProxy = C925D2021518FEBE003D315B /* PBXContainerItemProxy */;
- };
- C942130913901709004BA536 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = C942102D13900C8A004BA536 /* libc_dyld */;
- targetProxy = C942130813901709004BA536 /* PBXContainerItemProxy */;
- };
C95B817D138F3F72004311DA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = C95B7ED9138F3C55004311DA /* Variant_DarwinExtsn */;
target = C9258093138E2D3100B3107C /* NetBSD */;
targetProxy = C9FA32CB138E41800089A94B /* PBXContainerItemProxy */;
};
+ E47E981722150F0A006E312E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C9D9432E138DB73300FB7ACC /* libsystem_c.dylib */;
+ targetProxy = E47E981622150F0A006E312E /* PBXContainerItemProxy */;
+ };
+ E47E981922150F2C006E312E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C942102D13900C8A004BA536 /* libc_dyld */;
+ targetProxy = E47E981822150F2C006E312E /* PBXContainerItemProxy */;
+ };
+ E47E981B22150F2F006E312E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C0E343831C582ECB00E749C2 /* libc_static */;
+ targetProxy = E47E981A22150F2F006E312E /* PBXContainerItemProxy */;
+ };
+ E47E981D22150F32006E312E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C97A6F1E1517AF53005E1998 /* libc_eOS.a */;
+ targetProxy = E47E981C22150F32006E312E /* PBXContainerItemProxy */;
+ };
+ E47E981F22150F3C006E312E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C9D9432E138DB73300FB7ACC /* libsystem_c.dylib */;
+ targetProxy = E47E981E22150F3C006E312E /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
925E7FE719E8945A00AC7889 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
925E7FE819E8945A00AC7889 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
"$(PROJECT_DIR)/libdarwin/h",
);
LIBRARY_SEARCH_PATHS = /usr/lib/system;
- LIBSYSTEM_DARWIN_LDFLAGS = "-all_load -nostdlib -L/usr/lib/system -umbrella System $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBC_LDFLAGS) $(LIBDISPATCH_LDFLAGS) $(LIBXPC_LDFLAGS) -Wl,-upward-lsystem_trace";
+ LIBSYSTEM_DARWIN_LDFLAGS = "-all_load -nostdlib -L/usr/lib/system -umbrella System $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBC_LDFLAGS) $(LIBDISPATCH_LDFLAGS) $(LIBXPC_LDFLAGS) -lmacho -ldyld -Wl,-upward-lsystem_trace";
OTHER_LDFLAGS = "$(LIBSYSTEM_DARWIN_LDFLAGS)";
OTHER_TAPI_FLAGS = "$(inherited) -extra-public-header $(SRCROOT)/libdarwin/h/dirstat.h -extra-public-header $(SRCROOT)/libdarwin/internal.h -DDARWIN_TAPI=1 -extra-public-header $(SRCROOT)/os/variant_private.h";
PRIVATE_HEADERS_FOLDER_PATH = "$(DARWIN_PRIVATE_HEADERS_FOLDER_PATH)";
"$(PROJECT_DIR)/libdarwin/h",
);
LIBRARY_SEARCH_PATHS = /usr/lib/system;
- LIBSYSTEM_DARWIN_LDFLAGS = "-all_load -nostdlib -L/usr/lib/system -umbrella System $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBC_LDFLAGS) $(LIBDISPATCH_LDFLAGS) $(LIBXPC_LDFLAGS) -Wl,-upward-lsystem_trace";
+ LIBSYSTEM_DARWIN_LDFLAGS = "-all_load -nostdlib -L/usr/lib/system -umbrella System $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBC_LDFLAGS) $(LIBDISPATCH_LDFLAGS) $(LIBXPC_LDFLAGS) -lmacho -ldyld -Wl,-upward-lsystem_trace";
OTHER_LDFLAGS = "$(LIBSYSTEM_DARWIN_LDFLAGS)";
OTHER_TAPI_FLAGS = "$(inherited) -extra-public-header $(SRCROOT)/libdarwin/h/dirstat.h -extra-public-header $(SRCROOT)/libdarwin/internal.h -DDARWIN_TAPI=1 -extra-public-header $(SRCROOT)/os/variant_private.h";
PRIVATE_HEADERS_FOLDER_PATH = "$(DARWIN_PRIVATE_HEADERS_FOLDER_PATH)";
926F739F1E046E56001E049D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
926F73A01E046E56001E049D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
"$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
);
EXECUTABLE_PREFIX = lib;
- GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
"$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
);
EXECUTABLE_PREFIX = lib;
- GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
INCLUDED_SOURCE_FILE_NAMES = "$(FreeBSD_INCLUDED_SOURCE_FILE_NAMES)";
PRODUCT_NAME = TRE;
"$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
);
EXECUTABLE_PREFIX = lib;
- GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
"$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
);
EXECUTABLE_PREFIX = lib;
- GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
INCLUDED_SOURCE_FILE_NAMES = "$(FreeBSD_INCLUDED_SOURCE_FILE_NAMES)";
PRODUCT_NAME = "$(TARGET_NAME)";
DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
- /usr/lib/system,
+ "$(SDK_INSTALL_ROOT)/usr/lib/system",
);
"ORDER_FILE[sdk=iphoneos*]" = "$(SDKROOT)/AppleInternal/OrderFiles/libsystem_c.order";
OTHER_LDFLAGS = "$(LIBSYSTEM_C_LDFLAGS)";
DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
- /usr/lib/system,
+ "$(SDK_INSTALL_ROOT)/usr/lib/system",
);
"ORDER_FILE[sdk=iphoneos*]" = "$(SDKROOT)/AppleInternal/OrderFiles/libsystem_c.order";
OTHER_LDFLAGS = "$(LIBSYSTEM_C_LDFLAGS)";
};
name = Release;
};
+ E47E980F22150EAD006E312E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ E47E981022150EAD006E312E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ E47E981422150EBB006E312E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ E47E981522150EBB006E312E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ E47E981122150EAD006E312E /* Build configuration list for PBXAggregateTarget "Libc" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E47E980F22150EAD006E312E /* Debug */,
+ E47E981022150EAD006E312E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ E47E981322150EBB006E312E /* Build configuration list for PBXAggregateTarget "Libc_driverkit" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E47E981422150EBB006E312E /* Debug */,
+ E47E981522150EBB006E312E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = C9B53597138D9A690028D27C /* Project object */;
# Disable registration of specific signals (<rdar://problem/21952708>)
FEATURE_SIGNAL_RESTRICTION = 1
+
+# Enable 32-bit compilation in unistd.h (<rdar://problem/51818745>)
+# FEATURE_POSIX_ILP32_ALLOW = 0
# Disable registration of specific signals (<rdar://problem/21952708>)
FEATURE_SIGNAL_RESTRICTION = 1
+
+# Enable 32-bit compilation in unistd.h (<rdar://problem/51818745>)
+# FEATURE_POSIX_ILP32_ALLOW = 0
--- /dev/null
+#
+# Selectable features for DriverKit
+#
+
+# Legacy *64 APIs
+#FEATURE_LEGACY_64_APIS = 1
+
+# Legacy crt1.o environ support
+#FEATURE_LEGACY_CRT1_ENVIRON = 1
+
+# Legacy rune APIs
+#FEATURE_LEGACY_RUNE_APIS = 1
+
+# Legacy utmp APIs
+#FEATURE_LEGACY_UTMP_APIS = 1
+
+# OSThermalNotification APIs
+#FEATURE_THERM_NOTIFICATION_APIS = 1
+
+# No pre-1050 variants (should match sys/cdefs.h)
+FEATURE_ONLY_1050_VARIANTS = 1
+
+# No legacy variants (should match sys/cdefs.h)
+FEATURE_ONLY_UNIX_CONFORMANCE = 1
+
+# Only 64-bit ino_t (should match sys/cdefs.h)
+FEATURE_ONLY_64_BIT_INO_T = 1
+
+# Patch 3333969
+#FEATURE_PATCH_3333969 = 1
+
+# Patch 3417676
+#FEATURE_PATCH_3417676 = 1
+
+# plockstat dtrace support
+#FEATURE_PLOCKSTAT = 1
+
+# Timezone change notification
+#FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1
+
+# Extensible printf performance enhancement (uses more memory)
+#FEATURE_XPRINTF_PERF = 1
+
+# Disable registration of specific signals (<rdar://problem/21952708>)
+# FEATURE_SIGNAL_RESTRICTION = 0
+
+# Enable 32-bit compilation in unistd.h (<rdar://problem/51818745>)
+# FEATURE_POSIX_ILP32_ALLOW = 0
# Disable registration of specific signals (<rdar://problem/21952708>)
# FEATURE_SIGNAL_RESTRICTION = 0
+
+# Enable 32-bit compilation in unistd.h (<rdar://problem/51818745>)
+# FEATURE_POSIX_ILP32_ALLOW = 0
# Disable registration of specific signals (<rdar://problem/21952708>)
# FEATURE_SIGNAL_RESTRICTION = 0
+
+# Enable 32-bit compilation in unistd.h (<rdar://problem/51818745>)
+# FEATURE_POSIX_ILP32_ALLOW = 0
# Disable registration of specific signals (<rdar://problem/21952708>)
FEATURE_SIGNAL_RESTRICTION = 1
+
+# Enable 32-bit compilation in unistd.h (<rdar://problem/51818745>)
+FEATURE_POSIX_ILP32_ALLOW = 1
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
-#if !TARGET_OS_IPHONE
+#include <TargetConditionals.h>
+
+#if !TARGET_OS_IPHONE && !TARGET_OS_DRIVERKIT
#define WEAK_SYMBOL_LD_CMD(sym, version) \
__asm__(".section __TEXT,__const\n\t" \
__IOS_AVAILABLE(9.0) __OSX_AVAILABLE(10.11)
extern void
-abort_report_np(const char *, ...) __dead2 __printflike(1, 2);
+abort_report_np(const char *, ...) __dead2 __cold __printflike(1, 2);
__END_DECLS
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
+
+#include <TargetConditionals.h>
+#if !TARGET_OS_DRIVERKIT
+#define OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE 1
+#endif
#include <os/assumes.h>
#include <os/lock.h>
#include "string.h"
#include "libc_private.h"
-#define CACHE_LENGTH 64
-#define BUFFERSIZE 32
+#if defined(__APPLE__) && !defined(VARIANT_STATIC)
+#include <corecrypto/ccrng.h>
-#define INITIAL_COUNT 1600000
-#define MAX_BUF_COUNT 4096
+static struct ccrng_state *rng;
-static os_unfair_lock arc4_lock = OS_UNFAIR_LOCK_INIT;
-static int arc4_count;
+static void
+arc4_init(void)
+{
+ int err;
+
+ if (rng != NULL) return;
+
+ rng = ccrng(&err);
+ if (rng == NULL) {
+#if OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE
+ os_crash("arc4random: unable to get ccrng() handle (%d)", err);
+#else
+ os_crash("arc4random: unable to get ccrng() handle");
+#endif
+ }
+}
+
+void
+arc4random_addrandom(__unused u_char *dat, __unused int datlen)
+{
+ /* NOP - deprecated */
+}
+
+uint32_t
+arc4random(void)
+{
+ uint32_t rand;
-uint64_t arc4random64(void);
+ arc4random_buf(&rand, sizeof(rand));
+
+ return rand;
+}
+
+void
+arc4random_buf(void *buf, size_t buf_size)
+{
+ arc4_init();
+ ccrng_generate(rng, buf_size, buf);
+}
+
+void
+arc4random_stir(void)
+{
+ /* NOP */
+}
+
+uint32_t
+arc4random_uniform(uint32_t upper_bound)
+{
+ uint64_t rand;
+
+ arc4_init();
+ ccrng_uniform(rng, upper_bound, &rand);
+
+ return (uint32_t)rand;
+}
+
+__private_extern__ void
+_arc4_fork_child(void)
+{
+ /* NOP */
+}
+
+#else /* __APPLE__ && !VARIANT_STATIC */
#define RANDOMDEV "/dev/random"
(void)close(fd);
}
-#if defined(__APPLE__) && !defined(VARIANT_STATIC)
-#include <corecrypto/ccdrbg.h>
-#include <corecrypto/ccaes.h>
-
-static struct ccdrbg_info rng_info;
-static struct ccdrbg_nistctr_custom rng_custom;
-static struct ccdrbg_state *rng_state;
-
-static int cache_pos = CACHE_LENGTH;
-static uint32_t rand_buffer[CACHE_LENGTH];
-
-static void
-arc4_init(void)
-{
- if (rng_state != NULL) return;
-
- uint8_t entropy[BUFFERSIZE];
- int ret;
- rng_custom.ctr_info = ccaes_ctr_crypt_mode();
- rng_custom.keylen = 16;
- rng_custom.strictFIPS = 0;
- rng_custom.use_df = 1;
- ccdrbg_factory_nistctr(&rng_info, &rng_custom);
- rng_state = malloc(rng_info.size);
- os_assert(rng_state != NULL);
-
- _my_getentropy(entropy, BUFFERSIZE);
-
- ret = ccdrbg_init(&rng_info, rng_state,
- sizeof(entropy), entropy,
- 0, NULL, 0, NULL);
- os_assert_zero(ret);
-
- memset_s(entropy, sizeof(entropy), 0, sizeof(entropy));
-
- arc4_count = INITIAL_COUNT;
-}
-
-static void
-arc4_stir(void)
-{
- uint8_t entropy[BUFFERSIZE];
- int ret;
-
- arc4_init();
-
- _my_getentropy(entropy, BUFFERSIZE);
-
- ret = ccdrbg_reseed(&rng_info, rng_state,
- sizeof(entropy), entropy,
- 0, NULL);
- os_assert_zero(ret);
-
- memset_s(entropy, sizeof(entropy), 0, sizeof(entropy));
-
- arc4_count = INITIAL_COUNT;
-}
-
-void
-arc4random_addrandom(__unused u_char *dat, __unused int datlen)
-{
- /* NOP - deprecated */
-}
-
-uint32_t
-arc4random(void)
-{
- int ret;
- os_unfair_lock_lock(&arc4_lock);
- arc4_init();
- if (arc4_count <= 0) {
- arc4_stir();
- }
- if (cache_pos >= CACHE_LENGTH) {
- ret = ccdrbg_generate(&rng_info, rng_state, sizeof(rand_buffer), rand_buffer, 0, NULL);
- os_assert_zero(ret);
- cache_pos = 0;
- }
- uint32_t rand = rand_buffer[cache_pos];
- // Delete the current random number from buffer
- memset_s(rand_buffer+cache_pos, sizeof(rand_buffer[cache_pos]), 0, sizeof(rand_buffer[cache_pos]));
- arc4_count--;
- cache_pos++;
- os_unfair_lock_unlock(&arc4_lock);
- return rand;
-}
-
-void
-arc4random_buf(void *_buf, size_t buf_size)
-{
- uint8_t *buf = _buf;
- os_unfair_lock_lock(&arc4_lock);
- arc4_init();
- while (buf_size > 0) {
- if (arc4_count <= 0 ) {
- arc4_stir();
- }
- size_t n = MIN(buf_size, (size_t)MIN(MAX_BUF_COUNT, arc4_count) * sizeof(uint32_t));
- int ret = ccdrbg_generate(&rng_info, rng_state, n, buf, 0, NULL);
- os_assert_zero(ret);
- buf_size -= n;
- buf += n;
- arc4_count -= n/sizeof(uint32_t);
-
- if (buf_size > 0) {
- os_unfair_lock_unlock(&arc4_lock);
- // Give others a chance to get the lock
- os_unfair_lock_lock(&arc4_lock);
- }
- }
- os_unfair_lock_unlock(&arc4_lock);
-}
-
-__private_extern__ void
-_arc4_fork_child(void)
-{
- arc4_lock = OS_UNFAIR_LOCK_INIT;
- cache_pos = CACHE_LENGTH;
- if (rng_state != NULL) {
- arc4_count = 0;
- memset_s(rand_buffer, sizeof(rand_buffer), 0, sizeof(rand_buffer));
- memset_s(rng_state, rng_info.size, 0, rng_info.size);
- free(rng_state); rng_state = NULL;
- bzero(&rng_info, sizeof(rng_info));
- bzero(&rng_custom, sizeof(rng_custom));
- }
-}
-
-#else /* __APPLE__ && !VARIANT_STATIC */
-
struct arc4_stream {
u_int8_t i;
u_int8_t j;
_my_getentropy((uint8_t*)&rdat, KEYSIZE);
}
+static os_unfair_lock arc4_lock = OS_UNFAIR_LOCK_INIT;
+static int arc4_count;
+
static void
arc4_stir(void)
{
}
}
-#endif /* __APPLE__ */
-
void
arc4random_stir(void)
{
}
} while (1);
}
+
+#endif /* __APPLE__ */
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
+#if __has_include(<CrashReporterClient.h>)
#include <CrashReporterClient.h>
+#else
+#define CRGetCrashLogMessage() NULL
+#define CRSetCrashLogMessage(...)
+#endif
#include "_simple.h"
void
if (func == (const char *)-1L) {
/* 8462256: special case to replace __eprintf */
_simple_dprintf(STDERR_FILENO,
- "%s:%u: failed assertion `%s'\n", file, line, failedexpr);
+ "%s:%d: failed assertion `%s'\n", file, line, failedexpr);
if (!CRGetCrashLogMessage()) {
_SIMPLE_STRING s = _simple_salloc();
if (s) {
_simple_sprintf(s,
- "%s:%u: failed assertion `%s'\n",
+ "%s:%d: failed assertion `%s'\n",
file, line, failedexpr);
CRSetCrashLogMessage(_simple_string(s));
} else
errno = ENAMETOOLONG;
return (NULL);
}
- memcpy(dname, path, len);
+ memmove(dname, path, len);
dname[len] = '\0';
return (dname);
}
.Ft int
.Fn glob "const char * restrict pattern" "int flags" "int (*errfunc)(const char *epath, int errno)" "glob_t * restrict pglob"
.Ft int
-.Fn glob "const char * restrict pattern" "int flags" "int (^errblk)(const char *epath, int errno)" "glob_t * restrict pglob"
+.Fn glob_b "const char * restrict pattern" "int flags" "int (^errblk)(const char *epath, int errno)" "glob_t * restrict pglob"
.Ft void
.Fn globfree "glob_t *pglob"
.Sh DESCRIPTION
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
+#include <sys/sysctl.h>
#include <dirent.h>
#include <errno.h>
#include "telldir.h"
+static bool
+__kernel_supports_unionfs(void)
+{
+ static int8_t kernel_supports_unionfs = -1;
+ if (kernel_supports_unionfs == -1) {
+ int value = 0;
+ size_t len = sizeof(value);
+ sysctlbyname("kern.secure_kernel", &value, &len, NULL, 0);
+ kernel_supports_unionfs = !value;
+ }
+ return kernel_supports_unionfs;
+}
+
+static int
+__fd_is_on_union_mount(int fd)
+{
+ struct statfs stbuf;
+ int rc;
+
+ rc = fstatfs(fd, &stbuf);
+ if (rc < 0) {
+ return rc;
+ }
+ return (stbuf.f_flags & MNT_UNION) != 0;
+}
+
static DIR * __opendir_common(int, int, bool);
/*
__opendir_common(int fd, int flags, bool use_current_pos)
{
DIR *dirp;
- int incr;
int saved_errno;
int unionstack;
LIST_INIT(&dirp->dd_td->td_locq);
dirp->dd_td->td_loccnt = 0;
- /*
- * Use the system page size if that is a multiple of DIRBLKSIZ.
- * Hopefully this can be a big win someday by allowing page
- * trades to user space to be done by _getdirentries().
- */
- incr = getpagesize();
- if ((incr % DIRBLKSIZ) != 0)
- incr = DIRBLKSIZ;
-
/*
* Determine whether this directory is the top of a union stack.
*/
- if (flags & DTF_NODUP) {
- struct statfs sfb;
-
- if (_fstatfs(fd, &sfb) < 0)
+ if ((flags & DTF_NODUP) && __kernel_supports_unionfs()) {
+ unionstack = __fd_is_on_union_mount(fd);
+ if (unionstack < 0)
goto fail;
- unionstack = !strcmp(sfb.f_fstypename, "unionfs")
- || (sfb.f_flags & MNT_UNION);
} else {
unionstack = 0;
}
goto fail;
dirp->dd_flags |= __DTF_READALL;
} else {
- dirp->dd_len = incr;
+ /*
+ * Start with a small-ish size to avoid allocating full pages.
+ * readdir() will allocate a larger buffer if it didn't fit
+ * to stay fast for large directories.
+ */
+ _Static_assert(GETDIRENTRIES64_EXTENDED_BUFSIZE <= READDIR_INITIAL_SIZE,
+ "Make sure we'll get extended metadata");
+ dirp->dd_len = READDIR_INITIAL_SIZE;
dirp->dd_buf = malloc(dirp->dd_len);
if (dirp->dd_buf == NULL)
goto fail;
* fd passed to fdopendir() is a directory.
*/
#if __DARWIN_64_BIT_INO_T
+ /*
+ * sufficiently recent kernels when the buffer is large enough,
+ * will use the last bytes of the buffer to return status.
+ *
+ * To support older kernels:
+ * - make sure it's 0 initialized
+ * - make sure it's past `dd_size` before reading it
+ */
+ getdirentries64_flags_t *gdeflags =
+ (getdirentries64_flags_t *)(dirp->dd_buf + dirp->dd_len -
+ sizeof(getdirentries64_flags_t));
+ *gdeflags = 0;
dirp->dd_size = (long)__getdirentries64(dirp->dd_fd,
dirp->dd_buf, dirp->dd_len, &dirp->dd_td->seekoff);
+ if (dirp->dd_size >= 0 &&
+ dirp->dd_size <= dirp->dd_len - sizeof(getdirentries64_flags_t)) {
+ if (*gdeflags & GETDIRENTRIES64_EOF) {
+ dirp->dd_flags |= __DTF_ATEND;
+ }
+ }
#else /* !__DARWIN_64_BIT_INO_T */
dirp->dd_size = _getdirentries(dirp->dd_fd,
dirp->dd_buf, dirp->dd_len, &dirp->dd_seek);
.Pp
The
.Fn pause
-function
-forces a process to pause until
-a signal is received from either the
+function causes the calling thread to pause until a signal is received from
+either the
.Xr kill 2
function
or an interval timer.
#include <sys/param.h>
#include <dirent.h>
#include <errno.h>
+#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <pthread.h>
#include "un-namespace.h"
for (;;) {
if (dirp->dd_loc >= dirp->dd_size) {
- if (dirp->dd_flags & __DTF_READALL)
+ if (dirp->dd_flags & (__DTF_READALL | __DTF_ATEND))
return (NULL);
initial_loc = dirp->dd_loc;
dirp->dd_flags &= ~__DTF_SKIPREAD;
dirp->dd_loc = 0;
}
if (dirp->dd_loc == 0 &&
- !(dirp->dd_flags & (__DTF_READALL | __DTF_SKIPREAD))) {
+ !(dirp->dd_flags & (__DTF_READALL | __DTF_ATEND | __DTF_SKIPREAD))) {
+ if (dirp->dd_len == READDIR_INITIAL_SIZE) {
+ /*
+ * If we need to read more, and we still have the original size,
+ * then grow the internal buffer to a large size to amortize
+ * the cost of __getdirentries64 calls.
+ */
+ int len = READDIR_LARGE_SIZE;
+ char *buf = malloc(len);
+ if (buf) {
+ free(dirp->dd_buf);
+ dirp->dd_buf = buf;
+ dirp->dd_len = len;
+ }
+ }
#if __DARWIN_64_BIT_INO_T
+ /*
+ * sufficiently recent kernels when the buffer is large enough,
+ * will use the last bytes of the buffer to return status.
+ *
+ * To support older kernels:
+ * - make sure it's 0 initialized
+ * - make sure it's past `dd_size` before reading it
+ */
+ getdirentries64_flags_t *gdeflags =
+ (getdirentries64_flags_t *)(dirp->dd_buf + dirp->dd_len -
+ sizeof(getdirentries64_flags_t));
+ *gdeflags = 0;
initial_seek = dirp->dd_td->seekoff;
dirp->dd_size = (long)__getdirentries64(dirp->dd_fd,
dirp->dd_buf, dirp->dd_len, &dirp->dd_td->seekoff);
+ if (dirp->dd_size >= 0 &&
+ dirp->dd_size <= dirp->dd_len - sizeof(getdirentries64_flags_t)) {
+ if (*gdeflags & GETDIRENTRIES64_EOF) {
+ dirp->dd_flags |= __DTF_ATEND;
+ }
+ }
#else /* !__DARWIN_64_BIT_INO_T */
initial_seek = dirp->dd_seek;
dirp->dd_size = _getdirentries(dirp->dd_fd,
if (__isthreaded)
_pthread_mutex_lock(&dirp->dd_lock);
- dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid */
+ dirp->dd_flags &= ~(__DTF_SKIPREAD | __DTF_ATEND); /* current contents are invalid */
if (dirp->dd_flags & __DTF_READALL)
_filldir(dirp, false);
else {
dirp->dd_seek = lp->loc_seek;
#endif /* __DARWIN_64_BIT_INO_T */
dirp->dd_loc = 0;
- dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid */
+ dirp->dd_flags &= ~(__DTF_SKIPREAD | __DTF_ATEND); /* current contents are invalid */
while (dirp->dd_loc < lp->loc_loc) {
dp = _readdir_unlocked(dirp, 0);
if (dp == NULL)
#endif /* __DARWIN_64_BIT_INO_T */
};
+/*
+ * This lets paths like `/` or top-level bundles to return in a single
+ * __getdirentries64 while keeping pressure on malloc small.
+ */
+#define READDIR_INITIAL_SIZE 2048
+#define READDIR_LARGE_SIZE (8 << 10)
+
#if __DARWIN_64_BIT_INO_T
size_t __getdirentries64(int fd, void *buf, size_t bufsize, __darwin_off_t *basep);
#endif /* __DARWIN_64_BIT_INO_T */
__attribute__ ((visibility ("hidden")))
bool _filldir(DIR *, bool) __DARWIN_INODE64(_filldir);
struct dirent *_readdir_unlocked(DIR *, int) __DARWIN_INODE64(_readdir_unlocked);
-void _reclaim_telldir(DIR *);
-void _seekdir(DIR *, long) __DARWIN_ALIAS_I(_seekdir);
+void _reclaim_telldir(DIR *);
+void _seekdir(DIR *, long) __DARWIN_ALIAS_I(_seekdir);
__attribute__ ((visibility ("hidden")))
void _fixtelldir(DIR *dirp, long oldseek, long oldloc) __DARWIN_INODE64(_fixtelldir);
long telldir(DIR *) __DARWIN_ALIAS_I(telldir);
--- /dev/null
+.\" $NetBSD: timespec_get.3,v 1.2 2016/10/04 10:46:40 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Kamil Rytarowski.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 26, 2018
+.Dt TIMESPEC_GET 3
+.Os
+.Sh NAME
+.Nm timespec_get
+.Nd get current calendar time
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In time.h
+.Ft int
+.Fn timespec_get "struct timespec *ts" "int base"
+.Sh DESCRIPTION
+The
+.Nm
+function sets the interval pointed to by
+.Fa ts
+to hold the current calendar time based on the specified time base in
+.Fa base .
+.Pp
+The base
+.Dv TIME_UTC
+returns the time since the epoch.
+This time is expressed in seconds and nanoseconds since midnight (0 hour), January 1, 1970.
+This corresponds to
+.Dv CLOCK_REALTIME .
+.Sh RETURN VALUES
+The
+.Nm
+function returns the passed value of
+.Fa base
+if successful, otherwise
+.Dv 0
+on failure.
+.Sh SEE ALSO
+.Xr gettimeofday 2 ,
+.Xr clock_gettime 2 ,
+.Xr time 3
+.Sh STANDARDS
+The
+.Nm
+function with a
+.Fa base
+of
+.Dv TIME_UTC
+conforms to
+.St -isoC-2011 .
+.Sh AUTHORS
+.An Kamil Rytarowski Aq Mt kamil@NetBSD.org
+.An Warner Losh Aq Mt imp@FreeBSD.org
--- /dev/null
+/* $NetBSD: timespec_get.c,v 1.2 2016/10/04 12:48:15 christos Exp $ */
+
+/*-
+ * Copyright (c) 2016 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Kamil Rytarowski.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: timespec_get.c,v 1.2 2016/10/04 12:48:15 christos Exp $");
+__FBSDID("$FreeBSD$");
+
+#include <time.h>
+
+/* ISO/IEC 9899:201x 7.27.2.5 The timespec_get function */
+
+int
+timespec_get(struct timespec *ts, int base)
+{
+
+ switch (base) {
+ case TIME_UTC:
+ if (clock_gettime(CLOCK_REALTIME, ts) == -1)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+
+ return base;
+}
.Nm RB_TREE_MIN ,
.Nm RB_TREE_MAX ,
.Nm RB_TREE_FOREACH ,
-.Nm RB_TREE_FOREACH_REVERSE
+.Nm RB_TREE_FOREACH_SAFE ,
+.Nm RB_TREE_FOREACH_REVERSE ,
+.Nm RB_TREE_FOREACH_REVERSE_SAFE
.Nd red-black tree
.Sh LIBRARY
.Lb libc
.Ft void *
.Fn RB_TREE_MAX "rb_tree_t *rbt"
.Fn RB_TREE_FOREACH "void *rb" "rb_tree_t *rbt"
+.Fn RB_TREE_FOREACH_SAFE "void *rb" "rb_tree_t *rbt" "void *tmp"
.Fn RB_TREE_FOREACH_REVERSE "void *rb" "rb_tree_t *rbt"
+.Fn RB_TREE_FOREACH_REVERSE_SAFE "void *rb" "rb_tree_t *rbt" "void *tmp"
.Sh DESCRIPTION
.Nm
provides red-black trees.
from least to greatest, assigning
.Fa rb
to each node in turn and executing the statement.
+.It Fn RB_TREE_FOREACH_SAFE "rb" "rbt" "tmp"
+.Nm RB_TREE_FOREACH_SAFE
+is a macro to be used like
+.Nm RB_TREE_FOREACH
+but which uses a temporary variable to permit safe modification or deletion of
+.Fa rb
+in the body of the loop.
.It Fn RB_TREE_FOREACH_REVERSE "rb" "rbt"
.Nm RB_TREE_FOREACH_REVERSE
is a macro to be used in the place of a
from greatest to least, assigning
.Fa rb
to each node in turn and executing the statement.
+.It Fn RB_TREE_FOREACH_REVERSE_SAFE "rb" "rbt" "tmp"
+.Nm RB_TREE_FOREACH_REVERSE_SAFE
+is a macro to be used like
+.Nm RB_TREE_FOREACH_REVERSE
+but which uses a temporary variable to permit safe modification or deletion of
+.Fa rb
+in the body of the loop.
.El
.Sh SEE ALSO
.Xr queue 3 ,
* @APPLE_LICENSE_HEADER_END@
*/
+#include <TargetConditionals.h>
#include <mach/vm_types.h>
#include <sys/uio.h>
-
-#include <dlfcn.h>
#include <errno.h>
#include <mach-o/dyld_priv.h>
#include <stdint.h>
#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
#include <uuid/uuid.h>
-
-#include "stack_logging.h"
#include "execinfo.h"
extern void _thread_stack_pcs(vm_address_t *buffer, unsigned max,
return num_frames;
}
+#if !TARGET_OS_DRIVERKIT
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string.h>
+#include "stack_logging.h"
+
#if __LP64__
#define _BACKTRACE_FORMAT "%-4d%-35s 0x%016lx %s + %lu"
#define _BACKTRACE_FORMAT_SIZE 83 /* %lu can take up to 20, does not include %s, includes NUL */
#define _BACKTRACE_FORMAT_SIZE 65 /* %lu can take up to 10, does not include %s, includes NUL */
#define _BACKTRACE_ADDRESS_LEN 10 /* 0x + 8 (no NUL) */
#endif
+#define _BACKTRACE_IMAGE_LEN 35
+#define _BACKTRACE_UUID_LEN 36
static int _backtrace_snprintf(char* buf, size_t size, int frame, const void* addr, const Dl_info* info) {
- char symbuf[_BACKTRACE_ADDRESS_LEN + 1];
+ char addrbuf[_BACKTRACE_ADDRESS_LEN + 1];
+ char imagebuf[_BACKTRACE_IMAGE_LEN + 1];
+ uuid_string_t uuidbuf;
const char* image = "???";
const char* symbol = "0x0";
uintptr_t symbol_offset = 0;
if (info->dli_fname) {
const char *tmp = strrchr(info->dli_fname, '/');
- if(tmp == NULL)
- image = info->dli_fname;
- else
- image = tmp + 1;
+ if (tmp == NULL) {
+ strlcpy(imagebuf, info->dli_fname, sizeof(imagebuf));
+ } else {
+ strlcpy(imagebuf, tmp + 1, sizeof(imagebuf));
+ }
+ image = imagebuf;
}
-
+
if (info->dli_sname) {
- symbol = info->dli_sname;
- symbol_offset = (uintptr_t)addr - (uintptr_t)info->dli_saddr;
- } else if(info->dli_fname) {
+ uuid_t uuid;
+ if (strcmp(info->dli_sname, "<redacted>") == 0 &&
+ _dyld_get_image_uuid(info->dli_fbase, uuid)) {
+ /*
+ * dyld returns <redacted> when the symbol name has been elided in
+ * the shared cache. To enable symbolication later, we provide the
+ * UUID and UUID-offset instead.
+ */
+ uuid_unparse(uuid, uuidbuf);
+ symbol = uuidbuf;
+ symbol_offset = (uintptr_t)addr - (uintptr_t)info->dli_fbase;
+ } else {
+ symbol = info->dli_sname;
+ symbol_offset = (uintptr_t)addr - (uintptr_t)info->dli_saddr;
+ }
+ } else if (info->dli_fname) {
symbol = image;
symbol_offset = (uintptr_t)addr - (uintptr_t)info->dli_fbase;
- } else if(0 < snprintf(symbuf, sizeof(symbuf), "0x%lx", (uintptr_t)info->dli_saddr)) {
- symbol = symbuf;
+ } else if (0 < snprintf(addrbuf, sizeof(addrbuf), "0x%lx",
+ (uintptr_t)info->dli_saddr)) {
+ symbol = addrbuf;
symbol_offset = (uintptr_t)addr - (uintptr_t)info->dli_saddr;
} else {
symbol_offset = (uintptr_t)addr;
}
- return snprintf(buf, size,
- _BACKTRACE_FORMAT,
- frame,
- image,
- (uintptr_t)addr,
- symbol,
- symbol_offset);
+ return snprintf(buf, size, _BACKTRACE_FORMAT, frame, image,
+ (uintptr_t)addr, symbol, symbol_offset);
+}
+
+static size_t symbol_length(Dl_info *info)
+{
+ if (info->dli_sname) {
+ if (strcmp(info->dli_sname, "<redacted>") == 0) {
+ return _BACKTRACE_UUID_LEN;
+ } else {
+ return strlen(info->dli_sname);
+ }
+ } else if (info->dli_fname) {
+ const char *tmp = strrchr(info->dli_fname, '/');
+ if (tmp == NULL) {
+ return strlen(info->dli_fname);
+ } else {
+ return strlen(tmp + 1);
+ }
+ } else {
+ return _BACKTRACE_ADDRESS_LEN;
+ }
}
char** backtrace_symbols(void* const* buffer, int size) {
char** ptrs;
intptr_t strs, end;
Dl_info* info = calloc(size, sizeof (Dl_info));
-
+
if (info == NULL) return NULL;
-
+
// Compute the total size for the block that is returned.
// The block will contain size number of pointers to the
// symbol descriptions.
total_bytes = sizeof(char*) * size;
-
+
// Plus each symbol description
for (i = 0 ; i < size; ++i) {
dladdr(buffer[i], &info[i]);
total_bytes += _BACKTRACE_FORMAT_SIZE;
- if (info[i].dli_sname) {
- total_bytes += strlen(info[i].dli_sname);
- } else if(info[i].dli_fname) {
- const char *tmp = strrchr(info[i].dli_fname, '/');
- if(tmp == NULL)
- total_bytes += strlen(info[i].dli_fname);
- else
- total_bytes += strlen(tmp + 1);
- } else {
- total_bytes += _BACKTRACE_ADDRESS_LEN;
- }
+ total_bytes += symbol_length(&info[i]);
}
-
+
result = (char**)malloc(total_bytes);
if (result == NULL) {
- free(info);
- return NULL;
+ goto error;
}
end = (intptr_t)result + total_bytes;
-
+
// Fill in the array of pointers and append the strings for
// each symbol description.
-
+
ptrs = result;
strs = ((intptr_t)result) + sizeof(char*) * size;
for (i = 0; i < size; ++i) {
int chk = _backtrace_snprintf((char*)strs, end - (intptr_t)strs, i, buffer[i], &info[i]);
-
- if(chk < 0) {
- free(info);
- return NULL;
+ if (chk < 0) {
+ goto error;
}
ptrs[i] = (char*)strs;
strs += chk + 1; // Step over the '\0'
}
-
+
free(info);
-
return result;
+
+error:
+ free(info);
+ free(result);
+ return NULL;
}
void backtrace_symbols_fd(void* const* buffer, int size, int fd) {
}
}
+#endif // !TARGET_OS_DRIVERKIT
+
void
backtrace_image_offsets(void* const* buffer, struct image_offset *imgoffs, int size)
{
Insufficient storage space is available.
.It Bq Er EIO
I/O error communicating with
-.Xr opendirectoryd 8 .
+.Xr dirhelper 8 .
.El
.Sh LEGACY ERRORS
If the call to
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" @(#)directory.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd April 16, 2008
+.Dd May 22, 2017
.Dt DIRECTORY 3
.Os
.Sh NAME
.Ft int
.Fn dirfd "DIR *dirp"
.Sh DESCRIPTION
+.Bf -symbolic
+The
+.Fn readdir_r
+interface is deprecated
+because it cannot be used correctly unless
+.Brq Va NAME_MAX
+is a fixed value.
+.Ef
+.Pp
The
.Fn opendir
function
.Fa filename
cannot be accessed, or if it cannot
.Xr malloc 3
-enough memory to hold the whole thing,
-and sets the global variable
-.Va errno
-to indicate the error.
+enough memory to hold the whole thing.
.Pp
The
.Fn fdopendir
.Fn readdir
function
returns a pointer to the next directory entry.
-It returns
+The directory entry remains valid until the next call to
+.Fn readdir
+or
+.Fn closedir
+on the same
+.Em directory stream .
+The function returns
.Dv NULL
upon reaching the end of the directory or on error.
In the event of an error,
.Va errno
may be set to any of the values documented for the
.Xr getdirentries 2
-system call. Note that the order of the directory entries vended by
+system call. Note that the order of the directory entries vended by
.Fn readdir
-is not specified. Some filesystems may return entries in lexicographic sort order and others may not.
+is not specified.
+Some filesystems may return entries in lexicographic sort order and others may not.
+Also note that not all filesystems will provide a value for
+.Va d_type
+and may instead set the field to
+.Dv DT_UNKNOWN .
.Pp
The
.Fn readdir_r
but the caller must provide a directory
.Fa entry
buffer to store the results in.
+The buffer must be large enough for a
+.Vt struct dirent
+with a
+.Va d_name
+array with
+.Brq Va NAME_MAX
++ 1 elements.
If the read succeeds,
.Fa result
is pointed at the
The
.Fn telldir
function
-returns the current location associated with the named
+returns a token representing the current location associated with the named
.Em directory stream .
Values returned by
.Fn telldir
reopened, prior values returned by
.Fn telldir
will no longer be valid.
+Values returned by
+.Fn telldir
+are also invalidated by a call to
+.Fn rewinddir .
.Pp
The
.Fn seekdir
.Em directory stream ,
see
.Xr open 2 .
-On failure, \-1 is returned and the global variable
-.Va errno
-is set to indicate the error.
.Pp
Sample code which searches a directory for entry ``name'' is:
.Bd -literal -offset indent
break;
case FTS_F:
case FTS_DEFAULT:
+ SKIP_MOUNT;
fnflag = FTW_F;
break;
case FTS_NS:
{ "nohidden", UF_HIDDEN, 0 },
{ "nocompressed", UF_COMPRESSED, 0 },
{ "nodatavault", UF_DATAVAULT, 0 },
+ { "nodataless", SF_DATALESS, 0 },
};
#define longestflaglen 12
#define nmappings (sizeof(mapping) / sizeof(mapping[0]))
#include <mach/mach.h>
#include <mach/vm_statistics.h>
#include <stdlib.h>
+#include <pthread/stack_np.h>
#include "stack_logging.h"
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__)
-#define FP_LINK_OFFSET 1
-#else
-#error ********** Unimplemented architecture
-#endif
-
-
#define INSTACK(a) ((a) >= stackbot && (a) <= stacktop)
#if defined(__x86_64__)
#define ISALIGNED(a) ((((uintptr_t)(a)) & 0xf) == 0)
#define ISALIGNED(a) ((((uintptr_t)(a)) & 0x1) == 0)
#endif
-__private_extern__ __attribute__((noinline))
-void
-_thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb,
+__attribute__((noinline))
+static void
+__thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb,
unsigned skip, void *startfp)
{
void *frame, *next;
*nb = 0;
+ // Rely on the fact that our caller has an empty stackframe (no local vars)
+ // to determine the minimum size of a stackframe (frame ptr & return addr)
+ frame = __builtin_frame_address(0);
+ next = (void*)pthread_stack_frame_decode_np((uintptr_t)frame, NULL);
+
/* make sure return address is never out of bounds */
- stacktop -= (FP_LINK_OFFSET + 1) * sizeof(void *);
+ stacktop -= (next - frame);
- frame = __builtin_frame_address(0);
if(!INSTACK(frame) || !ISALIGNED(frame))
return;
- while ((startfp && startfp >= *(void **)frame) || skip--) {
- next = *(void **)frame;
+ while (startfp || skip--) {
+ if (startfp && startfp < next) break;
if(!INSTACK(next) || !ISALIGNED(next) || next <= frame)
return;
frame = next;
+ next = (void*)pthread_stack_frame_decode_np((uintptr_t)frame, NULL);
}
while (max--) {
- void *retaddr = (void *)*(vm_address_t *)
- (((void **)frame) + FP_LINK_OFFSET);
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wint-conversion"
+ uintptr_t retaddr;
+ next = (void*)pthread_stack_frame_decode_np((uintptr_t)frame, &retaddr);
buffer[*nb] = retaddr;
-#pragma clang diagnostic pop
(*nb)++;
- next = *(void **)frame;
if(!INSTACK(next) || !ISALIGNED(next) || next <= frame)
return;
frame = next;
}
}
+// Note that callee relies on this function having a minimal stackframe
+// to introspect (i.e. no tailcall and no local variables)
+__private_extern__ __attribute__((disable_tail_calls))
+void
+_thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb,
+ unsigned skip, void *startfp)
+{
+ // skip this frame
+ __thread_stack_pcs(buffer, max, nb, skip + 1, startfp);
+}
+
// Prevent thread_stack_pcs() from getting tail-call-optimized into
-// _thread_stack_pcs() on 64-bit environments, thus making the "number of hot
+// __thread_stack_pcs() on 64-bit environments, thus making the "number of hot
// frames to skip" be more predictable, giving more consistent backtraces.
//
// See <rdar://problem/5364825> "stack logging: frames keep getting truncated"
// for why this is necessary.
+//
+// Note that callee relies on this function having a minimal stackframe
+// to introspect (i.e. no tailcall and no local variables)
__attribute__((disable_tail_calls))
void
thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb)
{
- _thread_stack_pcs(buffer, max, nb, 0, NULL);
+ __thread_stack_pcs(buffer, max, nb, 0, NULL);
}
--- /dev/null
+/*
+ * Copyright (c) 2000, 2002-2006, 2008-2010, 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _CTERMID_H_
+#define _CTERMID_H_
+char *ctermid(char *);
+#endif
#include <sys/_types/_size_t.h>
#include <sys/_types/_null.h>
+#ifndef UNIFDEF_DRIVERKIT
#include <sys/stdio.h>
typedef __darwin_off_t fpos_t;
int _blksize; /* stat.st_blksize (may be != _bf._size) */
fpos_t _offset; /* current lseek offset (see WARNING) */
} FILE;
+#endif /* UNIFDEF_DRIVERKIT */
#endif /* __STDIO_H_ */
#define __strftimelike(fmtarg)
#endif
+#ifndef UNIFDEF_DRIVERKIT
typedef int __darwin_nl_item;
+#endif /* UNIFDEF_DRIVERKIT */
typedef int __darwin_wctrans_t;
#ifdef __LP64__
typedef __uint32_t __darwin_wctype_t;
#include <_types.h>
#include <sys/_types/_size_t.h>
+#ifndef UNIFDEF_DRIVERKIT
__BEGIN_DECLS
void *alloca(size_t); /* built-in for gcc */
__END_DECLS
+#endif /* UNIFDEF_DRIVERKIT */
#if defined(__GNUC__) && __GNUC__ >= 3
/* built-in for gcc 3 */
#define assert(e) ((void)0)
#else
+#ifndef UNIFDEF_DRIVERKIT
#ifndef __GNUC__
__BEGIN_DECLS
#ifndef __cplusplus
-void abort(void) __dead2;
+void abort(void) __dead2 __cold;
#endif /* !__cplusplus */
int printf(const char * __restrict, ...);
__END_DECLS
#define assert(e) \
((void) ((e) ? ((void)0) : __assert (#e, __FILE__, __LINE__)))
#define __assert(e, file, line) \
- ((void)printf ("%s:%u: failed assertion `%s'\n", file, line, e), abort())
+ ((void)printf ("%s:%d: failed assertion `%s'\n", file, line, e), abort())
#else /* __GNUC__ */
__BEGIN_DECLS
-void __assert_rtn(const char *, const char *, int, const char *) __dead2 __disable_tail_calls;
+void __assert_rtn(const char *, const char *, int, const char *) __dead2 __cold __disable_tail_calls;
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) < 1070)
-void __eprintf(const char *, const char *, unsigned, const char *) __dead2;
+void __eprintf(const char *, const char *, unsigned, const char *) __dead2 __cold;
#endif
__END_DECLS
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) < 1070)
#define __assert(e, file, line) \
- __eprintf ("%s:%u: failed assertion `%s'\n", file, line, e)
+ __eprintf ("%s:%d: failed assertion `%s'\n", file, line, e)
#else
/* 8462256: modified __assert_rtn() replaces deprecated __eprintf() */
#define __assert(e, file, line) \
#endif /* __DARWIN_UNIX03 */
#endif /* __GNUC__ */
+#else /* UNIFDEF_DRIVERKIT */
+__BEGIN_DECLS
+void __assert_rtn(const char *, const char *, int, const char *) __dead2 __cold __disable_tail_calls;
+__END_DECLS
+#define assert(e) \
+ (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
+#endif /* UNIFDEF_DRIVERKIT */
#endif /* NDEBUG */
#ifndef _ASSERT_H_
#define DTF_NODUP 0x0002 /* don't return duplicate names */
#define DTF_REWIND 0x0004 /* rewind after reading union stack */
#define __DTF_READALL 0x0008 /* everything has been read */
-#define __DTF_SKIPREAD 0x0010 /* assume internal buffer is populated */
+#define __DTF_SKIPREAD 0x0010 /* assume internal buffer is populated */
+#define __DTF_ATEND 0x0020 /* there's nothing more to read in the kernel */
#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
int scandir(const char *, struct dirent ***,
int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **)) __DARWIN_INODE64(scandir);
#ifdef __BLOCKS__
+#if __has_attribute(noescape)
+#define __scandir_noescape __attribute__((__noescape__))
+#else
+#define __scandir_noescape
+#endif
+
int scandir_b(const char *, struct dirent ***,
- int (^)(const struct dirent *), int (^)(const struct dirent **, const struct dirent **)) __DARWIN_INODE64(scandir_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+ int (^)(const struct dirent *) __scandir_noescape,
+ int (^)(const struct dirent **, const struct dirent **) __scandir_noescape)
+ __DARWIN_INODE64(scandir_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#endif /* __BLOCKS__ */
__END_DECLS
#include <Availability.h>
__BEGIN_DECLS
-void err(int, const char *, ...) __dead2 __printflike(2, 3);
-void verr(int, const char *, __darwin_va_list) __dead2 __printflike(2, 0);
-void errc(int, int, const char *, ...) __dead2 __printflike(3, 4);
-void verrc(int, int, const char *, __darwin_va_list) __dead2 __printflike(3, 0);
-void errx(int, const char *, ...) __dead2 __printflike(2, 3);
-void verrx(int, const char *, __darwin_va_list) __dead2 __printflike(2, 0);
-void warn(const char *, ...) __printflike(1, 2);
-void vwarn(const char *, __darwin_va_list) __printflike(1, 0);
-void warnc(int, const char *, ...) __printflike(2, 3);
-void vwarnc(int, const char *, __darwin_va_list) __printflike(2, 0);
-void warnx(const char *, ...) __printflike(1, 2);
-void vwarnx(const char *, __darwin_va_list) __printflike(1, 0);
+void err(int, const char *, ...) __cold __dead2 __printflike(2, 3);
+void verr(int, const char *, __darwin_va_list) __cold __dead2 __printflike(2, 0);
+void errc(int, int, const char *, ...) __cold __dead2 __printflike(3, 4);
+void verrc(int, int, const char *, __darwin_va_list) __cold __dead2 __printflike(3, 0);
+void errx(int, const char *, ...) __cold __dead2 __printflike(2, 3);
+void verrx(int, const char *, __darwin_va_list) __cold __dead2 __printflike(2, 0);
+void warn(const char *, ...) __cold __printflike(1, 2);
+void vwarn(const char *, __darwin_va_list) __cold __printflike(1, 0);
+void warnc(int, const char *, ...) __cold __printflike(2, 3);
+void vwarnc(int, const char *, __darwin_va_list) __cold __printflike(2, 0);
+void warnx(const char *, ...) __cold __printflike(1, 2);
+void vwarnx(const char *, __darwin_va_list) __cold __printflike(1, 0);
void err_set_file(void *);
void err_set_exit(void (* _Nullable)(int));
#ifdef __BLOCKS__
#endif /* !LIBC_ALIAS_FTS_OPEN */
//End-Libc
#ifdef __BLOCKS__
+#if __has_attribute(noescape)
+#define __fts_noescape __attribute__((__noescape__))
+#else
+#define __fts_noescape
+#endif
//Begin-Libc
#ifndef LIBC_ALIAS_FTS_OPEN_B
//End-Libc
FTS *fts_open_b(char * const *, int,
- int (^)(const FTSENT **, const FTSENT **)) __DARWIN_INODE64(fts_open_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+ int (^)(const FTSENT **, const FTSENT **) __fts_noescape)
+ __DARWIN_INODE64(fts_open_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
//Begin-Libc
#else /* LIBC_ALIAS_FTS_OPEN */
FTS *fts_open_b(char * const *, int,
- int (^)(const FTSENT **, const FTSENT **)) LIBC_INODE64(fts_open_b);
+ int (^)(const FTSENT **, const FTSENT **) __fts_noescape)
+ LIBC_INODE64(fts_open_b);
#endif /* !LIBC_ALIAS_FTS_OPEN */
//End-Libc
#endif /* __BLOCKS__ */
#endif /* !LIBC_ALIAS_GLOB */
//End-Libc
#ifdef __BLOCKS__
+#if __has_attribute(noescape)
+#define __glob_noescape __attribute__((__noescape__))
+#else
+#define __glob_noescape
+#endif
//Begin-Libc
#ifndef LIBC_ALIAS_GLOB_B
//End-Libc
-int glob_b(const char * __restrict, int, int (^)(const char *, int),
+int glob_b(const char * __restrict, int, int (^)(const char *, int) __glob_noescape,
glob_t * __restrict) __DARWIN_INODE64(glob_b) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
//Begin-Libc
#else /* LIBC_ALIAS_GLOB_B */
-int glob_b(const char * __restrict, int, int (^)(const char *, int),
+int glob_b(const char * __restrict, int, int (^)(const char *, int) __glob_noescape,
glob_t * __restrict) LIBC_INODE64(glob_b);
#endif /* !LIBC_ALIAS_GLOB_B */
//End-Libc
#include <sys/cdefs.h>
#include <machine/limits.h>
+#ifndef UNIFDEF_DRIVERKIT
#include <sys/syslimits.h>
#if __DARWIN_C_LEVEL > __DARWIN_C_ANSI
#endif /* __DARWIN_C_LEVEL > __DARWIN_C_ANSI */
/* NZERO to be defined here. TBD. See also sys/param.h */
+#endif /* UNIFDEF_DRIVERKIT */
#endif /* !_LIMITS_H_ */
#define REG_NOSPEC 0020 /* Compile turning off all special characters */
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 \
- || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0
+ || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 \
+ || defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
#define REG_LITERAL REG_NOSPEC
#endif
#define REG_PEND 0040 /* Use re_endp as end pointer */
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 \
- || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0
+ || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 \
+ || defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
#define REG_MINIMAL 0100 /* Compile using minimal repetition */
#define REG_UNGREEDY REG_MINIMAL
#endif
#define REG_DUMP 0200 /* Unused */
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 \
- || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0
+ || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 \
+ || defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
#define REG_ENHANCED 0400 /* Additional (non-POSIX) features */
#endif
#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
#define REG_BACKR 02000 /* force use of backref code */
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 \
- || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0
+ || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 \
+ || defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
#define REG_BACKTRACKING_MATCHER REG_BACKR
#endif
#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
int regcomp(regex_t * __restrict, const char * __restrict, int) LIBC_ALIAS(regcomp);
#endif /* !LIBC_ALIAS_REGCOMP */
//End-Libc
-size_t regerror(int, const regex_t * __restrict, char * __restrict, size_t);
+size_t regerror(int, const regex_t * __restrict, char * __restrict, size_t) __cold;
/*
* gcc under c99 mode won't compile "[ __restrict]" by itself. As a workaround,
* a dummy argument name is added.
#define __has_builtin(x) 0
#endif
+#ifndef UNIFDEF_DRIVERKIT
/* sprintf, vsprintf, snprintf, vsnprintf */
#if __has_builtin(__builtin___sprintf_chk) || defined(__GNUC__)
extern int __sprintf_chk (char * __restrict, int, size_t,
#define sprintf(str, ...) \
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
#endif
+#endif /* UNIFDEF_DRIVERKIT */
#if __DARWIN_C_LEVEL >= 200112L
#if __has_builtin(__builtin___snprintf_chk) || defined(__GNUC__)
__builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
#endif
+#ifndef UNIFDEF_DRIVERKIT
#if __has_builtin(__builtin___vsprintf_chk) || defined(__GNUC__)
extern int __vsprintf_chk (char * __restrict, int, size_t,
const char * __restrict, va_list);
#define vsprintf(str, format, ap) \
__builtin___vsprintf_chk (str, 0, __darwin_obsz(str), format, ap)
#endif
+#endif /* UNIFDEF_DRIVERKIT */
#if __has_builtin(__builtin___vsnprintf_chk) || defined(__GNUC__)
extern int __vsnprintf_chk (char * __restrict, size_t, int, size_t,
/* memccpy, memcpy, mempcpy, memmove, memset, strcpy, strlcpy, stpcpy,
strncpy, stpncpy, strcat, strlcat, and strncat */
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 || \
+ defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
#if __has_builtin(__builtin___memccpy_chk) && __HAS_FIXED_CHK_PROTOTYPES
#undef memccpy
/* void *memccpy(void *dst, const void *src, int c, size_t n) */
__builtin___memset_chk (dest, __VA_ARGS__, __darwin_obsz0 (dest))
#endif
+#ifndef UNIFDEF_DRIVERKIT
#if __has_builtin(__builtin___strcpy_chk) || defined(__GNUC__)
#undef strcpy
/* char *strcpy(char *dst, const char *src) */
#define stpcpy(dest, ...) \
__builtin___stpcpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
+#endif /* __DARWIN_C_LEVEL >= 200809L */
+#endif /* UNIFDEF_DRIVERKIT */
+#if __DARWIN_C_LEVEL >= 200809L
#if __has_builtin(__builtin___stpncpy_chk) || __APPLE_CC__ >= 5666 || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
#undef stpncpy
/* char *stpncpy(char *dst, const char *src, size_t n) */
#endif /* _DARWIN_C_LEVEL >= 200809L */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 || \
+ defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
#if __has_builtin(__builtin___strlcpy_chk) && __HAS_FIXED_CHK_PROTOTYPES
#undef strlcpy
/* size_t strlcpy(char *dst, const char *source, size_t size) */
__builtin___strncpy_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
+#ifndef UNIFDEF_DRIVERKIT
#if __has_builtin(__builtin___strcat_chk) || defined(__GNUC__)
#undef strcat
/* char *strcat(char *s1, const char *s2) */
#define strcat(dest, ...) \
__builtin___strcat_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
#endif
+#endif /* UNIFDEF_DRIVERKIT */
#if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000)
#if __has_builtin(__builtin___strncat_chk) || defined(__GNUC__)
#include <_types/_intmax_t.h>
#include <_types/_uintmax_t.h>
+/* 7.18.4 Macros for integer constants */
+#define INT8_C(v) (v)
+#define INT16_C(v) (v)
+#define INT32_C(v) (v)
+#define INT64_C(v) (v ## LL)
+
+#define UINT8_C(v) (v)
+#define UINT16_C(v) (v)
+#define UINT32_C(v) (v ## U)
+#define UINT64_C(v) (v ## ULL)
+
+#ifdef __LP64__
+#define INTMAX_C(v) (v ## L)
+#define UINTMAX_C(v) (v ## UL)
+#else
+#define INTMAX_C(v) (v ## LL)
+#define UINTMAX_C(v) (v ## ULL)
+#endif
+
/* 7.18.2 Limits of specified-width integer types:
* These #defines specify the minimum and maximum limits
* of each of the types declared above.
#endif
/* 7.18.2.5 Limits of greatest-width integer types */
-#define INTMAX_MIN INT64_MIN
-#define INTMAX_MAX INT64_MAX
-
-#define UINTMAX_MAX UINT64_MAX
+#define INTMAX_MAX INTMAX_C(9223372036854775807)
+#define UINTMAX_MAX UINTMAX_C(18446744073709551615)
+#define INTMAX_MIN (-INTMAX_MAX-1)
/* 7.18.3 "Other" */
#if __WORDSIZE == 64
-#define PTRDIFF_MIN INT64_MIN
-#define PTRDIFF_MAX INT64_MAX
+#define PTRDIFF_MIN INTMAX_MIN
+#define PTRDIFF_MAX INTMAX_MAX
#else
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
-/* 7.18.4 Macros for integer constants */
-#define INT8_C(v) (v)
-#define INT16_C(v) (v)
-#define INT32_C(v) (v)
-#define INT64_C(v) (v ## LL)
-
-#define UINT8_C(v) (v)
-#define UINT16_C(v) (v)
-#define UINT32_C(v) (v ## U)
-#define UINT64_C(v) (v ## ULL)
-
-#ifdef __LP64__
-#define INTMAX_C(v) (v ## L)
-#define UINTMAX_C(v) (v ## UL)
-#else
-#define INTMAX_C(v) (v ## LL)
-#define UINTMAX_C(v) (v ## ULL)
-#endif
-
#endif /* _STDINT_H_ */
#include <_stdio.h>
+#ifndef UNIFDEF_DRIVERKIT
__BEGIN_DECLS
extern FILE *__stdinp;
extern FILE *__stdoutp;
int getc(FILE *);
int getchar(void);
char *gets(char *);
-void perror(const char *);
+void perror(const char *) __cold;
int printf(const char * __restrict, ...) __printflike(1, 2);
int putc(int, FILE *);
int putchar(int);
#define L_ctermid 1024 /* size for ctermid(); PATH_MAX */
__BEGIN_DECLS
-#ifndef __CTERMID_DEFINED
-/* Multiply defined in stdio.h and unistd.h by SUS */
-#define __CTERMID_DEFINED 1
-char *ctermid(char *);
-#endif
+#include <_ctermid.h>
#if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE)
FILE *fdopen(int, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fdopen));
#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
+#else /* UNIFDEF_DRIVERKIT */
+#define EOF (-1)
+
+__BEGIN_DECLS
+int sscanf(const char * __restrict, const char * __restrict, ...) __scanflike(2, 3);
+#if __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus)
+int snprintf(char * __restrict __str, size_t __size, const char * __restrict __format, ...) __printflike(3, 4);
+int vsnprintf(char * __restrict __str, size_t __size, const char * __restrict __format, va_list) __printflike(3, 0);
+int vsscanf(const char * __restrict __str, const char * __restrict __format, va_list) __scanflike(2, 0);
+#endif /* __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) */
+#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
+int asprintf(char ** __restrict, const char * __restrict, ...) __printflike(2, 3);
+int vasprintf(char ** __restrict, const char * __restrict, va_list) __printflike(2, 0);
+#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
+__END_DECLS
+#endif /* UNIFDEF_DRIVERKIT */
#ifdef _USE_EXTENDED_LOCALES_
#include <xlocale/_stdio.h>
#include <_types.h>
#if !defined(_ANSI_SOURCE)
+#ifndef UNIFDEF_DRIVERKIT
#include <sys/wait.h>
+#endif /* UNIFDEF_DRIVERKIT */
#if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
#include <alloca.h>
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
#include <sys/_types/_null.h>
+#ifndef UNIFDEF_DRIVERKIT
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
+#endif /* UNIFDEF_DRIVERKIT */
#define RAND_MAX 0x7fffffff
#define LIBC_ABORT(f,...) abort_report_np("%s:%s:%u: " f, __FILE__, __func__, __LINE__, ## __VA_ARGS__)
//End-Libc
+#ifndef UNIFDEF_DRIVERKIT
#include <malloc/_malloc.h>
+#endif /* UNIFDEF_DRIVERKIT */
__BEGIN_DECLS
-void abort(void) __dead2;
+void abort(void) __cold __dead2;
int abs(int) __pure2;
+#ifndef UNIFDEF_DRIVERKIT
int atexit(void (* _Nonnull)(void));
+#endif /* UNIFDEF_DRIVERKIT */
double atof(const char *);
int atoi(const char *);
long atol(const char *);
#endif /* !__DARWIN_NO_LONG_LONG */
void *bsearch(const void *__key, const void *__base, size_t __nel,
size_t __width, int (* _Nonnull __compar)(const void *, const void *));
+#ifndef UNIFDEF_DRIVERKIT
/* calloc is now declared in _malloc.h */
+#endif /* UNIFDEF_DRIVERKIT */
div_t div(int, int) __pure2;
+#ifndef UNIFDEF_DRIVERKIT
void exit(int) __dead2;
/* free is now declared in _malloc.h */
char *getenv(const char *);
+#endif /* UNIFDEF_DRIVERKIT */
long labs(long) __pure2;
ldiv_t ldiv(long, long) __pure2;
#if !__DARWIN_NO_LONG_LONG
llabs(long long);
lldiv_t lldiv(long long, long long);
#endif /* !__DARWIN_NO_LONG_LONG */
+#ifndef UNIFDEF_DRIVERKIT
/* malloc is now declared in _malloc.h */
+#endif /* UNIFDEF_DRIVERKIT */
int mblen(const char *__s, size_t __n);
size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t);
int mbtowc(wchar_t * __restrict, const char * __restrict, size_t);
+#ifndef UNIFDEF_DRIVERKIT
/* posix_memalign is now declared in _malloc.h */
+#endif /* UNIFDEF_DRIVERKIT */
void qsort(void *__base, size_t __nel, size_t __width,
int (* _Nonnull __compar)(const void *, const void *));
+#ifndef UNIFDEF_DRIVERKIT
int rand(void) __swift_unavailable("Use arc4random instead.");
/* realloc is now declared in _malloc.h */
void srand(unsigned) __swift_unavailable("Use arc4random instead.");
+#endif /* UNIFDEF_DRIVERKIT */
double strtod(const char *, char **) __DARWIN_ALIAS(strtod);
float strtof(const char *, char **) __DARWIN_ALIAS(strtof);
long strtol(const char *__str, char **__endptr, int __base);
unsigned long long
strtoull(const char *__str, char **__endptr, int __base);
#endif /* !__DARWIN_NO_LONG_LONG */
+#ifndef UNIFDEF_DRIVERKIT
//Begin-Libc
#ifndef LIBC_ALIAS_SYSTEM
//End-Libc
//End-Libc
#undef __swift_unavailable_on
+#endif /* UNIFDEF_DRIVERKIT */
size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t);
int wctomb(char *, wchar_t);
+#ifndef UNIFDEF_DRIVERKIT
#ifndef _ANSI_SOURCE
void _Exit(int) __dead2;
long a64l(const char *);
void unsetenv(const char *);
#endif /* __DARWIN_UNIX03 */
#endif /* !_ANSI_SOURCE */
+#endif /* UNIFDEF_DRIVERKIT */
#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
#include <machine/types.h>
-
+#ifndef UNIFDEF_DRIVERKIT
#include <sys/_types/_dev_t.h>
#include <sys/_types/_mode_t.h>
+#endif /* UNIFDEF_DRIVERKIT */
#include <_types/_uint32_t.h>
uint32_t arc4random(void);
+#ifndef UNIFDEF_DRIVERKIT
void arc4random_addrandom(unsigned char * /*dat*/, int /*datlen*/)
__OSX_DEPRECATED(10.0, 10.12, "use arc4random_stir")
__IOS_DEPRECATED(2.0, 10.0, "use arc4random_stir")
__TVOS_DEPRECATED(2.0, 10.0, "use arc4random_stir")
__WATCHOS_DEPRECATED(1.0, 3.0, "use arc4random_stir");
+#endif /* UNIFDEF_DRIVERKIT */
void arc4random_buf(void * __buf, size_t __nbytes) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
void arc4random_stir(void);
uint32_t
arc4random_uniform(uint32_t __upper_bound) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
#ifdef __BLOCKS__
+#ifndef UNIFDEF_DRIVERKIT
int atexit_b(void (^ _Nonnull)(void)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+#endif /* UNIFDEF_DRIVERKIT */
void *bsearch_b(const void *__key, const void *__base, size_t __nel,
size_t __width, int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#endif /* __BLOCKS__ */
+#ifndef UNIFDEF_DRIVERKIT
/* getcap(3) functions */
char *cgetcap(char *, const char *, int);
int cgetclose(void);
int getloadavg(double [], int);
const char
*getprogname(void);
+void setprogname(const char *);
+#endif /* UNIFDEF_DRIVERKIT */
+
+#ifdef __BLOCKS__
+#if __has_attribute(noescape)
+#define __sort_noescape __attribute__((__noescape__))
+#else
+#define __sort_noescape
+#endif
+#endif /* __BLOCKS__ */
int heapsort(void *__base, size_t __nel, size_t __width,
int (* _Nonnull __compar)(const void *, const void *));
#ifdef __BLOCKS__
int heapsort_b(void *__base, size_t __nel, size_t __width,
- int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+ int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape)
+ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#endif /* __BLOCKS__ */
int mergesort(void *__base, size_t __nel, size_t __width,
int (* _Nonnull __compar)(const void *, const void *));
#ifdef __BLOCKS__
int mergesort_b(void *__base, size_t __nel, size_t __width,
- int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+ int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape)
+ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#endif /* __BLOCKS__ */
+#ifndef UNIFDEF_DRIVERKIT
void psort(void *__base, size_t __nel, size_t __width,
- int (* _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+ int (* _Nonnull __compar)(const void *, const void *))
+ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#ifdef __BLOCKS__
void psort_b(void *__base, size_t __nel, size_t __width,
- int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+ int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape)
+ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#endif /* __BLOCKS__ */
void psort_r(void *__base, size_t __nel, size_t __width, void *,
- int (* _Nonnull __compar)(void *, const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+ int (* _Nonnull __compar)(void *, const void *, const void *))
+ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+#endif /* UNIFDEF_DRIVERKIT */
#ifdef __BLOCKS__
void qsort_b(void *__base, size_t __nel, size_t __width,
- int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
+ int (^ _Nonnull __compar)(const void *, const void *) __sort_noescape)
+ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#endif /* __BLOCKS__ */
void qsort_r(void *__base, size_t __nel, size_t __width, void *,
int (* _Nonnull __compar)(void *, const void *, const void *));
int radixsort(const unsigned char **__base, int __nel, const unsigned char *__table,
unsigned __endbyte);
-void setprogname(const char *);
+int rpmatch(const char *)
+ __API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0), watchos(6.0));
int sradixsort(const unsigned char **__base, int __nel, const unsigned char *__table,
unsigned __endbyte);
+#ifndef UNIFDEF_DRIVERKIT
void sranddev(void);
void srandomdev(void);
void *reallocf(void *__ptr, size_t __size) __alloc_size(2);
+#endif /* UNIFDEF_DRIVERKIT */
#if !__DARWIN_NO_LONG_LONG
long long
strtoq(const char *__str, char **__endptr, int __base);
unsigned long long
strtouq(const char *__str, char **__endptr, int __base);
#endif /* !__DARWIN_NO_LONG_LONG */
+#ifndef UNIFDEF_DRIVERKIT
extern char *suboptarg; /* getsubopt(3) external variable */
/* valloc is now declared in _malloc.h */
+#endif /* UNIFDEF_DRIVERKIT */
#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
/* Poison the following routines if -fshort-wchar is set */
void *memcpy(void *__dst, const void *__src, size_t __n);
void *memmove(void *__dst, const void *__src, size_t __len);
void *memset(void *__b, int __c, size_t __len);
+#ifndef UNIFDEF_DRIVERKIT
char *strcat(char *__s1, const char *__s2);
+#endif /* UNIFDEF_DRIVERKIT */
char *strchr(const char *__s, int __c);
int strcmp(const char *__s1, const char *__s2);
int strcoll(const char *__s1, const char *__s2);
+#ifndef UNIFDEF_DRIVERKIT
char *strcpy(char *__dst, const char *__src);
+#endif /* UNIFDEF_DRIVERKIT */
size_t strcspn(const char *__s, const char *__charset);
//Begin-Libc
#ifndef LIBC_ALIAS_STRERROR
#if __DARWIN_C_LEVEL >= 200809L
__BEGIN_DECLS
+#ifndef UNIFDEF_DRIVERKIT
char *stpcpy(char *__dst, const char *__src);
+#endif /* UNIFDEF_DRIVERKIT */
char *stpncpy(char *__dst, const char *__src, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
char *strndup(const char *__s1, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
size_t strnlen(const char *__s1, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
(sizeof(arr) / sizeof(arr[0]))
#endif
+/*
+ * countof() cannot be safely used in a _Static_assert statement, so we provide
+ * an unsafe variant that does not verify the input array is statically-defined.
+ */
+#define countof_unsafe(arr) \
+ (sizeof(arr) / sizeof(arr[0]))
+
/* Length of a statically-defined string (does not include null terminator) */
#define lenof(str) \
(sizeof(str) - 1)
#define _TIME_H_
#include <_types.h>
+#include <sys/cdefs.h>
#include <Availability.h>
+#ifndef UNIFDEF_DRIVERKIT
#include <sys/_types/_clock_t.h>
#include <sys/_types/_null.h>
#include <sys/_types/_size_t.h>
//End-Libc
#endif /* __DARWIN_UNIX03 */
extern int daylight;
+#endif /* UNIFDEF_DRIVERKIT */
__BEGIN_DECLS
+#ifndef UNIFDEF_DRIVERKIT
char *asctime(const struct tm *);
//Begin-Libc
#ifndef LIBC_ALIAS_CLOCK
#endif /* !LIBC_ALIAS_NANOSLEEP */
//End-Libc
#endif
+#endif /* UNIFDEF_DRIVERKIT */
#if !defined(_DARWIN_FEATURE_CLOCK_GETTIME) || _DARWIN_FEATURE_CLOCK_GETTIME != 0
#if __DARWIN_C_LEVEL >= 199309L
#define CLOCK_THREAD_CPUTIME_ID _CLOCK_THREAD_CPUTIME_ID
} clockid_t;
+#ifndef UNIFDEF_DRIVERKIT
__CLOCK_AVAILABILITY
int clock_getres(clockid_t __clock_id, struct timespec *__res);
__CLOCK_AVAILABILITY
int clock_gettime(clockid_t __clock_id, struct timespec *__tp);
+#endif /* UNIFDEF_DRIVERKIT */
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
__CLOCK_AVAILABILITY
__uint64_t clock_gettime_nsec_np(clockid_t __clock_id);
#endif
+#ifndef UNIFDEF_DRIVERKIT
__OSX_AVAILABLE(10.12) __IOS_PROHIBITED
__TVOS_PROHIBITED __WATCHOS_PROHIBITED
int clock_settime(clockid_t __clock_id, const struct timespec *__tp);
+#endif /* UNIFDEF_DRIVERKIT */
#undef __CLOCK_AVAILABILITY
#endif /* __DARWIN_C_LEVEL */
#endif /* _DARWIN_FEATURE_CLOCK_GETTIME */
+#ifndef UNIFDEF_DRIVERKIT
+#if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL) && \
+ ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
+ (defined(__cplusplus) && __cplusplus >= 201703L))
+/* ISO/IEC 9899:201x 7.27.2.5 The timespec_get function */
+#define TIME_UTC 1 /* time elapsed since epoch */
+__API_AVAILABLE(macosx(10.15), ios(13.0), tvos(13.0), watchos(6.0))
+int timespec_get(struct timespec *ts, int base);
+#endif
+
+#endif /* UNIFDEF_DRIVERKIT */
__END_DECLS
#ifdef _USE_EXTENDED_LOCALES_
#endif /* __DARWIN_C_LEVEL */
#define __ILP32_OFF32 (-1)
+#ifdef UNIFDEF_POSIX_ILP32_ALLOW
#define __ILP32_OFFBIG (1)
+#else // UNIFDEF_POSIX_ILP32_ALLOW
+#define __ILP32_OFFBIG (-1)
+#endif // UNIFDEF_POSIX_ILP32_ALLOW
+
#define __LP64_OFF64 (1)
#define __LPBIG_OFFBIG (1)
*/
#if __DARWIN_C_LEVEL >= 199506L
+#include <_ctermid.h>
/* These F_* are really XSI or Issue 6 */
#define F_ULOCK 0 /* unlock locked section */
#define F_LOCK 1 /* lock a section for exclusive use */
#endif
char *crypt(const char *, const char *);
-#ifndef __CTERMID_DEFINED
-/* Multiply defined in stdio.h and unistd.h by SUS */
-#define __CTERMID_DEFINED 1
-char *ctermid(char *);
-#endif
#if __DARWIN_UNIX03
//Begin-Libc
#ifndef LIBC_ALIAS_ENCRYPT
#include <stdarg.h>
#include <stdio.h>
+#ifndef UNIFDEF_DRIVERKIT
#include <time.h>
+#endif /* UNIFDEF_DRIVERKIT */
#include <_wctype.h>
/* Initially added in Issue 4 */
__BEGIN_DECLS
wint_t btowc(int);
+#ifndef UNIFDEF_DRIVERKIT
wint_t fgetwc(FILE *);
wchar_t *fgetws(wchar_t * __restrict, int, FILE * __restrict);
wint_t fputwc(wchar_t, FILE *);
int fwscanf(FILE * __restrict, const wchar_t * __restrict, ...);
wint_t getwc(FILE *);
wint_t getwchar(void);
+#endif /* UNIFDEF_DRIVERKIT */
size_t mbrlen(const char * __restrict, size_t, mbstate_t * __restrict);
size_t mbrtowc(wchar_t * __restrict, const char * __restrict, size_t,
mbstate_t * __restrict);
int mbsinit(const mbstate_t *);
size_t mbsrtowcs(wchar_t * __restrict, const char ** __restrict, size_t,
mbstate_t * __restrict);
+#ifndef UNIFDEF_DRIVERKIT
wint_t putwc(wchar_t, FILE *);
wint_t putwchar(wchar_t);
+#endif /* UNIFDEF_DRIVERKIT */
int swprintf(wchar_t * __restrict, size_t, const wchar_t * __restrict, ...);
int swscanf(const wchar_t * __restrict, const wchar_t * __restrict, ...);
+#ifndef UNIFDEF_DRIVERKIT
wint_t ungetwc(wint_t, FILE *);
int vfwprintf(FILE * __restrict, const wchar_t * __restrict,
__darwin_va_list);
+#endif /* UNIFDEF_DRIVERKIT */
int vswprintf(wchar_t * __restrict, size_t, const wchar_t * __restrict,
__darwin_va_list);
+#ifndef UNIFDEF_DRIVERKIT
int vwprintf(const wchar_t * __restrict, __darwin_va_list);
+#endif /* UNIFDEF_DRIVERKIT */
size_t wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict);
wchar_t *wcscat(wchar_t * __restrict, const wchar_t * __restrict);
wchar_t *wcschr(const wchar_t *, wchar_t);
int wcscoll(const wchar_t *, const wchar_t *);
wchar_t *wcscpy(wchar_t * __restrict, const wchar_t * __restrict);
size_t wcscspn(const wchar_t *, const wchar_t *);
+#ifndef UNIFDEF_DRIVERKIT
//Begin-Libc
#ifndef LIBC_ALIAS_WCSFTIME
//End-Libc
const struct tm * __restrict) LIBC_ALIAS(wcsftime);
#endif /* !LIBC_ALIAS_WCSFTIME */
//End-Libc
+#endif /* UNIFDEF_DRIVERKIT */
size_t wcslen(const wchar_t *);
wchar_t *wcsncat(wchar_t * __restrict, const wchar_t * __restrict, size_t);
int wcsncmp(const wchar_t *, const wchar_t *, size_t);
wchar_t *wmemcpy(wchar_t * __restrict, const wchar_t * __restrict, size_t);
wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t);
wchar_t *wmemset(wchar_t *, wchar_t, size_t);
+#ifndef UNIFDEF_DRIVERKIT
int wprintf(const wchar_t * __restrict, ...);
int wscanf(const wchar_t * __restrict, ...);
+#endif /* UNIFDEF_DRIVERKIT */
int wcswidth(const wchar_t *, size_t);
int wcwidth(wchar_t);
__END_DECLS
#if __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus)
__BEGIN_DECLS
+#ifndef UNIFDEF_DRIVERKIT
int vfwscanf(FILE * __restrict, const wchar_t * __restrict,
__darwin_va_list);
+#endif /* UNIFDEF_DRIVERKIT */
int vswscanf(const wchar_t * __restrict, const wchar_t * __restrict,
__darwin_va_list);
+#ifndef UNIFDEF_DRIVERKIT
int vwscanf(const wchar_t * __restrict, __darwin_va_list);
+#endif /* UNIFDEF_DRIVERKIT */
float wcstof(const wchar_t * __restrict, wchar_t ** __restrict);
long double
wcstold(const wchar_t * __restrict, wchar_t ** __restrict);
size_t wcsnlen(const wchar_t *, size_t) __pure __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
size_t wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t,
size_t, mbstate_t * __restrict);
+#ifndef UNIFDEF_DRIVERKIT
FILE *open_wmemstream(wchar_t ** __bufp, size_t * __sizep) __API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
+#endif /* UNIFDEF_DRIVERKIT */
__END_DECLS
#endif /* __DARWIN_C_LEVEL >= 200809L */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
__BEGIN_DECLS
+#ifndef UNIFDEF_DRIVERKIT
wchar_t *fgetwln(FILE * __restrict, size_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
+#endif /* UNIFDEF_DRIVERKIT */
size_t wcslcat(wchar_t *, const wchar_t *, size_t);
size_t wcslcpy(wchar_t *, const wchar_t *, size_t);
__END_DECLS
#define _LC_LAST_MASK (1 << (_LC_NUM_MASK - 1))
#define LC_GLOBAL_LOCALE ((locale_t)-1)
+#define LC_C_LOCALE ((locale_t)NULL)
#ifdef MB_CUR_MAX
#undef MB_CUR_MAX
#include "internal.h"
#pragma mark Utilities
-static int
-_sysctl_12809455(int mib[4], size_t mib_cnt, void *old, size_t *old_len,
- void *new, size_t new_len)
-{
- int error = -1;
- int ret = -1;
- size_t mylen = 0;
- size_t *mylenp = NULL;
-#if RDAR_12809455
- bool workaround_12809455 = false;
-#endif
-
- if (old_len) {
- mylen = *old_len;
- mylenp = &mylen;
- }
-
- // sysctl(3) doesn't behave anything like its documentation leads you to
- // believe. If the given buffer is too small to hold the requested data,
- // what's supposed to happen is:
- //
- // - as much data as possible is copied into the buffer
- // - the number of bytes copied is written to the len parameter
- // - errno is set to ENOMEM
- // - -1 is returned (to indicate that you should check errno)
- //
- // What actually happens:
- //
- // - no data is copied
- // - len is set to zero
- // - errno is undefined
- // - zero is returned
- //
- // So... swing and a miss.
- //
- // Since it returns success in this case our only indication that something
- // went wrong is if mylen is set to zero.
- //
- // So we do our best to sniff out the misbehavior and emulate sysctl(3)'s
- // API contract until it's fixed.
- //
- // <rdar://problem/12809455>
-#if RDAR_12809455
- if (old_len && *old_len > 0) {
- // We can only work around the bug if the passed-in length was non-zero.
- workaround_12809455 = true;
- }
-#endif
-
- ret = sysctl(mib, (u_int)mib_cnt, old, mylenp, new, new_len);
-#if RDAR_12809455
- if (workaround_12809455 && old && ret == 0 && mylen == 0) {
- ret = -1;
- errno = ENOMEM;
- }
-#endif // RDAR_12809455
-
- if (ret == 0) {
- error = 0;
- } else {
- error = errno;
- }
-
- if (old_len) {
- *old_len = mylen;
- }
-
- return error;
-}
-static char *
-_strblk(const char *str)
+/*
+ * Factored out from _get_parse_boot_arg_value for unit testing purposes
+ */
+static bool
+_parse_boot_arg_value(char *argsbuff, const char *which, char *where, size_t max)
{
- const char *cur = str;
+ bool found = false;
- while (*cur && !isblank(*cur)) {
- cur++;
+ char *token = NULL;
+ char *argsstr = argsbuff;
+ static const char seps[] = { ' ', '\t', };
+ while ((token = strsep(&argsstr, seps)) != NULL) {
+ bool is_boolean = false;
+
+ char *value = NULL;
+ char *equals = strchr(token, '=');
+ if (token[0] == '-') {
+ /*
+ * Arguments whose names begins with "-" are booleans, so don't get
+ * key=value splitting. Though I'd still discourage you from
+ * naming your option "-edge=case".
+ */
+ is_boolean = true;
+ } else if (equals) {
+ equals[0] = '\0';
+ value = &equals[1];
+ } else {
+ is_boolean = true;
+ }
+
+ if (strcmp(which, token) == 0) {
+ /*
+ * Found it! Copy out the value as required.
+ */
+ found = true;
+
+ if (!where) {
+ // Caller just wants to know whether the boot-arg exists.
+ } else if (is_boolean || value == NULL) {
+ strlcpy(where, "", max);
+ } else {
+ strlcpy(where, value, max);
+ }
+
+ break;
+ }
}
- return (char *)cur;
+ return found;
}
+/*
+ * This is (very) loosely based on the implementation of
+ * PE_parse_boot_argn() (or at least the parts where I was able to easily
+ * decipher the policy).
+ */
static bool
_get_boot_arg_value(const char *which, char *where, size_t max)
{
- // This is (very) loosely based on the implementation of
- // PE_parse_boot_argn() (or at least the parts where I was able to easily
- // decipher the policy).
bool found = false;
- errno_t error = -1;
- char *buff = NULL;
- size_t buff_len = 0;
- char *theone = NULL;
- char *equals = NULL;
-
- error = sysctlbyname_get_data_np("kern.bootargs", (void **)&buff,
- &buff_len);
- if (error) {
- goto __out;
- }
+ __os_free char *argsbuff = NULL;
+ size_t argsbuff_len = 0;
+ errno_t error = sysctlbyname_get_data_np("kern.bootargs",
+ (void **)&argsbuff, &argsbuff_len);
- theone = strstr(buff, which);
- if (!theone) {
- goto __out;
+ if (!error) {
+ found = _parse_boot_arg_value(argsbuff, which, where, max);
}
- found = true;
- if (!where) {
- // Caller just wants to know whether the boot-arg exists.
- goto __out;
- }
-
- equals = strchr(theone, '=');
- if (!equals || isblank(equals[1])) {
- strlcpy(where, "", max);
- } else {
- char *nextsep = NULL;
- char nextsep_old = 0;
-
- // Find the next separator and nerf it temporarily for the benefit of
- // the underlying strcpy(3).
- nextsep = _strblk(theone);
- nextsep_old = *nextsep;
- *nextsep = 0;
- strlcpy(where, &equals[1], max);
-
- *nextsep = nextsep_old;
- }
-
-__out:
- free(buff);
return found;
}
errno_t
sysctl_get_data_np(int mib[4], size_t mib_cnt, void **buff, size_t *buff_len)
{
- errno_t error = -1;
+ errno_t error = 0;
+ int ret = 0;
size_t needed = 0;
void *mybuff = NULL;
// We need to get the length of the parameter so we can allocate a buffer
// that's large enough.
- error = _sysctl_12809455(mib, mib_cnt, NULL, &needed, NULL, 0);
- if (error) {
+ ret = sysctl(mib, (unsigned int)mib_cnt, NULL, &needed, NULL, 0);
+ if (ret) {
+ error = errno;
goto __out;
}
goto __out;
}
- error = _sysctl_12809455(mib, mib_cnt, mybuff, &needed, NULL, 0);
- if (error) {
+ ret = sysctl(mib, (unsigned int)mib_cnt, mybuff, &needed, NULL, 0);
+ if (ret) {
// It's conceivable that some other process came along within this
// window and modified the variable to be even larger than we'd
// previously been told, but if that's the case, just give up.
+ error = errno;
goto __out;
}
--- /dev/null
+#include "internal.h"
+
+#pragma mark Definitions
+#define CTL_OUTPUT_WIDTH (80)
+#define CTL_OUTPUT_OPTARG_PAD (28)
+#define CTL_OUTPUT_LIST_PAD (4)
+#define SUBCOMMAND_LINKER_SET "__subcommands"
+
+#pragma mark Module Globals
+static const os_subcommand_t _help_cmd;
+
+#pragma mark Module Routines
+static char *
+_os_subcommand_copy_optarg_usage(const os_subcommand_t *osc,
+ const struct option *opt, os_subcommand_optarg_format_t format,
+ os_subcommand_option_t *scopt)
+{
+ char optbuff[64] = "";
+ char argbuff[64] = "";
+ char *final = NULL;
+ int ret = -1;
+
+ snprintf(optbuff, sizeof(optbuff), "--%s", opt->name);
+
+ if (osc->osc_info) {
+ osc->osc_info(osc, format, opt, scopt);
+ }
+
+ switch (opt->has_arg) {
+ case no_argument:
+ break;
+ case optional_argument:
+ snprintf(argbuff, sizeof(argbuff), "[=%s]", scopt->osco_argdesc);
+ break;
+ case required_argument:
+ snprintf(argbuff, sizeof(argbuff), "=<%s>", scopt->osco_argdesc);
+ break;
+ default:
+ __builtin_unreachable();
+ }
+
+ ret = asprintf(&final, "%s%s", optbuff, argbuff);
+ if (ret < 0) {
+ os_assert_zero(ret);
+ }
+
+ return final;
+}
+
+static void
+_os_subcommand_print_optarg_usage(const os_subcommand_t *osc,
+ const struct option *opt, FILE *f)
+{
+ os_subcommand_option_t scopt = {
+ .osco_flags = 0,
+ .osco_argdesc = opt->name,
+ };
+ char *__os_free usage = NULL;
+ char *braces[2] = {
+ "",
+ "",
+ };
+
+ usage = _os_subcommand_copy_optarg_usage(osc, opt,
+ OS_SUBCOMMAND_OPTARG_USAGE, &scopt);
+ if (scopt.osco_flags & OS_SUBCOMMAND_OPTION_FLAG_OPTIONAL) {
+ braces[0] = "[";
+ braces[1] = "]";
+ }
+
+ fprintf(f, " %s%s%s", braces[0], usage, braces[1]);
+}
+
+static void
+_os_subcommand_print_usage(const os_subcommand_t *osc, FILE *f)
+{
+ const struct option *opts = osc->osc_options;
+ const struct option *curopt = NULL;
+ size_t i = 0;
+
+ fprintf(f, "usage: %s %s", getprogname(), osc->osc_name);
+
+ while ((curopt = &opts[i]) && curopt->name) {
+ _os_subcommand_print_optarg_usage(osc, curopt, f);
+ i++;
+ }
+
+ fprintf(f, "\n");
+}
+
+static void
+_os_subcommand_print_optarg_human(const os_subcommand_t *osc,
+ const struct option *opt, FILE *f)
+{
+ os_subcommand_option_t scopt = {
+ .osco_flags = 0,
+ .osco_argdesc = opt->name,
+ };
+ char *__os_free usage = NULL;
+ char *__os_free human = NULL;
+
+ usage = _os_subcommand_copy_optarg_usage(osc, opt,
+ OS_SUBCOMMAND_OPTARG_USAGE, &scopt);
+ fprintf(f, " %-24s", usage);
+
+ human = _os_subcommand_copy_optarg_usage(osc, opt,
+ OS_SUBCOMMAND_OPTARG_HUMAN, &scopt);
+ wfprintf_np(f, -CTL_OUTPUT_OPTARG_PAD, CTL_OUTPUT_OPTARG_PAD,
+ CTL_OUTPUT_WIDTH, "%s", scopt.osco_argdesc);
+}
+
+static void
+_os_subcommand_print_human(const os_subcommand_t *osc, FILE *f)
+{
+ const struct option *opts = osc->osc_options;
+ const struct option *curopt = NULL;
+ size_t i = 0;
+
+ _os_subcommand_print_usage(osc, f);
+
+ while ((curopt = &opts[i]) && curopt->name) {
+ _os_subcommand_print_optarg_human(osc, curopt, f);
+ i++;
+ }
+}
+
+static void
+_os_subcommand_print_list(const os_subcommand_t *osc, FILE *f)
+{
+ wfprintf_np(f, CTL_OUTPUT_LIST_PAD, 0, 0, "%-24s %s",
+ osc->osc_name, osc->osc_desc);
+}
+
+static const os_subcommand_t *
+_os_subcommand_find(const char *name)
+{
+ const os_subcommand_t **oscip = NULL;
+
+ if (strcmp(_help_cmd.osc_name, name) == 0) {
+ return &_help_cmd;
+ }
+
+ LINKER_SET_FOREACH(oscip, const os_subcommand_t **, SUBCOMMAND_LINKER_SET) {
+ const os_subcommand_t *osci = *oscip;
+
+ if (strcmp(osci->osc_name, name) == 0) {
+ return osci;
+ }
+ }
+
+ return NULL;
+}
+
+#pragma mark Default Usage
+static void
+_usage_default(FILE *f)
+{
+ const os_subcommand_t **oscip = NULL;
+
+ crfprintf_np(f, "usage: %s <subcommand> [...] | help [subcommand]",
+ getprogname());
+ crfprintf_np(f, "");
+
+ crfprintf_np(f, "subcommands:");
+ LINKER_SET_FOREACH(oscip, const os_subcommand_t **, SUBCOMMAND_LINKER_SET) {
+ const os_subcommand_t *osci = *oscip;
+ _os_subcommand_print_list(osci, f);
+ }
+
+ _os_subcommand_print_list(&_help_cmd, f);
+}
+
+static int
+_usage(FILE *f)
+{
+ _usage_default(f);
+ return EX_USAGE;
+}
+
+#pragma mark Help Subcommand
+static int _help_invoke(const os_subcommand_t *osc,
+ int argc,
+ const char *argv[]
+);
+
+static const os_subcommand_t _help_cmd = {
+ .osc_version = OS_SUBCOMMAND_VERSION,
+ .osc_flags = 0,
+ .osc_name = "help",
+ .osc_desc = "prints helpful information",
+ .osc_optstring = NULL,
+ .osc_options = NULL,
+ .osc_info = NULL,
+ .osc_invoke = &_help_invoke,
+};
+
+static void
+_help_print_subcommand(const os_subcommand_t *osc, FILE *f)
+{
+ wfprintf_np(f, 4, 4, 76, "%-16s%s", osc->osc_name, osc->osc_desc);
+}
+
+static void
+_help_print_all(FILE *f)
+{
+ const os_subcommand_t **oscip = NULL;
+
+ _usage_default(f);
+ crfprintf_np(f, "");
+
+ crfprintf_np(f, "subcommands:");
+ LINKER_SET_FOREACH(oscip, const os_subcommand_t **, SUBCOMMAND_LINKER_SET) {
+ const os_subcommand_t *osci = *oscip;
+ if (osci->osc_flags & OS_SUBCOMMAND_FLAG_HIDDEN) {
+ continue;
+ }
+ _help_print_subcommand(osci, f);
+ }
+}
+
+static int
+_help_invoke(const os_subcommand_t *osc, int argc, const char *argv[])
+{
+ const os_subcommand_t *target = NULL;
+
+ if (argc == 1) {
+ _help_print_all(stdout);
+ } else {
+ target = _os_subcommand_find(argv[1]);
+ if (!target) {
+ crfprintf_np(stderr, "unrecognized subcommand: %s", argv[1]);
+ _usage_default(stderr);
+ return EX_USAGE;
+ }
+
+ _os_subcommand_print_human(target, stdout);
+ }
+
+ return 0;
+}
+
+#pragma mark API
+int
+os_subcommand_main(int argc, const char *argv[])
+{
+ int exitcode = -1;
+ const char *cmdname = NULL;
+ const os_subcommand_t *osci = NULL;
+
+ if (argc < 2) {
+ exitcode = _usage(stderr);
+ goto __out;
+ }
+
+ // Advance argument pointer and make the subcommand argv[0].
+ argc -= 1;
+ argv += 1;
+ cmdname = argv[0];
+
+ osci = _os_subcommand_find(cmdname);
+ if (osci) {
+ if (osci->osc_flags & OS_SUBCOMMAND_FLAG_REQUIRE_ROOT) {
+ if (geteuid()) {
+ crfprintf_np(stderr, "subcommand requires root: %s", cmdname);
+ exitcode = EX_NOPERM;
+ goto __out;
+ }
+ }
+
+ if (osci->osc_flags & OS_SUBCOMMAND_FLAG_TTYONLY) {
+ if (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO)) {
+ crfprintf_np(stderr, "subcommand requires a tty: %s", cmdname);
+ exitcode = EX_UNAVAILABLE;
+ goto __out;
+ }
+ }
+
+ exitcode = osci->osc_invoke(osci, argc, argv);
+ if (exitcode == EX_USAGE) {
+ _os_subcommand_print_usage(osci, stderr);
+ }
+ } else {
+ crfprintf_np(stderr, "unrecognized subcommand: %s", cmdname);
+ exitcode = _usage(stderr);
+ }
+
+__out:
+ return exitcode;
+}
#include <os/api.h>
#include <os/assumes.h>
#include <os/object_private.h>
+#include <os/lock.h>
#include <sys/errno.h>
#include <sys/cdefs.h>
#include <mach/port.h>
#include <mach/mach_port.h>
#include <mach/kern_return.h>
+#include <mach/mach_right.h>
__BEGIN_DECLS;
/*!
* @define __os_close_mach_recv
* An attribute that may be applied to a variable's type. This attribute causes
- * the variable to be passed to {@link darwin_mach_port_close_recv} when it goes
- * out of scope. Applying this attribute to variables that do not reference a
- * valid Mach port receive right will result in undefined behavior. If the
- * variable's value is MACH_PORT_NULL or MACH_PORT_DEAD upon going out-of-scope,
- * no cleanup is performed.
+ * the variable to be wrapped in a mach receive right object and passed to
+ * {@link mach_right_recv_destruct} when it goes out of scope. Applying this
+ * attribute to variables that do not reference a valid Mach port receive right
+ * will result in undefined behavior. If the variable's value is MACH_PORT_NULL
+ * or MACH_PORT_DEAD upon going out-of-scope, no cleanup is performed.
*/
#define __os_close_mach_recv \
__attribute__((cleanup(__os_cleanup_close_mach_recv)))
__os_cleanup_close_mach_recv(mach_port_t *__p)
{
mach_port_t p = *__p;
- kern_return_t kr = KERN_FAILURE;
+ mach_right_recv_t mr = mach_right_recv(p);
if (!MACH_PORT_VALID(p)) {
return;
}
- kr = mach_port_destruct(mach_task_self(), p, 0, 0);
- os_assert_zero(kr);
+ mach_right_recv_destruct(mr, NULL, 0);
}
/*!
* @define __os_release_mach_send
* An attribute that may be applied to a variable's type. This attribute causes
- * the variable to be passed to {@link darwin_mach_port_release} when it goes
- * out of scope. Applying this attribute to variables that do not reference a
- * valid Mach port send right or MACH_PORT_NULL or MACH_PORT_DEAD will result
- * in undefined behavior. If the variable's value is MACH_PORT_NULL or
- * MACH_PORT_DEAD upon going out-of-scope, no cleanup is performed.
+ * the variable to be wrapped in a mach send right object and passed to
+ * {@link mach_right_send_release} when it goes out of scope. Applying this
+ * attribute to variables that do not reference a valid Mach port send right or
+ * MACH_PORT_NULL or MACH_PORT_DEAD will result in undefined behavior. If the
+ * variable's value is MACH_PORT_NULL or MACH_PORT_DEAD upon going out-of-scope,
+ * no cleanup is performed.
*/
#define __os_release_mach_send \
__attribute__((cleanup(__os_cleanup_release_mach_send)))
__os_cleanup_release_mach_send(mach_port_t *__p)
{
mach_port_t p = *__p;
- kern_return_t kr = KERN_FAILURE;
+ mach_right_send_t ms = mach_right_send(p);
if (!MACH_PORT_VALID(p)) {
return;
}
- kr = mach_port_deallocate(mach_task_self(), p);
- os_assert_zero(kr);
+ mach_right_send_release(ms);
}
/*!
* upon going out-of-scope, no cleanup is performed.
*
* This attribute may be applied to dispatch and XPC objects.
+ *
+ * When compiling with ARC, this attribute does nothing.
*/
+#if __has_feature(objc_arc)
+#define __os_release
+#else
#define __os_release __attribute__((cleanup(__os_cleanup_os_release)))
static inline void
__os_cleanup_os_release(void *__p)
}
os_release(o);
}
+#endif
#if __COREFOUNDATION__
/*!
}
#endif // __COREFOUNDATION__
+/*!
+ * @define __os_unfair_unlock
+ * An attribute that may be applied to a variable's type. This attribute causes
+ * the variable to be passed to os_unfair_lock_unlock() when it goes out of
+ * scope. Applying this attribute to a variable which does not reference a valid
+ * os_unfair_lock_t object will result in undefined behavior. If the variable's
+ * value is NULL upon going out-of-scope, no cleanup is performed.
+ *
+ * This attribute is useful even when the target lock is taken conditionally via
+ * the following pattern:
+ *
+ * os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
+ * os_unfair_lock_t __os_unfair_unlock l2un = NULL;
+ *
+ * if (take_the_lock) {
+ * os_unfair_lock_lock(&lock);
+ *
+ * // Guarantee that 'lock' will be unconditionally released when the
+ * // scope containing 'l2un' ends.
+ * l2un = &lock;
+ * }
+ */
+#define __os_unfair_unlock __attribute__((cleanup(__os_cleanup_unfair_unlock)))
+static inline void
+__os_cleanup_unfair_unlock(void *__p)
+{
+ os_unfair_lock_t *tp = (os_unfair_lock_t *)__p;
+ os_unfair_lock_t ufl = *tp;
+ if (!ufl) {
+ return;
+ }
+ os_unfair_lock_assert_owner(ufl);
+ os_unfair_lock_unlock(ufl);
+}
+
#else // __has_attribute(cleanup)
-#define __os_free __attribute__((__os_not_supported))
-#define __os_close __attribute__((__os_not_supported))
-#define __os_fclose __attribute__((__os_not_supported))
-#define __os_close_mach_recv __attribute__((__os_not_supported))
-#define __os_release_mach_send __attribute__((__os_not_supported))
-#define __os_preserve_errno __attribute__((__os_not_supported))
-#define __os_release __attribute__((__os_not_supported))
-#define __os_cfrelease __attribute__((__os_not_supported))
+#define __os_cleanup_unsupported \
+ _Pragma("GCC error \"automatic cleanup not supported\"")
+#define __os_free __os_cleanup_unsupported
+#define __os_close __os_cleanup_unsupported
+#define __os_fclose __os_cleanup_unsupported
+#define __os_close_mach_recv __os_cleanup_unsupported
+#define __os_release_mach_send __os_cleanup_unsupported
+#define __os_preserve_errno __os_cleanup_unsupported
+#define __os_release __os_cleanup_unsupported
+#define __os_cfrelease __os_cleanup_unsupported
+#define __os_unfair_unlock __os_cleanup_unsupported
#endif // __has_attribute(cleanup)
__END_DECLS;
--- /dev/null
+/*
+ * Copyright (c) 2018 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*!
+ * @header
+ * Interfaces to implement subcommand-style command line utilities (e.g.
+ * launchctl(1)) and automatically generate usage output. The usage generated by
+ * these interfaces assumes a long option convention (cf. getopt_long(3)) and is
+ * loosely based on the docopt convention described at
+ *
+ * http://docopt.org
+ *
+ * The user may define each subcommand taken by the utility as:
+ *
+ * static const os_subcommand_t _foo_cmd = {
+ * .osc_version = OS_SUBCOMMAND_VERSION,
+ * .osc_flags = 0,
+ * .osc_name = "foo",
+ * .osc_desc = "does a foo",
+ * .osc_optstring = NULL,
+ * .osc_options = NULL,
+ * .osc_info = NULL,
+ * .osc_invoke = &_foo_invoke,
+ * };
+ * OS_SUBCOMMAND_REGISTER(_foo_cmd);
+ *
+ * static const os_subcommand_t _bar_cmd = {
+ * .osc_version = OS_SUBCOMMAND_VERSION,
+ * .osc_flags = 0,
+ * .osc_name = "bar",
+ * .osc_desc = "bars a foo",
+ * .osc_optstring = "x:q",
+ * .osc_options = _bar_opts,
+ * .osc_info = &_bar_optinfo,
+ * .osc_invoke = &_bar_invoke,
+ * };
+ * OS_SUBCOMMAND_REGISTER(_bar_cmd);
+ * };
+ *
+ * Where the "bar" subcommand's option information is returned by the routine:
+ *
+ * static void
+ * _bar_optinfo(const os_subcommand_t *osc,
+ * os_subcommand_optarg_format_t format, const struct option *opt,
+ * os_subcommand_option_t *scopt)
+ * {
+ * switch (format) {
+ * case OS_SUBCOMMAND_OPTARG_USAGE:
+ * switch (opt->val) {
+ * case 'x':
+ * scopt->osco_flags |= OS_SUBCOMMAND_OPTION_FLAG_OPTIONAL;
+ * scopt->osco_argdesc = "x-argument";
+ * break;
+ * case 'q':
+ * scopt->osco_argdesc = "q-argument";
+ * break;
+ * default:
+ * __builtin_unreachable();
+ * }
+ * break;
+ * case OS_SUBCOMMAND_OPTARG_HUMAN:
+ * switch (opt->val) {
+ * case 'x':
+ * scopt->osco_flags |= OS_SUBCOMMAND_OPTION_FLAG_OPTIONAL;
+ * scopt->osco_argdesc = "argument describing x";
+ * break;
+ * case 'q':
+ * scopt->osco_argdesc = "Lorem ipsum dolor sit amet, consectetur "
+ * "adipiscing elit. Nullam a maximus lectus. Curabitur ornare "
+ * "convallis turpis, in porttitor augue tempus laoreet. Maecenas "
+ * "auctor mauris tortor, et tempor libero maximus id. Donec ac "
+ * "nunc et elit sagittis commodo. Donec tincidunt libero vehicula "
+ * "ex eleifend sagittis. Suspendisse consectetur cursus elit. "
+ * "Proin neque metus, commodo id rhoncus eu, cursus hendrerit ex. "
+ * "Etiam in fringilla nulla, vitae mollis eros.";
+ * break;
+ * default:
+ * __builtin_unreachable();
+ * }
+ * break;
+ * }
+ * }
+ *
+ * When {@link os_subcommand_main} is called, the tool's "help" subcommand will
+ * display approximately the following:
+ *
+ * $ tool help
+ * usage: playground <subcommand> [...] | help [subcommand]
+ *
+ * subcommands:
+ * foo does a foo
+ * bar bars a foo
+ *
+ * $ tool help foo
+ * usage: tool foo
+ *
+ * $ tool help bar
+ * usage: tool bar [--xarg] --qarg[=q-argument]
+ * --xarg argument describing x
+ * --qarg[=q-argument] Lorem ipsum dolor sit amet, consectetur
+ * adipiscing elit. Nullam a maximus lectus.
+ * Curabitur ornare convallis turpis, in porttitor
+ * augue tempus laoreet. Maecenas auctor mauris
+ * tortor, et tempor libero maximus id. Donec ac
+ * nunc et elit sagittis commodo. Donec tincidunt
+ * libero vehicula ex eleifend sagittis. Suspendisse
+ * consectetur cursus elit. Proin neque metus,
+ * commodo id rhoncus eu, cursus hendrerit ex. Etiam
+ * in fringilla nulla, vitae mollis eros.
+ */
+#ifndef __DARWIN_CTL_H
+#define __DARWIN_CTL_H
+
+#include <os/base.h>
+#include <os/api.h>
+
+#if DARWIN_TAPI
+#define LINKER_SET_ENTRY(_x, _y)
+#else
+#include <os/linker_set.h>
+#endif
+
+#include <sys/cdefs.h>
+#include <stdio.h>
+#include <getopt.h>
+
+__BEGIN_DECLS;
+
+/*!
+ * @define OS_SUBCOMMAND_REGISTER
+ * Registers a {@link os_subcommand_t} with the runtime. Subcommands may only be
+ * declared as part of the main executable image -- subcommands declared in
+ * dynamic libraries or bundles will not be recognized.
+ */
+#define OS_SUBCOMMAND_REGISTER(_subcommand) \
+ LINKER_SET_ENTRY(__subcommands, _subcommand)
+
+/*!
+ * @typedef os_subcommand_t
+ * The formal type name for the _os_subcommand structure.
+ */
+DARWIN_API_AVAILABLE_20181020
+typedef struct _os_subcommand os_subcommand_t;
+
+/*!
+ * @const OS_SUBCOMMAND_OPTION_VERSION
+ * The maximum version of the {@link os_subcommand_option_t} structure supported
+ * by the implementation.
+ */
+#define OS_SUBCOMMAND_OPTION_VERSION ((os_struct_version_t)0)
+
+/*!
+ * @typedef os_subcommand_optarg_format_t
+ * A type describing a usage format for the argument taken by an option.
+ *
+ * @const OS_SUBCOMMAND_OPTION_USAGE
+ * The short-form name of the argument given to the option. For example, if the
+ * subcommand takes a "--file" option with a required argument, this might be
+ * "file-path" and will be displayed as
+ *
+ * --file=<file-path>
+ *
+ * @const OS_SUBCOMMAND_OPTION_HUMAN
+ * The long-form description of the argument given to the option. Extending the
+ * above example, this might be "The path to a file to take as input. This path
+ * must be absolute; relative paths are not supported." and will be displayed as
+ *
+ * --file The path to a file to take as input. This path must be
+ * absolute; relative paths are not supported.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_CLOSED_ENUM(os_subcommand_optarg_format, uint64_t,
+ OS_SUBCOMMAND_OPTARG_USAGE,
+ OS_SUBCOMMAND_OPTARG_HUMAN,
+);
+
+/*!
+ * @typedef os_subcommand_option_flags_t
+ * Flags describing an option for a subcommand.
+ *
+ * @const OS_SUBCOMMAND_OPTION_FLAG_INIT
+ * No flags set. This value is suitable for initialization purposes.
+ *
+ * @const OS_SUBCOMMAND_OPTION_FLAG_OPTIONAL
+ * The option does not need to be present in the subcommand invocation. By
+ * default, options are considered required.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_CLOSED_ENUM(os_subcommand_option_flags, uint64_t,
+ OS_SUBCOMMAND_OPTION_FLAG_INIT = 0,
+ OS_SUBCOMMAND_OPTION_FLAG_OPTIONAL = (1 << 0),
+);
+
+/*!
+ * @typedef os_subcommand_option_t
+ * A structure describing human-readable information about a particular option
+ * taken by a subcommand. This structure is to be returned when the
+ * implementation queries about a command's options individually. This is done
+ * when the implementation is synthesizing a usage string.
+ *
+ * @field osco_version
+ * The version of the structure. Initialize to
+ * {@link OS_SUBCOMMAND_OPTION_VERSION}.
+ *
+ * @field osco_flags
+ * On return from a {@link os_subcommand_option_info_t} function, a set of flags
+ * describing information about the option.
+ *
+ * @field osco_argdesc
+ * On return from a {@link os_subcommand_option_info_t} function, this should
+ * point to a constant string describing the argument to the option.
+ */
+DARWIN_API_AVAILABLE_20181020
+typedef struct _os_subcommand_option {
+ const os_struct_version_t osco_version;
+ os_subcommand_option_flags_t osco_flags;
+ const char *osco_argdesc;
+} os_subcommand_option_t;
+
+/*!
+ * @typedef os_subcommand_option_info_t
+ * A type describing a function which returns option information.
+ *
+ * @param osc
+ * The subcommand to which the option belongs.
+ *
+ * @param format
+ * The format of usage information required.
+ *
+ * @param opt
+ * A pointer to the option structure for which to retrieve information.
+ *
+ * @param scopt
+ * A pointer to a subcommand option structure to be populated with information
+ * pertaining to the option. When passed to the callee, this structure is zero-
+ * filled.
+ */
+DARWIN_API_AVAILABLE_20181020
+typedef void (*os_subcommand_option_info_t)(
+ const os_subcommand_t *osc,
+ os_subcommand_optarg_format_t format,
+ const struct option *opt,
+ os_subcommand_option_t *scopt);
+
+/*!
+ * @const OS_SUBCOMMAND_VERSION
+ * The maximum version of the {@link os_subcommand_t} structure supported by the
+ * implementation.
+ */
+#define OS_SUBCOMMAND_VERSION ((os_struct_version_t)0)
+
+/*!
+ * @enum os_subcommand_flags_t
+ * A type describing flags associated with a subcommand for a command line
+ * utility.
+ *
+ * @const OS_SUBCOMMAND_FLAG_INIT
+ * No flags set. This value is suitable for initialization purposes.
+ *
+ * @const OS_SUBCOMMAND_FLAG_REQUIRE_ROOT
+ * This subcommand requires the user to be root. If the user is not root, the
+ * {@link os_subcommand_dispatch} routine will return {@EX_PERM}.
+ *
+ * @const OS_SUBCOMMAND_FLAG_TTYONLY
+ * This subcommand may only be invoked via a terminal interface, i.e. it should
+ * not be invoked by scripts. Use this option to emphasize that a command's
+ * output is human-readably only and should not be parsed.
+ *
+ * @const OS_SUBCOMMAND_FLAG_HIDDEN
+ * This subcommand should not be displayed in the list of subcommands.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_CLOSED_OPTIONS(os_subcommand_flags, uint64_t,
+ OS_SUBCOMMAND_FLAG_INIT,
+ OS_SUBCOMMAND_FLAG_REQUIRE_ROOT = (1 << 0),
+ OS_SUBCOMMAND_FLAG_TTYONLY = (1 << 1),
+ OS_SUBCOMMAND_FLAG_HIDDEN = (1 << 2),
+);
+
+/*!
+ * @typedef os_subcommand_invoke_t
+ * An type describing the invocation function for a subcommand.
+ *
+ * @param osc
+ * The descriptor for the command being invoked.
+ *
+ * @param argc
+ * The argument vector count.
+ *
+ * @param argv
+ * The argument vector. The first element of this array is the name of the
+ * subcommand.
+ *
+ * @result
+ * An exit code, preferably from sysexits(3). Note that exit codes should not
+ * intersect with POSIX error codes from errno.h (cf. intro(2)).
+ *
+ * @discussion
+ * You may exit directly from within the routine if you wish.
+ */
+DARWIN_API_AVAILABLE_20181020
+typedef int (*os_subcommand_invoke_t)(
+ const os_subcommand_t *osc,
+ int argc,
+ const char *argv[]);
+
+/*!
+ * @struct os_subcommand_t
+ * A type describing a subcommand for a command line tool.
+ *
+ * @field osc_version
+ * The version of the structure. Initialize to {@link OS_SUBCOMMAND_VERSION}.
+ *
+ * @field osc_flags
+ * The flags for the subcommand.
+ *
+ * @field osc_name
+ * The name of the subcommand. The second argument of user input will be matched
+ * against this name.
+ *
+ * @field osc_desc
+ * A brief description of the subcommand. This description will be displayed
+ * next to the subcommand when the user lists all subcommands.
+ *
+ * @field osc_optstring
+ * The option string associated with the subcommand. The implementation does not
+ * recognize this string directly; the intent of storing it here is to provide a
+ * convenient place to access the string for the implementation function.
+ * Combined with the {@link osc_options} field, this enables the following
+ * pattern:
+ *
+ * int ch = 0;
+ * while ((ch = getopt_long(argc, argv, cmd->osc_optstring,
+ * cmd->osc_options, NULL)) != -1) {
+ * switch (ch) {
+ * // process option
+ * }
+ * }
+ *
+ * This pattern keeps the option string and option structs co-located in code.
+ *
+ * @field osc_options
+ * A pointer to an array of option structures describing the long options
+ * recognized by the subcommand (cf. getopt_long(3)).
+ *
+ * @field osc_info
+ * A pointer to a function which returns information about the subcommand's
+ * individual options.
+ *
+ * @field osc_invoke
+ * The implementation for the subcommand.
+ */
+DARWIN_API_AVAILABLE_20181020
+struct _os_subcommand {
+ const os_struct_version_t osc_version;
+ const os_subcommand_flags_t osc_flags;
+ const char *const osc_name;
+ const char *const osc_desc;
+ const char *osc_optstring;
+ const struct option *osc_options;
+ const os_subcommand_option_info_t osc_info;
+ const os_subcommand_invoke_t osc_invoke;
+};
+
+/*!
+ * @function os_subcommand_main
+ * Dispatches the subcommand appropriate for the given arguments. All
+ * subcommands will be implicitly discovered by virtue of their delcarations
+ * with the OS_SUBCOMMAND_REGISTER attribute.
+ *
+ * @param argc
+ * The argument count supplied to main().
+ *
+ * @param argv
+ * The argument vector supplied to main().
+ *
+ * @result
+ * The exit status from the subcommand's invocation function or an exit status
+ * from the implementation indicating that the subcommand could not be
+ * dispatched. Exit codes that can be returned by the implementation are:
+ *
+ * [EX_USAGE] The subcommand was invoked with improper syntax. Usage
+ * has been printed to stderr.
+ * [EX_USAGE] The subcommand specified is not recognized.
+ * [EX_PERM] The command required root privileges, and the caller is
+ * not running as root.
+ * [EX_UNAVAILABLE] The command specified that it may only run within
+ * the context of a tty(3), and either stdin or stdout are
+ * not a tty(3).
+ *
+ * @discussion
+ * In general, the code returned by this routine should immediately be passed to
+ * exit(3). The reason this routine does not implicitly exit is to allow for the
+ * caller to process multiple subcommand invocations as a batch.
+ *
+ * The caller should not print anything after this routine has returned -- the
+ * expectation is that all relevant information has already been conveyed to the
+ * user either by the implementation or from one of the subcommand invocation
+ * routines.
+ *
+ * This routine implicitly implements a "help" subcommand.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_EXPORT OS_WARN_RESULT OS_NONNULL2
+int
+os_subcommand_main(int argc, const char *argv[]);
+
+__END_DECLS;
+
+#endif // __DARWIN_CTL_H
* error code using {@link darwin_sysexit} and pass it to exit(3).
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_NORETURN OS_NONNULL2 OS_FORMAT_PRINTF(2, 3)
+OS_EXPORT OS_NORETURN OS_COLD OS_NONNULL2 OS_FORMAT_PRINTF(2, 3)
void
err_np(errno_t code, const char *fmt, ...);
* The arguments corresponding to the format string.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_NORETURN OS_NONNULL3 OS_FORMAT_PRINTF(3, 4)
+OS_EXPORT OS_NORETURN OS_COLD OS_NONNULL3 OS_FORMAT_PRINTF(3, 4)
void
errc_np(int eval, errno_t code, const char *fmt, ...);
* The arguments corresponding to the format string.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_NONNULL2 OS_FORMAT_PRINTF(2, 3)
+OS_EXPORT OS_COLD OS_NONNULL2 OS_FORMAT_PRINTF(2, 3)
void
warn_np(errno_t code, const char *fmt, ...);
* error code using {@link darwin_sysexit} and pass it to exit(3).
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_NORETURN OS_NONNULL2 OS_NONNULL3
+OS_EXPORT OS_NORETURN OS_COLD OS_NONNULL2 OS_NONNULL3
void
verr_np(errno_t code, const char *fmt, va_list ap);
* The argument pointer corresponding to the format string.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_NORETURN OS_NONNULL3 OS_NONNULL4
+OS_EXPORT OS_NORETURN OS_COLD OS_NONNULL3 OS_NONNULL4
void
verrc_np(int eval, errno_t code, const char *fmt, va_list ap);
* The arguments corresponding to the format string.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_NONNULL2 OS_NONNULL3
+OS_EXPORT OS_COLD OS_NONNULL2 OS_NONNULL3
void
vwarn_np(errno_t code, const char *fmt, va_list ap);
* required.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_WARN_RESULT OS_MALLOC OS_NONNULL1
+OS_EXPORT OS_COLD OS_WARN_RESULT OS_MALLOC OS_NONNULL1
char *
os_mach_msg_copy_description(const mach_msg_header_t *msg);
* required.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_WARN_RESULT OS_MALLOC OS_NONNULL1
+OS_EXPORT OS_COLD OS_WARN_RESULT OS_MALLOC OS_NONNULL1
char *
os_mach_msg_trailer_copy_description(const mach_msg_trailer_t *tlr);
* required.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_WARN_RESULT OS_MALLOC
+OS_EXPORT OS_COLD OS_WARN_RESULT OS_MALLOC
char *
os_mach_port_copy_description(mach_port_t port);
#include <os/base.h>
#include <os/api.h>
#include <sys/cdefs.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+// TAPI and the compiler don't agree about header search paths, so if TAPI found
+// our header in the SDK, help it out.
+#if DARWIN_TAPI && DARWIN_API_VERSION < 20180727
+#define DARWIN_API_AVAILABLE_20180727
+#endif
__BEGIN_DECLS;
+/*!
+ * @typedef os_fd_t
+ * A type alias for a file descriptor.
+ */
+typedef int os_fd_t;
+
+/*!
+ * @function os_fd_valid
+ * Returns whether the given integer is a valid file descriptor number.
+ *
+ * @param fd
+ * The integer to check.
+ *
+ * @result
+ * A Boolean indicating whether the integer is a valid file descriptor number,
+ * that is, greater than or equal to zero.
+ */
+DARWIN_API_AVAILABLE_20180727
+OS_ALWAYS_INLINE OS_WARN_RESULT
+static inline bool
+os_fd_valid(os_fd_t fd)
+{
+ return (fd >= STDIN_FILENO);
+}
+
+/*!
+ * @function fcheck_np
+ * Checks the status of an fread(3) or fwrite(3) operation to a FILE.
+ *
+ * @param f
+ * The file on which the operation was performed.
+ *
+ * @param n
+ * The return value of the operation.
+ *
+ * @param expected
+ * The expected return value of the operation.
+ *
+ * @result
+ * One of the following integers:
+ *
+ * 0 The operation succeeded
+ * EOF The operation encountered the end of the FILE stream before it
+ * could complete
+ * 1 There was an error
+ */
+DARWIN_API_AVAILABLE_20180727
+OS_EXPORT OS_WARN_RESULT OS_NONNULL1
+int
+fcheck_np(FILE *f, size_t n, size_t expected);
+
+/*!
+ * @function dup_np
+ * Variant of dup(2) that guarantees the dup(2) operation will either succeed or
+ * not return.
+ *
+ * @param fd
+ * The descriptor to dup(2).
+ *
+ * @result
+ * A new file descriptor number that is functionally equivalent to what the
+ * caller passed.
+ *
+ * @discussion
+ * The implementation will retry if the operation was interrupted by a signal.
+ * If the operation failed for any other reason, the implementation will
+ * terminate the caller.
+ */
+DARWIN_API_AVAILABLE_20180727
+OS_EXPORT OS_WARN_RESULT
+os_fd_t
+dup_np(os_fd_t fd);
+
/*!
* @function zsnprintf_np
* snprintf(3) variant which returns the numnber of bytes written less the null
size_t
zsnprintf_np(char *buff, size_t len, const char *fmt, ...);
+/*!
+ * @function crfprintf_np
+ * fprintf(3) variant that appends a new line character to the output.
+ *
+ * @param f
+ * The file to which the output should be written.
+ *
+ * @param fmt
+ * The printf(3)-like format string.
+ *
+ * @param ...
+ * The arguments corresponding to the format string.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_EXPORT OS_NONNULL1 OS_NONNULL2 OS_FORMAT_PRINTF(2, 3)
+void
+crfprintf_np(FILE *f, const char *fmt, ...);
+
+/*!
+ * @function vcrfprintf_np
+ * vfprintf(3) variant that appends a new line character to the output.
+ *
+ * @param f
+ * The file to which the output should be written.
+ *
+ * @param fmt
+ * The printf(3)-like format string.
+ *
+ * @param ap
+ * The argument list corresponding to the format string.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_EXPORT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3
+void
+vcrfprintf_np(FILE *f, const char *fmt, va_list ap);
+
+/*!
+ * @function wfprintf_np
+ * fprintf(3) variant which wraps the output to the specified column width,
+ * inserting new lines as necessary. Output will be word-wrapped with a trivial
+ * algorithm.
+ *
+ * @param f
+ * The file to which the output should be written.
+ *
+ * @param initpad
+ * The number of spaces that should be inserted prior to the first line of
+ * output. If a negative value is given, the implementation will assume that an
+ * amount of spaces equal to the absolute value of the parameter has already
+ * been written, and therefore it will only use the parameter to compute line-
+ * wrapping information and not insert any additional spaces on the first line
+ * of output.
+ *
+ * @param pad
+ * The number of spaces that should be inserted prior to every line of output
+ * except the first line.
+ *
+ * @param width
+ * The maximum number of columns of each line of output. Pass zero to indicate
+ * that there is no maximum.
+ *
+ * @param fmt
+ * The printf(3)-like format string.
+ *
+ * @param ...
+ * The arguments corresponding to the format string.
+ *
+ * @discussion
+ * This routine will silently fail to print to the desired output stream if
+ * there was a failure to allocate heap memory.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_EXPORT OS_NONNULL1 OS_NONNULL5 OS_NONNULL6
+void
+wfprintf_np(FILE *f, ssize_t initpad, size_t pad, size_t width,
+ const char *fmt, ...);
+
+/*!
+ * @function vwfprintf_np
+ * vfprintf(3) variant which wraps the output to the specified column width,
+ * inserting new lines as necessary. Output will be word-wrapped with a trivial
+ * algorithm.
+ *
+ * @param f
+ * The file to which the output should be written.
+ *
+ * @param initpad
+ * The number of spaces that should be inserted prior to the first line of
+ * output. If a negative value is given, the implementation will assume that an
+ * amount of spaces equal to the absolute value of the parameter has already
+ * been written, and therefore it will only use the parameter to compute line-
+ * wrapping information and not insert any additional spaces on the first line
+ * of output.
+ *
+ * @param pad
+ * The number of spaces that should be inserted prior to every line of output
+ * except the first line.
+ *
+ * @param width
+ * The maximum number of columns of each line of output. Pass zero to indicate
+ * that there is no maximum.
+ *
+ * @param fmt
+ * The printf(3)-like format string.
+ *
+ * @param ap
+ * The argument list corresponding to the format string.
+ *
+ * @discussion
+ * This routine will silently fail to print to the desired output stream if
+ * there was a failure to allocate heap memory.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_EXPORT OS_NONNULL1 OS_NONNULL5 OS_NONNULL6
+void
+vwfprintf_np(FILE *f, ssize_t initpad, size_t pad, size_t width,
+ const char *fmt, va_list ap);
+
__END_DECLS;
#endif // __DARWIN_STDIO_H
#include <os/base.h>
#include <os/api.h>
#include <os/assumes.h>
+#include <os/stdio.h>
#include <dispatch/private.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/cdefs.h>
+#include <sys/syslimits.h>
__BEGIN_DECLS;
return strdup(str);
}
+#define __os_requires_experimental_libtrace \
+ _Pragma("GCC error \"requires OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE\"")
+
/*!
* @function os_malloc
* Wrapper around malloc(3) which guarantees that the allocation succeeds.
* the size is not known at compile-time, the routine will retry until it is
* successful.
*/
+#if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE)
#define os_malloc(__size) ({ \
void *ptr = NULL; \
size_t _size = (__size); \
} \
(ptr); \
})
+#else
+#define os_malloc(__size) __os_requires_experimental_libtrace
+#endif
/*!
* @function os_calloc
* the size is not known at compile-time, the routine will retry until it is
* successful.
*/
+#if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE)
#define os_calloc(__cnt, __size) ({ \
void *ptr = NULL; \
size_t _size = (__size); \
} \
(ptr); \
})
+#else
+#define os_calloc(__size) __os_requires_experimental_libtrace
+#endif
/*!
* @function os_strdup
* stdlib.h header because its semantic changes are solely related to the manner
* in which memory is allocated.
*/
+#if defined(OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE)
#define os_strdup(__str) ({ \
char *ptr = NULL; \
const char *_str = (__str); \
} \
(ptr); \
})
+#else
+#define os_strdup(__size) __os_requires_experimental_libtrace
+#endif
/*!
* @function os_localtime_file
DARWIN_API_AVAILABLE_20170407
OS_EXPORT
void
-os_localtime_file(char buff[32]);
+os_localtime_file(char buff[static 32]);
/*!
* @function os_simple_hash
* @discussion
* This routine is meant to be used as a simple way to obtain a value that can
* be used to choose a bucket in a simple hash table. Do not attach security
- * assumptions to the output of this routine. Do not assume thst the computed
+ * assumptions to the output of this routine. Do not assume that the computed
* hash is stable between hosts, OS versions, or boot sessions.
*/
DARWIN_API_AVAILABLE_20170407
uint64_t
os_simple_hash(const void *buff, size_t len);
+/*!
+ * @function os_simple_hash_with_seed
+ * A seeded variant of os_simple_hash.
+ *
+ * @param buff
+ * A pointer to the buffer to hash.
+ *
+ * @param len
+ * The length of the buffer.
+ *
+ * @param seed
+ * The seed value for the hash.
+ *
+ * @result
+ * The hashed value of the input.
+ *
+ * @discussion
+ * Usually, hashing the same buffer with different seeds will produce
+ * different hash values.
+ * All the same considerations of {@link os_simple_hash} apply.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_EXPORT OS_NONNULL1
+uint64_t
+os_simple_hash_with_seed(const void *buff, size_t len, uint64_t seed);
+
/*!
* @function os_simple_hash_string
* An implementation of a simple non-cryptographic hashing algorithm.
* @discussion
* This routine is the moral equivalent of a call to
*
- * os_simple_hash(buff, strlen(buff));
+ * os_simple_hash(buff, strlen(buff));
*
* All the same considerations of {@link os_simple_hash} apply.
*/
uint64_t
os_simple_hash_string(const char *string);
+/*!
+ * @function os_simple_hash_string_with_seed
+ * A seeded variant of os_simple_hash_string.
+ *
+ * @param string
+ * A pointer to the null-terminated string to hash.
+ *
+ * @result
+ * The hashed value of the input.
+ *
+ * @discussion
+ * Usually, hashing the same string with different seeds will produce
+ * different hash values.
+ * All the same considerations of {@link os_simple_hash_string} apply.
+ */
+DARWIN_API_AVAILABLE_20181020
+OS_EXPORT OS_NONNULL1
+uint64_t
+os_simple_hash_string_with_seed(const char *string, uint64_t seed);
+
+/*!
+ * @function realpath_np
+ * Obtains a fully-resolved representation of the path to the file represented
+ * by the given descriptor.
+ *
+ * @param fd
+ * The file descriptor whose path is to be obtained.
+ *
+ * @param buff
+ * The buffer in which to write the path.
+ *
+ * @result
+ * On success, zero is returned. Otherwise, the implementation may return any
+ * error that can be returned by fcntl(2).
+ */
+DARWIN_API_AVAILABLE_20180727
+OS_EXPORT OS_WARN_RESULT
+errno_t
+realpath_np(os_fd_t fd, char buff[static PATH_MAX]);
+
__END_DECLS;
#endif // __DARWIN_STDLIB_H
* is given, this is equivalent to a call to strerror(3).
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_WARN_RESULT OS_PURE
+OS_EXPORT OS_COLD OS_WARN_RESULT OS_PURE
const char *
strerror_np(int code);
* string "EPERM" is returned.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_WARN_RESULT OS_PURE
+OS_EXPORT OS_COLD OS_WARN_RESULT OS_PURE
const char *
symerror_np(int code);
* exit code.
*/
DARWIN_API_AVAILABLE_20170407
-OS_EXPORT OS_WARN_RESULT OS_PURE
+OS_EXPORT OS_COLD OS_WARN_RESULT OS_PURE
const char *
symexit_np(int code);
#include <mach/message.h>
#include <mach/host_priv.h>
#include <mach/host_reboot.h>
+#include <mach/kern_return.h>
#include <sys/sysctl.h>
#include <sys/reboot.h>
#include <sys/paths.h>
#include <sys/spawn.h>
#include <sys/proc_info.h>
+#include <crt_externs.h>
#define OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE 1
#include <os/assumes.h>
#include <bootstrap_priv.h>
#include <assert.h>
-#define RDAR_12809455 1
-
#include "h/bsd.h"
#include "h/cleanup.h"
+#include "h/ctl.h"
#include "h/err.h"
#include "h/errno.h"
#include "h/mach_exception.h"
#include "h/string.h"
#if DARWIN_TAPI
+#undef os_assert_mach
+#undef os_assert_mach_port_status
+
// Duplicate declarations to make TAPI happy. This header is included in the
// TAPI build as an extra public header.
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
OS_EXPORT OS_NONNULL1
void
-os_assert_mach(const char *op, kern_return_t kr);
+(os_assert_mach)(const char *op, kern_return_t kr);
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
OS_EXPORT
// libsystem_darwin. The long-term plan is to move assumes() and assert()
// functionality into libdarwin anyway.
void
-os_assert_mach(const char *op, kern_return_t kr)
+(os_assert_mach)(const char *op, kern_return_t kr)
{
kern_return_t real_kr = (kern_return_t)(kr & (~MACH_MSG_MASK));
kern_return_t extra = (kern_return_t)(kr & MACH_MSG_MASK);
#include "internal.h"
#pragma mark API
+int
+fcheck_np(FILE *f, size_t n, size_t expected)
+{
+ if (n == expected) {
+ return 0;
+ }
+ if (feof(f)) {
+ return EOF;
+ }
+ if (ferror(f)) {
+ return 1;
+ }
+ __builtin_unreachable();
+}
+
+os_fd_t
+dup_np(os_fd_t fd)
+{
+ os_fd_t dfd = -1;
+
+ while (true) {
+ dfd = dup(fd);
+
+ if (os_fd_valid(dfd)) {
+ break;
+ }
+
+ switch (errno) {
+ case EINTR:
+ break;
+ case EBADF:
+ os_crash("bad fd");
+ case EMFILE:
+ case ENFILE:
+ os_crash("failed to dup fd");
+ default:
+ os_crash("unhandled error: %s", symerror_np(errno));
+ }
+ }
+
+ return dfd;
+}
+
size_t
zsnprintf_np(char *buff, size_t len, const char *fmt, ...)
{
return (size_t)np;
}
+
+void
+crfprintf_np(FILE *f, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vcrfprintf_np(f, fmt, ap);
+ va_end(ap);
+}
+
+void
+vcrfprintf_np(FILE *f, const char *fmt, va_list ap)
+{
+ vfprintf(f, fmt, ap);
+ fprintf(f, "\n");
+}
+
+void
+wfprintf_np(FILE *f, ssize_t initpad, size_t pad, size_t width,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwfprintf_np(f, initpad, pad, width, fmt, ap);
+ va_end(ap);
+}
+
+void
+vwfprintf_np(FILE *f, ssize_t initpad, size_t pad, size_t width,
+ const char *fmt, va_list ap)
+{
+ char *__os_free string = NULL;
+ char *__os_free working = NULL;
+ char *__os_free init_padding = NULL;
+ char *__os_free padding = NULL;
+ const char *curline = NULL;;
+ size_t left = 0;
+ size_t initpad_labs = (size_t)labs(initpad);
+ int ret = -1;
+
+ if (width && width <= pad) {
+ os_crash("width cannot be smaller than pad");
+ }
+ if (width && (initpad > 0) && width <= initpad_labs) {
+ os_crash("width cannot be smaller than initpad");
+ }
+ if (width && (initpad < 0) && width <= initpad_labs) {
+ os_crash("width cannot be smaller than negative initpad");
+ }
+
+ ret = vasprintf(&string, fmt, ap);
+ if (ret < 0 || !string) {
+ return;
+ }
+
+ left = (size_t)ret;
+ curline = string;
+
+ // The working buffer will always be large enough to handle any individual
+ // line. vasprintf(3) returns the number of characters printed not including
+ // the null terminator, so add space for that.
+ working = malloc(left + 1);
+ if (!working) {
+ return;
+ }
+
+ init_padding = malloc(initpad_labs + 1);
+ if (!init_padding) {
+ return;
+ }
+
+ if (initpad >= 0) {
+ memset(init_padding, ' ', initpad);
+ init_padding[initpad] = 0;
+ } else {
+ init_padding[0] = 0;
+ }
+
+ padding = malloc(pad + 1);
+ if (!padding) {
+ return;
+ }
+
+ memset(padding, ' ', pad);
+ padding[pad] = 0;
+
+ do {
+ size_t which_pad = pad;
+ char *which_padding = padding;
+ bool findspace = true;
+ size_t n2consume = 0;
+ char *breakchar = NULL;
+
+ if (curline == string) {
+ which_padding = init_padding;
+ which_pad = initpad_labs;
+ }
+
+ if (width == 0) {
+ // Width is unconstrained so just consume the entire string and
+ // indent any new lines within.
+ n2consume = left;
+ findspace = false;
+ } else {
+ n2consume = width - which_pad;
+ if (n2consume >= left) {
+ n2consume = left;
+ findspace = false;
+ }
+ }
+
+ strlcpy(working, curline, n2consume + 1);
+ breakchar = strchr(working, '\n');
+ if (!breakchar && findspace) {
+ // No new line within our maximally-constrained width of characters,
+ // so search for a space instead.
+ breakchar = strrchr(working, ' ');
+ }
+
+ if (breakchar) {
+ // Found something to break on, so nerf it and only consume the
+ // characters up until that break character.
+ *breakchar = 0;
+ n2consume = (size_t)(breakchar - working);
+ curline += n2consume + 1;
+ }
+
+ fprintf(f, "%s%s\n", which_padding, working);
+ left -= n2consume;
+ } while (left);
+}
#pragma mark API
void
-os_localtime_file(char buff[32])
+os_localtime_file(char buff[static 32])
{
struct timeval tv;
struct tm curtime;
// MurmurHash2 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
uint64_t
-os_simple_hash(const void *buff, size_t len)
+os_simple_hash_with_seed(const void *buff, size_t len, uint64_t seed)
{
- const uint64_t seed = 0;
#ifdef __LP64__
// MurmurHash64A
const uint64_t m = 0xc6a4a7935bd1e995;
}
uint64_t
-os_simple_hash_string(const char *string)
+os_simple_hash(const void *buff, size_t len)
+{
+ return os_simple_hash_with_seed(buff, len, 0);
+}
+
+uint64_t
+os_simple_hash_string_with_seed(const char *string, uint64_t seed)
{
size_t len = strlen(string);
- return os_simple_hash(string, len);
+ return os_simple_hash_with_seed(string, len, seed);
+}
+
+uint64_t
+os_simple_hash_string(const char *string)
+{
+ return os_simple_hash_string_with_seed(string, 0);
+}
+
+errno_t
+realpath_np(os_fd_t fd, char buff[static PATH_MAX])
+{
+ errno_t error = -1;
+ int ret = -1;
+
+ ret = fcntl(fd, F_GETPATH, buff);
+ if (ret) {
+ error = errno;
+ } else {
+ error = 0;
+ }
+
+ return error;
}
#include <System/machine/cpu_capabilities.h>
#include <os/assumes.h>
+#include <os/bsd.h>
#include <os/stdlib.h>
#include <os/variant_private.h>
S_YES = 3
};
+typedef struct {
+ const char *variant;
+ bool (*function)(const char*);
+} variant_check_mapping;
+
static bool
status2bool(enum check_status status) {
switch (status) {
return false;
case S_YES:
return true;
+ case S_UNKNOWN:
default:
os_crash("os_variant had unexpected status");
}
#else
#define INTERNAL_DIAGS_PROFILE_PATH "/var/db/ConfigurationProfiles/Settings/com.apple.InternalDiagnostics.plist"
#define FACTORY_CONTENT_PATH "/System/Library/CoreServices/AppleFactoryVariant.plist"
+#define BASE_SYSTEM_CONTENT_PATH "/System/Library/BaseSystem"
#endif
#if !TARGET_OS_SIMULATOR
#if TARGET_OS_IPHONE
static enum check_status internal_release_type = S_UNKNOWN;
static enum check_status factory_release_type = S_UNKNOWN;
+static enum check_status darwin_release_type = S_UNKNOWN;
+static enum check_status recovery_release_type = S_UNKNOWN;
+static enum check_status development_kernel = S_UNKNOWN;
#else // TARGET_OS_IPHONE
static enum check_status internal_diags_profile = S_UNKNOWN;
static enum check_status factory_content = S_UNKNOWN;
+static enum check_status base_system_content = S_UNKNOWN;
#endif // TARGET_OS_IPHONE
#endif // !TARGET_OS_SIMULATOR
+static enum check_status is_ephemeral = S_UNKNOWN;
static bool disabled_status[VP_MAX] = {};
*/
internal_release_type = S_NO;
factory_release_type = S_NO;
- } else if (strcmp(release_type, "Internal") == 0 ||
- strcmp(release_type, "Lite Internal") == 0) {
- internal_release_type = S_YES;
- factory_release_type = S_NO;
+ darwin_release_type = S_NO;
+ recovery_release_type = S_NO;
} else if (strcmp(release_type, "NonUI") == 0) {
- internal_release_type = S_YES;
factory_release_type = S_YES;
+ internal_release_type = S_YES;
+ darwin_release_type = S_NO;
+ recovery_release_type = S_NO;
} else {
- internal_release_type = S_NO;
factory_release_type = S_NO;
+ internal_release_type = (strstr(release_type, "Internal") != NULL) ? S_YES : S_NO;
+ darwin_release_type = (strstr(release_type, "Darwin") != NULL) ? S_YES : S_NO;
+ recovery_release_type = (strstr(release_type, "Recovery") != NULL) ? S_YES : S_NO;
}
xpc_release(system_version_plist);
#endif // TARGET_OS_SIMULATOR
}
-#else
+static bool _check_darwin_release_type(void)
+{
+#if TARGET_OS_SIMULATOR
+ return false;
+#else // TARGET_OS_SIMULATOR
+ if (darwin_release_type == S_UNKNOWN) {
+ if (!_parse_system_version_plist()) {
+ darwin_release_type = S_NO;
+ }
+ }
+
+ return status2bool(darwin_release_type);
+#endif // TARGET_OS_SIMULATOR
+}
+
+static bool _check_recovery_release_type(void)
+{
+#if TARGET_OS_SIMULATOR
+ return false;
+#else // TARGET_OS_SIMULATOR
+ if (recovery_release_type == S_UNKNOWN) {
+ if (!_parse_system_version_plist()) {
+ recovery_release_type = S_NO;
+ }
+ }
+
+ return status2bool(recovery_release_type);
+#endif // TARGET_OS_SIMULATOR
+}
+
+#else // TARGET_OS_IPHONE
static bool _check_internal_diags_profile(void)
{
return status2bool(internal_diags_profile);
}
+static bool _check_base_system_content(void)
+{
+ if (base_system_content == S_UNKNOWN) {
+ const char * path = BASE_SYSTEM_CONTENT_PATH;
+ base_system_content = (access(path, F_OK) == 0) ? S_YES : S_NO;
+ }
+ return status2bool(base_system_content);
+}
+
#endif
+#if !TARGET_OS_SIMULATOR
static bool _check_can_has_debugger(void)
{
-#if TARGET_OS_SIMULATOR
- return _check_internal_content();
-#else
if (can_has_debugger == S_UNKNOWN) {
#if TARGET_OS_IPHONE
can_has_debugger = *((uint32_t *)_COMM_PAGE_DEV_FIRM) ? S_YES : S_NO;
#endif
}
return status2bool(can_has_debugger);
-#endif // TARGET_OS_SIMULATOR
}
+#endif // !TARGET_OS_SIMULATOR
+
+#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
+static bool _check_development_kernel(void)
+{
+ if (development_kernel == S_UNKNOWN) {
+ /*
+ * Whitelist values from SUPPORTED_KERNEL_CONFIGS.
+ */
+ char *osbuildconfig = NULL;
+ size_t osbuildconfig_sz = 0;
+ errno_t err = sysctlbyname_get_data_np("kern.osbuildconfig", (void **)&osbuildconfig, &osbuildconfig_sz);
+ if (err == 0) {
+ if (strcmp(osbuildconfig, "development") == 0 ||
+ strcmp(osbuildconfig, "debug") == 0 ||
+ strcmp(osbuildconfig, "profile") == 0 ||
+ strcmp(osbuildconfig, "kasan") == 0) {
+ development_kernel = S_YES;
+ }
+ }
+ free(osbuildconfig);
+
+ if (development_kernel == S_UNKNOWN) {
+ development_kernel = S_NO;
+ }
+ }
+ return status2bool(development_kernel);
+}
+#endif // TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
// For unit tests
#ifndef VARIANT_SKIP_EXPORTED
return false;
}
+#if TARGET_OS_SIMULATOR
+ return _check_internal_content();
+#elif TARGET_OS_IPHONE
+ return _check_can_has_debugger() || _check_development_kernel();
+#else
return _check_can_has_debugger();
+#endif
}
bool
#endif
}
+bool
+os_variant_is_darwinos(const char * __unused subsystem)
+{
+
+#if TARGET_OS_IPHONE
+ return _check_darwin_release_type();
+#else
+ return false;
+#endif
+}
+
+bool
+os_variant_is_recovery(const char * __unused subsystem)
+{
+#if TARGET_OS_IPHONE
+ return _check_recovery_release_type();
+#else
+ return _check_base_system_content();
+#endif
+}
+
+bool
+os_variant_uses_ephemeral_storage(const char * __unused subsystem)
+{
+ if (is_ephemeral == S_UNKNOWN) {
+ uint32_t buffer = 0;
+ size_t buffer_size = sizeof(buffer);
+
+ sysctlbyname("hw.ephemeral_storage", (void *)&buffer, &buffer_size, NULL, 0);
+
+ is_ephemeral = (buffer != 0) ? S_YES : S_NO;
+ }
+
+ return status2bool(is_ephemeral);
+}
+
+bool
+os_variant_check(const char * __unused subsystem, const char *variant)
+{
+ static const variant_check_mapping map[] = {
+ {.variant = "HasInternalContent", .function = os_variant_has_internal_content},
+ {.variant = "HasInternalDiagnostics", .function = os_variant_has_internal_diagnostics},
+ {.variant = "HasInternalUI", .function = os_variant_has_internal_ui},
+ {.variant = "AllowsInternalSecurityPolicies", .function = os_variant_allows_internal_security_policies},
+ {.variant = "HasFactoryContent", .function = os_variant_has_factory_content},
+ {.variant = "IsDarwinOS", .function = os_variant_is_darwinos},
+ {.variant = "UsesEphemeralStorage", .function = os_variant_uses_ephemeral_storage},
+ {.variant = "IsRecovery", .function = os_variant_is_recovery},
+ {.variant = NULL, .function = NULL}
+ };
+ variant_check_mapping *current = (variant_check_mapping *)map;
+
+ while (current->variant) {
+ if (0 == strncasecmp(current->variant, variant, strlen(current->variant))) {
+ return current->function("");
+ }
+ current ++;
+ }
+
+ return false;
+}
+
#endif // VARIANT_SKIP_EXPORTED
#define STATUS_INITIAL_BITS 0x70000000F0000000ULL
SFP_INTERNAL_DIAGS_PROFILE = 3,
SFP_FACTORY_CONTENT = 4,
SFP_FACTORY_RELEASE_TYPE = 5,
+ SFP_DARWINOS_RELEASE_TYPE = 6,
+ SFP_EPHEMERAL_VOLUME = 7,
+ SFP_RECOVERY_RELEASE_TYPE = 8,
+ SFP_BASE_SYSTEM_CONTENT = 9,
+ SFP_DEVELOPMENT_KERNEL = 10,
};
#if !TARGET_OS_SIMULATOR
if (can_has_debugger != S_UNKNOWN)
res |= can_has_debugger << SFP_CAN_HAS_DEBUGGER * STATUS_BIT_WIDTH;
+ (void)os_variant_uses_ephemeral_storage("");
+ if (is_ephemeral != S_UNKNOWN)
+ res |= is_ephemeral << SFP_EPHEMERAL_VOLUME * STATUS_BIT_WIDTH;
+
#if TARGET_OS_IPHONE
_check_internal_release_type();
if (internal_release_type != S_UNKNOWN)
_check_factory_release_type();
if (factory_release_type != S_UNKNOWN)
res |= factory_release_type << SFP_FACTORY_RELEASE_TYPE * STATUS_BIT_WIDTH;
+
+ _check_darwin_release_type();
+ if (darwin_release_type != S_UNKNOWN)
+ res |= darwin_release_type << SFP_DARWINOS_RELEASE_TYPE * STATUS_BIT_WIDTH;
+
+ _check_recovery_release_type();
+ if (recovery_release_type != S_UNKNOWN)
+ res |= recovery_release_type << SFP_RECOVERY_RELEASE_TYPE * STATUS_BIT_WIDTH;
+
+ _check_development_kernel();
+ if (development_kernel != S_UNKNOWN)
+ res |= development_kernel << SFP_DEVELOPMENT_KERNEL * STATUS_BIT_WIDTH;
#else
_check_internal_diags_profile();
if (internal_diags_profile != S_UNKNOWN)
_check_factory_content();
if (factory_content != S_UNKNOWN)
res |= factory_content << SFP_FACTORY_CONTENT * STATUS_BIT_WIDTH;
+
+ _check_base_system_content();
+ if (base_system_content != S_UNKNOWN)
+ res |= base_system_content << SFP_BASE_SYSTEM_CONTENT * STATUS_BIT_WIDTH;
#endif
_parse_disabled_status(NULL);
if ((status >> (SFP_CAN_HAS_DEBUGGER * STATUS_BIT_WIDTH)) & STATUS_SET)
can_has_debugger = (status >> (SFP_CAN_HAS_DEBUGGER * STATUS_BIT_WIDTH)) & STATUS_MASK;
+ if ((status >> (SFP_EPHEMERAL_VOLUME * STATUS_BIT_WIDTH)) & STATUS_SET)
+ is_ephemeral = (status >> (SFP_EPHEMERAL_VOLUME * STATUS_BIT_WIDTH)) & STATUS_MASK;
+
#if TARGET_OS_IPHONE
if ((status >> (SFP_INTERNAL_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_SET)
internal_release_type = (status >> (SFP_INTERNAL_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_MASK;
if ((status >> (SFP_FACTORY_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_SET)
factory_release_type = (status >> (SFP_FACTORY_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_MASK;
+
+ if ((status >> (SFP_DARWINOS_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_SET)
+ darwin_release_type = (status >> (SFP_DARWINOS_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_MASK;
+
+ if ((status >> (SFP_RECOVERY_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_SET)
+ recovery_release_type = (status >> (SFP_RECOVERY_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_MASK;
+
+ if ((status >> (SFP_DEVELOPMENT_KERNEL * STATUS_BIT_WIDTH)) & STATUS_SET)
+ development_kernel = (status >> (SFP_DEVELOPMENT_KERNEL * STATUS_BIT_WIDTH)) & STATUS_MASK;
#else
if ((status >> (SFP_INTERNAL_DIAGS_PROFILE * STATUS_BIT_WIDTH)) & STATUS_SET)
internal_diags_profile = (status >> (SFP_INTERNAL_DIAGS_PROFILE * STATUS_BIT_WIDTH)) & STATUS_MASK;
if ((status >> (SFP_FACTORY_CONTENT * STATUS_BIT_WIDTH)) & STATUS_SET)
factory_content = (status >> (SFP_FACTORY_CONTENT * STATUS_BIT_WIDTH)) & STATUS_MASK;
+
+ if ((status >> (SFP_BASE_SYSTEM_CONTENT * STATUS_BIT_WIDTH)) & STATUS_SET)
+ base_system_content = (status >> (SFP_BASE_SYSTEM_CONTENT * STATUS_BIT_WIDTH)) & STATUS_MASK;
#endif
for (int i = 0; i < VP_MAX; i++) {
.Vt locale_t
value that corresponds to the global, process-wide locale.
.It
+LC_C_LOCALE - A special
+.Vt locale_t
+value that corresponds to the C, system locale.
+.It
MB_CUR_MAX - This macro is traditionally defined as an integer
containing the value of the longest multi-byte string
that a single-wide character in the global locale can translate into.
(x) = &__global_locale; \
}
-#define NORMALIZE_LOCALE(x) if ((x) == NULL) { \
+#define NORMALIZE_LOCALE(x) if ((x) == LC_C_LOCALE) { \
(x) = _c_locale; \
} else if ((x) == LC_GLOBAL_LOCALE) { \
(x) = &__global_locale; \
times.3 times.3
timezone.3 timezone.3
timingsafe_bcmp.3 timingsafe_bcmp.3
+timespec_get.3 timespec_get.3
tmpnam.3 tmpnam.3 tempnam.3 tmpfile.3
toascii.3 toascii.3
tolower.3 tolower.3 tolower_l.3
*
* @APPLE_LICENSE_HEADER_END@
*/
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
-#include <sys/types.h>
-#include <netinet/in.h>
#include <arpa/inet.h>
-#include <stdio.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <netinet/in.h>
#include <stdint.h>
+#include <stdio.h>
#include <string.h>
-#include <errno.h>
#include <sys/socket.h>
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wcomma"
-#pragma clang diagnostic ignored "-Wint-conversion"
+#include <sys/types.h>
#define MAX_V4_ADDR_LEN 16
-#define MAX_V6_ADDR_LEN 64
-
-static const char *hexchars = "0123456789abcdef";
const char * inet_ntop6(const struct in6_addr *addr, char *dst, socklen_t size);
const char * inet_ntop4(const struct in_addr *addr, char *dst, socklen_t size);
const char *
inet_ntop(int af, const void *addr, char *buf, socklen_t len)
{
- if (af == AF_INET6) return inet_ntop6(addr, buf, len);
- if (af == AF_INET) return inet_ntop4(addr, buf, len);
+ if (addr && af == AF_INET6) return inet_ntop6(addr, buf, len);
+ if (addr && af == AF_INET) return inet_ntop4(addr, buf, len);
errno = EAFNOSUPPORT;
return NULL;
}
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
const char *
inet_ntop6(const struct in6_addr *addr, char *dst, socklen_t size)
{
- char hexa[8][5], tmp[MAX_V6_ADDR_LEN];
- int zr[8];
- socklen_t len;
- int32_t i, j, k, skip;
- uint8_t x8, hx8;
- uint16_t x16;
- struct in_addr a4;
-
- if (addr == NULL)
- {
- errno = EAFNOSUPPORT;
- return NULL;
- }
-
- if (dst == NULL)
- {
- errno = ENOSPC;
- return NULL;
- }
-
- memset(tmp, 0, MAX_V6_ADDR_LEN);
-
- /* check for mapped or compat addresses */
- i = IN6_IS_ADDR_V4MAPPED(addr);
- j = IN6_IS_ADDR_V4COMPAT(addr);
- if ((i != 0) || (j != 0))
- {
- const char *prefix;
- socklen_t prefix_len;
- if (i != 0) {
- prefix = "::ffff:";
- prefix_len = 7;
+ const u_char *src = addr->__u6_addr.__u6_addr8;
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < NS_IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ best.len = 0;
+ cur.base = -1;
+ cur.len = 0;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1) {
+ cur.base = i;
+ cur.len = 1;
+ } else {
+ cur.len++;
+ }
} else {
- prefix = "::";
- prefix_len = 2;
- }
- a4.s_addr = addr->__u6_addr.__u6_addr32[3];
- inet_ntop4(&a4, tmp, sizeof(tmp));
- len = strlen(tmp) + 1;
- if (prefix_len + len > size)
- {
- errno = ENOSPC;
- return NULL;
- }
-
- memcpy(dst, prefix, prefix_len);
- memcpy(dst + prefix_len, tmp, len);
- return dst;
- }
-
- k = 0;
- for (i = 0; i < 16; i += 2)
- {
- j = 0;
- skip = 1;
-
- memset(hexa[k], 0, 5);
-
- x8 = addr->__u6_addr.__u6_addr8[i];
-
- hx8 = x8 >> 4;
- if (hx8 != 0)
- {
- skip = 0;
- hexa[k][j++] = hexchars[hx8];
- }
-
- hx8 = x8 & 0x0f;
- if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
- {
- skip = 0;
- hexa[k][j++] = hexchars[hx8];
- }
-
- x8 = addr->__u6_addr.__u6_addr8[i + 1];
-
- hx8 = x8 >> 4;
- if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
- {
- hexa[k][j++] = hexchars[hx8];
- }
-
- hx8 = x8 & 0x0f;
- hexa[k][j++] = hexchars[hx8];
-
- k++;
- }
-
- /* find runs of zeros for :: convention */
- j = 0;
- for (i = 7; i >= 0; i--)
- {
- zr[i] = j;
- x16 = addr->__u6_addr.__u6_addr16[i];
- if (x16 == 0) j++;
- else j = 0;
- zr[i] = j;
- }
-
- /* find longest run of zeros */
- k = -1;
- j = 0;
- for(i = 0; i < 8; i++)
- {
- if (zr[i] > j)
- {
- k = i;
- j = zr[i];
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
}
}
-
- for(i = 0; i < 8; i++)
- {
- if (i != k) zr[i] = 0;
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
}
-
- len = 0;
- for (i = 0; i < 8; i++)
- {
- if (zr[i] != 0)
- {
- /* check for leading zero */
- if (i == 0) tmp[len++] = ':';
- tmp[len++] = ':';
- i += (zr[i] - 1);
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
continue;
}
- for (j = 0; hexa[i][j] != '\0'; j++) tmp[len++] = hexa[i][j];
- if (i != 7) tmp[len++] = ':';
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 && (best.len == 6 ||
+ (best.len == 7 && words[7] != 0x0001) ||
+ (best.len == 5 && words[5] == 0xffff))) {
+ struct in_addr ipv4_addr;
+ memcpy(&ipv4_addr, src+12, sizeof(ipv4_addr));
+ if (!inet_ntop4(&ipv4_addr, tp, (socklen_t)sizeof(tmp) - (socklen_t)(tp - tmp))) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ tp += strlen(tp);
+ break;
+ }
+ tp += sprintf(tp, "%x", words[i]);
}
-
- /* trailing NULL */
- len++;
-
- if (len > size)
- {
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) ==
+ (NS_IN6ADDRSZ / NS_INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((socklen_t)(tp - tmp) > size) {
errno = ENOSPC;
- return NULL;
+ return (NULL);
}
-
- memcpy(dst, tmp, len);
- return dst;
+ strcpy(dst, tmp);
+ return (dst);
}
const char *
{
char tmp[MAX_V4_ADDR_LEN], *p;
const u_int8_t *ap = (u_int8_t *)&addr->s_addr;
- int i, ql, len;
+ int i;
+ size_t ql, len;
- if (addr == NULL)
- {
+ if (addr == NULL) {
errno = EAFNOSUPPORT;
return NULL;
}
- if (dst == NULL)
- {
+ if (dst == NULL) {
errno = ENOSPC;
return NULL;
}
p = tmp;
- for (i = 0; i < 4; i++, ap++)
- {
+ for (i = 0; i < 4; i++, ap++) {
snprintf(p, 4, "%d", *ap);
ql = strlen(p);
len += ql;
if (i < 3) *p++ = '.';
}
- if (len > size)
- {
+ if (len > size) {
errno = ENOSPC;
return NULL;
}
memcpy(dst, tmp, len);
return dst;
}
-#pragma clang diagnostic pop
#define __DARWIN_API_H
#include <os/availability.h>
+#include <stdint.h>
/*!
* @const DARWIN_API_VERSION
* individual preprocessor macros in this header that declare new behavior as
* required.
*/
-#define DARWIN_API_VERSION 20170407lu
+#define DARWIN_API_VERSION 20181020u
+#if !DARWIN_BUILDING_LIBSYSTEM_DARWIN
#define DARWIN_API_AVAILABLE_20170407 \
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
+#define DARWIN_API_AVAILABLE_20180727 \
+ API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0), watchos(6.0))
+#define DARWIN_API_AVAILABLE_20181020 \
+ API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0), watchos(6.0))
+#else
+#define DARWIN_API_AVAILABLE_20170407
+#define DARWIN_API_AVAILABLE_20180727
+#define DARWIN_API_AVAILABLE_20181020
+#endif
+
+/*!
+ * @typedef os_struct_magic_t
+ * A type representing the magic number of a transparent structure.
+ */
+typedef uint32_t os_struct_magic_t;
+
+/*!
+ * @typedef os_struct_version_t
+ * A type representing the version of a transparent structure.
+ */
+typedef uint32_t os_struct_version_t;
#endif // __DARWIN_API_H
*/
#include <TargetConditionals.h>
-#include <dispatch/dispatch.h>
#include <uuid/uuid.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach-o/loader.h>
#include <mach-o/fat.h>
-#include <mach-o/arch.h>
#include <mach-o/getsect.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/reason.h>
+#include <unistd.h>
#include <execinfo.h>
#include <stdio.h>
-#include <dlfcn.h>
#include <_simple.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include "os/assumes.h"
+
+#if !TARGET_OS_DRIVERKIT
+#include <dlfcn.h>
#include <os/debug_private.h>
#include <os/log.h>
#include <os/log_private.h>
#include <os/reason_private.h>
-
+#else
+#define _os_debug_log_error_str(...)
+// placeholder to disable usage of dlfcn.h
+typedef struct dl_info {
+ void *dli_fbase;
+} Dl_info;
+#endif
+#if __has_include(<CrashReporterClient.h>)
#include <CrashReporterClient.h>
#define os_set_crash_message(arg) CRSetCrashLogMessage(arg)
+#else
+#define os_set_crash_message(arg)
+#endif
#define OSX_ASSUMES_LOG_REDIRECT_SECT_NAME "__osx_log_func"
#define os_atomic_cmpxchg(p, o, n) __sync_bool_compare_and_swap((p), (o), (n))
static bool _os_should_abort_on_assumes = false;
+#if !TARGET_OS_DRIVERKIT
static const char *
_os_basename(const char *p)
{
return ((strrchr(p, '/') ? : p - 1) + 1);
}
+#endif
static void
_os_get_build(char *build, size_t sz)
#endif
}
+#if !TARGET_OS_DRIVERKIT
static void
_os_get_image_uuid(void *hdr, uuid_t uuid)
{
uuid_clear(uuid);
}
}
+#endif
static void
_os_abort_on_assumes_once(void)
{
os_redirect_t result = NULL;
+#if !TARGET_OS_DRIVERKIT
char name[128];
unsigned long size = 0;
uint8_t *data = getsectiondata(hdr, OS_ASSUMES_REDIRECT_SEG, OS_ASSUMES_REDIRECT_SECT, &size);
struct _os_redirect_assumes_s *redirect = (struct _os_redirect_assumes_s *)data;
result = redirect->redirect;
}
+#endif
return result;
}
uintptr_t offset = 0;
uuid_string_t uuid_str;
+#if !TARGET_OS_DRIVERKIT
void *ret = __builtin_return_address(0);
if (dladdr(ret, info)) {
uuid_t uuid;
offset = ret - info->dli_fbase;
}
+#else
+ info->dli_fbase = NULL;
+#endif
char sig[64];
(void)snprintf(sig, sizeof(sig), "%s:%lu", uuid_str, offset);
static inline void
_os_crash_impl(const char *message) {
os_set_crash_message(message);
+#if !TARGET_OS_DRIVERKIT
if (!_os_crash_callback) {
_os_crash_callback = dlsym(RTLD_MAIN_ONLY, "os_crash_function");
}
if (_os_crash_callback) {
_os_crash_callback(message);
}
+#endif
}
+#if !TARGET_OS_DRIVERKIT
__attribute__((always_inline))
static inline bool
_os_crash_fmt_impl(os_log_pack_t pack, size_t pack_size)
abort_with_payload(OS_REASON_LIBSYSTEM, OS_REASON_LIBSYSTEM_CODE_FAULT, pack, pack_size, composed, 0);
}
+#endif
__attribute__((always_inline))
static inline void
_os_crash_impl(message);
}
+#if !TARGET_OS_DRIVERKIT
void _os_crash_fmt(os_log_pack_t pack, size_t pack_size)
{
_os_crash_fmt_impl(pack, pack_size);
}
+#endif
void
_os_assumes_log(uint64_t code)
#define os_crash(...) \
__os_crash_invoke(__has_more_than_one_argument(__VA_ARGS__), __VA_ARGS__)
+OS_COLD
extern void
_os_crash_fmt(os_log_pack_t, size_t);
* statically-sized buffer.
*/
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
-OS_ALWAYS_INLINE
+OS_ALWAYS_INLINE OS_COLD
static inline void
os_assert_sprintf(int ret, size_t buff_size)
{
- union {
- size_t size;
- int ret;
- } myret = {
- .ret = ret,
- };
-
if (ret < 0) {
os_crash("error printing buffer: %s", strerror(errno));
}
- if (myret.size > buff_size) {
+ if ((size_t)ret > buff_size) {
os_crash("buffer too small: needed = %d, actual = %lu",
ret, buff_size);
}
* section of the resulting crash log.
*/
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
-OS_EXPORT OS_NONNULL1
+OS_EXPORT OS_NONNULL1 OS_COLD
void
os_assert_mach(const char *op, kern_return_t kr);
+#define os_assert_mach(op, kr) ({ \
+ kern_return_t __kr = (kr); \
+ if (os_unlikely(__kr != KERN_SUCCESS)) os_assert_mach(op, kr); \
+})
+
/*!
* @function os_assert_mach_port_status
* A routine to assert the status of a Mach port.
__OS_COMPILETIME_ASSERT__(e); \
} \
_os_assumes_log((uint64_t)(uintptr_t)_e); \
- _os_avoid_tail_call(); \
} \
_e; \
})
__OS_COMPILETIME_ASSERT__(!(e)); \
} \
_os_assumes_log((uint64_t)(uintptr_t)_e); \
- _os_avoid_tail_call(); \
} \
_e; \
})
__typeof__(e) _e = os_slowpath(e); \
if (_e == (__typeof__(e))-1) { \
_os_assumes_log((uint64_t)(uintptr_t)errno); \
- _os_avoid_tail_call(); \
} \
_e; \
})
__OS_COMPILETIME_ASSERT__(e); \
} \
_os_assumes_log_ctx(f, ctx, (uintptr_t)_e); \
- _os_avoid_tail_call(); \
} \
_e; \
})
__OS_COMPILETIME_ASSERT__(!(e)); \
} \
_os_assumes_log_ctx((f), (ctx), (uintptr_t)_e); \
- _os_avoid_tail_call(); \
} \
_e; \
})
__typeof__(e) _e = os_slowpath(e); \
if (_e == (__typeof__(e))-1) { \
_os_assumes_log_ctx((f), (ctx), (uintptr_t)errno); \
- _os_avoid_tail_call(); \
} \
_e; \
})
#pragma mark internal symbols
__OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0)
+OS_COLD OS_NOT_TAIL_CALLED
extern void
_os_crash(const char *);
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+OS_COLD OS_NOT_TAIL_CALLED
extern void
_os_assumes_log(uint64_t code);
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+OS_COLD OS_NOT_TAIL_CALLED
extern char *
_os_assert_log(uint64_t code);
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+OS_COLD OS_NOT_TAIL_CALLED
extern void
_os_assumes_log_ctx(os_log_callout_t callout, void *ctx, uint64_t code);
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+OS_COLD OS_NOT_TAIL_CALLED
extern char *
_os_assert_log_ctx(os_log_callout_t callout, void *ctx, uint64_t code);
#include <stdarg.h>
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
-OS_FORMAT_PRINTF(1, 2)
+OS_FORMAT_PRINTF(1, 2) OS_COLD
extern void
_os_debug_log(const char *msg, ...);
*/
#define os_debug_log_redirect(func) \
__attribute__((__used__)) \
+ __attribute__((__cold__)) \
__attribute__((__visibility__("default"))) \
bool _os_debug_log_redirect_func(const char *msg) { \
return func(msg); \
// str must be modifiable (non-const)!
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+OS_COLD
extern void
_os_debug_log_error_str(char *str);
--- /dev/null
+/*
+ * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ *
+ *
+ * Copyright (c) 1999 John D. Polstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _SYS_LINKER_SET_H_
+#define _SYS_LINKER_SET_H_
+
+#include <sys/appleapiopts.h>
+#if !defined(KERNEL) || defined(__APPLE_API_PRIVATE)
+
+/*
+ * The following macros are used to declare global sets of objects, which
+ * are collected by the linker into a `linker set' as defined below.
+ * For Mach-O, this is done by constructing a separate segment inside the
+ * __DATA section for each set. The contents of this segment are an array
+ * of pointers to the objects in the set.
+ *
+ * Note that due to limitations of the Mach-O format, there cannot
+ * be more than 255 sections in a segment, so linker set usage should be
+ * conserved. Set names may not exceed 16 characters.
+ */
+
+#ifdef KERNEL
+# include <mach-o/loader.h>
+# include <libkern/kernel_mach_header.h>
+
+# define MACH_HEADER_TYPE kernel_mach_header_t
+# define GETSECTIONDATA_VARIANT getsectdatafromheader
+# define SECTDATA_SIZE_TYPE unsigned long
+# define MH_EXECUTE_HEADER &_mh_execute_header
+# define IMAGE_SLIDE_CORRECT 0
+#else
+# include <mach-o/ldsyms.h>
+# include <mach-o/getsect.h>
+# include <mach-o/loader.h>
+# include <mach-o/dyld.h>
+
+# if __LP64__
+# define MACH_HEADER_TYPE struct mach_header_64
+# define GETSECTIONDATA_VARIANT getsectdatafromheader_64
+# define SECTDATA_SIZE_TYPE uint64_t
+# define MH_EXECUTE_HEADER _NSGetMachExecuteHeader()
+# else
+# define MACH_HEADER_TYPE struct mach_header
+# define GETSECTIONDATA_VARIANT getsectdatafromheader
+# define SECTDATA_SIZE_TYPE uint32_t
+# define MH_EXECUTE_HEADER _NSGetMachExecuteHeader()
+# endif
+#endif
+
+
+/*
+ * Private macros, not to be used outside this header file.
+ *
+ * The objective of this macro stack is to produce the following output,
+ * given SET and SYM as arguments:
+ *
+ * void const * __set_SET_sym_SYM __attribute__((section("__DATA,SET"))) = & SYM
+ */
+
+/* Wrap entries in a type that can be blacklisted from KASAN */
+struct linker_set_entry {
+ void *ptr;
+} __attribute__((packed));
+
+#ifdef __LS_VA_STRINGIFY__
+# undef __LS_VA_STRINGIFY__
+#endif
+#ifdef __LS_VA_STRCONCAT__
+# undef __LS_VA_STRCONCAT__
+#endif
+#define __LS_VA_STRINGIFY(_x ...) #_x
+#define __LS_VA_STRCONCAT(_x, _y) __LS_VA_STRINGIFY(_x,_y)
+#define __LINKER_MAKE_SET(_set, _sym) \
+ /*__unused*/ /*static*/ const struct linker_set_entry /*const*/ __set_##_set##_sym_##_sym \
+ __attribute__ ((section(__LS_VA_STRCONCAT(__DATA,_set)),used)) = { (void *)&_sym }
+/* the line above is very fragile - if your compiler breaks linker sets,
+ * just play around with "static", "const", "used" etc. :-) */
+
+/*
+ * Public macros.
+ */
+#define LINKER_SET_ENTRY(_set, _sym) __LINKER_MAKE_SET(_set, _sym)
+
+/*
+ * FreeBSD compatibility.
+ */
+#ifdef __APPLE_API_OBSOLETE
+# define TEXT_SET(_set, _sym) __LINKER_MAKE_SET(_set, _sym)
+# define DATA_SET(_set, _sym) __LINKER_MAKE_SET(_set, _sym)
+# define BSS_SET(_set, _sym) __LINKER_MAKE_SET(_set, _sym)
+# define ABS_SET(_set, _sym) __LINKER_MAKE_SET(_set, _sym)
+# define SET_ENTRY(_set, _sym) __LINKER_MAKE_SET(_set, _sym)
+#endif /* __APPLE_API_OBSOLETE */
+
+/*
+ * Extended linker set API.
+ *
+ * Since linker sets are per-object-file, and we may have multiple
+ * object files, we need to be able to specify which object's set
+ * to scan.
+ *
+ * The set itself is a contiguous array of pointers to the objects
+ * within the set.
+ */
+
+/*
+ * Public interface.
+ *
+ * void **LINKER_SET_OBJECT_BEGIN(_object, _set)
+ * Preferred interface to linker_set_object_begin(), takes set name unquoted.
+ * void **LINKER_SET_OBJECT_LIMIT(_object, _set)
+ * Preferred interface to linker_set_object_begin(), takes set name unquoted.
+ * LINKER_SET_OBJECT_FOREACH(_object, (set_member_type **)_pvar, _cast, _set)
+ * Iterates over the members of _set within _object. Since the set contains
+ * pointers to its elements, for a set of elements of type etyp, _pvar must
+ * be (etyp **).
+ * LINKER_SET_FOREACH((set_member_type **)_pvar, _cast, _set)
+ *
+ * Example of _cast: For the _pvar "struct sysctl_oid **oidpp", _cast would be
+ * "struct sysctl_oid **"
+ *
+ */
+
+#define LINKER_SET_OBJECT_BEGIN(_object, _set) __linker_set_object_begin(_object, _set)
+#define LINKER_SET_OBJECT_LIMIT(_object, _set) __linker_set_object_limit(_object, _set)
+
+#define LINKER_SET_OBJECT_FOREACH(_object, _pvar, _cast, _set) \
+ for (_pvar = (_cast) LINKER_SET_OBJECT_BEGIN(_object, _set); \
+ _pvar < (_cast) LINKER_SET_OBJECT_LIMIT(_object, _set); \
+ _pvar++)
+
+#define LINKER_SET_OBJECT_ITEM(_object, _cast, _set, _i) \
+ (((_cast)(LINKER_SET_OBJECT_BEGIN(_object, _set)))[_i])
+
+#define LINKER_SET_FOREACH(_pvar, _cast, _set) \
+ LINKER_SET_OBJECT_FOREACH((MACH_HEADER_TYPE *)MH_EXECUTE_HEADER, _pvar, _cast, _set)
+
+/*
+ * Implementation.
+ *
+ * void **__linker_set_object_begin(_header, _set)
+ * Returns a pointer to the first pointer in the linker set.
+ * void **__linker_set_object_limi(_header, _set)
+ * Returns an upper bound to the linker set (base + size).
+ */
+
+static __inline intptr_t
+__linker_get_slide(struct mach_header *_header)
+{
+#ifndef KERNEL
+ /*
+ * Gross.
+ *
+ * We cannot get the image slide directly from the header, so we need to
+ * determine the image's index and ask for the slide of that index.
+ */
+ uint32_t i = 0;
+ for (i = 0; i < _dyld_image_count(); i++) {
+ const struct mach_header *hdr = _dyld_get_image_header(i);
+ if (_header == hdr) {
+ return _dyld_get_image_vmaddr_slide(i);
+ }
+ }
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+static __inline void **
+__linker_set_object_begin(MACH_HEADER_TYPE *_header, const char *_set)
+__attribute__((__const__));
+static __inline void **
+__linker_set_object_begin(MACH_HEADER_TYPE *_header, const char *_set)
+{
+ void *_set_begin;
+ SECTDATA_SIZE_TYPE _size;
+
+ _set_begin = GETSECTIONDATA_VARIANT(_header, "__DATA", _set, &_size);
+ _set_begin += __linker_get_slide((struct mach_header *)_header);
+ return (void **) _set_begin;
+}
+
+static __inline void **
+__linker_set_object_limit(MACH_HEADER_TYPE *_header, const char *_set)
+__attribute__((__const__));
+static __inline void **
+__linker_set_object_limit(MACH_HEADER_TYPE *_header, const char *_set)
+{
+ void *_set_begin;
+ SECTDATA_SIZE_TYPE _size;
+
+ _set_begin = GETSECTIONDATA_VARIANT(_header, "__DATA", _set, &_size);
+ _set_begin += __linker_get_slide((struct mach_header *)_header);
+
+ return (void **) ((uintptr_t) _set_begin + _size);
+}
+
+#endif /* !KERNEL || __APPLE_API_PRIVATE */
+
+#endif /* _SYS_LINKER_SET_H_ */
* Provides a mechanism to determine the currently running OS variant.
*
* Any of these APIs may be overridden to its non-internal behavior on a
- * device by creating on override file. On macOS, this file is placed
- * at:
+ * device by creating on override file. On macOS, the path of this file
+ * is:
* /var/db/os_variant_override
- * On embedded platforms, this file is placed at:
+ * On embedded platforms, the path of the override file is:
* /usr/share/misc/os_variant_override
*
* Individual internal behaviors can be selectively disabled (ie.
* individual os_variant_has_internal_*() predicates can be overriden to
* false) by writing the file with a comma- or newline-delimited list of
- * names to disable. To disable all internal behaviors, empty the file.
+ * behaviors to disable. To disable all internal behaviors, empty the file.
+ *
+ * There is currently no support for configuring per-subsystem overrides.
+ *
+ * Examples:
+ * This will disable internal diagnostics and UI on macOS:
+ * sudo sh -c 'echo "diagnostics,ui" > /var/db/os_variant_override'
+ * This will disable internal UI on iOS (assuming logged in as root):
+ * echo "ui" > /usr/share/misc/os_variant_override
+ * This will disable all internal behaviors on macOS:
+ * sudo sh -c '/bin/echo -n > /var/db/os_variant_override'
+ *
+ * Note that the values returned by these APIs are cached in the kernel at
+ * system boot. A reboot will be required after changing the overrides
+ * before the new settings will take effect.
*
* Each of these functions takes a constant string argument for the requesting
* subsystem. This should be a reverse-DNS string describing the subsystem
*
* On macOS, this will check for the presence of AppleInternal content. On
* embedded platforms, this check will look for an internal install variant in
- * a manor similar to the MobileGestalt check for InternalBuild.
+ * a manner similar to the MobileGestalt check for InternalBuild.
*
* @result
* Returns true if this build has this property. False otherwise or upon error.
* @result
* Returns true if this build has this property. False otherwise or upon error.
*/
-API_AVAILABLE(macosx(10.14), ios(12.0), tvos(12.0), watchos(5.0))
+API_AVAILABLE(macosx(10.14.4), ios(12.2), tvos(12.2), watchos(5.2))
OS_EXPORT OS_WARN_RESULT
bool
os_variant_has_factory_content(const char *subsystem);
+/*!
+ * @function os_variant_is_darwinos
+ *
+ * @abstract returns whether this system variant is a darwinOS variant
+ *
+ * @result
+ * Returns true if this variant is a darwinOS variant.
+ */
+API_AVAILABLE(macosx(10.15), ios(13.0), tvos(13.0), watchos(6.0))
+OS_EXPORT OS_WARN_RESULT
+bool
+os_variant_is_darwinos(const char *subsystem);
+
+/*!
+ * @function os_variant_uses_ephemeral_storage
+ *
+ * @abstract returns whether the system is booted from an ephermeral volume
+ *
+ * @result
+ * Returns true if the system is booted with ephemeral storage for the data volume.
+ */
+API_AVAILABLE(macosx(10.15), ios(13.0), tvos(13.0), watchos(6.0))
+OS_EXPORT OS_WARN_RESULT
+bool
+os_variant_uses_ephemeral_storage(const char *subsystem);
+
+/*!
+ * @function os_variant_is_recovery
+ *
+ * @abstract returns whether this system variant is the recovery OS.
+ *
+ * @description
+ * On macOS, this returns whether the running environment is the BaseSystem.
+ * This will be true in the installer and recovery environments. On embedded
+ * platforms, this returns whether this is the NeRD (Network Recovery on
+ * Device) OS.
+ *
+ * @result
+ * Returns true if this variant is a recoveryOS
+ */
+API_AVAILABLE(macosx(10.15), ios(13.0), tvos(13.0), watchos(6.0))
+OS_EXPORT OS_WARN_RESULT
+bool
+os_variant_is_recovery(const char *subsystem);
+
+/*!
+ * @function os_variant_check
+ *
+ * @abstract returns whether the system is of the specified variant
+ *
+ * @description
+ * This check checks against below known variants. False is returned if the
+ * variant passed in is not in the list.
+ *
+ * HasInternalContent
+ * HasInternalDiagnostics
+ * HasInternalUI
+ * AllowsInternalSecurityPolicies
+ * HasFactoryContent
+ * IsDarwinOS
+ * UsesEphemeralStorage
+ * IsRecovery
+ *
+ * @result
+ * Returns true if the system is of the specified variant.
+ */
+API_AVAILABLE(macosx(10.15), ios(13.0), tvos(13.0), watchos(6.0))
+OS_EXPORT OS_WARN_RESULT
+bool
+os_variant_check(const char *subsystem, const char *variant);
+
__END_DECLS
#endif // __os_variant_H__
*/
field = strsep(&entry, " ");
errno = 0;
- if (!*field || strtol(field, NULL, 0) != 1)
+ if (field == NULL || !*field || strtol(field, NULL, 0) != 1)
{
error = EINVAL;
goto exit;
* @APPLE_LICENSE_HEADER_END@
*/
-#include <syslog.h>
-#include <sys/sysctl.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <stdlib.h>
+#include <os/assumes.h>
+#include <stdint.h>
#include <TargetConditionals.h>
-
-#if !defined(PR_13085474_CHECK)
-#define PR_13085474_CHECK 1
-
-/* Some shipped applications fail this check and were tested against
- * versions of these functions that supported overlapping buffers.
- *
- * We would rather let such applications run, using the old memmove
- * implementation, than abort() because they can't use the new
- * implementation.
- */
-
-#include <libkern/OSAtomic.h>
-#include <mach-o/dyld.h>
-#include <mach-o/dyld_priv.h>
-#define DYLD_OS_VERSION(major, minor, tiny) ((((major) & 0xffff) << 16) | (((minor) & 0xff) << 8) | ((tiny) & 0xff))
-#if TARGET_OS_IPHONE
-#define START_VERSION DYLD_OS_VERSION(7,0,0)
-#else
-#define START_VERSION DYLD_OS_VERSION(10,9,0)
-#endif
-#endif /* !PR_13085474_CHECK */
-
-/* For PR_13085474_CHECK set, we initialize __chk_assert_no_overlap to
- * a value neither 0 or 1. We call _dyld_register_func_for_add_image()
- * to register a callback, and use the non-one value of
- * __chk_assert_no_overlap to skip sdk version checks (but we do
- * perform overlap checks). To detect if the main program was built
- * prior to START_VERSION, we call dyld_get_program_sdk_version(),
- * which we do before setting up the callback (since we don't need it
- * if the main program is older).
- *
- * After _dyld_register_func_for_add_image() returns, we set
- * __chk_assert_no_overlap to 1, which enables the sdk version checking
- * for subsequent loaded shared objects. If we then find an old version,
- * we set __chk_assert_no_overlap to 0 to turn off overlap checking.
- *
- * If PR_13085474_CHECK is zero, then we never do any sdk version checking
- * and always do overlap checks.
- */
__attribute__ ((visibility ("hidden")))
-uint32_t __chk_assert_no_overlap
-#if PR_13085474_CHECK
- = 42;
-#else
- = 1;
-#endif
-
-#if PR_13085474_CHECK
-static void
-__chk_assert_no_overlap_callback(const struct mach_header *mh, intptr_t vmaddr_slide __unused) {
- if (__chk_assert_no_overlap != 1) return;
- if (dyld_get_sdk_version(mh) < START_VERSION) OSAtomicAnd32(0U, &__chk_assert_no_overlap);
-}
-#endif
-
-__attribute__ ((visibility ("hidden")))
-void __chk_init(void) {
-#if PR_13085474_CHECK
- if (dyld_get_program_sdk_version() < START_VERSION) {
- __chk_assert_no_overlap = 0;
- } else {
- _dyld_register_func_for_add_image(__chk_assert_no_overlap_callback);
- __chk_assert_no_overlap = 1;
- }
-#endif
-}
-
-__attribute__ ((noreturn))
-static void
-__chk_fail (const char *message)
-{
- syslog(LOG_CRIT, "%s", message);
- abort_report_np("%s", message);
-}
+uint32_t __chk_assert_no_overlap = 1;
__attribute__ ((visibility ("hidden")))
__attribute__ ((noreturn))
void
__chk_fail_overflow (void) {
- __chk_fail("detected buffer overflow");
+ os_crash("detected buffer overflow");
}
__attribute__ ((visibility ("hidden")))
__attribute__ ((noreturn))
void
__chk_fail_overlap (void) {
- __chk_fail("detected source and destination buffer overlap");
+ os_crash("detected source and destination buffer overlap");
}
-
__attribute__ ((visibility ("hidden")))
void
__chk_overlap (const void *_a, size_t an, const void *_b, size_t bn) {
return done;
}
+
+int
+__snprintf_object_size_chk (char *dest, size_t dstlen, size_t len,
+const char *format, ...)
+{
+ va_list arg;
+ int done;
+
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail_overflow ();
+
+ va_start (arg, format);
+
+ done = vsnprintf (dest, len, format, arg);
+
+ va_end (arg);
+
+ return done;
+}
return done;
}
+
+int
+__sprintf_object_size_chk (char *dest, size_t dstlen, const char *format, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, format);
+
+ if (__builtin_expect (dstlen > (size_t) INT_MAX, 0))
+ done = vsprintf (dest, format, arg);
+ else
+ {
+ done = vsnprintf (dest, dstlen, format, arg);
+ if (__builtin_expect(done >= 0 && (size_t) done >= dstlen, 0))
+ __chk_fail_overflow ();
+ }
+
+ va_end (arg);
+
+ return done;
+}
return (EOF);
}
FLOCKFILE(fp);
- r = fp->_flags & __SWR ? __sflush(fp) : 0;
+ r = __sflush(fp);
if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
r = EOF;
if (fp->_flags & __SMBF)
.\" @(#)fflush.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD: src/lib/libc/stdio/fflush.3,v 1.11 2007/01/09 00:28:06 imp Exp $
.\"
-.Dd June 4, 1993
+.Dd August 1, 2019
.Dt FFLUSH 3
.Os
.Sh NAME
.Sh DESCRIPTION
The function
.Fn fflush
-forces a write of all buffered data for the given output or update
+synchronizes the state of the given
.Fa stream
-via the stream's underlying write function.
+in light of buffered I/O.
+For output or update streams it writes all buffered data via the stream's
+underlying write function.
+For input streams it seeks to the current file position indicator via the
+stream's underlying seek function.
The open status of the stream is unaffected.
.Pp
If the
.Fn fflush
flushes
.Em all
-open output streams.
+open streams.
.Pp
The function
.Fn fpurge
The
.Fa stream
argument
-is not an open stream, or, in the case of
-.Fn fflush ,
-not a stream open for writing.
+is not an open stream.
.El
.Pp
The function
.Fn fflush
may also fail and set
.Va errno
-for any of the errors specified for the routine
-.Xr write 2 .
+for any of the errors specified for the routines
+.Xr write 2
+and
+.Xr lseek 2 .
.Sh SEE ALSO
.Xr write 2 ,
.Xr fclose 3 ,
.Xr fopen 3 ,
+.Xr lseek 2 ,
.Xr setbuf 3
.Sh STANDARDS
The
.Fn fflush
function
conforms to
-.St -isoC .
+.St -isoC
+and
+.St -susv3 .
int
fflush(FILE *fp)
{
- int retval;
+ int retval = 0;
- if (fp == NULL)
+ if (fp == NULL) {
return (_fwalk(sflush_locked));
- FLOCKFILE(fp);
+ }
- /*
- * 11103146: Conformance change:
- * --- Begin History ---
- * There is disagreement about the correct behaviour of fflush()
- * when passed a file which is not open for writing. According to
- * the ISO C standard, the behaviour is undefined.
- * Under linux, such an fflush returns success and has no effect;
- * under Windows, such an fflush is documented as behaving instead
- * as fpurge().
- * Given that applications may be written with the expectation of
- * either of these two behaviours, the only safe (non-astonishing)
- * option is to return EBADF and ask that applications be fixed.
- * --- End History ---
- * SUSv3 now requires that fflush() returns success on a read-only
- * stream. In addition, the conformance tests will warn if a fflush
- * on a read-only stream does not set the file descriptor's file offset
- * to the real position. We won't be fixing the warning at this time.
- */
- if ((fp->_flags & (__SWR | __SRW)) == 0) {
- retval = 0;
- } else
- retval = __sflush(fp);
+ FLOCKFILE(fp);
+ retval = __sflush(fp);
FUNLOCKFILE(fp);
return (retval);
}
int n, t;
t = fp->_flags;
- if ((t & __SWR) == 0)
- return (0);
if ((p = fp->_bf._base) == NULL)
return (0);
- n = fp->_p - p; /* write this much */
-
/*
- * Set these immediately to avoid problems with longjmp and to allow
- * exchange buffering (via setvbuf) in user write function.
+ * SUSv3 requires that fflush() on a seekable input stream updates the file
+ * position indicator with the underlying seek function. Use a dumb fseek
+ * for this (don't attempt to preserve the buffers).
*/
- fp->_p = p;
- fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
-
- for (; n > 0; n -= t, p += t) {
- t = _swrite(fp, (char *)p, n);
- if (t <= 0) {
- /* 5340694: reset _p and _w on EAGAIN */
- if (t < 0 && errno == EAGAIN) {
- if (p > fp->_p) {
- /* some was written */
- memmove(fp->_p, p, n);
- fp->_p += n;
- if (!(fp->_flags & (__SLBF|__SNBF)))
- fp->_w -= n;
+ if ((t & __SRD) != 0) {
+ if (fp->_seek == NULL) {
+ /*
+ * No way to seek this file -- just return "success."
+ */
+ return (0);
+ }
+
+ n = fp->_r;
+
+ if (n > 0) {
+ /*
+ * See _fseeko's dumb path.
+ */
+ if (_sseek(fp, (fpos_t)-n, SEEK_CUR) == -1) {
+ if (errno == ESPIPE) {
+ /*
+ * Ignore ESPIPE errors, since there's no way to put the bytes
+ * back into the pipe.
+ */
+ return (0);
+ }
+ return (EOF);
+ }
+
+ if (HASUB(fp)) {
+ FREEUB(fp);
+ }
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ fp->_flags &= ~__SEOF;
+ memset(&fp->_mbstate, 0, sizeof(mbstate_t));
+ }
+ return (0);
+ }
+
+ if ((t & __SWR) != 0) {
+ n = fp->_p - p; /* write this much */
+
+ /*
+ * Set these immediately to avoid problems with longjmp and to allow
+ * exchange buffering (via setvbuf) in user write function.
+ */
+ fp->_p = p;
+ fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+
+ for (; n > 0; n -= t, p += t) {
+ t = _swrite(fp, (char *)p, n);
+ if (t <= 0) {
+ /* 5340694: reset _p and _w on EAGAIN */
+ if (t < 0 && errno == EAGAIN) {
+ if (p > fp->_p) {
+ /* some was written */
+ memmove(fp->_p, p, n);
+ fp->_p += n;
+ if (!(fp->_flags & (__SLBF|__SNBF)))
+ fp->_w -= n;
+ }
}
+ fp->_flags |= __SERR;
+ return (EOF);
}
- fp->_flags |= __SERR;
- return (EOF);
}
}
return (0);
return flags; // No number found, this protects us from negative size values
}
- size = strtol_l(evp, &end, 10, NULL); // No locale
+ size = strtol_l(evp, &end, 10, LC_C_LOCALE);
if (*end != '\0') {
return flags;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wint-conversion"
+#include <TargetConditionals.h>
+#if !TARGET_OS_DRIVERKIT
#define OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE 1
+#endif
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
static_format_checked = __printf_is_memory_read_only((void*)fmt0, strlen(fmt0));
}
if (!static_format_checked) {
+#if OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE
os_crash("%%n used in a non-immutable format string: %s", fmt0);
+#else
+ os_crash("%%n used in a non-immutable format string");
+#endif
}
#endif // ALLOW_DYNAMIC_PERCENT_N
#include "libc_private.h"
+#if __has_include(<CrashReporterClient.h>)
#include <CrashReporterClient.h>
+#else
+#define CRGetCrashLogMessage() NULL
+#define CRSetCrashLogMessage(...)
+#endif
#include "_simple.h"
extern void (*__cleanup)();
-extern void __abort(void) __dead2;
+extern void __abort(void) __cold __dead2;
#define TIMEOUT 10000 /* 10 milliseconds */
*/
sigdelset(&act.sa_mask, SIGABRT);
+ /*
+ * Don't block SIGSEGV since we might trigger a segfault if the pthread
+ * struct is corrupt. The end user behavior is that the program will
+ * terminate with a SIGSEGV instead of a SIGABRT which is acceptable. If
+ * the user registers a SIGSEGV handler, then they are responsible for
+ * dealing with any corruption themselves and abort may not work.
+ * rdar://48853131
+ */
+ sigdelset(&act.sa_mask, SIGSEGV);
+ sigdelset(&act.sa_mask, SIGBUS);
+
/* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread
* This helps gdb focus on the thread calling abort()
*/
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.8 2007/01/09 00:28:09 imp Exp $");
+#include <TargetConditionals.h>
#include "namespace.h"
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
-#if defined(__DYNAMIC__) || defined (__BLOCKS__)
+#if (defined(__DYNAMIC__) || defined (__BLOCKS__)) && !TARGET_OS_DRIVERKIT
#include <dlfcn.h>
#endif /* defined(__DYNAMIC__) */
#include "atexit.h"
#include "libc_private.h"
#include <os/alloc_once_private.h>
-#include <TargetConditionals.h>
-
#define ATEXIT_FN_EMPTY 0
#define ATEXIT_FN_STD 1
#define ATEXIT_FN_CXA 2
fn.fn_arg = NULL;
fn.fn_dso = NULL;
-#if defined(__DYNAMIC__) && !TARGET_OS_IPHONE
+#if defined(__DYNAMIC__) && !TARGET_OS_IPHONE && !TARGET_OS_DRIVERKIT
// <rdar://problem/14596032&15173956>
struct dl_info info;
if (dladdr(func, &info)) {
#include <sys/vnode.h>
#include "un-namespace.h"
+
struct attrs {
u_int32_t len;
attrreference_t name;
return (NULL);
}
#endif /* __DARWIN_UNIX03 */
+
/*
* Extension to the standard; if inresolved == NULL, allocate memory
*/
*/
#include <sys/cdefs.h>
+#include <xlocale.h>
#ifndef lint
#ifndef NOID
static char elsieid[] __unused = "@(#)asctime.c 8.2";
** Assume that strftime is unaffected by other out-of-range members
** (e.g., timeptr->tm_mday) when processing "%Y".
*/
- (void) strftime(year, sizeof year, "%Y", timeptr);
+ (void) strftime_l(year, sizeof(year), "%Y", timeptr, NULL);
/*
** We avoid using snprintf since it's not available on all systems.
*/
((year % 100) / 4) + (isleap(year) ? 6 : 0) + 1) % 7);
}
+static inline bool is_plus(char c) {
+ return c == '+';
+}
+
+static inline bool is_minus(char c) {
+ return c == '-';
+}
+
+static inline bool is_zero(char c) {
+ return c == '0';
+}
+
static char *
_strptime0(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t locale, int flags, int week_number, enum week_kind week_kind)
{
const char *ptr;
int wday_offset;
int i, len;
+ bool negative;
int Ealternative, Oalternative;
const struct lc_time_T *tptr = __get_current_time_locale(locale);
static int start_of_month[2][13] = {
ptr = fmt;
while (*ptr != 0) {
+ int field_width = 0;
c = *ptr++;
if (c != '%') {
Oalternative = 0;
label:
c = *ptr++;
+ if (is_zero(c)) {
+ // Leading '0' is to be ignored.
+ c = *ptr++;
+ } else if (is_plus(c)) {
+ // POSIX sats leading '+' should be ignored, but FreeBSD interprets
+ // "%+" to mean locale-specific date format. Try to handle both by
+ // checking the next character.
+ char next = *ptr;
+ if (next != '\0' && next != '%' && !isspace_l(next, locale)) {
+ // Use POSIX interpretation.
+ c = *ptr++;
+ }
+ }
+
+ if (isdigit_l(c, locale)) {
+ // Field width
+ field_width = c - '0';
+ while (*ptr != '\0' && isdigit_l(*ptr, locale)) {
+ field_width *= 10;
+ field_width += *ptr++ - '0';
+ }
+ c = *ptr++;
+ }
switch (c) {
case '%':
if (*buf++ != '%')
break;
case 'C':
- if (!isdigit_l((unsigned char)*buf, locale))
+ if (!isdigit_l((unsigned char)*buf, locale) && !is_plus(*buf) && !is_minus(*buf))
return (NULL);
/* XXX This will break for 3-digit centuries. */
- len = 2;
+ negative = false;
+ len = field_width ? field_width : 2;
+ if (is_plus(*buf)) {
+ len--;
+ buf++;
+ } else if (is_minus(*buf)) {
+ len--;
+ negative = true;
+ buf++;
+ }
for (i = 0; len && *buf != 0 &&
isdigit_l((unsigned char)*buf, locale); buf++) {
i *= 10;
i += *buf - '0';
len--;
}
- if (i < 19)
- return (NULL);
+
+ if (negative) {
+ i = -i;
+ }
if (flags & FLAG_YEAR_IN_CENTURY) {
tm->tm_year = i * 100 + (tm->tm_year % 100) - TM_YEAR_BASE;
if (!isdigit_l((unsigned char)*buf, locale))
return (NULL);
- len = 3;
+ len = field_width ? field_width : 3;
for (i = 0; len && *buf != 0 &&
isdigit_l((unsigned char)*buf, locale); buf++){
i *= 10;
if (!isdigit_l((unsigned char)*buf, locale))
return (NULL);
- len = 2;
+ len = field_width ? field_width : 2;
for (i = 0; len && *buf != 0 &&
isdigit_l((unsigned char)*buf, locale); buf++){
i *= 10;
if (!isdigit_l((unsigned char)*buf, locale))
return (NULL);
- len = 2;
+ len = field_width ? field_width : 2;
for (i = 0; len && *buf != 0 &&
isdigit_l((unsigned char)*buf, locale); buf++) {
i *= 10;
if (tm->tm_hour > 12)
return (NULL);
- len = strlen(tptr->am);
+ len = (int)strlen(tptr->am);
if (strncasecmp_l(buf, tptr->am, len, locale) == 0) {
if (tm->tm_hour == 12)
tm->tm_hour = 0;
break;
}
- len = strlen(tptr->pm);
+ len = (int)strlen(tptr->pm);
if (strncasecmp_l(buf, tptr->pm, len, locale) == 0) {
if (tm->tm_hour != 12)
tm->tm_hour += 12;
case 'A':
case 'a':
for (i = 0; i < asizeof(tptr->weekday); i++) {
- len = strlen(tptr->weekday[i]);
+ len = (int)strlen(tptr->weekday[i]);
if (strncasecmp_l(buf, tptr->weekday[i],
len, locale) == 0)
break;
- len = strlen(tptr->wday[i]);
+ len = (int)strlen(tptr->wday[i]);
if (strncasecmp_l(buf, tptr->wday[i],
len, locale) == 0)
break;
if (!isdigit_l((unsigned char)*buf, locale))
return (NULL);
- len = 2;
+ len = field_width ? field_width : 2;
for (i = 0; len && *buf != 0 &&
isdigit_l((unsigned char)*buf, locale); buf++) {
i *= 10;
* digits if used incorrectly.
*/
/* Leading space is ok if date is single digit */
- len = 2;
+ len = field_width ? field_width : 2;
if (isspace_l((unsigned char)buf[0], locale) &&
isdigit_l((unsigned char)buf[1], locale) &&
!isdigit_l((unsigned char)buf[2], locale)) {
for (i = 0; i < asizeof(tptr->month); i++) {
if (Oalternative) {
if (c == 'B') {
- len = strlen(tptr->alt_month[i]);
+ len = (int)strlen(tptr->alt_month[i]);
if (strncasecmp_l(buf,
tptr->alt_month[i],
len, locale) == 0)
break;
}
} else {
- len = strlen(tptr->month[i]);
+ len = (int)strlen(tptr->month[i]);
if (strncasecmp_l(buf, tptr->month[i],
len, locale) == 0)
break;
*/
if (i == asizeof(tptr->month) && !Oalternative) {
for (i = 0; i < asizeof(tptr->month); i++) {
- len = strlen(tptr->mon[i]);
+ len = (int)strlen(tptr->mon[i]);
if (strncasecmp_l(buf, tptr->mon[i],
len, locale) == 0)
break;
if (!isdigit_l((unsigned char)*buf, locale))
return (NULL);
- len = 2;
+ len = field_width ? field_width : 2;
for (i = 0; len && *buf != 0 &&
isdigit_l((unsigned char)*buf, locale); buf++) {
i *= 10;
isspace_l((unsigned char)*buf, locale))
break;
- if (!isdigit_l((unsigned char)*buf, locale))
+ if (!isdigit_l((unsigned char)*buf, locale) && !is_plus(*buf)
+ && !is_minus(*buf))
return (NULL);
-#if __DARWIN_UNIX03
- if (c == 'Y') {
- int savei = 0;
- const char *savebuf = buf;
- int64_t i64 = 0;
- int overflow = 0;
-
- for (len = 0; *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++) {
- i64 *= 10;
- i64 += *buf - '0';
- if (++len <= 4) {
- savei = i64;
- savebuf = buf + 1;
- }
- if (i64 > INT_MAX) {
- overflow++;
- break;
- }
- }
- /*
- * Conformance requires %Y to be more then 4
- * digits. However, there are several cases
- * where %Y is immediately followed by other
- * digits values. So we do the conformance
- * case first (as many digits as possible),
- * and if we fail, we backup and try just 4
- * digits for %Y.
- */
- if (len > 4 && !overflow) {
- struct tm savetm = *tm;
- int saveconv = *convp;
- const char *saveptr = ptr;
- char *ret;
-
- if (i64 < 1900)
- return 0;
-
- tm->tm_year = i64 - 1900;
-
- if (*buf != 0 && isspace_l((unsigned char)*buf, locale))
- while (*ptr != 0 && !isspace_l((unsigned char)*ptr, locale) && *ptr != '%')
- ptr++;
- ret = _strptime0(buf, ptr, tm, convp, locale, flags, week_number, week_kind);
- if (ret) return ret;
- /* Failed, so try 4-digit year */
- *tm = savetm;
- *convp = saveconv;
- ptr = saveptr;
- }
- buf = savebuf;
- i = savei;
- } else {
- len = 2;
-#else /* !__DARWIN_UNIX03 */
- len = (c == 'Y') ? 4 : 2;
-#endif /* __DARWIN_UNIX03 */
-
- for (i = 0; len && *buf != 0 &&
- isdigit_l((unsigned char)*buf, locale); buf++) {
- i *= 10;
- i += *buf - '0';
- len--;
- }
-#if __DARWIN_UNIX03
+ len = field_width ? field_width : ((c == 'Y') ? 4 : 2);
+ negative = false;
+ if (is_plus(*buf)) {
+ len--;
+ buf++;
+ } else if (is_minus(*buf)) {
+ len--;
+ buf++;
+ negative = true;
+ }
+ for (i = 0; len && *buf != 0 &&
+ isdigit_l((unsigned char)*buf, locale); buf++) {
+ i *= 10;
+ i += *buf - '0';
+ len--;
}
-#endif /* __DARWIN_UNIX03 */
if (i < 0)
return (NULL);
+ if (negative) {
+ i = -i;
+ }
+
if (c == 'Y'){
i -= TM_YEAR_BASE;
} else if (c == 'y' && flags & FLAG_CENTURY) {
isupper_l((unsigned char)*cp, locale); ++cp) {
/*empty*/
}
- len = cp - buf;
+ len = field_width ? field_width : cp - buf;
if (len == 3 && strncmp(buf, "GMT", 3) == 0) {
*convp = CONVERT_GMT;
buf += len;
--- /dev/null
+.\"
+.\" Copyright (c) 2005 Tim J. Robbins
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 21, 2005
+.Dt RPMATCH 3
+.Os
+.Sh NAME
+.Nm rpmatch
+.Nd "determine whether the response to a question is affirmative or negative"
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft int
+.Fn rpmatch "const char *response"
+.Sh DESCRIPTION
+The
+.Fn rpmatch
+function determines whether the
+.Fa response
+argument is an affirmative or negative response to a question
+according to the current locale.
+.Sh RETURN VALUES
+The
+.Fn rpmatch
+functions returns:
+.Bl -tag -width indent
+.It 1
+The response is affirmative.
+.It 0
+The response is negative.
+.It \&-1
+The response is not recognized.
+.El
+.Sh SEE ALSO
+.Xr nl_langinfo 3 ,
+.Xr setlocale 3
+.Sh HISTORY
+The
+.Fn rpmatch
+function appeared in macOS 10.15.
--- /dev/null
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2004-2005 Tim J. Robbins.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <langinfo.h>
+#include <regex.h>
+#include <stdlib.h>
+
+int
+rpmatch(const char *response)
+{
+ regex_t yes, no;
+ int ret;
+
+ if (regcomp(&yes, nl_langinfo(YESEXPR), REG_EXTENDED|REG_NOSUB) != 0)
+ return (-1);
+ if (regcomp(&no, nl_langinfo(NOEXPR), REG_EXTENDED|REG_NOSUB) != 0) {
+ regfree(&yes);
+ return (-1);
+ }
+ if (regexec(&yes, response, 0, NULL, 0) == 0)
+ ret = 1;
+ else if (regexec(&no, response, 0, NULL, 0) == 0)
+ ret = 0;
+ else
+ ret = -1;
+ regfree(&yes);
+ regfree(&no);
+ return (ret);
+}
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
- int ret = 0;
+ unsigned char ret = 0;
- for (; n > 0; n--)
+ for (; n > 0; n--) {
ret |= *p1++ ^ *p2++;
- return ret;
+ }
+
+ /* map zero to zero and nonzero to one */
+ return (ret + 0xff) >> 8;
}
* @APPLE_LICENSE_HEADER_END@
*/
-#include <dispatch/dispatch.h>
#include <libkern/OSThermalNotification.h>
-#include <notify.h>
#include <TargetConditionals.h>
const char * const kOSThermalNotificationPressureLevelName = OSThermalPressureLevelName;
#if TARGET_OS_IPHONE
+
+#include <dispatch/dispatch.h>
+#include <notify.h>
+
#define OSThermalAlert "com.apple.system.thermalalert"
#define OSThermalDecision "com.apple.system.thermaldecision"
#define OSThermalStatusName "com.apple.system.thermalstatus"
#include <signal.h>
#include <string.h>
#include <stdlib.h>
-#include <asl.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
+#if __has_include(<CrashReporterClient.h>)
#include <CrashReporterClient.h>
+#else
+#define CRSetCrashLogMessage(...)
+#endif
#include "libproc.h"
#include "_simple.h"
#define GUARD_MAX 8
long __stack_chk_guard[GUARD_MAX] = {0, 0, 0, 0, 0, 0, 0, 0};
-void __abort(void) __dead2;
+void __abort(void) __cold __dead2;
void __guard_setup(const char *apple[]) __attribute__ ((visibility ("hidden")));
void __stack_chk_fail(void);
((unsigned char *)__stack_chk_guard)[3] = 255;
}
-#define STACKOVERFLOW "] stack overflow"
+static const char *stackoverflow_msg = "stack buffer overflow";
void
__stack_chk_fail()
{
- char n[16]; // bigger than will hold the digits in a pid_t
- char *np;
- int pid = getpid();
- char message[sizeof(n) + sizeof(STACKOVERFLOW)] = "[";
- char prog[2*MAXCOMLEN+1] = {0};
+ CRSetCrashLogMessage(stackoverflow_msg);
- proc_name(pid, prog, 2*MAXCOMLEN);
- prog[2*MAXCOMLEN] = 0;
- np = n + sizeof(n);
- *--np = 0;
- while(pid > 0) {
- *--np = (pid % 10) + '0';
- pid /= 10;
- }
- strlcat(message, np, sizeof(message));
- strlcat(message, STACKOVERFLOW, sizeof(message));
/* This may fail on a chroot jail... */
- _simple_asl_log_prog(ASL_LEVEL_CRIT, "user", message, prog);
+ char prog[2*MAXCOMLEN+1] = {0};
+ proc_name(getpid(), prog, 2*MAXCOMLEN);
+ prog[2*MAXCOMLEN] = 0;
+ _simple_asl_log_prog(ASL_LEVEL_CRIT, "user", stackoverflow_msg, prog);
- CRSetCrashLogMessage(message);
__abort();
}
* _libc_fork_child() is called from Libsystem's libSystem_atfork_child()
*/
#include <TargetConditionals.h>
+#if __has_include(<CrashReporterClient.h>)
#include <CrashReporterClient.h>
+#else
+#define CRSetCrashLogMessage(...)
+#endif
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-prototypes"
extern void __atexit_init(void);
extern void __confstr_init(const struct _libc_functions *funcs);
extern void _init_clock_port(void);
-extern void __chk_init(void);
extern void __xlocale_init(void);
extern void __guard_setup(const char *apple[]);
__confstr_init(funcs);
__atexit_init();
_init_clock_port();
- __chk_init();
__xlocale_init();
__guard_setup(apple);
}
* @APPLE_LICENSE_HEADER_END@
*/
-#include <sys/time.h>
+#include <TargetConditionals.h>
+#if !TARGET_OS_DRIVERKIT
#include <notify.h>
#include <notify_keys.h>
+#else
+#define notify_post(...)
+#endif
+#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include "_simple.h"
* @APPLE_LICENSE_HEADER_END@
*/
+#if __has_include(<CrashReporterClient.h>)
#include <CrashReporterClient.h>
+#else
+#define CRSetCrashLogMessage(...)
+#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
PROJECT := Libc
TEST_DIR := tests/
+CUSTOM_TARGETS += osvariantutil
+
ifeq ($(DEVELOPER_DIR),)
DEVELOPER_DIR := $(shell xcode-select -p)
endif
EXCLUDED_SOURCES += locale.c
endif
+FRAMEWORK_CFLAGS := $(patsubst %,-iframework %,$(SYSTEM_FRAMEWORK_SEARCH_PATHS))
WARNING_CFLAGS := -Weverything \
-Wno-vla -Wno-missing-field-initializers -Wno-padded \
-Wno-gnu-flexible-array-initializer -Wno-gnu-empty-initializer \
-Wno-partial-availability -Wno-used-but-marked-unused \
-Wno-reserved-id-macro -fmacro-backtrace-limit=0 \
- -Wno-c++98-compat
-OTHER_CFLAGS := -DDARWINTEST --std=gnu11 $(WARNING_CFLAGS)
-OTHER_LDFLAGS := -ldarwintest_utils
+ -Wno-c++98-compat -Wno-extra-semi -Wno-language-extension-token
+OTHER_CFLAGS := -DDARWINTEST --std=gnu11 $(FRAMEWORK_CFLAGS) $(WARNING_CFLAGS)
+DT_LDFLAGS += -ldarwintest_utils
ASAN_DYLIB_PATH := /usr/local/lib/sanitizers/
nxheap: OTHER_CFLAGS += -Wno-cast-align
endif
os_variant: OTHER_CFLAGS += -DOS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE
+osvariantutil: OTHER_CFLAGS += -Wno-gnu-statement-expression -Wno-covered-switch-default -DOS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE
+
include $(DEVELOPER_DIR)/AppleInternal/Makefiles/darwintest/Makefile.targets
+OSVARIANTUTIL_INSTALLDIR = $(DSTROOT)/usr/local/bin
+
+install-osvariantutil: osvariantutil
+ mkdir -p $(OSVARIANTUTIL_INSTALLDIR)
+ cp $(SYMROOT)/osvariantutil $(OSVARIANTUTIL_INSTALLDIR)/
+ifeq ($(DWARF_DSYM_FILE_SHOULD_ACCOMPANY_PRODUCT),YES)
+ cp $(SYMROOT)/osvariantutil.dSYM $(OSVARIANTUTIL_INSTALLDIR)/
+endif
--- /dev/null
+#include <darwintest.h>
+#include <sys/types.h>
+#include <pthread.h>
+#include <mach/mach_types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dispatch/dispatch.h>
+
+static void *
+body(void *corrupt)
+{
+ T_LOG("Helper thread running: %d", (bool)corrupt);
+ if (corrupt) {
+ // The pthread_t is stored at the top of the stack and could be
+ // corrupted because of a stack overflow. To make the test more
+ // reliable, we will manually smash the pthread struct directly.
+ pthread_t self = pthread_self();
+ memset(self, 0x41, 4096);
+ }
+ // Expected behavior is that if a thread calls abort, the process should
+ // abort promptly.
+ abort();
+ T_FAIL("Abort didn't?");
+}
+
+typedef enum { PTHREAD, WORKQUEUE } thread_type_t;
+
+static void
+abort_test(thread_type_t type, int expected_signal)
+{
+ pid_t child = fork();
+ bool corrupt = expected_signal == SIGSEGV;
+
+ if (child == 0) {
+ T_LOG("Child running");
+ switch (type) {
+ case PTHREAD: {
+ pthread_t tid;
+ T_QUIET;
+ T_ASSERT_POSIX_ZERO(
+ pthread_create(&tid, NULL, body, (void *)corrupt), NULL);
+ break;
+ }
+ case WORKQUEUE: {
+ dispatch_async_f(dispatch_get_global_queue(
+ DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
+ (void *)corrupt, &body);
+ break;
+ }
+ }
+ sleep(5);
+ T_FAIL("Child didn't abort");
+ exit(-1);
+ } else {
+ // Wait and check the exit status of the child
+ int status = 0;
+ pid_t pid = wait(&status);
+ T_QUIET;
+ T_ASSERT_EQ(pid, child, NULL);
+ T_QUIET;
+ T_EXPECT_FALSE(WIFEXITED(status), "WIFEXITED Status: %x", status);
+ T_QUIET;
+ T_EXPECT_TRUE(WIFSIGNALED(status), "WIFSIGNALED Status: %x", status);
+ T_QUIET;
+ T_EXPECT_FALSE(WIFSTOPPED(status), "WIFSTOPPED Status: %x", status);
+ // This test is successful if we trigger a SIGSEGV|SIGBUS or SIGABRT
+ // since both will promptly terminate the program
+ int signal = WTERMSIG(status);
+ if (signal == SIGBUS) {
+ // rdar://53269061
+ T_LOG("Converting %d to SIGSEGV", signal);
+ signal = SIGSEGV;
+ }
+ T_EXPECT_EQ(signal, expected_signal, NULL);
+ }
+}
+
+static void
+signal_handler(int signo)
+{
+ // The user's signal handler should not be called during abort
+ T_FAIL("Unexpected signal: %d\n", signo);
+}
+
+T_DECL(abort_pthread_corrupt_test, "Tests abort")
+{
+ abort_test(PTHREAD, SIGSEGV);
+}
+
+T_DECL(abort_workqueue_corrupt_test, "Tests abort")
+{
+ abort_test(WORKQUEUE, SIGSEGV);
+}
+
+T_DECL(abort_pthread_handler_test, "Tests abort")
+{
+ // rdar://52892057
+ T_SKIP("Abort hangs if the user registers their own SIGSEGV handler");
+ signal(SIGSEGV, signal_handler);
+ abort_test(PTHREAD, SIGSEGV);
+}
+
+T_DECL(abort_workqueue_handler_test, "Tests abort")
+{
+ // rdar://52892057
+ T_SKIP("Abort hangs if the user registers their own SIGSEGV handler");
+ signal(SIGSEGV, signal_handler);
+ abort_test(WORKQUEUE, SIGSEGV);
+}
+
+T_DECL(abort_pthread_test, "Tests abort")
+{
+ abort_test(PTHREAD, SIGABRT);
+}
+
+T_DECL(abort_workqueue_test, "Tests abort")
+{
+ abort_test(WORKQUEUE, SIGABRT);
+}
--- /dev/null
+#include <darwintest.h>
+#include <sys/types.h>
+#include <sys/acl.h>
+
+T_DECL(acl_bad_test, "Tests invalid acl") {
+
+ acl_t acl = acl_from_text("!#acl");
+ T_EXPECT_NULL(acl, "Invalid acl detected");
+}
#define MAX_FRAMES 32
static const int expected_nframes = 20;
+static const int skip_nframes = 5;
static void *observed_bt[MAX_FRAMES] = {};
static int observed_nframes = 0;
static int __attribute__((noinline,not_tail_called,disable_tail_calls))
recurse_a(unsigned int frames)
{
- if (frames == 1) {
+ if (frames == 0) {
if (save_fp_at_nframes > 0) {
observed_nframes = backtrace_from_fp(save_fp, observed_bt,
MAX_FRAMES);
static int __attribute__((noinline,not_tail_called,disable_tail_calls))
recurse_b(unsigned int frames)
{
- if (frames == 1) {
+ if (frames == 0) {
if (save_fp_at_nframes > 0) {
observed_nframes = backtrace_from_fp(save_fp, observed_bt,
MAX_FRAMES);
}
static void __attribute__((noinline,not_tail_called,disable_tail_calls))
-setup_and_backtrace(unsigned int nframes, unsigned int skip_nframes)
+setup_and_backtrace(unsigned int nframes, unsigned int skip)
{
- save_fp_at_nframes = skip_nframes ? skip_nframes - 1 : 0;
+ save_fp_at_nframes = skip ? skip - 1 : 0;
recurse_a(nframes - 1);
}
return info->dli_saddr == setup_fp;
}
-static void __attribute__((noinline))
+static void __attribute__((noinline,not_tail_called))
expect_backtrace(void)
{
void *recurse_a_fp = (void *)&recurse_a;
T_EXPECT_EQ(expected_nframes,
observed_nframes - observed_existing_nframes,
- "number of frames traced matches");
- bool expect_a = true;
+ "number of frames traced matches %d", expected_nframes);
+ bool expect_a = !(skip_nframes % 2);
bool found_setup = false;
for (int i = 0; i < observed_nframes; i++) {
void *expected_saddr = expect_a ? recurse_a_fp : recurse_b_fp;
void *observed_saddr = info.dli_saddr;
- T_EXPECT_GE(observed_saddr, expected_saddr,
- "frame %d (%p) matches", i, observed_bt[i]);
+ T_EXPECT_EQ(observed_saddr, expected_saddr,
+ "frame %d (%p: %s) matches", i, observed_bt[i], info.dli_sname);
expect_a = !expect_a;
}
T_DECL(backtrace_from_fp,
"ensure backtrace_from_fp(3) starts from the correct frame")
{
- const int skip_nframes = 5;
setup_and_backtrace(expected_nframes + skip_nframes, skip_nframes);
expect_backtrace();
}
T_EXPECT_TRUE(found_setup, "should have found the setup frame");
}
+
+T_DECL(backtrace_symbols, "tests backtrace_symbols")
+{
+ setup_and_backtrace(expected_nframes, 0);
+
+ char **symbols = backtrace_symbols(observed_bt, observed_nframes);
+
+ bool found_setup = false;
+
+ for (int i = 0; i < observed_nframes; i++) {
+ T_LOG("frame[%d]: %s", i, symbols[i]);
+ if (strstr(symbols[i], "setup_and_backtrace") != NULL) {
+ found_setup = true;
+ }
+ }
+
+ T_EXPECT_TRUE(found_setup, "should have found the setup frame");
+
+ free(symbols);
+}
--- /dev/null
+#include <darwintest.h>
+
+#include "../libdarwin/bsd.c"
+
+static struct test_case {
+ const char *args;
+ const char *argname;
+ const char *argvalue;
+} test_cases[] = {
+ {"-x -a b=3 y=42", "-a", ""},
+ {"-x -a b=3 y=42", "b", "3"},
+ {"-x -a b=2 ba=3 y=42", "b", "2"},
+ {"-x -a ba=3 b=2 y=42", "b", "2"},
+ {"-x -a b=2 ba=3 y=42", "ba", "3"},
+ {"-x -a ba=3 b=2 y=42", "ba", "3"},
+ {"-x -ab -aa y=42", "-a", NULL},
+ {"-x b=96 y=42", "bx", NULL},
+ {"-x ab=96 y=42", "a", NULL},
+};
+
+T_DECL(parse_boot_arg_value, "Parsing boot args")
+{
+ for (int i = 0; i < (int)(sizeof(test_cases)/sizeof(test_cases[0])); i++) {
+ struct test_case *test_case = &test_cases[i];
+ T_LOG("\"%s\": Looking for \"%s\", expecting \"%s\"",
+ test_case->args, test_case->argname, test_case->argvalue);
+
+ char *argbuff = strdup(test_case->args);
+
+ char result[256] = "NOT_FOUND";
+ bool found = _parse_boot_arg_value(argbuff, test_case->argname,
+ result,sizeof(result));
+
+ if (test_case->argvalue) {
+ T_EXPECT_EQ(found, true, "Should find argument");
+ T_EXPECT_EQ_STR(result, test_case->argvalue, "Should find correct result");
+ } else {
+ T_EXPECT_EQ(found, false, "Should not find argument");
+ }
+
+ free(argbuff);
+ }
+}
+
+T_DECL(os_parse_boot_arg, "Getting boot args")
+{
+ int64_t value = 0;
+ T_EXPECT_EQ(os_parse_boot_arg_int("notarealthing", &value), false, NULL);
+
+ T_MAYFAIL;
+ T_EXPECT_EQ(os_parse_boot_arg_int("debug", &value), true, NULL);
+ T_EXPECT_GT(value, 0LL, "non-zero debug= value");
+
+ char buf[64] = {};
+
+ T_EXPECT_EQ(os_parse_boot_arg_string("notarealthing", buf, sizeof(buf)), false, NULL);
+
+ T_MAYFAIL;
+ T_EXPECT_EQ(os_parse_boot_arg_string("debug", buf, sizeof(buf)), true, NULL);
+ T_EXPECT_GT(strlen(buf), 0UL, "non-empty debug= value");
+}
--- /dev/null
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <darwintest.h>
+#include <darwintest_utils.h>
+
+static char tmpfile_template[] = "/tmp/libc_test_fflushXXXXX";
+#define BUFSZ 128
+static char wrbuf[BUFSZ] = "";
+static const size_t filesz = BUFSZ * 120;
+
+static void
+cleanup_tmp_file(void)
+{
+ (void)unlink(tmpfile_template);
+}
+
+static const char *
+assert_empty_tmp_file(void)
+{
+ T_SETUPBEGIN;
+
+ int tmpfd = mkstemp(tmpfile_template);
+ T_ASSERT_POSIX_SUCCESS(tmpfd, "created tmp file at %s", tmpfile_template);
+ T_ATEND(cleanup_tmp_file);
+ close(tmpfd);
+
+ T_SETUPEND;
+
+ return tmpfile_template;
+}
+
+static const char *
+assert_full_tmp_file(void)
+{
+ T_SETUPBEGIN;
+
+ int tmpfd = mkstemp(tmpfile_template);
+ T_ASSERT_POSIX_SUCCESS(tmpfd, "created tmp file at %s", tmpfile_template);
+ T_ATEND(cleanup_tmp_file);
+
+ /*
+ * Write a pattern of bytes into the file -- the lowercase alphabet,
+ * separated by newlines.
+ */
+ for (size_t i = 0; i < BUFSZ; i++) {
+ wrbuf[i] = 'a' + (i % 27);
+ if (i % 27 == 26) {
+ wrbuf[i] = '\n';
+ }
+ }
+ for (size_t i = 0; i < filesz; i++) {
+ ssize_t byteswr = 0;
+ do {
+ byteswr = write(tmpfd, wrbuf, BUFSZ);
+ } while (byteswr == -1 && errno == EAGAIN);
+
+ T_QUIET; T_ASSERT_POSIX_SUCCESS(byteswr, "wrote %d bytes to tmp file",
+ BUFSZ);
+ T_QUIET; T_ASSERT_EQ(byteswr, (ssize_t)BUFSZ,
+ "wrote correct amount of bytes to tmp file");
+ }
+
+ close(tmpfd);
+
+ T_SETUPEND;
+
+ return tmpfile_template;
+}
+
+/*
+ * Ensure that fflush on an input stream conforms to the SUSv3 definition, which
+ * requires synchronizing the FILE position with the underlying file descriptor.
+ */
+T_DECL(fflush_input, "fflush on a read-only FILE resets fd offset")
+{
+ const char *tmpfile = assert_full_tmp_file();
+
+ T_SETUPBEGIN;
+
+ FILE *tmpf = fopen(tmpfile, "r");
+ T_QUIET; T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(tmpf, "opened tmp file for reading");
+
+ /*
+ * Move some way into the file.
+ */
+ char buf[100] = "";
+ size_t nread = fread(buf, sizeof(buf), 1, tmpf);
+ T_ASSERT_EQ(nread, (size_t)1, "read correct number of items from FILE");
+ char last_read_char = buf[sizeof(buf) - 1];
+
+ off_t curoff = lseek(fileno(tmpf), 0, SEEK_CUR);
+ T_ASSERT_GT(curoff, (off_t)0, "file offset should be non-zero");
+
+ T_SETUPEND;
+
+ /*
+ * fflush(3) to reset the fd back to the FILE offset.
+ */
+ int ret = fflush(tmpf);
+ T_ASSERT_POSIX_SUCCESS(ret, "fflush on read-only FILE");
+
+ off_t flushoff = lseek(fileno(tmpf), 0, SEEK_CUR);
+ T_ASSERT_EQ(flushoff, (off_t)sizeof(buf),
+ "offset of file should be bytes read on FILE after fflush");
+
+ /*
+ * Make sure the FILE is reading the right thing -- the next character
+ * should be one letter after the last byte read, from the last call to
+ * fread(3).
+ */
+ char c = '\0';
+ nread = fread(&c, sizeof(c), 1, tmpf);
+ T_QUIET;
+ T_ASSERT_EQ(nread, (size_t)1, "read correct number of items from FILE");
+
+ /*
+ * The pattern in the file is the alphabet -- and this doesn't land on
+ * a newline.
+ */
+ T_QUIET;
+ T_ASSERT_NE((flushoff) % 27, (off_t)0,
+ "previous offset shouldn't land on newline");
+ T_QUIET;
+ T_ASSERT_NE((flushoff + 1) % 27, (off_t)0,
+ "current offset shouldn't land on newline");
+
+ T_ASSERT_EQ(c, last_read_char + 1, "read correct byte after fflush");
+
+ ret = fflush(tmpf);
+ T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "fflush on read-only FILE");
+
+ flushoff = lseek(fileno(tmpf), 0, SEEK_CUR);
+ T_ASSERT_EQ(flushoff, (off_t)(sizeof(buf) + sizeof(c)),
+ "offset of file should be incremented after subsequent read");
+
+ /*
+ * Use ungetc(3) to induce the optimized ungetc behavior in the FILE.
+ */
+ int ugret = ungetc(c, tmpf);
+ T_QUIET; T_ASSERT_NE(ugret, EOF, "ungetc after fflush");
+ T_QUIET; T_ASSERT_EQ((char)ugret, c, "ungetc un-got the correct char");
+
+ ret = fflush(tmpf);
+ T_ASSERT_POSIX_SUCCESS(ret, "fflush after ungetc");
+ flushoff = lseek(fileno(tmpf), 0, SEEK_CUR);
+ T_ASSERT_EQ(flushoff, (off_t)sizeof(buf),
+ "offset of file should be correct after ungetc and fflush");
+
+ nread = fread(&c, sizeof(c), 1, tmpf);
+ T_QUIET;
+ T_ASSERT_EQ(nread, (size_t)1, "read correct number of items from FILE");
+ T_ASSERT_EQ(c, last_read_char + 1,
+ "read correct byte after ungetc and fflush");
+}
+
+/*
+ * Try to trick fclose into not reporting an ENOSPC error from the underlying
+ * descriptor in update mode. Previous versions of Libc only flushed the FILE
+ * if it was write-only.
+ */
+
+#if TARGET_OS_OSX
+/*
+ * Only macOS contains a version of hdiutil that can create disk images.
+ */
+
+#define DMGFILE "/tmp/test_fclose_enospc.dmg"
+#define VOLNAME "test_fclose_enospc"
+static const char *small_file = "/Volumes/" VOLNAME "/test.txt";
+
+static void
+cleanup_dmg(void)
+{
+ char *hdiutil_detach_argv[] = {
+ "/usr/bin/hdiutil", "detach", "/Volumes/" VOLNAME, NULL,
+ };
+ pid_t hdiutil_detach = -1;
+ int ret = dt_launch_tool(&hdiutil_detach, hdiutil_detach_argv, false, NULL,
+ NULL);
+ if (ret != -1) {
+ int status = 0;
+ (void)waitpid(hdiutil_detach, &status, 0);
+ }
+ (void)unlink(DMGFILE);
+}
+
+T_DECL(fclose_enospc, "ensure ENOSPC is preserved on fclose")
+{
+ T_SETUPBEGIN;
+
+ /*
+ * Ensure a disk is available that will fill up and start returning ENOSPC.
+ *
+ * system(3) would be easier...
+ */
+ char *hdiutil_argv[] = {
+ "/usr/bin/hdiutil", "create", "-size", "5m", "-type", "UDIF",
+ "-volname", VOLNAME, "-nospotlight", "-fs", "HFS+", DMGFILE, "-attach",
+ NULL,
+ };
+ pid_t hdiutil_create = -1;
+ int ret = dt_launch_tool(&hdiutil_create, hdiutil_argv, false, NULL, NULL);
+ T_ASSERT_POSIX_SUCCESS(ret, "created and attached 5MB DMG");
+ int status = 0;
+ pid_t waited = waitpid(hdiutil_create, &status, 0);
+ T_QUIET; T_ASSERT_EQ(waited, hdiutil_create,
+ "should have waited for the process that was launched");
+ T_QUIET;
+ T_ASSERT_TRUE(WIFEXITED(status), "hdiutil should have exited");
+ T_QUIET;
+ T_ASSERT_EQ(WEXITSTATUS(status), 0,
+ "hdiutil should have exited successfully");
+
+ T_ATEND(cleanup_dmg);
+
+ /*
+ * Open for updating, as previously only write-only files would be flushed
+ * on fclose.
+ */
+ FILE *fp = fopen(small_file, "a+");
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fp, "opened file at %s for append-updating", small_file);
+
+ char *buf = malloc(BUFSIZ);
+ T_QUIET; T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(buf, "should allocate BUFSIZ bytes");
+
+ for (int i = 0; i < BUFSIZ; i++) {
+ buf[i] = (char)(i % 256);
+ }
+
+ /*
+ * Fill up the disk -- induce ENOSPC.
+ */
+ size_t wrsize = BUFSIZ;
+ for (int i = 0; i < 2; i++) {
+ for (;;) {
+ errno = 0;
+ if (write(fileno(fp), buf, wrsize) < 0) {
+ if (errno == ENOSPC) {
+ break;
+ }
+ T_WITH_ERRNO; T_ASSERT_FAIL("write(2) failed");
+ }
+ }
+ wrsize = 1;
+ }
+ T_PASS("filled up the file until ENOSPC");
+ free(buf);
+
+ /*
+ * Make sure the FILE is at the end, so any writes it does hit ENOSPC.
+ */
+ ret = fseek(fp, 0, SEEK_END);
+ T_ASSERT_POSIX_SUCCESS(ret, "fseek to the end of a complete file");
+
+ /*
+ * Try to push a character into the file; since this is buffered, it should
+ * succeed.
+ */
+ ret = fputc('a', fp);
+ T_ASSERT_POSIX_SUCCESS(ret,
+ "fputc to put an additional character in the FILE");
+
+ T_SETUPEND;
+
+ /*
+ * fclose should catch the ENOSPC error when it flushes the file, before it
+ * closes the underlying descriptor.
+ */
+ errno = 0;
+ ret = fclose(fp);
+ if (ret != EOF) {
+ T_ASSERT_FAIL("fclose should fail when the FILE is full");
+ }
+ if (errno != ENOSPC) {
+ T_WITH_ERRNO; T_ASSERT_FAIL("fclose should fail with ENOSPC");
+ }
+
+ T_PASS("fclose returned ENOSPC");
+}
+
+#endif // TARGET_OS_OSX
+
+/*
+ * Ensure no errors are returned when flushing a read-only, unseekable input
+ * stream.
+ */
+T_DECL(fflush_unseekable_input,
+ "ensure sanity when an unseekable input stream is flushed")
+{
+ T_SETUPBEGIN;
+
+ /*
+ * Use a pipe for the unseekable streams.
+ */
+ int pipes[2];
+ int ret = pipe(pipes);
+ T_ASSERT_POSIX_SUCCESS(ret, "create a pipe");
+ FILE *in = fdopen(pipes[0], "r");
+ T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(in,
+ "open input stream to read end of pipe");
+ FILE *out = fdopen(pipes[1], "w");
+ T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(out,
+ "open output stream to write end of pipe");
+
+ /*
+ * Fill the pipe with some text (but not too much that the write would
+ * block!).
+ */
+ fprintf(out, "this is a test and has some more text");
+ ret = fflush(out);
+ T_ASSERT_POSIX_SUCCESS(ret, "flushed the output stream");
+
+ /*
+ * Protect stdio from delving too deep into the pipe.
+ */
+ char inbuf[8] = {};
+ setbuffer(in, inbuf, sizeof(inbuf));
+
+ /*
+ * Just read a teensy bit to get the FILE offset different from the
+ * descriptor "offset."
+ */
+ char rdbuf[2] = {};
+ size_t nitems = fread(rdbuf, sizeof(rdbuf), 1, in);
+ T_QUIET; T_ASSERT_GT(nitems, (size_t)0,
+ "read from the read end of the pipe");
+
+ T_SETUPEND;
+
+ ret = fflush(in);
+ T_ASSERT_POSIX_SUCCESS(ret,
+ "should successfully flush unseekable input stream after reading");
+}
+
+/*
+ * Ensure that reading to the end of a file and then calling ftell() still
+ * causes EOF.
+ */
+T_DECL(ftell_feof,
+ "ensure ftell does not reset feof when actually at end of file") {
+ T_SETUPBEGIN;
+ FILE *fp = fopen("/System/Library/CoreServices/SystemVersion.plist", "rb");
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fp, "opened SystemVersion.plist");
+ struct stat sb;
+ T_ASSERT_POSIX_SUCCESS(fstat(fileno(fp), &sb), "fstat SystemVersion.plist");
+ void *buf = malloc(sb.st_size * 2);
+ T_ASSERT_NOTNULL(buf, "allocating buffer for size of SystemVersion.plist");
+ T_SETUPEND;
+
+ T_ASSERT_POSIX_SUCCESS(fseek(fp, 0, SEEK_SET), "seek to beginning");
+ // fread can return short *or* zero, according to manpage
+ fread(buf, sb.st_size * 2, 1, fp);
+ T_ASSERT_EQ(ftell(fp), sb.st_size, "tfell() == file size");
+ T_ASSERT_TRUE(feof(fp), "feof() reports end-of-file");
+ free(buf);
+}
+
+T_DECL(putc_flush, "ensure putc flushes to file on close") {
+ const char *fname = assert_empty_tmp_file();
+ FILE *fp = fopen(fname, "w");
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fp, "opened temporary file read/write");
+ T_WITH_ERRNO;
+ T_ASSERT_EQ(fwrite("testing", 1, 7, fp), 7, "write temp contents");
+ (void)fclose(fp);
+
+ fp = fopen(fname, "r+");
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fp, "opened temporary file read/write");
+
+ T_ASSERT_POSIX_SUCCESS(fseek(fp, -1, SEEK_END), "seek to end - 1");
+ T_ASSERT_EQ(fgetc(fp), 'g', "fgetc should read 'g'");
+ T_ASSERT_EQ(fgetc(fp), EOF, "fgetc should read EOF");
+ T_ASSERT_EQ(ftell(fp), 7, "tfell should report position 7");
+
+ int ret = fputc('!', fp);
+ T_ASSERT_POSIX_SUCCESS(ret,
+ "fputc to put an additional character in the FILE");
+ T_ASSERT_EQ(ftell(fp), 8, "tfell should report position 8");
+
+ T_QUIET;
+ T_ASSERT_POSIX_SUCCESS(fclose(fp), "close temp file");
+
+ fp = fopen(fname, "r");
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fp, "opened temporary file read/write");
+
+ char buf[9];
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fgets(buf, sizeof(buf), fp), "read file data");
+ T_ASSERT_EQ_STR(buf, "testing!", "read all the new data");
+
+ (void)fclose(fp);
+}
+
+T_DECL(putc_writedrop, "ensure writes are flushed with a pending read buffer") {
+ const char *fname = assert_empty_tmp_file();
+ FILE *fp = fopen(fname, "w");
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fp, "opened temporary file read/write");
+ T_WITH_ERRNO;
+ T_ASSERT_EQ(fwrite("testing", 1, 7, fp), 7, "write temp contents");
+ (void)fclose(fp);
+
+ fp = fopen(fname, "r+");
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fp, "opened temporary file read/write");
+
+ T_ASSERT_POSIX_SUCCESS(fseek(fp, -1, SEEK_END), "seek to end - 1");
+
+ int ret = fputc('!', fp);
+ T_ASSERT_POSIX_SUCCESS(ret,
+ "fputc to put an additional character in the FILE");
+ // flush the write buffer by reading a byte from the stream to put the
+ // FILE* into read mode
+ T_ASSERT_EQ(fgetc(fp), EOF, "fgetc should read EOF");
+
+ T_QUIET;
+ T_ASSERT_POSIX_SUCCESS(fclose(fp), "close temp file");
+
+ fp = fopen(fname, "r");
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fp, "opened temporary file read/write");
+
+ char buf[9];
+ T_WITH_ERRNO;
+ T_ASSERT_NOTNULL(fgets(buf, sizeof(buf), fp), "read file data");
+ T_ASSERT_EQ_STR(buf, "testin!", "read all the new data");
+
+ (void)fclose(fp);
+}
T_EXPECT_EQ(inet_pton(AF_INET6, in_addr, &addr6), 1, "inet_pton(AF_INET6, %s)", in_addr);
char *str = inet_ntop(AF_INET6, &addr6, buf, sizeof(buf));
T_EXPECT_NOTNULL(str, "inet_ntop(AF_INET6) of %s", in_addr);
- // <rdar://problem/32825795> Single-zero tests will fail until change
- // implemented.
- if (i < 2) {
- T_EXPECTFAIL;
- }
T_EXPECT_EQ_STR(str, expected_out_addr, NULL);
}
T_QUIET;
T_EXPECT_NOTNULL(str, "inet_ntop(AF_INET6) of %s", in_addr);
T_QUIET;
- // <rdar://problem/32825795>
- if (i == 0) {
- T_PASS("Never displayed"); // Cancel out the T_QUIET
- T_EXPECTFAIL;
- }
T_EXPECT_EQ_STR(str, expected_out_addr, NULL);
}
T_PASS("Passed ipv6 value testing");
}
+
+static void
+conv(const char *addr)
+{
+ int ret;
+ void *retp;
+
+ struct in6_addr addr6;
+ memset(&addr6, 0, sizeof addr6);
+ ret = inet_pton(AF_INET6, addr, &addr6);
+ T_ASSERT_EQ(ret, 1, "inet_pton");
+
+ T_LOG("%s: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", addr,
+ ((unsigned char *) &addr6)[0], ((unsigned char *) &addr6)[1], ((unsigned char *) &addr6)[2], ((unsigned char *) &addr6)[3],
+ ((unsigned char *) &addr6)[4], ((unsigned char *) &addr6)[5], ((unsigned char *) &addr6)[6], ((unsigned char *) &addr6)[7],
+ ((unsigned char *) &addr6)[8], ((unsigned char *) &addr6)[9], ((unsigned char *) &addr6)[10], ((unsigned char *) &addr6)[11],
+ ((unsigned char *) &addr6)[12], ((unsigned char *) &addr6)[13], ((unsigned char *) &addr6)[14], ((unsigned char *) &addr6)[15]);
+
+ char buf6[INET6_ADDRSTRLEN];
+ memset(buf6, 0, sizeof buf6);
+ retp = inet_ntop(AF_INET6, &addr6, buf6, (socklen_t) sizeof buf6);
+ T_ASSERT_NOTNULL(retp, "inet_ntop");
+
+ T_LOG("%s: %s\n", addr, buf6);
+
+ T_EXPECT_EQ_STR(addr, buf6, NULL);
+}
+
+T_DECL(inet_ntop_PR46867324, "Regression test for PR46867324")
+{
+ conv("2001:db8::1");
+ conv("::192.168.1.2");
+ conv("::ffff:10.11.12.13");
+}
case FTS_DP:
(void)memset(buf, 0, sizeof(buf));
+ T_WITH_ERRNO;
T_ASSERT_NOTNULL(getcwd(buf, sizeof(buf)), NULL);
+ T_LOG("ftse->fts_path: %s", ftse->fts_path);
T_ASSERT_NOTNULL(strstr(ftse->fts_path, buf), NULL);
break;
hashval = os_simple_hash(buf, sizeof(buf));
T_EXPECT_NE(hashval, 0ULL, "usually should get a non-0 hash value");
}
+
+T_DECL(os_simple_hash_seeds, "os_simple_hash different seeds give different hashes",
+ T_META_ALL_VALID_ARCHS(true))
+{
+ const char * string =
+ "We made the buttons on the screen look so good you'll want to lick them.";
+
+ uint64_t hashval0 = os_simple_hash_string_with_seed(string, 0x0);
+ T_EXPECT_NE(hashval0, 0ULL, "usually should get a non-0 hash value");
+ uint64_t hashval1 = os_simple_hash_string_with_seed(string, 0x1);
+ T_EXPECT_NE(hashval1, 0ULL, "usually should get a non-0 hash value");
+ uint64_t hashvalF = os_simple_hash_string_with_seed(string, 0xF);
+ T_EXPECT_NE(hashvalF, 0ULL, "usually should get a non-0 hash value");
+ uint64_t hashvalFoo = os_simple_hash_string_with_seed(string, 0xF0000000);
+ T_EXPECT_NE(hashvalFoo, 0ULL, "usually should get a non-0 hash value");
+
+ T_EXPECT_NE(hashval0, hashval1, NULL);
+ T_EXPECT_NE(hashval0, hashvalF, NULL);
+ T_EXPECT_NE(hashval0, hashvalFoo, NULL);
+ T_EXPECT_NE(hashval1, hashvalF, NULL);
+ T_EXPECT_NE(hashval1, hashvalFoo, NULL);
+ T_EXPECT_NE(hashvalF, hashvalFoo, NULL);
+}
T_MAYFAIL;
T_EXPECT_FALSE(os_variant_has_factory_content("com.apple.Libc.tests"), NULL);
+
+ T_MAYFAIL;
+ T_EXPECT_FALSE(os_variant_is_darwinos("com.apple.Libc.tests"), NULL);
+
+ T_MAYFAIL;
+ T_EXPECT_FALSE(os_variant_uses_ephemeral_storage("com.apple.Libc.tests"), NULL);
}
#define VARIANT_SKIP_EXPORTED
T_EXPECT_TRUE(os_variant_allows_internal_security_policies(NULL), NULL);
status = STATUS_INITIAL_BITS |
- (S_NO << (SFP_CAN_HAS_DEBUGGER * STATUS_BIT_WIDTH));
- T_LOG("Restoring status without can_has_debugger: %llx", status);
+ (S_NO << (SFP_CAN_HAS_DEBUGGER * STATUS_BIT_WIDTH)) |
+ (S_NO << (SFP_DEVELOPMENT_KERNEL * STATUS_BIT_WIDTH));
+ T_LOG("Restoring status without can_has_debugger and development_kernel: %llx", status);
_restore_cached_check_status(status);
T_EXPECT_FALSE(_check_can_has_debugger(), NULL);
--- /dev/null
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <os/variant_private.h>
+
+#include "../libdarwin/variant.c"
+
+#define bool2str(b) (b ? "true" : "false")
+
+static void __dead2
+usage(void)
+{
+ printf("osvariantutil status\n");
+ printf("osvariantutil parse <kern.osvariant_status>\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[]) {
+ // Warm up the dispatch_once
+ _check_disabled(VP_CONTENT);
+
+ if (argc == 2 && strcmp(argv[1], "status") == 0) {
+ uint64_t status = _get_cached_check_status();
+ printf("Cached status: %llx\n", status);
+ } else if (argc == 3 && strcmp(argv[1], "parse") == 0) {
+ uint64_t status = strtoull(argv[2], NULL, 0);
+ if ((status & STATUS_INITIAL_BITS) != STATUS_INITIAL_BITS) {
+ printf("Invalid status: 0x%llx\n", status);
+ exit(1);
+ }
+ _restore_cached_check_status(status);
+ printf("Using status: %llx\n", status);
+ } else {
+ usage();
+ }
+
+ printf("\nOS Variants:\n");
+ printf("\tos_variant_has_internal_content: %s\n",
+ bool2str(os_variant_has_internal_content("com.apple.osvariantutil")));
+ printf("\tos_variant_has_internal_diagnostics: %s\n",
+ bool2str(os_variant_has_internal_diagnostics("com.apple.osvariantutil")));
+ printf("\tos_variant_has_internal_ui: %s\n",
+ bool2str(os_variant_has_internal_ui("com.apple.osvariantutil")));
+ printf("\tos_variant_allows_internal_security_properties: %s\n",
+ bool2str(os_variant_allows_internal_security_policies("com.apple.osvariantutil")));
+ printf("\tos_variant_has_factory_content: %s\n",
+ bool2str(os_variant_has_factory_content("com.apple.osvariantutil")));
+ printf("\tos_variant_is_darwinos: %s\n",
+ bool2str(os_variant_is_darwinos("com.apple.osvariantutil")));
+ printf("\tos_variant_uses_ephemeral_storage: %s\n",
+ bool2str(os_variant_uses_ephemeral_storage("com.apple.osvariantutil")));
+ printf("\tos_variant_is_recovery: %s\n",
+ bool2str(os_variant_is_recovery("com.apple.osvariantutil")));
+
+ printf("\nOS Variant Overrides:\n");
+ printf("\tCONTENT: %s\n", bool2str(_check_disabled(VP_CONTENT)));
+ printf("\tDIAGNOSTICS: %s\n", bool2str(_check_disabled(VP_DIAGNOSTICS)));
+ printf("\tUI: %s\n", bool2str(_check_disabled(VP_UI)));
+ printf("\tSECURITY: %s\n", bool2str(_check_disabled(VP_SECURITY)));
+
+ printf("\nOS Variant Inputs:\n");
+#if !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ printf("\tInternal Content: %s\n", bool2str(_check_internal_content()));
+#endif
+#if TARGET_OS_IPHONE
+ printf("\tInternal Release Type: %s\n", bool2str(_check_internal_release_type()));
+ printf("\tFactory Release Type: %s\n", bool2str(_check_factory_release_type()));
+ printf("\tDarwin Release Type: %s\n", bool2str(_check_darwin_release_type()));
+ printf("\tRecovery Release Type: %s\n", bool2str(_check_recovery_release_type()));
+ printf("\tDevelopment Kernel: %s\n", bool2str(_check_development_kernel()));
+#else
+ printf("\tInternal Diags Profile: %s\n", bool2str(_check_internal_diags_profile()));
+ printf("\tFactory Content: %s\n", bool2str(_check_factory_content()));
+ printf("\tBaseSystem Content: %s\n", bool2str(_check_base_system_content()));
+#endif
+ printf("\tCan Has Debugger: %s\n", bool2str(_check_can_has_debugger()));
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <locale.h>
+
+#include <darwintest.h>
+
+static char *expectations[] = {
+ "inclonclusive", /* -1 */
+ "negative", /* 0 */
+ "affirmative" /* 1 */
+};
+
+static size_t
+dumb_strescape(char * dst, const char * in, size_t len) {
+ size_t count = 0;
+
+ while (*in && count + 3 < len) {
+ switch (*in) {
+ case '\"':
+ *dst++ = '\\';
+ *dst++ = '\"';
+ count += 2;
+ break;
+ case '\'':
+ *dst++ = '\\';
+ *dst++ = '\"';
+ count += 2;
+ break;
+ case '\\':
+ *dst++ = '\\';
+ *dst++ = '\\';
+ count += 2;
+ break;
+ case '\a':
+ *dst++ = '\\';
+ *dst++ = 'a';
+ count += 2;
+ break;
+ case '\b':
+ *dst++ = '\\';
+ *dst++ = 'b';
+ count += 2;
+ break;
+ case '\n':
+ *dst++ = '\\';
+ *dst++ = 'n';
+ count += 2;
+ break;
+ case '\t':
+ *dst++ = '\\';
+ *dst++ = 't';
+ count += 2;
+ break;
+ /* There are many more special cases */
+ default:
+ if (iscntrl(*in)) {
+ count += (size_t)snprintf(dst, len - count, "\\%03o", *in);
+ }
+ else {
+ *dst++ = *in;
+ count++;
+ }
+ }
+ in++;
+ }
+ *dst++ = '\0';
+ return count;
+}
+
+static void
+rpmatch_testcase(const char * response, int expectation) {
+ const char * expect_msg = expectations[expectation+1];
+
+ char escaped_response[16];
+ dumb_strescape(escaped_response, response, sizeof(escaped_response)/sizeof(char));
+
+ /* darwintest should escape special characters in message strings */
+ T_EXPECT_EQ(rpmatch(response), expectation, "'%s' is %s in the %s locale", escaped_response, expect_msg, setlocale(LC_ALL, NULL));
+}
+
+T_DECL(rpmatch, "Ensure rpmatch responds to locales")
+{
+ setlocale(LC_ALL, "C");
+
+ /* Check several single character variants */
+ rpmatch_testcase("y", 1);
+ rpmatch_testcase("Y", 1);
+ rpmatch_testcase("j", -1); /* becomes afirmative in german */
+ rpmatch_testcase("J", -1);
+ rpmatch_testcase("x", -1);
+ rpmatch_testcase(" ", -1);
+ rpmatch_testcase("", -1);
+ rpmatch_testcase("n", 0);
+ rpmatch_testcase("N", 0);
+
+ /* A few full words */
+ rpmatch_testcase("yes", 1);
+ rpmatch_testcase("ja", -1);
+ rpmatch_testcase("no", 0);
+
+ /* Check each variant with a newline */
+ rpmatch_testcase("y\n", 1);
+ rpmatch_testcase("Y\n", 1);
+ rpmatch_testcase("j\n", -1);
+ rpmatch_testcase("J\n", -1);
+ rpmatch_testcase("x\n", -1);
+ rpmatch_testcase(" \n", -1);
+ rpmatch_testcase("\n", -1);
+ rpmatch_testcase("n\n", 0);
+ rpmatch_testcase("N\n", 0);
+
+ rpmatch_testcase("yes\n", 1);
+ rpmatch_testcase("ja\n", -1);
+ rpmatch_testcase("no\n", 0);
+
+ /* Do it all again in a german locale */
+ setlocale(LC_ALL, "de_DE.ISO8859-1");
+
+ if (strcmp(setlocale(LC_ALL, NULL), "de_DE.ISO8859-1") != 0) {
+ T_LOG("This system does not have a de_DE.ISO8859-1 locale");
+ return;
+ }
+
+ /* Check several single character variants */
+ rpmatch_testcase("y", 1);
+ rpmatch_testcase("Y", 1);
+ rpmatch_testcase("j", 1); /* now afirmative */
+ rpmatch_testcase("J", 1);
+ rpmatch_testcase("x", -1);
+ rpmatch_testcase(" ", -1);
+ rpmatch_testcase("", -1);
+ rpmatch_testcase("n", 0);
+ rpmatch_testcase("N", 0);
+
+ /* A few full words */
+ rpmatch_testcase("yes", 1);
+ rpmatch_testcase("ja", 1);
+ rpmatch_testcase("xx", -1);
+ rpmatch_testcase("no", 0);
+
+ /* Check each variant with a newline */
+ rpmatch_testcase("y\n", 1);
+ rpmatch_testcase("Y\n", 1);
+ rpmatch_testcase("j\n", 1);
+ rpmatch_testcase("J\n", 1);
+ rpmatch_testcase("x\n", -1);
+ rpmatch_testcase(" \n", -1);
+ rpmatch_testcase("\n", -1);
+ rpmatch_testcase("n\n", 0);
+ rpmatch_testcase("N\n", 0);
+
+ rpmatch_testcase("yes\n", 1);
+ rpmatch_testcase("ja\n", 1);
+ rpmatch_testcase("xx\n", -1);
+ rpmatch_testcase("no\n", 0);
+}
T_DECL(strptime_five_digit_year, "strptime(%Y) with a 5 digit year")
{
+ // POSIX conformance requires that %Y only use 4 characters, so use the
+ // field width to change that for this test.
char *timestr = "20080922T020000";
struct tm tm;
bzero(&tm, sizeof(tm));
- T_ASSERT_NOTNULL(strptime("10001", "%Y", &tm), NULL);
+ T_ASSERT_NOTNULL(strptime("10001", "%5Y", &tm), NULL);
T_EXPECT_EQ(tm.tm_year, 10001 - 1900, NULL);
T_ASSERT_NOTNULL(strptime(timestr, "%Y%m%dT%H%M%S", &tm), NULL);
}
#include <darwintest.h>
-T_DECL(strlcpy_PR_30745460, "Test return value of strlcpy(2)",
+T_DECL(strlcpy_PR_30745460, "Test return value of strlcpy(3)",
T_META_CHECK_LEAKS(NO))
{
char buf[1];
(void)strptime("1993-03-02 12:00:00", "%F %T", &t);
T_EXPECT_EQ(t.tm_wday, 2, NULL);
}
+
+
+T_DECL(strptime_PR_42669744_1, "strptime() with %%C, %%y and %%Y")
+{
+ struct tm tm;
+ char *result;
+
+ // %C%y combinations
+ T_LOG("201, %%C%%y");
+ result = strptime("201", "%C%y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "201, %%C%%y");
+ T_EXPECT_EQ(tm.tm_year, 2001 - 1900, NULL);
+
+ T_LOG("2010, %%C%%y");
+ result = strptime("2010", "%C%y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "2010, %%C%%y");
+ T_EXPECT_EQ(tm.tm_year, 2010 - 1900, NULL);
+
+ T_LOG("20010, %%C%%y");
+ result = strptime("20010", "%C%y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "20010, %%C%%y");
+ T_EXPECT_EQ(tm.tm_year, 2001 - 1900, NULL);
+
+ T_LOG("+2010, %%C%%y");
+ result = strptime("+2010", "%C%y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "2010, %%C%%y");
+ T_EXPECT_EQ(tm.tm_year, 201 - 1900, NULL);
+
+ T_LOG("-20100, %%C%%y");
+ result = strptime("-20100", "%C%y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "-20100, %%C%%y");
+ T_EXPECT_EQ(tm.tm_year, -200 + 1 - 1900, NULL);
+
+ T_LOG("-2-1, %%C%%y");
+ result = strptime("-2-1", "%C%y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "-2-1, %%C%%y");
+ T_EXPECT_EQ(tm.tm_year, -200 - 1 - 1900, NULL);
+
+ T_LOG("-2+1, %%C%%y");
+ result = strptime("-2+1", "%C%y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "-2+1, %%C%%y");
+ T_EXPECT_EQ(tm.tm_year, -200 + 1 - 1900, NULL);
+
+ // %Y combinations
+ T_LOG("201, %%Y");
+ result = strptime("201", "%Y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "201, %%Y");
+ T_EXPECT_EQ(tm.tm_year, 201 - 1900, NULL);
+
+ T_LOG("2001, %%Y");
+ result = strptime("2001", "%Y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "2001, %%Y");
+ T_EXPECT_EQ(tm.tm_year, 2001 - 1900, NULL);
+
+ T_LOG("20010, %%Y");
+ result = strptime("20010", "%Y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "20010, %%Y");
+ T_EXPECT_EQ(tm.tm_year, 2001 - 1900, NULL);
+
+ T_LOG("+2010, %%Y");
+ result = strptime("+2010", "%Y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "+2010, %%Y");
+ T_EXPECT_EQ(tm.tm_year, 201 - 1900, NULL);
+
+ T_LOG("-2010, %%Y");
+ result = strptime("-2010", "%Y", &tm);
+ T_QUIET; T_EXPECT_NOTNULL(result, "-2010, %%Y");
+ T_EXPECT_EQ(tm.tm_year, -201 - 1900, NULL);
+}
+
--- /dev/null
+#include <time.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <darwintest.h>
+
+T_DECL(timespec_get, "timespec_get")
+{
+ struct timespec ts;
+ T_ASSERT_EQ(timespec_get(&ts, TIME_UTC), TIME_UTC, NULL);
+
+ struct timeval tv;
+ T_ASSERT_POSIX_ZERO(gettimeofday(&tv, NULL), NULL);
+
+ T_EXPECT_LE((unsigned long)tv.tv_sec - (unsigned long)ts.tv_sec, (unsigned long)1,
+ "gettimeofday() should return same as timespec_get(TIME_UTC)");
+}
+
T_ASSERT_EQ(0, timingsafe_bcmp("foo", "foo", strlen("foo")), NULL);
// unequal
- T_ASSERT_NE(0, timingsafe_bcmp("foo", "bar", strlen("foo")), NULL);
- T_ASSERT_NE(0, timingsafe_bcmp("foo", "goo", strlen("foo")), NULL);
- T_ASSERT_NE(0, timingsafe_bcmp("foo", "fpo", strlen("foo")), NULL);
- T_ASSERT_NE(0, timingsafe_bcmp("foo", "fop", strlen("foo")), NULL);
+ T_ASSERT_EQ(1, timingsafe_bcmp("foo", "bar", strlen("foo")), NULL);
+ T_ASSERT_EQ(1, timingsafe_bcmp("foo", "goo", strlen("foo")), NULL);
+ T_ASSERT_EQ(1, timingsafe_bcmp("foo", "fpo", strlen("foo")), NULL);
+ T_ASSERT_EQ(1, timingsafe_bcmp("foo", "fop", strlen("foo")), NULL);
+
+ // all possible bitwise differences
+ int i;
+ for (i = 1; i < 256; i += 1) {
+ unsigned char a = 0;
+ unsigned char b = (unsigned char)i;
+
+ T_ASSERT_EQ(1, timingsafe_bcmp(&a, &b, sizeof(a)), NULL);
+ }
// large
char buf[1024 * 16];
arc4random_buf(buf, sizeof(buf));
T_ASSERT_EQ(0, timingsafe_bcmp(buf, buf, sizeof(buf)), NULL);
- T_ASSERT_NE(0, timingsafe_bcmp(buf, buf + 1, sizeof(buf) - 1), NULL);
- T_ASSERT_NE(0, timingsafe_bcmp(buf, buf + 128, 128), NULL);
+ T_ASSERT_EQ(1, timingsafe_bcmp(buf, buf + 1, sizeof(buf) - 1), NULL);
+ T_ASSERT_EQ(1, timingsafe_bcmp(buf, buf + 128, 128), NULL);
memcpy(buf+128, buf, 128);
T_ASSERT_EQ(0, timingsafe_bcmp(buf, buf + 128, 128), NULL);
elsif ($unifdef == 1) {
# assume FEATURE_BLOCKS was on by default
$unifdefs{"UNIFDEF_BLOCKS"} = 1;
+ $unifdefs{"UNIFDEF_DRIVERKIT"} = defined($ENV{"DRIVERKITSDK"});
$unifdefs{"UNIFDEF_LEGACY_64_APIS"} = defined($features{"FEATURE_LEGACY_64_APIS"});
$unifdefs{"UNIFDEF_LEGACY_RUNE_APIS"} = defined($features{"FEATURE_LEGACY_RUNE_APIS"});
$unifdefs{"UNIFDEF_LEGACY_UTMP_APIS"} = defined($features{"FEATURE_LEGACY_UTMP_APIS"});
+ $unifdefs{"UNIFDEF_POSIX_ILP32_ALLOW"} = defined($features{"FEATURE_POSIX_ILP32_ALLOW"});
my $output = "";
for my $d (keys %unifdefs) {
# Installs Libc header files
+if [ -n "${DRIVERKIT}" -a -z "${DRIVERKITSDK}" ]; then
+ # Run script in the mode that installs public DriverKit SDK headers first:
+ # required to get the correct header unifdef ordering, that mode strips out more
+ # and rewrites all headers under the parent directory (/System/DriverKit)
+ DRIVERKITSDK=1 SDK_INSTALL_HEADERS_ROOT="${SDK_INSTALL_ROOT}" "${BASH}" -e "$0"
+fi
+
MKDIR="mkdir -p"
INSTALL=install
MV=mv
HDRROOT=${DSTROOT}
fi
-INCDIR=${HDRROOT}/${PUBLIC_HEADERS_FOLDER_PATH}
-LOCINCDIR=${HDRROOT}/${PRIVATE_HEADERS_FOLDER_PATH}
-SYSTEMFRAMEWORK=${HDRROOT}/System/Library/Frameworks/System.framework
-KERNELFRAMEWORK=${HDRROOT}/System/Library/Frameworks/Kernel.framework
+INCDIR=${HDRROOT}/${SDK_INSTALL_HEADERS_ROOT}/usr/include
+LOCINCDIR=${HDRROOT}/${SDK_INSTALL_HEADERS_ROOT}/usr/local/include
+SYSTEMFRAMEWORK=${HDRROOT}/${SDK_INSTALL_HEADERS_ROOT}/System/Library/Frameworks/System.framework
+KERNELFRAMEWORK=${HDRROOT}/${SDK_INSTALL_HEADERS_ROOT}/System/Library/Frameworks/Kernel.framework
PRIVHDRS=${SYSTEMFRAMEWORK}/Versions/B/PrivateHeaders
PRIVKERNELHDRS=${KERNELFRAMEWORK}/Versions/A/PrivateHeaders
INSTALLMODE=$([[ `id -u` -eq 0 ]] && echo 444 || echo 644)
+if [ -z "${DRIVERKITSDK}" ]; then
+
INSTHDRS=(
${SRCROOT}/gen/get_compat.h
${SRCROOT}/gen/execinfo.h
_types.h
_wctype.h
_xlocale.h
+ _ctermid.h
aio.h
alloca.h
ar.h
)
PRIVUUID_INSTHDRS=( ${SRCROOT}/uuid/namespace.h )
-${MKDIR} ${INCDIR}/arpa
-${MKDIR} ${INCDIR}/libkern
-${MKDIR} ${INCDIR}/malloc
-${MKDIR} ${INCDIR}/protocols
-${MKDIR} ${INCDIR}/secure
-${MKDIR} ${INCDIR}/sys
-${MKDIR} ${INCDIR}/xlocale
-${MKDIR} ${INCDIR}/_types
+else # DRIVERKITSDK
+
+# Public DriverKit SDK headers
+
+UNIFDEFARGS="${UNIFDEFARGS} -U_USE_EXTENDED_LOCALES_"
+
+INC_INSTHDRS=(
+ __wctype.h
+ _ctype.h
+ _locale.h
+ _stdio.h
+ _types.h
+ _wctype.h
+ alloca.h
+ assert.h
+ ctype.h
+ inttypes.h
+ limits.h
+ locale.h
+ runetype.h
+ stddef.h
+ stdio.h
+ stdint.h
+ stdlib.h
+ string.h
+ strings.h
+ time.h
+ wchar.h
+ wctype.h
+)
+
+TYPES_INSTHDRS=(
+ ${SRCROOT}/include/_types/_intmax_t.h
+ ${SRCROOT}/include/_types/_uint16_t.h
+ ${SRCROOT}/include/_types/_uint32_t.h
+ ${SRCROOT}/include/_types/_uint64_t.h
+ ${SRCROOT}/include/_types/_uint8_t.h
+ ${SRCROOT}/include/_types/_uintmax_t.h
+ ${SRCROOT}/include/_types/_wctrans_t.h
+ ${SRCROOT}/include/_types/_wctype_t.h
+)
+
+INC_INSTHDRS=(
+ "${INC_INSTHDRS[@]/#/${SRCROOT}/include/}"
+)
+INSTHDRS=( "${INSTHDRS[@]}" "${INC_INSTHDRS[@]}" )
+
+INC_SECURE_INSTHDRS=( _common.h _string.h _strings.h _stdio.h )
+SECURE_INSTHDRS=( "${INC_SECURE_INSTHDRS[@]/#/${SRCROOT}/include/secure/}" )
+
+fi # DRIVERKITSDK
+
+if [ -n "${INSTHDRS}" ]; then
+${MKDIR} ${INCDIR}
${INSTALL} -m ${INSTALLMODE} ${INSTHDRS[@]} ${INCDIR}
+fi
+if [ -n "${ARPA_INSTHDRS}" ]; then
+${MKDIR} ${INCDIR}/arpa
${INSTALL} -m ${INSTALLMODE} ${ARPA_INSTHDRS[@]} ${INCDIR}/arpa
-if [ "x${FEATURE_MEM_NOTIFICATION_APIS}" == "x1" ]; then
-${INSTALL} -m ${INSTALLMODE} ${MEM_INSTHDRS[@]} ${INCDIR}/libkern
fi
-if [ "x${FEATURE_THERM_NOTIFICATION_APIS}" == "x1" ]; then
+if [ -n "${THERM_INSTHDRS}" ]; then
+${MKDIR} ${INCDIR}/libkern
${INSTALL} -m ${INSTALLMODE} ${THERM_INSTHDRS[@]} ${INCDIR}/libkern
fi
+if [ -n "${PROTO_INSTHDRS}" ]; then
+${MKDIR} ${INCDIR}/protocols
${INSTALL} -m ${INSTALLMODE} ${PROTO_INSTHDRS[@]} ${INCDIR}/protocols
+fi
+if [ -n "${SECURE_INSTHDRS}" ]; then
+${MKDIR} ${INCDIR}/secure
${INSTALL} -m ${INSTALLMODE} ${SECURE_INSTHDRS[@]} ${INCDIR}/secure
+fi
+if [ -n "${SYS_INSTHDRS}" ]; then
+${MKDIR} ${INCDIR}/sys
${INSTALL} -m ${INSTALLMODE} ${SYS_INSTHDRS[@]} ${INCDIR}/sys
+fi
+if [ -n "${XLOCALE_INSTHDRS}" ]; then
+${MKDIR} ${INCDIR}/xlocale
${INSTALL} -m ${INSTALLMODE} ${XLOCALE_INSTHDRS[@]} ${INCDIR}/xlocale
+fi
+if [ -n "${TYPES_INSTHDRS}" ]; then
+${MKDIR} ${INCDIR}/_types
${INSTALL} -m ${INSTALLMODE} ${TYPES_INSTHDRS[@]} ${INCDIR}/_types
+fi
+if [ -n "${LOCALHDRS}" ]; then
${MKDIR} ${LOCINCDIR}
-${MKDIR} ${LOCINCDIR}/os
${INSTALL} -m ${INSTALLMODE} ${LOCALHDRS[@]} ${LOCINCDIR}
+fi
+if [ -n "${OS_LOCALHDRS}" ]; then
+${MKDIR} ${LOCINCDIR}/os
${INSTALL} -m ${INSTALLMODE} ${OS_LOCALHDRS[@]} ${LOCINCDIR}/os
-${MKDIR} ${PRIVHDRS}/btree
-${MKDIR} ${PRIVHDRS}/machine
-${MKDIR} ${PRIVHDRS}/uuid
-${MKDIR} ${PRIVHDRS}/sys
-${MKDIR} ${PRIVKERNELHDRS}/uuid
+fi
+if [ -n "${PRIV_INSTHDRS}" ]; then
+${MKDIR} ${PRIVHDRS}
${INSTALL} -m ${INSTALLMODE} ${PRIV_INSTHDRS[@]} ${PRIVHDRS}
+fi
+if [ -n "${PRIV_BTREEHDRS}" ]; then
+${MKDIR} ${PRIVHDRS}/btree
${INSTALL} -m ${INSTALLMODE} ${PRIV_BTREEHDRS[@]} ${PRIVHDRS}/btree
-${MV} ${INCDIR}/asm.h ${PRIVHDRS}/machine
+fi
+if [ -n "${SYS_INSTHDRS}" ]; then
+${MKDIR} ${PRIVHDRS}/sys
${INSTALL} -m ${INSTALLMODE} ${SYS_INSTHDRS[@]} ${PRIVHDRS}/sys
+fi
+if [ -n "${PRIVUUID_INSTHDRS}" ]; then
+${MKDIR} ${PRIVHDRS}/uuid
${INSTALL} -m ${INSTALLMODE} ${PRIVUUID_INSTHDRS[@]} ${PRIVHDRS}/uuid
+${MKDIR} ${PRIVKERNELHDRS}/uuid
${INSTALL} -m ${INSTALLMODE} ${PRIVUUID_INSTHDRS[@]} ${PRIVKERNELHDRS}/uuid
+fi
+if [ -f "${INCDIR}/asm.h" ]; then
+${MKDIR} ${PRIVHDRS}/machine
+${MV} ${INCDIR}/asm.h ${PRIVHDRS}/machine
+fi
-for i in `${FIND} "${HDRROOT}" -name \*.h -print0 | ${XARGS} -0 ${GREP} -l '^//Begin-Libc'`; do
+for i in `${FIND} "${HDRROOT}/${SDK_INSTALL_HEADERS_ROOT}" -name \*.h -print0 | ${XARGS} -0 ${GREP} -l '^//Begin-Libc'`; do
${CHMOD} u+w $i &&
${ECHO} ${ED} - $i \< ${SRCROOT}/xcodescripts/strip-header.ed &&
${ED} - $i < ${SRCROOT}/xcodescripts/strip-header.ed &&
${CHMOD} u-w $i || exit 1;
done
-for i in `${FIND} "${HDRROOT}" -name \*.h -print0 | ${XARGS} -0 ${FGREP} -l -e UNIFDEF -e OPEN_SOURCE`; do
+for i in `${FIND} "${HDRROOT}/${SDK_INSTALL_HEADERS_ROOT}" -name \*.h -print0 | ${XARGS} -0 ${FGREP} -l -e UNIFDEF -e OPEN_SOURCE -e _USE_EXTENDED_LOCALES_`; do
${CHMOD} u+w $i &&
${CP} $i $i.orig &&
${ECHO} ${UNIFDEF} ${UNIFDEFARGS} $i.orig \> $i &&
// Standard settings
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator iphoneosnano iphonesimulatornano bridgeos
+
+SDK_INSTALL_VARIANT = $(SDK_INSTALL_VARIANT_$(DRIVERKIT))
+SDK_INSTALL_VARIANT_1 = driverkit
+SDK_INSTALL_VARIANT_ = default
+SDK_INSTALL_ROOT = $(SDK_INSTALL_ROOT_$(SDK_INSTALL_VARIANT))
+SDK_INSTALL_ROOT_driverkit = $(DRIVERKITROOT)
+SDK_INSTALL_HEADERS_ROOT = $(SDK_INSTALL_HEADERS_ROOT_$(SDK_INSTALL_VARIANT))
+SDK_INSTALL_HEADERS_ROOT_driverkit = $(SDK_INSTALL_ROOT)/$(SDK_RUNTIME_HEADERS_PREFIX)
+SDK_RUNTIME_HEADERS_PREFIX = Runtime
+
SRCROOT_SEARCH_PATHS = $(SRCROOT) $(SRCROOT)/include $(SRCROOT)/gen $(SRCROOT)/locale $(SRCROOT)/locale/FreeBSD $(SRCROOT)/stdtime/FreeBSD $(SRCROOT)/darwin
-SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
-HEADER_SEARCH_PATHS = $($(TARGET_NAME)_SEARCH_PATHS) $(DERIVED_FILES_DIR)/dtrace $(SRCROOT_SEARCH_PATHS) $(SYSTEM_FRAMEWORK_HEADERS) $(SDKROOT)/usr/local/include $(inherited)
+SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
+SDK_SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders
+HEADER_SEARCH_PATHS = $($(TARGET_NAME)_SEARCH_PATHS) $(DERIVED_FILES_DIR)/dtrace $(SRCROOT_SEARCH_PATHS) $(inherited)
+SYSTEM_HEADER_SEARCH_PATHS = $(SYSTEM_FRAMEWORK_HEADERS) $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/usr/local/include $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/usr/include
+SYSTEM_FRAMEWORK_SEARCH_PATHS = $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/Frameworks
ALWAYS_SEARCH_USER_PATHS = YES
USE_HEADERMAP = NO
BUILD_VARIANTS = normal
GCC_OPTIMIZATION_LEVEL = s
-GCC_C_LANGUAGE_STANDARD = gnu99
+GCC_C_LANGUAGE_STANDARD = gnu11
GCC_ENABLE_OBJC_EXCEPTIONS = YES
GCC_SYMBOLS_PRIVATE_EXTERN = NO
GCC_DYNAMIC_NO_PIC = NO
VERSION_INFO_PREFIX = __attribute__((visibility("hidden")))
COPY_PHASE_STRIP = NO
STRIP_INSTALLED_PRODUCT = NO
-LD_DYLIB_INSTALL_NAME = /usr/lib/system/$(EXECUTABLE_NAME)
+LD_DYLIB_INSTALL_NAME = $(SDK_INSTALL_ROOT)/usr/lib/system/$(EXECUTABLE_NAME)
IS_ZIPPERED = YES
BUILD_VARIANTS = normal debug
GCC_VERSION[arch=armv6] = com.apple.compilers.llvmgcc42
EXECUTABLE_PREFIX = libsystem_
-INSTALL_PATH = /usr/lib/system
-PUBLIC_HEADERS_FOLDER_PATH = /usr/include
-PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include
+INSTALL_PATH = $(SDK_INSTALL_ROOT)/usr/lib/system
+PUBLIC_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/include
+PRIVATE_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/local/include
-DARWIN_PUBLIC_HEADERS_FOLDER_PATH = /usr/include/os
-DARWIN_PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/os
+DARWIN_PUBLIC_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/include/os
+DARWIN_PRIVATE_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/local/include/os
// Simulator
BASE_PREPROCESSOR_MACROS = __LIBC__ __DARWIN_UNIX03=1 __DARWIN_64_BIT_INO_T=1 __DARWIN_NON_CANCELABLE=1 __DARWIN_VERS_1050=1 _FORTIFY_SOURCE=0
// libsystem_c.dylib linking
CR_LDFLAGS = -lCrashReporterClient
+CR_LDFLAGS[sdk=driverkit*] =
LIBCOMPILER_RT_LDFLAGS = -lcompiler_rt
LIBMALLOC_LDFLAGS = -lsystem_malloc
LIBC_LDFLAGS = -lsystem_c
LIBSYSCALL_LDFLAGS = -lsystem$(SIM_SUFFIX)_kernel
LIBM_LDFLAGS = -lsystem_m
LIBDYLD_LDFLAGS = -ldyld
-LIBSYSTEM_C_LDFLAGS = -all_load -nostdlib -L/usr/lib/system -umbrella System $(CR_LDFLAGS) $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(UPWARD_LDFLAGS) $(LIBSYSTEM_C_EXTRA_LDFLAGS_$(CURRENT_ARCH)) -Wl,-interposable_list,$(DERIVED_FILES_DIR)/interposable.list -Wl,-unexported_symbols_list,$(DERIVED_FILES_DIR)/unexport.list -Wl,-alias_list,$(SRCROOT)/xcodescripts/alias.list -Wl,-order_file,$(SRCROOT)/xcodescripts/Libc.order -Wl,-sectalign,__DATA,__data,1000 @$(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist
+LIBSYSTEM_C_LDFLAGS = -all_load -nostdlib -L$(SDK_INSTALL_ROOT)/usr/lib/system -umbrella System $(CR_LDFLAGS) $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(UPWARD_LDFLAGS) $(LIBSYSTEM_C_EXTRA_LDFLAGS_$(CURRENT_ARCH)) -Wl,-interposable_list,$(DERIVED_FILES_DIR)/interposable.list -Wl,-unexported_symbols_list,$(DERIVED_FILES_DIR)/unexport.list -Wl,-alias_list,$(SRCROOT)/xcodescripts/alias.list -Wl,-order_file,$(SRCROOT)/xcodescripts/Libc.order @$(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist
LIBSYSTEM_C_EXTRA_LDFLAGS_i386 = -Wl,-alias_list,$(SRCROOT)/xcodescripts/legacy_alias.list
// TODO: Remove upward links - mostly <rdar://problem/13183469>, macho is for assumes.c
UPWARD_LDFLAGS = -Wl,-upward-ldispatch -Wl,-upward-lmacho -Wl,-upward-lsystem_asl -Wl,-upward-lsystem_blocks -Wl,-upward-lsystem_info -Wl,-upward-lsystem_notify -Wl,-upward-lxpc -Wl,-upward-lcorecrypto -Wl,-upward-lsystem_trace
+UPWARD_LDFLAGS[sdk=driverkit*] = -Wl,-upward-lmacho -Wl,-upward-lsystem_blocks -Wl,-upward-lcorecrypto
-LIBSYSTEM_DARWIN_LDFLAGS = -all_load -nostdlib -L/usr/lib/system -umbrella System $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBC_LDFLAGS) $(LIBDISPATCH_LDFLAGS) $(LIBXPC_LDFLAGS)
+LIBSYSTEM_DARWIN_LDFLAGS = -all_load -nostdlib -L$(SDK_INSTALL_ROOT)/usr/lib/system -umbrella System $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBC_LDFLAGS) $(LIBDISPATCH_LDFLAGS) $(LIBXPC_LDFLAGS)
// libPlatform.a architectures
ARCH_FAMILY = $(ARCH_FAMILY_$(CURRENT_ARCH))
BASE_EXCLUDED_SOURCE_FILE_NAMES_watchos = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos)
BASE_EXCLUDED_SOURCE_FILE_NAMES_watchsimulator = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator)
BASE_EXCLUDED_SOURCE_FILE_NAMES_bridgeos = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos)
+BASE_EXCLUDED_SOURCE_FILE_NAMES_driverkit = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_macosx) $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos) getlogin.c setlogin.c logwtmp.c utmpx.c utmpx-darwin.c daemon.c authentication.c pty.c opendev.c fparseln.c psort*.c crypt.c glob.c readpassphrase.c atexit_receipt.c debug_private.c sourcefilter.c inet*.c nsap_addr.c ascii2addr.c addr2ascii.c acl*.c filesec.c chmodx_np.c openx_np.c umaskx_np.c statx_np.c
// TODO: Remove these legacy platform names:
BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneosnano = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_watchos)
// TODO: Remove this hack once Marzipan bringup is done
VARIANT_PLATFORM_NAME = $(VARIANT_PLATFORM_NAME_$(RC_MARZIPAN))
-VARIANT_PLATFORM_NAME_ = $(PLATFORM_NAME)
VARIANT_PLATFORM_NAME_YES = macosx
+VARIANT_PLATFORM_NAME_ = $(VARIANT_PLATFORM_NAME_$(SDK_INSTALL_VARIANT))
+VARIANT_PLATFORM_NAME_default = $(PLATFORM_NAME)
+VARIANT_PLATFORM_NAME_driverkit = driverkit
if [ "$ACTION" = installhdrs ]; then exit 0; fi
if [ "${PLATFORM_NAME}" != "macosx" ]; then exit 0; fi
if [ "${SKIP_MANPAGES}" = "YES" ]; then exit 0; fi
+if [ "${DRIVERKIT}" = 1 ]; then exit 0; fi
UNIFDEF_FLAGS=`${SRCROOT}/xcodescripts/generate_features.pl --unifdef`
MANPAGES_LIST="${SRCROOT}/man/manpages.lst"
VARIANT_DARWINEXTSN_MACROS = -DVARIANT_DARWINEXTSN
-VARIANT_DARWINEXTSN_INCLUDE = $(VARIANT_DARWINEXTSN_INCLUDE_gen) $(VARIANT_DARWINEXTSN_INCLUDE_stdio) $(VARIANT_DARWINEXTSN_INCLUDE_stdlib) $(VARIANT_DARWINEXTSN_INCLUDE_sys)
+VARIANT_DARWINEXTSN_INCLUDE = $(VARIANT_DARWINEXTSN_INCLUDE_gen) $(VARIANT_DARWINEXTSN_INCLUDE_stdio) $(VARIANT_DARWINEXTSN_INCLUDE_stdlib) $(VARIANT_DARWINEXTSN_INCLUDE_sys_$(SDK_INSTALL_VARIANT))
VARIANT_DARWINEXTSN_INCLUDE_gen = popen.c
VARIANT_DARWINEXTSN_INCLUDE_stdio = fdopen.c fopen.c
VARIANT_DARWINEXTSN_INCLUDE_stdlib = realpath.c
-VARIANT_DARWINEXTSN_INCLUDE_sys = getgroups.c
+VARIANT_DARWINEXTSN_INCLUDE_sys_default = getgroups.c
// $DARWINEXTSN + no cancel (everyone else is cancelable anyway)