├── .github └── workflows │ └── build.yml ├── .gitignore ├── CocoaTop.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── CocoaTop.xcscheme ├── IOKit.framework ├── Headers │ ├── IOKitKeys.h │ ├── IOKitLib.h │ ├── IOReturn.h │ ├── IOTypes.h │ └── OSMessageNotification.h ├── IOKit.tbd └── Versions │ ├── A │ └── IOKit.tbd │ └── Current ├── LICENSE ├── README.md └── src ├── AppDelegate.h ├── AppDelegate.m ├── AppIcon.h ├── AppIcon.m ├── BackButtonHandler.h ├── BackButtonHandler.m ├── Column.h ├── Column.m ├── Column_after_ios7.h ├── Column_pre_ios7.h ├── Compat.h ├── Compat.m ├── GridCell.h ├── GridCell.m ├── Info.plist ├── Makefile ├── NetArray.h ├── NetArray.m ├── PopupMenuView.h ├── PopupMenuView.m ├── Proc.h ├── Proc.m ├── ProcArray.h ├── ProcArray.m ├── README.md ├── RootViewController.h ├── RootViewController.m ├── Setup.h ├── Setup.m ├── SetupColumns.h ├── SetupColumns.m ├── Sock.h ├── Sock.m ├── SockViewController.h ├── SockViewController.m ├── THtmlViewController.h ├── THtmlViewController.m ├── TextViewController.h ├── TextViewController.m ├── kern └── debug.h ├── layout └── DEBIAN │ ├── control │ └── postinst ├── main.m ├── net ├── ntstat.h ├── ntstat_16xx_ios5.h ├── ntstat_20xx_ios6.h ├── ntstat_24xx_ios7.h ├── ntstat_27xx_ios8.h └── ntstat_32xx_ios9.h ├── netinet └── tcp_fsm.h ├── postinst ├── Makefile ├── main.m └── task.xml ├── res ├── Base.lproj │ └── LaunchScreen.storyboardc │ │ ├── 01J-lp-oVM-view-Ze5-6b-2t3.nib │ │ ├── Info.plist │ │ └── UIViewController-01J-lp-oVM.nib ├── CocoaTop_ ├── Default-1024h.png ├── Default-1024h@2x.png ├── Default-568h@2x.png ├── Default-667h@2x.png ├── Default-736h@3x.png ├── Default.png ├── Default@2x.png ├── Icon-60.png ├── Icon-72.png ├── Icon-76~ipad.png ├── Icon-Small-40.png ├── Icon-Small-50.png ├── Icon-Small.png ├── Icon-Small@2x.png ├── Icon.png ├── Icon@2x.png ├── Info.plist ├── UIButtonBarHamburger.png ├── UIButtonBarHamburger@2x.png ├── UIButtonBarRefresh.png ├── UIButtonBarRefresh@2x.png ├── guide.html ├── ios7-chevron.png ├── ios7-chevron@2x.png ├── story.html └── style.css ├── sys ├── dyld64.h ├── kern_control.h ├── libproc.h ├── proc_info.h ├── resource.h └── sys_domain.h ├── task.xml └── xpc ├── base.h └── xpc.h /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: macOS-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | with: 13 | submodules: true 14 | 15 | - name: prepare environment 16 | run: | 17 | brew install ldid make 18 | echo "THEOS=/Users/runner/work/CocoaTop/CocoaTop/theos" >> $GITHUB_ENV 19 | echo "PATH=/usr/local/opt/make/libexec/gnubin:$PATH" >> $GITHUB_ENV 20 | 21 | 22 | - name: verify updated cache 23 | id: verify-cache 24 | run: | 25 | echo "::set-output name=heads::`git ls-remote https://github.com/theos/theos | head -n 1 | cut -f 1`-`git ls-remote https://github.com/xybp888/iOS-SDKs | head -n 1 | cut -f 1`" 26 | 27 | - name: use cache 28 | id: cache 29 | uses: actions/cache@v2 30 | with: 31 | path: /Users/runner/work/CocoaTop/CocoaTop/theos 32 | key: ${{ runner.os }}-${{ steps.verify-cache.outputs.heads }} 33 | 34 | - name: get theos 35 | if: steps.cache.outputs.cache-hit != 'true' 36 | uses: actions/checkout@v2 37 | with: 38 | submodules: recursive 39 | path: 'theos' 40 | repository: theos/theos 41 | 42 | - name: get sdks 43 | if: steps.cache.outputs.cache-hit != 'true' 44 | run: | 45 | curl -LO https://github.com/xybp888/iOS-SDKs/archive/master.zip 46 | TMP=$(mktemp -d) 47 | unzip -q master.zip -d $TMP 48 | if [ ! -d "/Users/runner/work/CocoaTop/CocoaTop/theos/sdks" ]; then 49 | mkdir /Users/runner/work/CocoaTop/CocoaTop/theos/sdks 50 | fi 51 | mv $TMP/iOS-SDKs-master/*.sdk /Users/runner/work/CocoaTop/CocoaTop/theos/sdks 52 | rm -r master.zip $TMP 53 | 54 | - name: actual build 55 | run: | 56 | cd src 57 | mkdir -p packages 58 | rm -f packages/* 59 | make package FINALPACKAGE=1 60 | 61 | - name: upload deb 62 | uses: actions/upload-artifact@v2.2.0 63 | with: 64 | name: 'Package' 65 | path: ${{ github.workspace }}/src/packages/*.deb 66 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.xcodeproj/xcuserdata/ 3 | *.xcodeproj/project.xcworkspace/xcuserdata/*.xcuserdatad/UserInterfaceState.xcuserstate 4 | *.xcodeproj/project.xcworkspace/xcuserdata/*.xcuserdatad/IDEFindNavigatorScopes.plist 5 | *.xcodeproj/project.xcworkspace/xcuserdata/*.xcuserdatad/WorkspaceSettings.xcsettings 6 | /src/_ 7 | /src/obj 8 | /src/.theos 9 | /src/theos 10 | /src/packages 11 | -------------------------------------------------------------------------------- /CocoaTop.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CocoaTop.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CocoaTop.xcodeproj/xcshareddata/xcschemes/CocoaTop.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /IOKit.framework/Headers/IOKitKeys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* 29 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 30 | * 31 | * Common symbol definitions for IOKit. 32 | * 33 | * HISTORY 34 | * 35 | */ 36 | 37 | 38 | #ifndef _IOKIT_IOKITKEYS_H 39 | #define _IOKIT_IOKITKEYS_H 40 | 41 | // properties found in the registry root 42 | #define kIOKitBuildVersionKey "IOKitBuildVersion" 43 | #define kIOKitDiagnosticsKey "IOKitDiagnostics" 44 | // a dictionary keyed by plane name 45 | #define kIORegistryPlanesKey "IORegistryPlanes" 46 | #define kIOCatalogueKey "IOCatalogue" 47 | 48 | // registry plane names 49 | #define kIOServicePlane "IOService" 50 | #define kIOPowerPlane "IOPower" 51 | #define kIODeviceTreePlane "IODeviceTree" 52 | #define kIOAudioPlane "IOAudio" 53 | #define kIOFireWirePlane "IOFireWire" 54 | #define kIOUSBPlane "IOUSB" 55 | 56 | // registry ID number 57 | #define kIORegistryEntryIDKey "IORegistryEntryID" 58 | 59 | // IOService class name 60 | #define kIOServiceClass "IOService" 61 | 62 | // IOResources class name 63 | #define kIOResourcesClass "IOResources" 64 | 65 | // IOService driver probing property names 66 | #define kIOClassKey "IOClass" 67 | #define kIOProbeScoreKey "IOProbeScore" 68 | #define kIOKitDebugKey "IOKitDebug" 69 | 70 | // IOService matching property names 71 | #define kIOProviderClassKey "IOProviderClass" 72 | #define kIONameMatchKey "IONameMatch" 73 | #define kIOPropertyMatchKey "IOPropertyMatch" 74 | #define kIOPathMatchKey "IOPathMatch" 75 | #define kIOLocationMatchKey "IOLocationMatch" 76 | #define kIOParentMatchKey "IOParentMatch" 77 | #define kIOResourceMatchKey "IOResourceMatch" 78 | #define kIOMatchedServiceCountKey "IOMatchedServiceCountMatch" 79 | 80 | #define kIONameMatchedKey "IONameMatched" 81 | 82 | #define kIOMatchCategoryKey "IOMatchCategory" 83 | #define kIODefaultMatchCategoryKey "IODefaultMatchCategory" 84 | 85 | // IOService default user client class, for loadable user clients 86 | #define kIOUserClientClassKey "IOUserClientClass" 87 | 88 | // key to find IOMappers 89 | #define kIOMapperIDKey "IOMapperID" 90 | 91 | #define kIOUserClientCrossEndianKey "IOUserClientCrossEndian" 92 | #define kIOUserClientCrossEndianCompatibleKey "IOUserClientCrossEndianCompatible" 93 | #define kIOUserClientSharedInstanceKey "IOUserClientSharedInstance" 94 | // diagnostic string describing the creating task 95 | #define kIOUserClientCreatorKey "IOUserClientCreator" 96 | 97 | // IOService notification types 98 | #define kIOPublishNotification "IOServicePublish" 99 | #define kIOFirstPublishNotification "IOServiceFirstPublish" 100 | #define kIOMatchedNotification "IOServiceMatched" 101 | #define kIOFirstMatchNotification "IOServiceFirstMatch" 102 | #define kIOTerminatedNotification "IOServiceTerminate" 103 | 104 | // IOService interest notification types 105 | #define kIOGeneralInterest "IOGeneralInterest" 106 | #define kIOBusyInterest "IOBusyInterest" 107 | #define kIOAppPowerStateInterest "IOAppPowerStateInterest" 108 | #define kIOPriorityPowerStateInterest "IOPriorityPowerStateInterest" 109 | 110 | #define kIOPlatformDeviceMessageKey "IOPlatformDeviceMessage" 111 | 112 | // IOService interest notification types 113 | #define kIOCFPlugInTypesKey "IOCFPlugInTypes" 114 | 115 | // properties found in services that implement command pooling 116 | #define kIOCommandPoolSizeKey "IOCommandPoolSize" // (OSNumber) 117 | 118 | // properties found in services that have transfer constraints 119 | #define kIOMaximumBlockCountReadKey "IOMaximumBlockCountRead" // (OSNumber) 120 | #define kIOMaximumBlockCountWriteKey "IOMaximumBlockCountWrite" // (OSNumber) 121 | #define kIOMaximumByteCountReadKey "IOMaximumByteCountRead" // (OSNumber) 122 | #define kIOMaximumByteCountWriteKey "IOMaximumByteCountWrite" // (OSNumber) 123 | #define kIOMaximumSegmentCountReadKey "IOMaximumSegmentCountRead" // (OSNumber) 124 | #define kIOMaximumSegmentCountWriteKey "IOMaximumSegmentCountWrite" // (OSNumber) 125 | #define kIOMaximumSegmentByteCountReadKey "IOMaximumSegmentByteCountRead" // (OSNumber) 126 | #define kIOMaximumSegmentByteCountWriteKey "IOMaximumSegmentByteCountWrite" // (OSNumber) 127 | #define kIOMinimumSegmentAlignmentByteCountKey "IOMinimumSegmentAlignmentByteCount" // (OSNumber) 128 | #define kIOMaximumSegmentAddressableBitCountKey "IOMaximumSegmentAddressableBitCount" // (OSNumber) 129 | 130 | // properties found in services that wish to describe an icon 131 | // 132 | // IOIcon = 133 | // { 134 | // CFBundleIdentifier = "com.example.driver.example"; 135 | // IOBundleResourceFile = "example.icns"; 136 | // }; 137 | // 138 | // where IOBundleResourceFile is the filename of the resource 139 | 140 | #define kIOIconKey "IOIcon" // (OSDictionary) 141 | #define kIOBundleResourceFileKey "IOBundleResourceFile" // (OSString) 142 | 143 | #define kIOBusBadgeKey "IOBusBadge" // (OSDictionary) 144 | #define kIODeviceIconKey "IODeviceIcon" // (OSDictionary) 145 | 146 | // property of root that describes the machine's serial number as a string 147 | #define kIOPlatformSerialNumberKey "IOPlatformSerialNumber" // (OSString) 148 | 149 | // property of root that describes the machine's UUID as a string 150 | #define kIOPlatformUUIDKey "IOPlatformUUID" // (OSString) 151 | 152 | // IODTNVRAM property keys 153 | #define kIONVRAMDeletePropertyKey "IONVRAM-DELETE-PROPERTY" 154 | #define kIODTNVRAMPanicInfoKey "aapl,panic-info" 155 | 156 | // keys for complex boot information 157 | #define kIOBootDeviceKey "IOBootDevice" // dict | array of dicts 158 | #define kIOBootDevicePathKey "IOBootDevicePath" // arch-neutral OSString 159 | #define kIOBootDeviceSizeKey "IOBootDeviceSize" // OSNumber of bytes 160 | 161 | // keys for OS Version information 162 | #define kOSBuildVersionKey "OS Build Version" 163 | 164 | #endif /* ! _IOKIT_IOKITKEYS_H */ 165 | -------------------------------------------------------------------------------- /IOKit.framework/Headers/IOReturn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* 29 | * HISTORY 30 | */ 31 | 32 | /* 33 | * Core IOReturn values. Others may be family defined. 34 | */ 35 | 36 | #ifndef __IOKIT_IORETURN_H 37 | #define __IOKIT_IORETURN_H 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | #include 44 | 45 | typedef kern_return_t IOReturn; 46 | 47 | #ifndef sys_iokit 48 | #define sys_iokit err_system(0x38) 49 | #endif /* sys_iokit */ 50 | #define sub_iokit_common err_sub(0) 51 | #define sub_iokit_usb err_sub(1) 52 | #define sub_iokit_firewire err_sub(2) 53 | #define sub_iokit_block_storage err_sub(4) 54 | #define sub_iokit_graphics err_sub(5) 55 | #define sub_iokit_networking err_sub(6) 56 | #define sub_iokit_bluetooth err_sub(8) 57 | #define sub_iokit_pmu err_sub(9) 58 | #define sub_iokit_acpi err_sub(10) 59 | #define sub_iokit_smbus err_sub(11) 60 | #define sub_iokit_ahci err_sub(12) 61 | #define sub_iokit_powermanagement err_sub(13) 62 | //#define sub_iokit_hidsystem err_sub(14) 63 | #define sub_iokit_scsi err_sub(16) 64 | //#define sub_iokit_pccard err_sub(21) 65 | 66 | #define sub_iokit_vendor_specific err_sub(-2) 67 | #define sub_iokit_reserved err_sub(-1) 68 | 69 | #define iokit_common_err(return) (sys_iokit|sub_iokit_common|return) 70 | #define iokit_family_err(sub,return) (sys_iokit|sub|return) 71 | #define iokit_vendor_specific_err(return) (sys_iokit|sub_iokit_vendor_specific|return) 72 | 73 | #define kIOReturnSuccess KERN_SUCCESS // OK 74 | #define kIOReturnError iokit_common_err(0x2bc) // general error 75 | #define kIOReturnNoMemory iokit_common_err(0x2bd) // can't allocate memory 76 | #define kIOReturnNoResources iokit_common_err(0x2be) // resource shortage 77 | #define kIOReturnIPCError iokit_common_err(0x2bf) // error during IPC 78 | #define kIOReturnNoDevice iokit_common_err(0x2c0) // no such device 79 | #define kIOReturnNotPrivileged iokit_common_err(0x2c1) // privilege violation 80 | #define kIOReturnBadArgument iokit_common_err(0x2c2) // invalid argument 81 | #define kIOReturnLockedRead iokit_common_err(0x2c3) // device read locked 82 | #define kIOReturnLockedWrite iokit_common_err(0x2c4) // device write locked 83 | #define kIOReturnExclusiveAccess iokit_common_err(0x2c5) // exclusive access and 84 | // device already open 85 | #define kIOReturnBadMessageID iokit_common_err(0x2c6) // sent/received messages 86 | // had different msg_id 87 | #define kIOReturnUnsupported iokit_common_err(0x2c7) // unsupported function 88 | #define kIOReturnVMError iokit_common_err(0x2c8) // misc. VM failure 89 | #define kIOReturnInternalError iokit_common_err(0x2c9) // internal error 90 | #define kIOReturnIOError iokit_common_err(0x2ca) // General I/O error 91 | //#define kIOReturn???Error iokit_common_err(0x2cb) // ??? 92 | #define kIOReturnCannotLock iokit_common_err(0x2cc) // can't acquire lock 93 | #define kIOReturnNotOpen iokit_common_err(0x2cd) // device not open 94 | #define kIOReturnNotReadable iokit_common_err(0x2ce) // read not supported 95 | #define kIOReturnNotWritable iokit_common_err(0x2cf) // write not supported 96 | #define kIOReturnNotAligned iokit_common_err(0x2d0) // alignment error 97 | #define kIOReturnBadMedia iokit_common_err(0x2d1) // Media Error 98 | #define kIOReturnStillOpen iokit_common_err(0x2d2) // device(s) still open 99 | #define kIOReturnRLDError iokit_common_err(0x2d3) // rld failure 100 | #define kIOReturnDMAError iokit_common_err(0x2d4) // DMA failure 101 | #define kIOReturnBusy iokit_common_err(0x2d5) // Device Busy 102 | #define kIOReturnTimeout iokit_common_err(0x2d6) // I/O Timeout 103 | #define kIOReturnOffline iokit_common_err(0x2d7) // device offline 104 | #define kIOReturnNotReady iokit_common_err(0x2d8) // not ready 105 | #define kIOReturnNotAttached iokit_common_err(0x2d9) // device not attached 106 | #define kIOReturnNoChannels iokit_common_err(0x2da) // no DMA channels left 107 | #define kIOReturnNoSpace iokit_common_err(0x2db) // no space for data 108 | //#define kIOReturn???Error iokit_common_err(0x2dc) // ??? 109 | #define kIOReturnPortExists iokit_common_err(0x2dd) // port already exists 110 | #define kIOReturnCannotWire iokit_common_err(0x2de) // can't wire down 111 | // physical memory 112 | #define kIOReturnNoInterrupt iokit_common_err(0x2df) // no interrupt attached 113 | #define kIOReturnNoFrames iokit_common_err(0x2e0) // no DMA frames enqueued 114 | #define kIOReturnMessageTooLarge iokit_common_err(0x2e1) // oversized msg received 115 | // on interrupt port 116 | #define kIOReturnNotPermitted iokit_common_err(0x2e2) // not permitted 117 | #define kIOReturnNoPower iokit_common_err(0x2e3) // no power to device 118 | #define kIOReturnNoMedia iokit_common_err(0x2e4) // media not present 119 | #define kIOReturnUnformattedMedia iokit_common_err(0x2e5)// media not formatted 120 | #define kIOReturnUnsupportedMode iokit_common_err(0x2e6) // no such mode 121 | #define kIOReturnUnderrun iokit_common_err(0x2e7) // data underrun 122 | #define kIOReturnOverrun iokit_common_err(0x2e8) // data overrun 123 | #define kIOReturnDeviceError iokit_common_err(0x2e9) // the device is not working properly! 124 | #define kIOReturnNoCompletion iokit_common_err(0x2ea) // a completion routine is required 125 | #define kIOReturnAborted iokit_common_err(0x2eb) // operation aborted 126 | #define kIOReturnNoBandwidth iokit_common_err(0x2ec) // bus bandwidth would be exceeded 127 | #define kIOReturnNotResponding iokit_common_err(0x2ed) // device not responding 128 | #define kIOReturnIsoTooOld iokit_common_err(0x2ee) // isochronous I/O request for distant past! 129 | #define kIOReturnIsoTooNew iokit_common_err(0x2ef) // isochronous I/O request for distant future 130 | #define kIOReturnNotFound iokit_common_err(0x2f0) // data was not found 131 | #define kIOReturnInvalid iokit_common_err(0x1) // should never be seen 132 | 133 | #ifdef __cplusplus 134 | } 135 | #endif 136 | 137 | #endif /* ! __IOKIT_IORETURN_H */ 138 | -------------------------------------------------------------------------------- /IOKit.framework/Headers/IOTypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | #ifndef __IOKIT_IOTYPES_H 29 | #define __IOKIT_IOTYPES_H 30 | 31 | #ifndef IOKIT 32 | #define IOKIT 1 33 | #endif /* !IOKIT */ 34 | 35 | #if KERNEL 36 | #include 37 | #else 38 | #include 39 | #include 40 | #endif 41 | 42 | #include "IOReturn.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | #ifndef NULL 49 | #if defined (__cplusplus) 50 | #define NULL 0 51 | #else 52 | #define NULL ((void *)0) 53 | #endif 54 | #endif 55 | 56 | /* 57 | * Simple data types. 58 | */ 59 | #ifndef __MACTYPES__ /* CF MacTypes.h */ 60 | #ifndef __TYPES__ /* guess... Mac Types.h */ 61 | 62 | #include 63 | #include 64 | 65 | #endif /* __TYPES__ */ 66 | #endif /* __MACTYPES__ */ 67 | 68 | #if KERNEL 69 | #include 70 | #endif 71 | 72 | typedef UInt32 IOOptionBits; 73 | typedef SInt32 IOFixed; 74 | typedef UInt32 IOVersion; 75 | typedef UInt32 IOItemCount; 76 | typedef UInt32 IOCacheMode; 77 | 78 | typedef UInt32 IOByteCount32; 79 | typedef UInt64 IOByteCount64; 80 | 81 | typedef UInt32 IOPhysicalAddress32; 82 | typedef UInt64 IOPhysicalAddress64; 83 | typedef UInt32 IOPhysicalLength32; 84 | typedef UInt64 IOPhysicalLength64; 85 | 86 | #ifdef __LP64__ 87 | typedef mach_vm_address_t IOVirtualAddress; 88 | #else 89 | typedef vm_address_t IOVirtualAddress; 90 | #endif 91 | 92 | #if defined(__LP64__) && defined(KERNEL) 93 | typedef IOByteCount64 IOByteCount; 94 | #else 95 | typedef IOByteCount32 IOByteCount; 96 | #endif 97 | 98 | typedef IOVirtualAddress IOLogicalAddress; 99 | 100 | #if defined(__LP64__) && defined(KERNEL) 101 | 102 | typedef IOPhysicalAddress64 IOPhysicalAddress; 103 | typedef IOPhysicalLength64 IOPhysicalLength; 104 | #define IOPhysical32( hi, lo ) ((UInt64) lo + ((UInt64)(hi) << 32)) 105 | #define IOPhysSize 64 106 | 107 | #else 108 | 109 | typedef IOPhysicalAddress32 IOPhysicalAddress; 110 | typedef IOPhysicalLength32 IOPhysicalLength; 111 | #define IOPhysical32( hi, lo ) (lo) 112 | #define IOPhysSize 32 113 | 114 | #endif 115 | 116 | 117 | typedef struct 118 | { 119 | IOPhysicalAddress address; 120 | IOByteCount length; 121 | } IOPhysicalRange; 122 | 123 | typedef struct 124 | { 125 | IOVirtualAddress address; 126 | IOByteCount length; 127 | } IOVirtualRange; 128 | 129 | #ifdef __LP64__ 130 | typedef IOVirtualRange IOAddressRange; 131 | #else /* !__LP64__ */ 132 | typedef struct 133 | { 134 | mach_vm_address_t address; 135 | mach_vm_size_t length; 136 | } IOAddressRange; 137 | #endif /* !__LP64__ */ 138 | 139 | /* 140 | * Map between #defined or enum'd constants and text description. 141 | */ 142 | typedef struct { 143 | int value; 144 | const char *name; 145 | } IONamedValue; 146 | 147 | 148 | /* 149 | * Memory alignment -- specified as a power of two. 150 | */ 151 | typedef unsigned int IOAlignment; 152 | 153 | #define IO_NULL_VM_TASK ((vm_task_t)0) 154 | 155 | 156 | /* 157 | * Pull in machine specific stuff. 158 | */ 159 | 160 | //#include 161 | 162 | #ifndef MACH_KERNEL 163 | 164 | #ifndef __IOKIT_PORTS_DEFINED__ 165 | #define __IOKIT_PORTS_DEFINED__ 166 | #ifdef KERNEL 167 | typedef struct OSObject * io_object_t; 168 | #else /* KERNEL */ 169 | typedef mach_port_t io_object_t; 170 | #endif /* KERNEL */ 171 | #endif /* __IOKIT_PORTS_DEFINED__ */ 172 | 173 | #include 174 | 175 | typedef io_object_t io_connect_t; 176 | typedef io_object_t io_enumerator_t; 177 | typedef io_object_t io_iterator_t; 178 | typedef io_object_t io_registry_entry_t; 179 | typedef io_object_t io_service_t; 180 | 181 | #define IO_OBJECT_NULL ((io_object_t) 0) 182 | 183 | #endif /* MACH_KERNEL */ 184 | 185 | // IOConnectMapMemory memoryTypes 186 | enum { 187 | kIODefaultMemoryType = 0 188 | }; 189 | 190 | enum { 191 | kIODefaultCache = 0, 192 | kIOInhibitCache = 1, 193 | kIOWriteThruCache = 2, 194 | kIOCopybackCache = 3, 195 | kIOWriteCombineCache = 4 196 | }; 197 | 198 | // IOMemory mapping options 199 | enum { 200 | kIOMapAnywhere = 0x00000001, 201 | 202 | kIOMapCacheMask = 0x00000700, 203 | kIOMapCacheShift = 8, 204 | kIOMapDefaultCache = kIODefaultCache << kIOMapCacheShift, 205 | kIOMapInhibitCache = kIOInhibitCache << kIOMapCacheShift, 206 | kIOMapWriteThruCache = kIOWriteThruCache << kIOMapCacheShift, 207 | kIOMapCopybackCache = kIOCopybackCache << kIOMapCacheShift, 208 | kIOMapWriteCombineCache = kIOWriteCombineCache << kIOMapCacheShift, 209 | 210 | kIOMapUserOptionsMask = 0x00000fff, 211 | 212 | kIOMapReadOnly = 0x00001000, 213 | 214 | kIOMapStatic = 0x01000000, 215 | kIOMapReference = 0x02000000, 216 | kIOMapUnique = 0x04000000 217 | #ifdef XNU_KERNEL_PRIVATE 218 | , kIOMap64Bit = 0x08000000 219 | #endif 220 | }; 221 | 222 | /*! @enum Scale Factors 223 | @discussion Used when a scale_factor parameter is required to define a unit of time. 224 | @constant kNanosecondScale Scale factor for nanosecond based times. 225 | @constant kMicrosecondScale Scale factor for microsecond based times. 226 | @constant kMillisecondScale Scale factor for millisecond based times. 227 | @constant kTickScale Scale factor for the standard (100Hz) tick. 228 | @constant kSecondScale Scale factor for second based times. */ 229 | 230 | enum { 231 | kNanosecondScale = 1, 232 | kMicrosecondScale = 1000, 233 | kMillisecondScale = 1000 * 1000, 234 | kSecondScale = 1000 * 1000 * 1000, 235 | kTickScale = (kSecondScale / 100) 236 | }; 237 | 238 | /* compatibility types */ 239 | 240 | #ifndef KERNEL 241 | 242 | typedef unsigned int IODeviceNumber; 243 | 244 | #endif 245 | 246 | #ifdef __cplusplus 247 | } 248 | #endif 249 | 250 | #endif /* ! __IOKIT_IOTYPES_H */ 251 | -------------------------------------------------------------------------------- /IOKit.framework/Headers/OSMessageNotification.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 25 | * 26 | * HISTORY 27 | * 28 | */ 29 | 30 | #ifndef __OS_OSMESSAGENOTIFICATION_H 31 | #define __OS_OSMESSAGENOTIFICATION_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | #include "IOReturn.h" 39 | 40 | enum { 41 | kFirstIOKitNotificationType = 100, 42 | kIOServicePublishNotificationType = 100, 43 | kIOServiceMatchedNotificationType = 101, 44 | kIOServiceTerminatedNotificationType = 102, 45 | kIOAsyncCompletionNotificationType = 150, 46 | kIOServiceMessageNotificationType = 160, 47 | kLastIOKitNotificationType = 199 48 | }; 49 | 50 | enum { 51 | kOSNotificationMessageID = 53, 52 | kOSAsyncCompleteMessageID = 57, 53 | kMaxAsyncArgs = 16 54 | }; 55 | 56 | enum { 57 | kIOAsyncReservedIndex = 0, 58 | kIOAsyncReservedCount, 59 | 60 | kIOAsyncCalloutFuncIndex = kIOAsyncReservedCount, 61 | kIOAsyncCalloutRefconIndex, 62 | kIOAsyncCalloutCount, 63 | 64 | kIOMatchingCalloutFuncIndex = kIOAsyncReservedCount, 65 | kIOMatchingCalloutRefconIndex, 66 | kIOMatchingCalloutCount, 67 | 68 | kIOInterestCalloutFuncIndex = kIOAsyncReservedCount, 69 | kIOInterestCalloutRefconIndex, 70 | kIOInterestCalloutServiceIndex, 71 | kIOInterestCalloutCount 72 | }; 73 | 74 | enum { 75 | kOSAsyncRefCount = 8, 76 | kOSAsyncRefSize = 32 77 | }; 78 | typedef natural_t OSAsyncReference[kOSAsyncRefCount]; 79 | 80 | struct OSNotificationHeader { 81 | vm_size_t size; /* content size */ 82 | natural_t type; 83 | OSAsyncReference reference; 84 | 85 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 86 | unsigned char content[]; 87 | #else 88 | unsigned char content[0]; 89 | #endif 90 | }; 91 | 92 | struct IOServiceInterestContent { 93 | natural_t messageType; 94 | void * messageArgument[1]; 95 | }; 96 | 97 | struct IOAsyncCompletionContent { 98 | IOReturn result; 99 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 100 | void * args[]; 101 | #else 102 | void * args[0]; 103 | #endif 104 | }; 105 | 106 | #ifndef __cplusplus 107 | typedef struct OSNotificationHeader OSNotificationHeader; 108 | typedef struct IOServiceInterestContent IOServiceInterestContent; 109 | typedef struct IOAsyncCompletionContent IOAsyncCompletionContent; 110 | #endif 111 | 112 | #ifdef __cplusplus 113 | } 114 | #endif 115 | 116 | #endif /* __OS_OSMESSAGENOTIFICATION_H */ 117 | 118 | -------------------------------------------------------------------------------- /IOKit.framework/IOKit.tbd: -------------------------------------------------------------------------------- 1 | Versions/A/IOKit.tbd -------------------------------------------------------------------------------- /IOKit.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CocoaTop 2 | CocoaTop: Process Viewer for iOS GUI 3 | 4 | Current 64-bit version should work on iOS 10-13, with support for safe area on iPhone X screen, dark mode, and split view on iPad! 5 | 6 | Versions prior to 2.0.1 are 32 bit and work on iOS 6-10. They are separated into the **32bit** branch. The **master** branch is intended for new iOS versions, thus it will only support 64-bit builds. Non-relevant code should be removed. 7 | 8 | # Crash/reboot issues 9 | If CocoaTop crashes and/or reboots your phone, you should try removing the SUID bit from /Applications/CocoaTop.app/CocoaTop. You can do it via Filza: find the executable file, tap (i), then make sure "Set UID" is unchecked. 10 | 11 | # Contributing 12 | Source code is available for everyone to improve. The license is GPL-3, except for the include files in *kern*, *net*, *netinet*, *sys*, and *xpc* folders. These are taken from public Mach kernel code and put here to simplify building. You are free to modify the *About* text (a.k.a. *The Story*) any way you want, but I will appreciate if you keep the "Developers" section up-to-date. 13 | 14 | # Building 15 | To build CocoaTop you need: 16 | * Theos (https://github.com/theos/theos), make sure $(THEOS) environment variable points to it. 17 | * Appe iOS SDK (currently version 13.0 is used). Download it from Apple and unpack to theos\sdks\. Also look here: https://github.com/theos/sdks/ 18 | * make 19 | * make package 20 | 21 | or, you can use XCode. 22 | -------------------------------------------------------------------------------- /src/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface TopAppDelegate : NSObject 4 | @property (nonatomic, strong) UIWindow *window; 5 | @property (nonatomic, strong) UINavigationController *navigationController; 6 | @end 7 | 8 | @class RootViewController; 9 | @interface RootTabMaskController : UIViewController { 10 | UIView *mask; 11 | RootViewController *controller; 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /src/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "RootViewController.h" 3 | 4 | @implementation RootTabMaskController 5 | 6 | -(instancetype)init { 7 | if (self = [super init]) { 8 | controller = [RootViewController new]; 9 | [self addChildViewController: controller]; 10 | } 11 | return self; 12 | } 13 | 14 | -(void)viewDidLoad { 15 | [super viewDidLoad]; 16 | [self.view addSubview: controller.view]; 17 | if (@available(iOS 11, *)) { 18 | mask = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 19 | mask.translatesAutoresizingMaskIntoConstraints = NO; 20 | if (@available(iOS 13, *)) { 21 | mask.backgroundColor = [UIColor colorWithDynamicProvider:^(UITraitCollection *collection) { 22 | if (collection.userInterfaceStyle == UIUserInterfaceStyleDark) { 23 | return [UIColor colorWithWhite:.31 alpha:.85]; 24 | } else { 25 | return [UIColor colorWithWhite:.75 alpha:.85]; 26 | } 27 | }]; 28 | } else { 29 | mask.backgroundColor = [UIColor colorWithWhite:.75 alpha:.85]; 30 | } 31 | [self.view addSubview: mask]; 32 | [self.view bringSubviewToFront: mask]; 33 | } 34 | } 35 | 36 | -(void)viewWillLayoutSubviews { 37 | [super viewWillLayoutSubviews]; 38 | if (@available(iOS 11, *)) { 39 | UIEdgeInsets insets = self.view.safeAreaInsets; 40 | if (insets.bottom != 0) { 41 | mask.hidden = false; 42 | mask.frame = CGRectMake(0, self.view.bounds.size.height - insets.bottom, self.view.bounds.size.width, insets.bottom); 43 | [self.view bringSubviewToFront: mask]; 44 | } else { 45 | mask.hidden = true; 46 | } 47 | } 48 | if (controller.view != nil) { 49 | controller.view.frame = self.view.frame; 50 | } 51 | } 52 | 53 | @end 54 | 55 | @implementation TopAppDelegate 56 | 57 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 58 | { 59 | //[UITableView appearance].estimatedRowHeight = 0; 60 | [UITableView appearance].rowHeight = 44; 61 | [UITableView appearance].sectionHeaderHeight = 23; 62 | [UITableView appearance].sectionFooterHeight = 23; 63 | if (@available(iOS 11, *)) { 64 | [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic; 65 | } 66 | // Create UIWindow 67 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 68 | // Allocate the navigation controller 69 | self.navigationController = [[UINavigationController alloc] initWithRootViewController:[RootTabMaskController new]]; 70 | // Set the navigation controller as the window's root view controller and display. 71 | self.window.rootViewController = self.navigationController; 72 | [self.window makeKeyAndVisible]; 73 | return YES; 74 | } 75 | /* 76 | - (void)applicationWillResignActive:(UIApplication *)application 77 | { 78 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 79 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 80 | } 81 | 82 | - (void)applicationDidEnterBackground:(UIApplication *)application 83 | { 84 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 85 | // If your application supports background execution, called instead of applicationWillTerminate: when the user quits. 86 | } 87 | 88 | - (void)applicationWillEnterForeground:(UIApplication *)application 89 | { 90 | // Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. 91 | } 92 | 93 | - (void)applicationDidBecomeActive:(UIApplication *)application 94 | { 95 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 96 | } 97 | 98 | - (void)applicationWillTerminate:(UIApplication *)application 99 | { 100 | // Called when the application is about to terminate. See also applicationDidEnterBackground:. 101 | } 102 | 103 | - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application 104 | { 105 | // Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later. 106 | } 107 | */ 108 | @end 109 | -------------------------------------------------------------------------------- /src/AppIcon.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface PSAppIcon : NSObject 4 | + (NSDictionary *)getAppByPath:(NSString *)path; 5 | + (UIImage *)getIconForApp:(NSDictionary *)app bundle:(NSString *)bundle path:(NSString *)path size:(NSInteger)dim; 6 | @end 7 | -------------------------------------------------------------------------------- /src/AppIcon.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "Compat.h" 3 | #import "AppIcon.h" 4 | 5 | @interface UIImage (Private) 6 | + (UIImage *)_applicationIconImageForBundleIdentifier:(NSString *)bundle roleIdentifier:(id)role format:(int)format scale:(CGFloat)scale; 7 | + (UIImage *)_applicationIconImageForBundleIdentifier:(NSString *)bundle format:(int)format scale:(CGFloat)scale; 8 | @end 9 | 10 | @implementation PSAppIcon 11 | 12 | + (NSDictionary *)getAppByPath:(NSString *)path 13 | { 14 | return [NSDictionary dictionaryWithContentsOfFile:[path stringByAppendingPathComponent:@"Info.plist"]]; 15 | } 16 | 17 | + (NSArray *)getIconFileForApp:(NSDictionary *)app 18 | { 19 | @try { 20 | for (NSString *Key in @[@"CFBundleIcons~ipad", @"CFBundleIcons", @"CFBundleIconFiles", @"CFBundleIconFile"]) { 21 | id Value = app[Key], Try = nil; 22 | while ([Value isKindOfClass:[NSDictionary class]]) { 23 | for (NSString *Key2 in @[@"CFBundlePrimaryIcon", @"CFBundleIconFiles", @"CFBundleIconFile"]) 24 | if ((Try = Value[Key2])) break; 25 | if (!Try) break; 26 | Value = Try; 27 | } 28 | Try = nil; 29 | while ([Value isKindOfClass:[NSArray class]] && [Value count]) { 30 | Try = Value; Value = Value[0]; 31 | } 32 | if ([Value isKindOfClass:[NSString class]]) 33 | return Try ? Try : @[Value]; 34 | } 35 | } 36 | @finally {} 37 | return nil; 38 | } 39 | 40 | + (NSString *)getIconFileForPath:(NSString *)path iconFiles:(NSArray *)icons 41 | { 42 | NSArray* preferred = [@[@"Icon-76", @"Icon-60", @"icon_120x120", @"icon_80x80", @"Icon-Small-50", @"Icon-Small-40", @"Icon-Small"] arrayByAddingObjectsFromArray:icons]; 43 | NSMutableArray *iconNames = [@[@"icon-about"] mutableCopy]; // for MobileCalendar 44 | for (NSString* icon in preferred) 45 | if ([icons containsObject:icon]) 46 | [iconNames addObject:icon]; 47 | for (NSString* icon in preferred) 48 | if (![icons containsObject:icon]) 49 | [iconNames addObject:icon]; 50 | NSFileManager *fileMgr = [NSFileManager defaultManager]; 51 | NSString *iconFull; 52 | for (NSString *Icon in iconNames) { 53 | iconFull = [path stringByAppendingPathComponent:Icon]; 54 | if (![Icon pathExtension].length) { 55 | for (NSString *IconExt in @[@"@3x.png", @"@2x~ipad.png", @"@2x.png", @"@2x~iphone.png", @"~ipad.png", @"~iphone.png", @".png"]) 56 | if ([fileMgr fileExistsAtPath:[iconFull stringByAppendingString:IconExt]]) 57 | return [iconFull stringByAppendingString:IconExt]; 58 | } 59 | if ([fileMgr fileExistsAtPath:iconFull]) 60 | return iconFull; 61 | } 62 | iconFull = [path stringByAppendingPathComponent:@"iTunesArtwork"]; 63 | if ([fileMgr fileExistsAtPath:iconFull]) 64 | return iconFull; 65 | return nil; 66 | } 67 | 68 | + (UIImage *)roundCorneredImage:(UIImage *)orig size:(NSInteger)dim radius:(CGFloat)r 69 | { 70 | CGSize size = (CGSize){dim, dim}; 71 | UIGraphicsBeginImageContextWithOptions(size, NO, 0); 72 | [[UIBezierPath bezierPathWithRoundedRect:(CGRect){CGPointZero, size} cornerRadius:r] addClip]; 73 | [orig drawInRect:(CGRect){CGPointZero, size}]; 74 | UIImage* result = UIGraphicsGetImageFromCurrentImageContext(); 75 | UIGraphicsEndImageContext(); 76 | return result; 77 | } 78 | 79 | + (UIImage *)getIconForApp:(NSDictionary *)app bundle:(NSString *)bundle path:(NSString *)path size:(NSInteger)dim 80 | { 81 | NSString *iconPath = [PSAppIcon getIconFileForPath:path iconFiles:[PSAppIcon getIconFileForApp:app]]; 82 | if (!iconPath) 83 | return nil; 84 | UIImage *image = [UIImage imageWithContentsOfFile:iconPath]; 85 | if (!image) 86 | return nil; 87 | // NSLog(@"Icon(%fx%f) = %@", image.size.width, image.size.height, iconPath); 88 | if (image.size.height * image.scale < 58) { 89 | if ([UIImage respondsToSelector:@selector(_applicationIconImageForBundleIdentifier:roleIdentifier:format:scale:)]) 90 | return [UIImage _applicationIconImageForBundleIdentifier:bundle roleIdentifier:nil format:1 scale:[UIScreen mainScreen].scale]; 91 | else if ([UIImage respondsToSelector:@selector(_applicationIconImageForBundleIdentifier:format:scale:)]) 92 | return [UIImage _applicationIconImageForBundleIdentifier:bundle format:1 scale:[UIScreen mainScreen].scale]; 93 | } 94 | return [PSAppIcon roundCorneredImage:image size:dim radius:dim/4.5]; 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /src/BackButtonHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+BackButtonHandler.h 3 | // 4 | // Created by Sergey Nikitenko on 10/1/13. 5 | // Copyright 2013 Sergey Nikitenko. All rights reserved. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import 27 | 28 | @protocol BackButtonHandlerProtocol 29 | @optional 30 | // Override this method in UIViewController derived class to handle 'Back' button click 31 | -(BOOL)navigationShouldPopOnBackButton; 32 | @end 33 | 34 | @interface UIViewController(BackButtonHandler) 35 | @end 36 | -------------------------------------------------------------------------------- /src/BackButtonHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // BackButtonHandler.m 3 | // 4 | // Created by Sergey Nikitenko on 10/1/13. 5 | // Copyright 2013 Sergey Nikitenko. All rights reserved. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "BackButtonHandler.h" 27 | 28 | @implementation UIViewController(BackButtonHandler) 29 | @end 30 | 31 | @implementation UINavigationController(ShouldPopOnBackButton) 32 | 33 | - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { 34 | 35 | if (self.viewControllers.count < navigationBar.items.count) 36 | return YES; 37 | 38 | BOOL shouldPop = YES; 39 | UIViewController* vc = self.topViewController; 40 | if ([vc respondsToSelector:@selector(navigationShouldPopOnBackButton)]) 41 | shouldPop = [vc navigationShouldPopOnBackButton]; 42 | 43 | if (shouldPop) { 44 | dispatch_async(dispatch_get_main_queue(), ^{ 45 | [self popViewControllerAnimated:YES]; 46 | }); 47 | } else { 48 | // Workaround for iOS7.1. Thanks to @boliva - http://stackoverflow.com/posts/comments/34452906 49 | for (UIView *subview in [navigationBar subviews]) { 50 | if (0. < subview.alpha && subview.alpha < 1.) { 51 | [UIView animateWithDuration:.25 animations:^{ 52 | subview.alpha = 1.; 53 | }]; 54 | } 55 | } 56 | } 57 | return NO; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /src/Column.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | typedef enum { 4 | ColumnModeSummary = 0, 5 | ColumnModeThreads, 6 | ColumnModeFiles, 7 | ColumnModePorts, 8 | ColumnModeModules, 9 | ColumnModes 10 | } column_mode_t; 11 | 12 | typedef enum { 13 | ColumnStyleExtend = 1, // This column will take up all remaining unused space 14 | ColumnStyleEllipsis = 2, // Trim data with ellipsis instead of shrinking font 15 | ColumnStyleForSummary = 4, // Column is shown only in process summary 16 | ColumnStyleMonoFont = 8, // Use mono font (used to display memory addresses) 17 | ColumnStyleTooLong = 16, // Use a shorter text for cell (but not summary) 18 | ColumnStyleNoSummary = 32, // Column is not shown in process summary 19 | ColumnStyleSortDesc = 64, // Default sorting is "high to low" 20 | ColumnStylePath = 128, // This column should be truncated path-like 21 | ColumnStylePathTrunc = 131, // ColumnStylePath + ColumnStyleExtend + ColumnStyleEllipsis 22 | ColumnStyleColor = 256, // Column label can change color 23 | ColumnStyleLowSpace = 512, // Column will not be shown in low-space environments (i.e. iPhone portrait mode) 24 | } column_style_t; 25 | 26 | typedef NSString *(^PSColumnData)(id proc); 27 | typedef UIColor *(^PSColumnColor)(id proc); 28 | typedef double (^PSColumnFloat)(id proc); 29 | 30 | @interface PSColumn : NSObject 31 | // Full column name (in settings) 32 | @property (strong) NSString *fullname; 33 | // Short name (in header) 34 | @property (strong) NSString *name; 35 | // Multiline description (in settings column info) 36 | @property (strong) NSString *descr; 37 | // NSTextAlignmentLeft or NSTextAlignmentRight 38 | @property (assign) NSTextAlignment align; 39 | // Minimal column width 40 | @property (assign) NSInteger minwidth; 41 | // Current column width 42 | @property (assign) NSInteger width; 43 | // Data displayer (based on PSProc/PSSock data) 44 | @property (assign) PSColumnData getData; 45 | // Data filtering supplement 46 | @property (assign) PSColumnFloat getFloatData; 47 | // Summary displayer (based on PSProcArray data) 48 | @property (assign) PSColumnData getSummary; 49 | // Color changer 50 | @property (assign) PSColumnColor getColor; 51 | // Sort comparator 52 | @property (assign) NSComparator sort; 53 | // Column styles bitmask 54 | @property (assign) column_style_t style; 55 | // Label tag 56 | @property (assign) int tag; 57 | 58 | + (instancetype)psColumnWithName:(NSString *)name fullname:(NSString *)fullname align:(NSTextAlignment)align 59 | width:(NSInteger)width tag:(NSInteger)tag style:(column_style_t)style data:(PSColumnData)data floatData:(PSColumnFloat)floatData sort:(NSComparator)sort summary:(PSColumnData)summary color:(PSColumnColor)color descr:(NSString *)descr; 60 | + (instancetype)psColumnWithName:(NSString *)name fullname:(NSString *)fullname align:(NSTextAlignment)align 61 | width:(NSInteger)width tag:(NSInteger)tag style:(column_style_t)style data:(PSColumnData)data sort:(NSComparator)sort summary:(PSColumnData)summary color:(PSColumnColor)color descr:(NSString *)descr; 62 | + (instancetype)psColumnWithName:(NSString *)name fullname:(NSString *)fullname align:(NSTextAlignment)align 63 | width:(NSInteger)width tag:(NSInteger)tag style:(column_style_t)style data:(PSColumnData)data sort:(NSComparator)sort summary:(PSColumnData)summary descr:(NSString *)descr; 64 | + (instancetype)psColumnWithName:(NSString *)name fullname:(NSString *)fullname align:(NSTextAlignment)align width:(NSInteger)width tag:(NSInteger)tag 65 | style:(column_style_t)style data:(PSColumnData)data floatData:(PSColumnFloat)floatData sort:(NSComparator)sort summary:(PSColumnData)summary descr:(NSString *)descr; 66 | + (instancetype)psColumnWithName:(NSString *)name fullname:(NSString *)fullname align:(NSTextAlignment)align 67 | width:(NSInteger)width tag:(NSInteger)tag style:(column_style_t)style data:(PSColumnData)data sort:(NSComparator)sort summary:(PSColumnData)summary; 68 | + (NSArray *)psGetAllColumns; 69 | + (NSMutableArray *)psGetShownColumnsWithWidth:(NSUInteger)width; 70 | + (NSArray *)psGetTaskColumns:(column_mode_t)mode; 71 | + (NSArray *)psGetTaskColumnsWithWidth:(NSUInteger)width mode:(column_mode_t)mode; 72 | + (PSColumn *)psColumnWithTag:(NSInteger)tag; 73 | + (PSColumn *)psTaskColumnWithTag:(NSInteger)tag forMode:(column_mode_t)mode; 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /src/Compat.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #if 0 4 | #ifndef __IPHONE_6_0 5 | #define __IPHONE_6_0 60000 6 | #endif 7 | 8 | #ifndef __IPHONE_7_0 9 | #define __IPHONE_7_0 70000 10 | #endif 11 | 12 | #ifndef __IPHONE_8_0 13 | #define __IPHONE_8_0 80000 14 | #endif 15 | 16 | #ifndef __IPHONE_9_0 17 | #define __IPHONE_9_0 90000 18 | #endif 19 | 20 | #ifndef __MAC_10_9 21 | #define __MAC_10_9 1090 22 | #endif 23 | 24 | #ifndef NSFoundationVersionNumber_iOS_6_0 25 | #define NSFoundationVersionNumber_iOS_6_0 992.00 26 | #endif 27 | 28 | #ifndef NSFoundationVersionNumber_iOS_7_0 29 | #define NSFoundationVersionNumber_iOS_7_0 1047.00 30 | #endif 31 | 32 | #ifndef NSFoundationVersionNumber_iOS_8_0 33 | #define NSFoundationVersionNumber_iOS_8_0 1134.0 34 | #endif 35 | 36 | #ifndef NSFoundationVersionNumber_iOS_9_0 37 | #define NSFoundationVersionNumber_iOS_9_0 1221.0 38 | #endif 39 | 40 | #ifndef NSFoundationVersionNumber_iOS_10_0 41 | #define NSFoundationVersionNumber_iOS_10_0 1300 42 | #endif 43 | 44 | //#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0 45 | //#define UITableViewCellAccessoryDetailButton UITableViewCellAccessoryDetailDisclosureButton 46 | //#define barTintColor tintColor 47 | //#endif 48 | // 49 | //#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0 50 | // 51 | //#endif 52 | 53 | #undef YES 54 | #undef NO 55 | #define YES __objc_yes 56 | #define NO __objc_no 57 | 58 | #define NSLineBreakByWordWrapping UILineBreakModeWordWrap 59 | #define NSLineBreakByTruncatingMiddle UILineBreakModeMiddleTruncation 60 | #define NSTextAlignment UITextAlignment 61 | #define NSTextAlignmentLeft UITextAlignmentLeft 62 | #define NSTextAlignmentRight UITextAlignmentRight 63 | #define NSTextAlignmentCenter UITextAlignmentCenter 64 | #define NSFontAttributeName UITextAttributeFont 65 | 66 | @interface NSArray(Subscripts) 67 | - (id)objectAtIndexedSubscript:(NSUInteger)idx; 68 | @end 69 | 70 | @interface NSMutableArray(Subscripts) 71 | - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx; 72 | @end 73 | 74 | @interface NSDictionary(Subscripts) 75 | - (id)objectForKeyedSubscript:(id)key; 76 | @end 77 | 78 | @interface NSMutableDictionary(Subscripts) 79 | - (void)setObject:(id)obj forKeyedSubscript:(id)key; 80 | @end 81 | 82 | #define NSByteCountFormatterCountStyleMemory 1 83 | 84 | @interface NSByteCountFormatter : NSObject 85 | + (NSString *)stringFromByteCount:(long long)byteCount countStyle:(int)countStyle; 86 | @end 87 | 88 | #define UITableViewHeaderFooterView UIView 89 | 90 | #define mach_task_basic_info_data_t task_basic_info_data_t 91 | #define MACH_TASK_BASIC_INFO TASK_BASIC_INFO 92 | #define MACH_TASK_BASIC_INFO_COUNT TASK_BASIC_INFO_COUNT 93 | 94 | #endif 95 | 96 | uint64_t mach_time_to_milliseconds(uint64_t mach_time); 97 | 98 | 99 | @interface PSSymLink : NSObject 100 | + (NSString *)simplifyPathName:(NSString *)path; 101 | @end 102 | 103 | @interface UIScrollView (AdjustInset) 104 | @property(nonatomic, readonly) UIEdgeInsets realUIContentInset; 105 | @end 106 | -------------------------------------------------------------------------------- /src/Compat.m: -------------------------------------------------------------------------------- 1 | #import "Compat.h" 2 | #import 3 | 4 | #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0 5 | 6 | @implementation NSArray(Subscripts) 7 | - (id)objectAtIndexedSubscript:(NSUInteger)idx { return [self objectAtIndex:idx]; } 8 | @end 9 | 10 | @implementation NSMutableArray(Subscripts) 11 | - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx { [self replaceObjectAtIndex:idx withObject:obj]; } 12 | @end 13 | 14 | @implementation NSDictionary(Subscripts) 15 | - (id)objectForKeyedSubscript:(id)key { return [self objectForKey:key]; } 16 | @end 17 | 18 | @implementation NSMutableDictionary(Subscripts) 19 | - (void)setObject:(id)obj forKeyedSubscript:(id)key { [self setObject:obj forKey:key]; } 20 | @end 21 | 22 | @implementation NSByteCountFormatter 23 | + (NSString *)stringFromByteCount:(long long)byteCount countStyle:(int)countStyle 24 | { 25 | if (byteCount < 1024) 26 | return [NSString stringWithFormat:@"%lld bytes", byteCount]; 27 | else if (byteCount < 1024 * 1024) 28 | return [NSString stringWithFormat:@"%.1f KB", (float)byteCount / 1024]; 29 | else if (byteCount < 1024 * 1024 * 1024) 30 | return [NSString stringWithFormat:@"%.1f MB", (float)byteCount / 1024 / 1024]; 31 | else 32 | return [NSString stringWithFormat:@"%.1f GB", (float)byteCount / 1024 / 1024 / 1024]; 33 | } 34 | @end 35 | 36 | #endif 37 | 38 | uint64_t mach_time_to_milliseconds(uint64_t mach_time) 39 | { 40 | static mach_timebase_info_data_t timebase = {0}; 41 | if (!timebase.denom) 42 | mach_timebase_info(&timebase); 43 | return mach_time * timebase.numer / timebase.denom / 1000000; 44 | } 45 | 46 | 47 | @implementation PSSymLink 48 | 49 | + (NSString *)absoluteSymLinkDestination:(NSString *)link 50 | { 51 | if ([link hasSuffix:@"/"]) 52 | link = [link substringToIndex:link.length - 1]; 53 | NSString *target = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:link error:NULL]; 54 | if (!target) 55 | return @""; 56 | if (target && ![target hasPrefix:@"/"]) 57 | target = [[link stringByDeletingLastPathComponent] stringByAppendingPathComponent:target]; 58 | return [target stringByAppendingString:@"/"]; 59 | } 60 | 61 | // Replace some symlinks to shorten path 62 | + (NSString *)simplifyPathName:(NSString *)path 63 | { 64 | static NSArray *source = nil, *target = nil; 65 | static dispatch_once_t onceToken; 66 | dispatch_once(&onceToken, ^{ 67 | // Initialize symlinks 68 | source = @[@"/var/", @"/var/stash/", @"/usr/include/", @"/usr/share/", @"/usr/lib/pam/", @"/tmp/", @"/User/", @"/Applications/", @"/Library/Ringtones/", @"/Library/Wallpaper/"]; 69 | NSMutableArray *results = [NSMutableArray arrayWithCapacity:source.count]; 70 | for (NSString *src in source) 71 | [results addObject:[PSSymLink absoluteSymLinkDestination:src]]; 72 | target = [results copy]; 73 | }); 74 | path = [path stringByStandardizingPath]; 75 | if (![path hasPrefix:@"/"] || ![[NSUserDefaults standardUserDefaults] boolForKey:@"ShortenPaths"]) 76 | return path; 77 | // Replace link targets with symlinks 78 | for (int i = 0; i < target.count; i++) { 79 | NSString *key = target[i], *val = source[i]; 80 | if (!key.length) 81 | continue; 82 | if ([[path stringByAppendingString:@"/"] isEqualToString:key]) 83 | path = [val substringToIndex:val.length - 1]; 84 | else if ([path hasPrefix:key]) 85 | path = [val stringByAppendingString:[path substringFromIndex:key.length]]; 86 | } 87 | // Replace long bundle path with a short "old" version 88 | static NSString *appBundle = @"/User/Containers/Bundle/Application/"; 89 | if (path.length > appBundle.length + 37 && [path hasPrefix:appBundle]) 90 | path = [NSString stringWithFormat:@"/User/Applications/%@.../%@", 91 | [path substringWithRange:NSMakeRange(appBundle.length, 4)], // First four chars from App ID 92 | [path substringFromIndex:appBundle.length + 37]]; // The rest of the path 93 | static NSString *appData = @"/User/Containers/Data/Application/"; 94 | if (path.length > appData.length + 37 && [path hasPrefix:appData]) 95 | path = [NSString stringWithFormat:@"%@%@.../%@", appData, 96 | [path substringWithRange:NSMakeRange(appData.length, 4)], // First four chars from App ID 97 | [path substringFromIndex:appData.length + 37]]; // The rest of the path 98 | return path; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /src/GridCell.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "Proc.h" 3 | #import "ProcArray.h" 4 | #import "Sock.h" 5 | #import "Column.h" 6 | 7 | @interface GridTableCell : UITableViewCell 8 | @property (assign) NSUInteger id; 9 | @property (assign) NSUInteger firstColWidth; 10 | @property (assign) BOOL extendArgsLabel; 11 | @property (assign) BOOL colorDiffs; 12 | @property (strong) NSMutableArray *labels; 13 | @property (strong) NSMutableArray *dividers; 14 | + (NSString *)reuseIdWithIcon:(bool)withicon; 15 | + (instancetype)cellWithIcon:(bool)withicon; 16 | - (void)configureWithId:(int)id columns:(NSArray *)columns size:(CGSize)size; 17 | - (void)updateWithProc:(PSProc *)proc columns:(NSArray *)columns; 18 | - (void)updateWithSock:(PSSock *)sock columns:(NSArray *)columns; 19 | @end 20 | 21 | @interface GridHeaderView : UITableViewHeaderFooterView 22 | @property (strong) NSMutableArray *labels; 23 | @property (strong) NSMutableArray *dividers; 24 | + (instancetype)headerWithColumns:(NSArray *)columns size:(CGSize)size; 25 | + (instancetype)footerWithColumns:(NSArray *)columns size:(CGSize)size; 26 | - (void)sortColumnOld:(PSColumn *)oldCol New:(PSColumn *)newCol desc:(BOOL)desc; 27 | - (void)updateSummaryWithColumns:(NSArray *)columns procs:(PSProcArray *)procs; 28 | @end 29 | -------------------------------------------------------------------------------- /src/GridCell.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "Compat.h" 3 | #import "GridCell.h" 4 | 5 | /* 6 | @interface SmallGraph : UIView 7 | @property (strong) NSArray *dots; 8 | @end 9 | 10 | @implementation SmallGraph 11 | 12 | - (id)initWithFrame:(CGRect)frame 13 | { 14 | self = [super initWithFrame:frame]; 15 | self.backgroundColor = [UIColor whiteColor]; // clear 16 | return self; 17 | } 18 | 19 | + (id)graphWithFrame:(CGRect)frame 20 | { 21 | return [[SmallGraph alloc] initWithFrame:frame]; 22 | } 23 | 24 | //void draw1PxStroke(CGContextRef context, CGPoint startPoint, CGPoint endPoint, CGColorRef color) 25 | //{ 26 | // CGContextSaveGState(context); 27 | // CGContextSetLineCap(context, kCGLineCapSquare); 28 | // CGContextSetLineWidth(context, 1.0); 29 | // CGContextSetStrokeColorWithColor(context, color); 30 | // CGContextMoveToPoint(context, startPoint.x + 0.5, startPoint.y + 0.5); 31 | // CGContextAddLineToPoint(context, endPoint.x + 0.5, endPoint.y + 0.5); 32 | // CGContextStrokePath(context); 33 | // CGContextRestoreGState(context); 34 | //} 35 | 36 | - (void)drawRect:(CGRect)rect 37 | { 38 | if (!self.dots) return; 39 | CGContextRef context = UIGraphicsGetCurrentContext(); 40 | UIColor *color = [UIColor colorWithRed:0.7 green:0.7 blue:1.0 alpha:1.0]; 41 | CGFloat width = self.bounds.size.width, 42 | height = self.bounds.size.height; 43 | CGPoint bot = CGPointMake(self.bounds.origin.x + 0.5, self.bounds.origin.y + height + 0.5); 44 | 45 | CGContextSaveGState(context); 46 | CGContextSetLineCap(context, kCGLineCapSquare); 47 | CGContextSetLineWidth(context, 1.0); 48 | CGContextSetStrokeColorWithColor(context, color.CGColor); 49 | for (NSNumber *val in self.dots) { 50 | // draw1PxStroke(context, bot, CGPointMake(bot.x, bot.y - (height * [val unsignedIntegerValue] / 100)), color.CGColor); 51 | CGContextMoveToPoint(context, bot.x, bot.y); 52 | CGContextAddLineToPoint(context, bot.x, bot.y - (height * [val unsignedIntegerValue] / 200)); 53 | CGContextStrokePath(context); 54 | bot.x++; 55 | if (bot.x >= width) break; 56 | } 57 | CGContextRestoreGState(context); 58 | } 59 | 60 | @end 61 | */ 62 | 63 | 64 | 65 | @implementation GridTableCell 66 | 67 | + (NSString *)reuseIdWithIcon:(bool)withicon 68 | { 69 | return withicon ? @"GridTableIconCell" : @"GridTableCell"; 70 | } 71 | 72 | - (instancetype)initWithIcon:(bool)withicon 73 | { 74 | self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:[GridTableCell reuseIdWithIcon:withicon]]; 75 | self.accessoryView = [UIView new]; 76 | self.id = 0; 77 | return self; 78 | } 79 | 80 | + (instancetype)cellWithIcon:(bool)withicon 81 | { 82 | return [[GridTableCell alloc] initWithIcon:withicon]; 83 | } 84 | 85 | - (void)configureWithId:(int)id columns:(NSArray *)columns size:(CGSize)size 86 | { 87 | // Configuration did not change 88 | if (self.id == id) 89 | return; 90 | // Remove old views 91 | if (self.labels) 92 | for (UILabel *item in self.labels) [item removeFromSuperview]; 93 | if (self.dividers) 94 | for (UIView *item in self.dividers) [item removeFromSuperview]; 95 | // Create new views 96 | self.labels = [NSMutableArray arrayWithCapacity:columns.count-1]; 97 | self.dividers = [NSMutableArray arrayWithCapacity:columns.count]; 98 | self.extendArgsLabel = [[NSUserDefaults standardUserDefaults] boolForKey:@"FullWidthCommandLine"]; 99 | self.colorDiffs = [[NSUserDefaults standardUserDefaults] boolForKey:@"ColorDiffs"]; 100 | self.textLabel.font = size.height > 40 ? [UIFont systemFontOfSize:18.0] : [UIFont systemFontOfSize:12.0]; 101 | if (size.height > 40 && self.extendArgsLabel) 102 | size.height /= 2; 103 | NSUInteger totalCol; 104 | for (PSColumn *col in columns) 105 | if (col == columns[0]) { 106 | self.firstColWidth = totalCol = col.width - 5; 107 | self.textLabel.adjustsFontSizeToFitWidth = !(col.style & ColumnStyleEllipsis); 108 | if (col.style & ColumnStylePath) { 109 | if (!(col.style & ColumnStyleTooLong)) self.textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; 110 | self.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; 111 | } 112 | } else { 113 | UIView *divider = [[UIView alloc] initWithFrame:CGRectMake(totalCol, 0, 1, size.height)]; 114 | if (@available(iOS 13, *)) { 115 | divider.backgroundColor = UIColor.secondarySystemBackgroundColor; 116 | } else { 117 | divider.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1]; 118 | } 119 | [self.dividers addObject:divider]; 120 | [self.contentView addSubview:divider]; 121 | 122 | //if (col.tag == 4) { 123 | // SmallGraph *graph = [SmallGraph graphWithFrame:CGRectMake(totalCol + 1, 0, col.width - 1, size.height)]; 124 | // graph.tag = 1000;//col.tag; 125 | // [self.labels addObject:graph]; 126 | // [self.contentView addSubview:graph]; 127 | //} 128 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(totalCol + 4, 0, col.width - 8, size.height)]; 129 | label.textAlignment = col.align; 130 | label.font = col.style & ColumnStyleMonoFont ? [UIFont fontWithName:@"Courier" size:13.0] : [UIFont systemFontOfSize:12.0]; 131 | label.adjustsFontSizeToFitWidth = !(col.style & ColumnStyleEllipsis); 132 | if (col.style & ColumnStylePath) label.lineBreakMode = NSLineBreakByTruncatingMiddle; 133 | label.backgroundColor = [UIColor clearColor]; 134 | label.tag = col.tag + 1; 135 | [self.labels addObject:label]; 136 | [self.contentView addSubview:label]; 137 | 138 | totalCol += col.width; 139 | } 140 | if (self.extendArgsLabel) { 141 | UIView *divider = [[UIView alloc] initWithFrame:CGRectMake(self.firstColWidth, size.height, totalCol - self.firstColWidth, 1)]; 142 | [self.dividers addObject:divider]; 143 | if (@available(iOS 13, *)) { 144 | divider.backgroundColor = UIColor.secondarySystemBackgroundColor; 145 | } else { 146 | divider.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1]; 147 | } 148 | [self.contentView addSubview:divider]; 149 | } 150 | self.id = id; 151 | } 152 | 153 | - (void)updateWithProc:(PSProc *)proc columns:(NSArray *)columns 154 | { 155 | self.textLabel.text = proc.name; 156 | self.detailTextLabel.text = [proc.executable stringByAppendingString:proc.args]; 157 | if (proc.icon) 158 | self.imageView.image = proc.icon; 159 | for (PSColumn *col in columns) 160 | if (col != columns[0]) { 161 | //if (col.tag == 4) { 162 | // SmallGraph *graph = (SmallGraph *)[self viewWithTag:1000];//col.tag]; 163 | // if (graph) { graph.dots = [proc.cpuhistory copy]; [graph setNeedsDisplay]; } 164 | //} //else { 165 | UILabel *label = (UILabel *)[self viewWithTag:col.tag + 1]; 166 | if (label) { 167 | label.text = col.getData(proc); 168 | if (self.colorDiffs && (col.style & ColumnStyleColor)) 169 | label.textColor = col.getColor(proc); 170 | } 171 | } 172 | } 173 | 174 | - (void)updateWithSock:(PSSock *)sock columns:(NSArray *)columns 175 | { 176 | self.detailTextLabel.textColor = [UIColor grayColor]; 177 | for (PSColumn *col in columns) { 178 | UILabel *label; 179 | if (col != columns[0]) 180 | label = (UILabel *)[self viewWithTag:col.tag + 1]; 181 | else if (col.style & ColumnStyleTooLong) { 182 | self.textLabel.text = sock.description; 183 | label = self.detailTextLabel; 184 | } else { 185 | self.detailTextLabel.text = nil; 186 | label = self.textLabel; 187 | } 188 | if (label) { 189 | // The cell label gets a shorter text (sock.name), but the summary page will get the full one 190 | label.text = col.style & ColumnStyleTooLong ? sock.name : col.getData(sock); 191 | if (col != columns[0]) 192 | label.textColor = sock.color; 193 | } 194 | } 195 | } 196 | 197 | - (void)layoutSubviews 198 | { 199 | [super layoutSubviews]; 200 | CGRect frame; 201 | NSInteger imageWidth = self.imageView.frame.size.width; 202 | frame = self.contentView.frame; 203 | frame.origin.x = 5; 204 | frame.size.width -= 10; 205 | self.contentView.frame = frame; 206 | frame = self.imageView.frame; 207 | frame.origin.x = 0; 208 | self.imageView.frame = frame; 209 | frame = self.textLabel.frame; 210 | frame.origin.x = imageWidth; 211 | if (frame.origin.x) frame.origin.x += 5; 212 | frame.size.width = self.firstColWidth - imageWidth - 5; 213 | self.textLabel.frame = frame; 214 | frame = self.detailTextLabel.frame; 215 | frame.origin.x = imageWidth; 216 | if (frame.origin.x) frame.origin.x += 5; 217 | if (!self.extendArgsLabel) frame.size.width = self.firstColWidth - imageWidth - 5; 218 | else frame.size.width = self.contentView.frame.size.width - imageWidth; 219 | self.detailTextLabel.frame = frame; 220 | } 221 | 222 | @end 223 | 224 | 225 | @implementation GridHeaderView 226 | 227 | - (instancetype)initWithColumns:(NSArray *)columns size:(CGSize)size footer:(bool)footer 228 | { 229 | if (@available(iOS 6.0, *)) { 230 | self = [super initWithReuseIdentifier:@"Header"]; 231 | self.backgroundView = [[NSClassFromString(@"_UITableViewHeaderFooterView") alloc] initWithFrame:self.bounds]; 232 | } else { 233 | self = [super initWithReuseIdentifier:@"Header"]; 234 | } 235 | 236 | self.labels = [NSMutableArray arrayWithCapacity:columns.count]; 237 | self.dividers = [NSMutableArray arrayWithCapacity:columns.count]; 238 | NSUInteger totalCol = 0; 239 | for (PSColumn *col in columns) { 240 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(totalCol + 2, 0, col.width - 4, size.height)]; 241 | [self.labels addObject:label]; 242 | label.textAlignment = footer && col.getSummary ? col.align : NSTextAlignmentCenter; 243 | label.font = footer && col != columns[0] ? [UIFont systemFontOfSize:12.0] : [UIFont boldSystemFontOfSize:16.0]; 244 | label.adjustsFontSizeToFitWidth = YES; 245 | label.text = footer ? @"-" : col.name; 246 | if (@available(iOS 13, *)) { 247 | label.textColor = [UIColor labelColor]; 248 | } else { 249 | label.textColor = [UIColor blackColor]; 250 | } 251 | label.backgroundColor = [UIColor clearColor]; 252 | label.tag = col.tag + 1; 253 | //#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0 254 | if (@available(iOS 6, *)) { 255 | [self.contentView addSubview:label]; 256 | } else { 257 | //#else 258 | [self addSubview:label]; 259 | } 260 | //#endif 261 | totalCol += col.width; 262 | } 263 | 264 | return self; 265 | } 266 | 267 | + (instancetype)headerWithColumns:(NSArray *)columns size:(CGSize)size 268 | { 269 | return [[GridHeaderView alloc] initWithColumns:columns size:size footer:NO]; 270 | } 271 | 272 | + (instancetype)footerWithColumns:(NSArray *)columns size:(CGSize)size 273 | { 274 | return [[GridHeaderView alloc] initWithColumns:columns size:size footer:YES]; 275 | } 276 | 277 | - (void)sortColumnOld:(PSColumn *)oldCol New:(PSColumn *)newCol desc:(BOOL)desc 278 | { 279 | UILabel *label; 280 | if (oldCol && oldCol != newCol) 281 | if ((label = (UILabel *)[self viewWithTag:oldCol.tag + 1])) { 282 | // 283 | if (@available(iOS 13, *)) { 284 | label.textColor = [UIColor labelColor]; 285 | } else { 286 | label.textColor = [UIColor blackColor]; 287 | } 288 | label.text = oldCol.name; 289 | } 290 | if ((label = (UILabel *)[self viewWithTag:newCol.tag + 1])) { 291 | label.textColor = self.tintColor; 292 | label.text = [newCol.name stringByAppendingString:(desc ? @"\u25BC" : @"\u25B2")]; 293 | } 294 | } 295 | 296 | - (void)updateSummaryWithColumns:(NSArray *)columns procs:(PSProcArray *)procs 297 | { 298 | for (PSColumn *col in columns) 299 | if (col.getSummary) { 300 | UILabel *label = (UILabel *)[self viewWithTag:col.tag + 1]; 301 | if (label) label.text = col.getSummary(procs); 302 | } 303 | } 304 | 305 | @end 306 | -------------------------------------------------------------------------------- /src/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | CocoaTop 9 | CFBundleExecutable 10 | CocoaTop 11 | CFBundleIconFiles 12 | 13 | Icon.png 14 | Icon@2x.png 15 | Icon-72.png 16 | Icon-60 17 | Icon-76 18 | Icon-Small-40 19 | Icon-Small 20 | Icon-Small@2x 21 | Icon-Small-50 22 | 23 | CFBundleIdentifier 24 | $(PRODUCT_BUNDLE_IDENTIFIER) 25 | CFBundleInfoDictionaryVersion 26 | 6.0 27 | CFBundleName 28 | CocoaTop 29 | CFBundlePackageType 30 | APPL 31 | CFBundleSignature 32 | ???? 33 | CFBundleVersion 34 | 1.0 35 | CFBundleShortVersionString 36 | 1.0 37 | UIDeviceFamily 38 | 39 | 1 40 | 2 41 | 42 | UILaunchImages 43 | 44 | 45 | UILaunchImageMinimumOSVersion 46 | 7.0 47 | UILaunchImageName 48 | Default 49 | UILaunchImageOrientation 50 | Portrait 51 | UILaunchImageSize 52 | {320, 480} 53 | 54 | 55 | UILaunchImageMinimumOSVersion 56 | 7.0 57 | UILaunchImageName 58 | Default 59 | UILaunchImageOrientation 60 | Landscape 61 | UILaunchImageSize 62 | {320, 480} 63 | 64 | 65 | UILaunchImageMinimumOSVersion 66 | 7.0 67 | UILaunchImageName 68 | Default-568h 69 | UILaunchImageOrientation 70 | Portrait 71 | UILaunchImageSize 72 | {320, 568} 73 | 74 | 75 | UILaunchImageMinimumOSVersion 76 | 7.0 77 | UILaunchImageName 78 | Default-568h 79 | UILaunchImageOrientation 80 | Landscape 81 | UILaunchImageSize 82 | {320, 568} 83 | 84 | 85 | UILaunchImageMinimumOSVersion 86 | 7.0 87 | UILaunchImageName 88 | Default-667h 89 | UILaunchImageOrientation 90 | Portrait 91 | UILaunchImageSize 92 | {375, 667} 93 | 94 | 95 | UILaunchImageMinimumOSVersion 96 | 7.0 97 | UILaunchImageName 98 | Default-667h 99 | UILaunchImageOrientation 100 | Landscape 101 | UILaunchImageSize 102 | {375, 667} 103 | 104 | 105 | UILaunchImageMinimumOSVersion 106 | 7.0 107 | UILaunchImageName 108 | Default-736h 109 | UILaunchImageOrientation 110 | Portrait 111 | UILaunchImageSize 112 | {414, 736} 113 | 114 | 115 | UILaunchImageMinimumOSVersion 116 | 7.0 117 | UILaunchImageName 118 | Default-736h 119 | UILaunchImageOrientation 120 | Landscape 121 | UILaunchImageSize 122 | {414, 736} 123 | 124 | 125 | UILaunchImageMinimumOSVersion 126 | 7.0 127 | UILaunchImageName 128 | Default-1024h 129 | UILaunchImageOrientation 130 | Portrait 131 | UILaunchImageSize 132 | {768, 1024} 133 | 134 | 135 | UILaunchImageMinimumOSVersion 136 | 7.0 137 | UILaunchImageName 138 | Default-1024h 139 | UILaunchImageOrientation 140 | Landscape 141 | UILaunchImageSize 142 | {768, 1024} 143 | 144 | 145 | UILaunchStoryboardName 146 | LaunchScreen 147 | UISupportedInterfaceOrientations 148 | 149 | UIInterfaceOrientationPortrait 150 | UIInterfaceOrientationPortraitUpsideDown 151 | UIInterfaceOrientationLandscapeLeft 152 | UIInterfaceOrientationLandscapeRight 153 | 154 | UISupportedInterfaceOrientations~ipad 155 | 156 | UIInterfaceOrientationLandscapeRight 157 | UIInterfaceOrientationLandscapeLeft 158 | UIInterfaceOrientationPortraitUpsideDown 159 | UIInterfaceOrientationPortrait 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 arm64 2 | TARGET = iphone:clang:13.0:6.0 3 | APPLICATION_NAME = CocoaTop 4 | ADDITIONAL_OBJCFLAGS = -fobjc-arc # -Wno-deprecated-declarations 5 | CocoaTop_FILES = RootViewController.m SockViewController.m Proc.m ProcArray.m NetArray.m Sock.m Column.m GridCell.m Setup.m SetupColumns.m AppIcon.m TextViewController.m THtmlViewController.m PopupMenuView.m BackButtonHandler.m Compat.m AppDelegate.m main.m 6 | CocoaTop_FRAMEWORKS = UIKit IOKit CoreGraphics MessageUI 7 | CocoaTop_CODESIGN_FLAGS = -Stask.xml 8 | #ifeq ($(TARGET),iphone:clang:7.0) 9 | CocoaTop_RESOURCE_DIRS = res 10 | #endif 11 | 12 | include $(THEOS)/makefiles/common.mk 13 | include $(THEOS_MAKE_PATH)/application.mk 14 | 15 | SUBPROJECTS = postinst 16 | include $(THEOS_MAKE_PATH)/aggregate.mk 17 | 18 | #before-package:: 19 | # @cp .theos/obj/five/CocoaTop.app/CocoaTop .theos/_/Applications/CocoaTop.app/CocoaTop5 20 | # @cp .theos/obj/six/CocoaTop.app/CocoaTop .theos/_/Applications/CocoaTop.app/CocoaTop6 21 | -------------------------------------------------------------------------------- /src/NetArray.h: -------------------------------------------------------------------------------- 1 | @class PSProcArray; 2 | 3 | @interface PSNetArray : NSObject 4 | @property (strong) NSMutableDictionary *nstats; 5 | @property (assign) unsigned int tcp; 6 | @property (assign) unsigned int udp; 7 | @property (assign) CFSocketRef netStat; 8 | @property (assign) CFDataRef netStatAddr; 9 | + (instancetype)psNetArray; 10 | - (void)reopen; 11 | - (void)query; 12 | - (void)refresh:(PSProcArray *)procs; 13 | @end 14 | -------------------------------------------------------------------------------- /src/NetArray.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import "sys/kern_control.h" 5 | #import "sys/sys_domain.h" 6 | #define PRIVATE 7 | #import "Compat.h" 8 | #import "net/ntstat.h" 9 | //#import 10 | //#import 11 | //#import 12 | #import "ProcArray.h" 13 | #import "NetArray.h" 14 | 15 | @interface NSValue(PSCounts) 16 | + (instancetype)valueWithCounts:(PSCounts)value; 17 | @property (readonly) PSCounts countsValue; 18 | @end 19 | 20 | @implementation NSValue(PSCounts) 21 | + (instancetype)valueWithCounts:(PSCounts)value 22 | { 23 | return [self valueWithBytes:&value objCType:@encode(PSCounts)]; 24 | } 25 | - (PSCounts)countsValue 26 | { 27 | PSCounts value; 28 | [self getValue:&value]; 29 | return value; 30 | } 31 | @end 32 | 33 | int nstatAddSrc(int fd, int provider, uint64_t ctx) 34 | { 35 | nstat_msg_add_all_srcs aasreq = {{ctx, NSTAT_MSG_TYPE_ADD_ALL_SRCS, 0}, provider, NSTAT_FILTER_ACCEPT_ALL | NSTAT_FILTER_PROVIDER_NOZEROBYTES | NSTAT_FILTER_REQUIRE_SRC_ADDED}; 36 | // CFDataRef data = CFDataCreate(NULL, &aasreq, sizeof(aasreq)); 37 | // CFSocketError err = CFSocketSendData(s, NULL, data, 0); 38 | // CFRelease(data); 39 | return write(fd, &aasreq, sizeof(aasreq)); 40 | } 41 | 42 | int nstatQuerySrc(int fd, nstat_src_ref_t srcref, uint64_t ctx) 43 | { 44 | nstat_msg_query_src_req qsreq = {{ctx, NSTAT_MSG_TYPE_QUERY_SRC, 0}, srcref}; 45 | return write(fd, &qsreq, sizeof(qsreq)); 46 | } 47 | 48 | int nstatGetSrcDesc(int fd, nstat_provider_id_t provider, nstat_src_ref_t srcref) 49 | { 50 | nstat_msg_get_src_description gsdreq = {{provider, NSTAT_MSG_TYPE_GET_SRC_DESC, 0}, srcref}; 51 | return write(fd, &gsdreq, sizeof(gsdreq)); 52 | } 53 | 54 | void NetStatCallBack(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info) 55 | { 56 | PSNetArray *self = (__bridge PSNetArray *)info; 57 | NSValue *srcval; 58 | int fd = CFSocketGetNative(s); 59 | nstat_msg_hdr *ns = (nstat_msg_hdr *)CFDataGetBytePtr((CFDataRef)data); 60 | int len = CFDataGetLength((CFDataRef)data); 61 | 62 | if (!len || callbackType != kCFSocketDataCallBack) { 63 | // 100% working hack: if an empty packet comes in, we should just reconnect 64 | NSLog(@"NSTAT: callbackType=%lu len=%d, reconnecting...", callbackType, len); 65 | [self reopen]; 66 | return; 67 | } 68 | switch (ns->type) { 69 | case NSTAT_MSG_TYPE_SRC_ADDED: { 70 | nstat_msg_src_added *nsa = (nstat_msg_src_added *)ns; 71 | nstatGetSrcDesc(fd, nsa->provider, nsa->srcref); 72 | break; } 73 | case NSTAT_MSG_TYPE_SRC_REMOVED: { 74 | nstat_msg_src_removed *nsr = (nstat_msg_src_removed *)ns; 75 | if ((srcval = self.nstats[@(nsr->srcref)])) { 76 | PSCounts cnt = srcval.countsValue; 77 | cnt.provider = NSTAT_PROVIDER_NONE; 78 | self.nstats[@(nsr->srcref)] = [NSValue valueWithCounts:cnt]; 79 | } 80 | break; } 81 | case NSTAT_MSG_TYPE_SRC_DESC: { 82 | nstat_msg_src_description *nmsd = (nstat_msg_src_description *)ns; 83 | PSCounts cnt = {-1, nmsd->provider, nmsd->srcref}; 84 | if ((srcval = self.nstats[@(nmsd->srcref)])) 85 | cnt = srcval.countsValue; 86 | if (nmsd->provider == NSTAT_PROVIDER_UDP) { 87 | // if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_7_0) 88 | // cnt.pid = ((nstat_udp_descriptor_ios6_9 *)nmsd->data)->epid; 89 | // else if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_6_0) 90 | // cnt.pid = ((nstat_udp_descriptor_ios6_9 *)nmsd->data)->pid; 91 | // else 92 | // cnt.pid = ((nstat_udp_descriptor_ios5 *)nmsd->data)->pid; 93 | if (@available(iOS 7, *)) { 94 | cnt.pid = ((nstat_udp_descriptor_ios6_9 *)nmsd->data)->epid; 95 | } else if (@available(iOS 6, *)) { 96 | cnt.pid = ((nstat_udp_descriptor_ios6_9 *)nmsd->data)->pid; 97 | } else { 98 | cnt.pid = ((nstat_udp_descriptor_ios5 *)nmsd->data)->pid; 99 | } 100 | } else if (nmsd->provider == NSTAT_PROVIDER_TCP) { 101 | // if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_8_0) 102 | // cnt.pid = ((nstat_tcp_descriptor_ios8_9 *)nmsd->data)->epid; 103 | // else if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_7_0) 104 | // cnt.pid = ((nstat_tcp_descriptor_ios6_7 *)nmsd->data)->epid; 105 | // else if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_6_0) 106 | // cnt.pid = ((nstat_tcp_descriptor_ios6_7 *)nmsd->data)->pid; 107 | // else 108 | // cnt.pid = ((nstat_tcp_descriptor_ios5 *)nmsd->data)->pid; 109 | if (@available(iOS 8, *)) { 110 | cnt.pid = ((nstat_tcp_descriptor_ios8_9 *)nmsd->data)->epid; 111 | } else if (@available(iOS 7, *)) { 112 | cnt.pid = ((nstat_tcp_descriptor_ios6_7 *)nmsd->data)->epid; 113 | } else if (@available(iOS 6, *)) { 114 | cnt.pid = ((nstat_tcp_descriptor_ios6_7 *)nmsd->data)->pid; 115 | } else { 116 | cnt.pid = ((nstat_tcp_descriptor_ios5 *)nmsd->data)->pid; 117 | } 118 | } 119 | if (cnt.pid > 0) { 120 | self.nstats[@(nmsd->srcref)] = [NSValue valueWithCounts:cnt]; 121 | nstatQuerySrc(fd, nmsd->srcref, nmsd->srcref); 122 | } 123 | break; } 124 | case NSTAT_MSG_TYPE_SRC_COUNTS: { 125 | nstat_msg_src_counts *cnts = (nstat_msg_src_counts *)ns; 126 | if ((srcval = self.nstats[@(cnts->srcref)])) { 127 | PSCounts cnt = srcval.countsValue; 128 | cnt.rxpackets = cnts->counts.nstat_rxpackets; cnt.rxbytes = cnts->counts.nstat_rxbytes; 129 | cnt.txpackets = cnts->counts.nstat_txpackets; cnt.txbytes = cnts->counts.nstat_txbytes; 130 | self.nstats[@(cnts->srcref)] = [NSValue valueWithCounts:cnt]; 131 | } 132 | break; } 133 | // case NSTAT_MSG_TYPE_SUCCESS: NSLog(@"NSTAT_MSG_TYPE_SUCCESS, size:%d, ctx:%llu", len, ns->context); break; 134 | // case NSTAT_MSG_TYPE_ERROR: NSLog(@"NSTAT_MSG_TYPE_ERROR, size:%d, ctx:%llu", len, ns->context); break; 135 | // default: NSLog(@"NSTAT:%d, size:%d, ctx:%llu", ns->type, len, ns->context); 136 | } 137 | } 138 | 139 | @implementation PSNetArray 140 | 141 | - (void)close 142 | { 143 | if (self.netStat) { 144 | CFSocketInvalidate(self.netStat); 145 | CFRelease(self.netStat); 146 | self.netStat = 0; 147 | } 148 | } 149 | 150 | - (void)reopen 151 | { 152 | [self close]; 153 | CFSocketContext ctx = {0, (__bridge void *)self}; 154 | self.netStat = CFSocketCreate(0, PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL, kCFSocketDataCallBack, NetStatCallBack, &ctx); 155 | CFRunLoopAddSource( 156 | [[NSRunLoop currentRunLoop] getCFRunLoop], 157 | CFSocketCreateRunLoopSource(0, self.netStat, 0/*order*/), 158 | kCFRunLoopCommonModes); 159 | int fd = CFSocketGetNative(self.netStat); 160 | if (!self.netStatAddr) { 161 | struct ctl_info ctlInfo = {0, NET_STAT_CONTROL_NAME}; 162 | if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1) { 163 | NSLog(@"NSTAT ioctl failed"); 164 | [self close]; 165 | return; 166 | } 167 | struct sockaddr_ctl sc = {sizeof(sc), AF_SYSTEM, AF_SYS_CONTROL, ctlInfo.ctl_id, 0}; 168 | self.netStatAddr = CFDataCreate(0, (const UInt8 *)&sc, sizeof(sc)); 169 | } 170 | // Make a connect-callback, then do nstatAddSrc/nstatQuerySrc in the callback??? 171 | CFSocketError err = CFSocketConnectToAddress(self.netStat, self.netStatAddr, .1); 172 | if (err != kCFSocketSuccess) { 173 | NSLog(@"NSTAT CFSocketConnectToAddress err=%ld", err); 174 | [self close]; 175 | return; 176 | } 177 | nstatAddSrc(fd, NSTAT_PROVIDER_TCP, (uint64_t)self); 178 | nstatAddSrc(fd, NSTAT_PROVIDER_UDP, (uint64_t)self); 179 | // nstatQuerySrc(fd, NSTAT_SRC_REF_ALL, ctx); 180 | } 181 | 182 | - (instancetype)initNetArray 183 | { 184 | self = [super init]; 185 | if (!self) return nil; 186 | self.nstats = [NSMutableDictionary dictionaryWithCapacity:200]; 187 | self.netStat = 0; 188 | self.netStatAddr = 0; 189 | [self reopen]; 190 | return self; 191 | } 192 | 193 | + (instancetype)psNetArray 194 | { 195 | return [[PSNetArray alloc] initNetArray]; 196 | } 197 | 198 | - (void)query 199 | { 200 | // Query all sources 201 | int fd = CFSocketGetNative(self.netStat); 202 | if (fd != -1) 203 | for (NSValue *val in self.nstats.allValues) { 204 | PSCounts cnt = val.countsValue; 205 | if (cnt.pid == 1) 206 | // Because launchd runs as root, it can create low-numbered TCP/IP listen sockets and hand them off to the daemon (from developer.apple.com) 207 | nstatGetSrcDesc(fd, cnt.provider, cnt.srcref); 208 | else 209 | nstatQuerySrc(fd, cnt.srcref, cnt.srcref); 210 | } 211 | } 212 | 213 | - (void)refresh:(PSProcArray *)procs 214 | { 215 | // Update all process statistics 216 | for (NSNumber *key in self.nstats.allKeys) { 217 | PSCounts cnt = ((NSValue *)self.nstats[key]).countsValue; 218 | PSProc *proc = [procs procForPid:cnt.pid]; 219 | if (proc) { 220 | proc->netstat.rxpackets += cnt.rxpackets; proc->netstat.rxbytes += cnt.rxbytes; 221 | proc->netstat.txpackets += cnt.txpackets; proc->netstat.txbytes += cnt.txbytes; 222 | // Removed sources also go to cache 223 | if (cnt.provider == NSTAT_PROVIDER_NONE) { 224 | proc->netstat_cache.rxpackets += cnt.rxpackets; proc->netstat_cache.rxbytes += cnt.rxbytes; 225 | proc->netstat_cache.txpackets += cnt.txpackets; proc->netstat_cache.txbytes += cnt.txbytes; 226 | } 227 | } 228 | // Remove closed source 229 | if (cnt.provider == NSTAT_PROVIDER_NONE) 230 | [self.nstats removeObjectForKey:key]; 231 | } 232 | } 233 | 234 | - (void)dealloc 235 | { 236 | [self close]; 237 | } 238 | 239 | @end 240 | -------------------------------------------------------------------------------- /src/PopupMenuView.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @protocol PopupMenuHandlerProtocol 4 | @optional 5 | - (void)popupMenuTappedItem:(NSInteger)item; 6 | @end 7 | 8 | @interface UITableViewControllerWithMenu : UITableViewController 9 | @property (assign) NSInteger popupMenuSelected; 10 | - (void)popupMenuWithItems:(NSArray *)items selected:(NSInteger)sel aligned:(UIControlContentHorizontalAlignment)align; 11 | - (void)popupMenuLayout; 12 | - (IBAction)popupMenuToggle; 13 | @end 14 | -------------------------------------------------------------------------------- /src/PopupMenuView.m: -------------------------------------------------------------------------------- 1 | #import "Compat.h" 2 | #import "PopupMenuView.h" 3 | 4 | @interface UIButtonWithColorStates : UIButton 5 | @end 6 | 7 | @implementation UIButtonWithColorStates 8 | - (UIColor *)colorForHigh:(BOOL)high sel:(BOOL)sel 9 | { 10 | return high ? [UIColor colorWithRed:( 16.0 / 255.0) green:( 84.0 / 255.0) blue:(152.0 / 255.0) alpha:1.0]: 11 | sel ? [UIColor colorWithRed:(101.0 / 255.0) green:(170.0 / 255.0) blue:(239.0 / 255.0) alpha:1.0]: 12 | [UIColor colorWithRed:( 36.0 / 255.0) green:(132.0 / 255.0) blue:(232.0 / 255.0) alpha:1.0]; 13 | } 14 | 15 | - (void)setHighlighted:(BOOL)highlighted 16 | { 17 | self.backgroundColor = [self colorForHigh:highlighted sel:self.selected]; 18 | [super setHighlighted:highlighted]; 19 | } 20 | 21 | - (void)setSelected:(BOOL)selected 22 | { 23 | self.backgroundColor = [self colorForHigh:self.highlighted sel:selected]; 24 | [super setSelected:selected]; 25 | } 26 | @end 27 | 28 | @implementation UITableViewControllerWithMenu 29 | { 30 | UIView *menuContainerView; 31 | UIView *menuTintView; 32 | UIView *menuView; 33 | } 34 | 35 | - (void)popupMenuLayout 36 | { 37 | if ([menuContainerView superview] != nil) { 38 | CGRect frame = [self.navigationController.view convertRect:self.view.frame fromView:self.view.superview]; 39 | frame.origin.y += self.tableView.realUIContentInset.top; 40 | frame.size.height -= self.tableView.realUIContentInset.top; 41 | [menuContainerView setFrame:frame]; 42 | for (UIButton *button in menuView.subviews) 43 | button.selected = button.tag == self.popupMenuSelected; 44 | } 45 | } 46 | 47 | - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration 48 | { 49 | [self popupMenuLayout]; 50 | } 51 | 52 | - (IBAction)popupMenuToggle 53 | { 54 | const BOOL willAppear = (menuContainerView.superview == nil); 55 | if (willAppear) { 56 | [self.navigationController.view addSubview:menuContainerView]; 57 | [self popupMenuLayout]; 58 | } 59 | // Show/hide animation 60 | CGRect menuFrame = menuView.frame; 61 | menuFrame.origin.y = willAppear ? 0.0 : -menuFrame.size.height; 62 | CGFloat menuTintAlpha = willAppear ? 0.7 : 0.0; 63 | void (^animations)(void) = ^ { 64 | menuView.frame = menuFrame; 65 | menuTintView.alpha = menuTintAlpha; 66 | }; 67 | void (^completion)(BOOL) = ^(BOOL finished) { 68 | if (!willAppear) [menuContainerView removeFromSuperview]; 69 | }; 70 | //#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0 71 | if (@available(iOS 7, *)) { 72 | //if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_7_0) 73 | [UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:1.0 74 | initialSpringVelocity:4.0 options:UIViewAnimationOptionCurveEaseInOut 75 | animations:animations completion:completion]; 76 | } else { 77 | //#endif 78 | [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut 79 | animations:animations completion:completion]; 80 | } 81 | } 82 | 83 | - (void)popupMenuItemTapped:(UIButton *)sender 84 | { 85 | [self popupMenuToggle]; 86 | if ([self respondsToSelector:@selector(popupMenuTappedItem:)]) 87 | [self popupMenuTappedItem:sender.tag]; 88 | } 89 | 90 | - (UIButton *)popupMenuButtonWithTitle:(NSString *)title position:(NSInteger)position aligned:(UIControlContentHorizontalAlignment)align 91 | { 92 | const CGFloat buttonHeight = 45.0; 93 | UIButtonWithColorStates *button = [UIButtonWithColorStates buttonWithType:UIButtonTypeCustom]; 94 | button.autoresizingMask = UIViewAutoresizingFlexibleWidth; 95 | button.frame = CGRectMake(0.0, position * (1.0 + buttonHeight), 0.0, buttonHeight); 96 | button.tag = position; 97 | button.contentEdgeInsets = UIEdgeInsetsMake(0, buttonHeight / 2, 0, buttonHeight / 2); 98 | button.selected = self.popupMenuSelected == position; 99 | button.contentHorizontalAlignment = align; 100 | [button addTarget:self action:@selector(popupMenuItemTapped:) forControlEvents:UIControlEventTouchUpInside]; 101 | [button setTitle:title forState:UIControlStateNormal]; 102 | return button; 103 | } 104 | 105 | - (void)popupMenuWithItems:(NSArray *)items selected:(NSInteger)sel aligned:(UIControlContentHorizontalAlignment)align 106 | { 107 | const CGFloat buttonHeight = 45.0; 108 | const CGFloat menuHeight = items.count * (1.0 + buttonHeight); 109 | 110 | menuView = [[UIView alloc] initWithFrame:CGRectMake(0.0, -menuHeight, 0.0, menuHeight)]; 111 | menuView.autoresizingMask = UIViewAutoresizingFlexibleWidth; 112 | menuView.backgroundColor = [UIColor colorWithWhite:0.85 alpha:1.0]; 113 | self.popupMenuSelected = sel; 114 | NSInteger pos = 0; 115 | for (NSString* item in items) { 116 | [menuView addSubview:[self popupMenuButtonWithTitle:item position:pos aligned:align]]; 117 | pos++; 118 | } 119 | 120 | menuTintView = [[UIView alloc] initWithFrame:CGRectZero]; 121 | menuTintView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 122 | menuTintView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; 123 | // Add tap recognizer to dismiss menu when tapping outside its bounds. 124 | [menuTintView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(popupMenuToggle)]]; 125 | 126 | menuContainerView = [[UIView alloc] initWithFrame:CGRectZero]; 127 | menuContainerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 128 | menuContainerView.clipsToBounds = YES; 129 | [menuContainerView addSubview:menuTintView]; 130 | [menuContainerView addSubview:menuView]; 131 | } 132 | 133 | - (void)viewWillDisappear:(BOOL)animated 134 | { 135 | if (menuContainerView.superview != nil) 136 | [self popupMenuToggle]; 137 | [super viewWillDisappear:animated]; 138 | } 139 | 140 | - (void)viewDidUnload 141 | { 142 | if (menuContainerView != nil) { 143 | [menuContainerView removeFromSuperview]; 144 | menuContainerView = nil; 145 | menuTintView = nil; 146 | menuView = nil; 147 | } 148 | [super viewDidUnload]; 149 | } 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /src/Proc.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "sys/resource.h" 4 | #import 5 | #define PRIVATE 6 | #import "Compat.h" 7 | #import "net/ntstat.h" 8 | 9 | // Display states determine grid row colors 10 | typedef enum { 11 | ProcDisplayUser, 12 | ProcDisplayNormal, 13 | ProcDisplayStarted, 14 | ProcDisplayTerminated 15 | } display_t; 16 | 17 | // Thread states are sorted by priority, top priority becomes a "task state" 18 | typedef enum { 19 | ProcStateDebugging, 20 | ProcStateZombie, 21 | ProcStateRunning, 22 | ProcStateUninterruptible, 23 | ProcStateSleeping, 24 | ProcStateIndefiniteSleep, 25 | ProcStateTerminated, 26 | ProcStateHalted, 27 | ProcStateMax 28 | } proc_state_t; 29 | 30 | #define PROC_STATE_CHARS "DZRUSITH?" 31 | 32 | typedef struct PSCounts { 33 | pid_t pid; 34 | nstat_provider_id_t provider; 35 | nstat_src_ref_t srcref; 36 | uint64_t rxpackets; 37 | uint64_t rxbytes; 38 | uint64_t txpackets; 39 | uint64_t txbytes; 40 | } PSCounts; 41 | 42 | @interface PSProc : NSObject 43 | { 44 | @public mach_task_basic_info_data_t basic; 45 | @public struct task_events_info events; 46 | @public struct task_events_info events_prev; 47 | //#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0 48 | @public struct task_power_info power; 49 | @public struct task_power_info power_prev; 50 | //#endif 51 | @public struct rusage_info_v2 rusage; 52 | @public struct rusage_info_v2 rusage_prev; 53 | @public struct PSCounts netstat; 54 | @public struct PSCounts netstat_prev; 55 | @public struct PSCounts netstat_cache; 56 | } 57 | @property (assign) display_t display; 58 | @property (assign) pid_t pid; 59 | @property (assign) pid_t ppid; 60 | @property (assign) unsigned int prio; 61 | @property (assign) unsigned int priobase; 62 | @property (assign) task_role_t role; 63 | @property (assign) int nice; 64 | @property (assign) unsigned int flags; 65 | @property (assign) uint64_t ptime; // 0.01's of a second 66 | @property (assign) dev_t tdev; 67 | @property (assign) uid_t uid; 68 | @property (assign) gid_t gid; 69 | @property (assign) proc_state_t state; 70 | @property (assign) unsigned int pcpu; 71 | @property (assign) unsigned int threads; 72 | @property (assign) unsigned int ports; 73 | @property (assign) unsigned int files; 74 | @property (assign) unsigned int socks; 75 | @property (strong) NSString *name; 76 | @property (strong) NSString *executable; 77 | @property (strong) NSString *args; 78 | @property (strong) UIImage *icon; 79 | @property (strong) NSDictionary *app; 80 | @property (strong) NSMutableDictionary *dispQueue; 81 | //@property (strong) NSMutableArray *cpuhistory; 82 | //@property (strong) NSString *moredata; 83 | @property (strong) PSProc *prev; // Previous data for comparison 84 | + (instancetype)psProcWithKinfo:(struct kinfo_proc *)ki iconSize:(CGFloat)size; 85 | - (instancetype)psProcCopy; 86 | - (void)update; 87 | - (void)updateWithKinfo:(struct kinfo_proc *)ki; 88 | @end 89 | 90 | proc_state_t mach_state_order(struct thread_basic_info *tbi); 91 | unsigned int mach_thread_priority(thread_t thread, policy_t policy); 92 | -------------------------------------------------------------------------------- /src/ProcArray.h: -------------------------------------------------------------------------------- 1 | #import "Proc.h" 2 | #import "Column.h" 3 | #import "NetArray.h" 4 | 5 | @interface PSProcInfo : NSObject 6 | { 7 | @public struct kinfo_proc *kp; 8 | @public size_t count; 9 | @public int ret; 10 | } 11 | + (instancetype)psProcInfoSort:(BOOL)sort; 12 | @end 13 | 14 | @interface PSProcArray : NSObject 15 | @property (strong) NSMutableArray *procs; 16 | @property (strong) NSMutableArray *procsFiltered; 17 | @property (strong) PSNetArray *nstats; 18 | @property (assign) CGFloat iconSize; 19 | @property (assign) uint64_t memUsed; 20 | @property (assign) uint64_t memFree; 21 | @property (assign) uint64_t memTotal; 22 | @property (assign) unsigned int totalCpu; 23 | @property (assign) unsigned int threadCount; 24 | @property (assign) unsigned int portCount; 25 | @property (assign) unsigned int machCalls; 26 | @property (assign) unsigned int unixCalls; 27 | @property (assign) unsigned int switchCount; 28 | @property (assign) unsigned int guiCount; 29 | @property (assign) unsigned int mobileCount; 30 | @property (assign) unsigned int runningCount; 31 | @property (assign) unsigned int coresCount; 32 | @property (assign) unsigned int filterCount; 33 | + (instancetype)psProcArrayWithIconSize:(CGFloat)size; 34 | - (int)refresh; 35 | - (void)sortUsingComparator:(NSComparator)comp desc:(BOOL)desc; 36 | - (void)setAllDisplayed:(display_t)display; 37 | - (NSUInteger)indexOfDisplayed:(display_t)display; 38 | - (NSUInteger)totalCount; 39 | - (NSUInteger)count; 40 | - (PSProc *)objectAtIndexedSubscript:(NSUInteger)idx; 41 | - (NSUInteger)indexForPid:(pid_t)pid; 42 | - (PSProc *)procForPid:(pid_t)pid; 43 | - (void)filter:(NSString *)text column:(PSColumn *)col; 44 | @end 45 | -------------------------------------------------------------------------------- /src/ProcArray.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import "ProcArray.h" 6 | #import "NetArray.h" 7 | 8 | @implementation PSProcInfo 9 | int sort_procs_by_pid(const void *p1, const void *p2) 10 | { 11 | pid_t kp1 = ((struct kinfo_proc *)p1)->kp_proc.p_pid, kp2 = ((struct kinfo_proc *)p2)->kp_proc.p_pid; 12 | return kp1 == kp2 ? 0 : kp1 > kp2 ? 1 : -1; 13 | } 14 | 15 | - (instancetype)initProcInfoSort:(BOOL)sort 16 | { 17 | static int maxproc; 18 | static dispatch_once_t once; 19 | dispatch_once(&once, ^{ 20 | int mib[2]; 21 | size_t len; 22 | 23 | mib[0] = CTL_KERN; 24 | mib[1] = KERN_MAXPROC; 25 | len = sizeof(maxproc); 26 | sysctl(mib, 2, &maxproc, &len, NULL, 0); 27 | }); 28 | 29 | self = [super init]; 30 | self->kp = 0; 31 | self->count = 0; 32 | 33 | // Get buffer size 34 | size_t alloc_size = maxproc * sizeof(struct kinfo_proc); 35 | size_t bufSize = 0; 36 | self->kp = (struct kinfo_proc *)malloc(alloc_size); 37 | static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; 38 | if (self->kp == NULL) { 39 | if (sysctl(mib, 4, NULL, &alloc_size, NULL, 0) < 0) 40 | { self->ret = errno; return self; } 41 | alloc_size *= 2; 42 | self->kp = (struct kinfo_proc *)malloc(alloc_size); 43 | } 44 | bufSize = alloc_size; 45 | // Get process list 46 | self->ret = sysctl(mib, 4, self->kp, &bufSize, NULL, 0); 47 | if (self->ret) 48 | { free(self->kp); self->kp = 0; return self; } 49 | self->count = bufSize / sizeof(struct kinfo_proc); 50 | if (sort) 51 | qsort(self->kp, self->count, sizeof(*kp), sort_procs_by_pid); 52 | if (@available(iOS 11, *)) { 53 | } else if (@available(iOS 10, *)) { 54 | if (self->kp[self->count - 1].kp_proc.p_pid == 1) { 55 | if (alloc_size > (self->count + 1) * sizeof(struct kinfo_proc)) { 56 | static int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, 0 }; 57 | size_t length = sizeof(struct kinfo_proc); 58 | sysctl(mib, 4, &self->kp[self->count++], &length, NULL, 0); 59 | } 60 | } 61 | } 62 | return self; 63 | } 64 | 65 | + (instancetype)psProcInfoSort:(BOOL)sort 66 | { 67 | return [[PSProcInfo alloc] initProcInfoSort:sort]; 68 | } 69 | 70 | - (void)dealloc 71 | { 72 | if (self->kp) free(self->kp); 73 | } 74 | @end 75 | 76 | @implementation PSProcArray 77 | 78 | - (instancetype)initProcArrayWithIconSize:(CGFloat)size 79 | { 80 | self = [super init]; 81 | if (!self) return nil; 82 | self.iconSize = size; 83 | self.procs = [NSMutableArray arrayWithCapacity:300]; 84 | self.nstats = [PSNetArray psNetArray]; 85 | NSProcessInfo *procinfo = [NSProcessInfo processInfo]; 86 | self.memTotal = procinfo.physicalMemory; 87 | self.coresCount = procinfo.processorCount; 88 | self.filterCount = 0; 89 | return self; 90 | } 91 | 92 | + (instancetype)psProcArrayWithIconSize:(CGFloat)size 93 | { 94 | return [[PSProcArray alloc] initProcArrayWithIconSize:size]; 95 | } 96 | 97 | - (void)refreshMemStats 98 | { 99 | mach_port_t host_port = mach_host_self(); 100 | mach_msg_type_number_t host_size = HOST_VM_INFO64_COUNT; 101 | vm_statistics64_data_t vm_stat; 102 | vm_size_t pagesize; 103 | 104 | host_page_size(host_port, &pagesize); 105 | if (host_statistics64(host_port, HOST_VM_INFO64, (host_info_t)&vm_stat, &host_size) == KERN_SUCCESS) { 106 | // self.memUsed = (vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * pagesize; 107 | //#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0 108 | // self.memUsed += vm_stat.compressor_page_count * pagesize; 109 | //#endif 110 | self.memFree = vm_stat.free_count * pagesize; 111 | self.memUsed = self.memTotal - self.memFree; 112 | } 113 | /* 114 | host_cpu_load_info_data_t cpu_stat; 115 | host_size = HOST_CPU_LOAD_INFO_COUNT; 116 | if (host_statistics(host_port, HOST_CPU_LOAD_INFO, (host_info_t)&cpu_stat, &host_size) == KERN_SUCCESS) { 117 | cpu_stat.cpu_ticks[CPU_STATE_MAX] 118 | } 119 | */ 120 | } 121 | 122 | - (int)refresh 123 | { 124 | static uid_t mobileuid = 0; 125 | if (!mobileuid) { 126 | struct passwd *mobile = getpwnam("mobile"); 127 | if (mobile) { 128 | mobileuid = mobile->pw_uid; 129 | } 130 | } 131 | // Reset totals 132 | self.totalCpu = self.threadCount = self.portCount = self.machCalls = self.unixCalls = self.switchCount = self.runningCount = self.mobileCount = self.guiCount = 0; 133 | // Remove terminated processes 134 | [self.procs filterUsingPredicate:[NSPredicate predicateWithBlock: ^BOOL(PSProc *obj, NSDictionary *bind) { 135 | return obj.display != ProcDisplayTerminated; 136 | }]]; 137 | [self setAllDisplayed:ProcDisplayTerminated]; 138 | // Get process list and update the procs array 139 | PSProcInfo *procs = [PSProcInfo psProcInfoSort:NO]; 140 | if (procs->ret) 141 | return procs->ret; 142 | for (int i = 0; i < procs->count; i++) { 143 | PSProc *proc = [self procForPid:procs->kp[i].kp_proc.p_pid]; 144 | if (!proc) { 145 | proc = [PSProc psProcWithKinfo:&procs->kp[i] iconSize:self.iconSize]; 146 | [self.procs addObject:proc]; 147 | } else { 148 | [proc updateWithKinfo:&procs->kp[i]]; 149 | proc.display = ProcDisplayUser; 150 | } 151 | // Compute totals 152 | if (proc.pid) self.totalCpu += proc.pcpu; // Kernel gets all idle CPU time 153 | if (proc.uid == mobileuid) self.mobileCount++; 154 | if (proc.state == ProcStateRunning) self.runningCount++; 155 | if (proc.role != TASK_UNSPECIFIED) self.guiCount++; 156 | self.threadCount += proc.threads; 157 | self.portCount += proc.ports; 158 | self.machCalls += proc->events.syscalls_mach - proc->events_prev.syscalls_mach; 159 | self.unixCalls += proc->events.syscalls_unix - proc->events_prev.syscalls_unix; 160 | self.switchCount += proc->events.csw - proc->events_prev.csw; 161 | } 162 | [self refreshMemStats]; 163 | [self.nstats refresh:self]; 164 | self.procsFiltered = self.procs; 165 | return 0; 166 | } 167 | 168 | - (void)sortUsingComparator:(NSComparator)comp desc:(BOOL)desc 169 | { 170 | if (desc) { 171 | [self.procs sortUsingComparator:^NSComparisonResult(id a, id b) { return comp(b, a); }]; 172 | } else 173 | [self.procs sortUsingComparator:comp]; 174 | } 175 | 176 | - (void)setAllDisplayed:(display_t)display 177 | { 178 | for (PSProc *proc in self.procs) 179 | // Setting all items to "normal" is used only to hide "started" 180 | if (display != ProcDisplayNormal || proc.display == ProcDisplayStarted) 181 | proc.display = display; 182 | } 183 | 184 | - (NSUInteger)indexOfDisplayed:(display_t)display 185 | { 186 | return [self.procsFiltered indexOfObjectPassingTest:^BOOL(PSProc *proc, NSUInteger idx, BOOL *stop) { 187 | return proc.display == display; 188 | }]; 189 | // return [self.procs enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^void(PSProc *proc, NSUInteger idx, BOOL *stop) { 190 | // if (proc.display == display) *stop = YES; 191 | // }]; 192 | // for (PSProc *proc in [self.procs reverseObjectEnumerator]) { 193 | // if (proc.display == display) return idx; 194 | // } 195 | } 196 | 197 | - (NSUInteger)totalCount 198 | { 199 | return self.procs.count; 200 | } 201 | 202 | - (NSUInteger)count 203 | { 204 | return self.procsFiltered.count; 205 | } 206 | 207 | - (PSProc *)objectAtIndexedSubscript:(NSUInteger)idx 208 | { 209 | return (PSProc *)self.procsFiltered[idx]; 210 | } 211 | 212 | - (NSUInteger)indexForPid:(pid_t)pid 213 | { 214 | NSUInteger idx = [self.procsFiltered indexOfObjectPassingTest:^BOOL(id proc, NSUInteger idx, BOOL *stop) { 215 | return ((PSProc *)proc).pid == pid; 216 | }]; 217 | return idx; 218 | } 219 | 220 | - (PSProc *)procForPid:(pid_t)pid 221 | { 222 | NSUInteger idx = [self.procs indexOfObjectPassingTest:^BOOL(id proc, NSUInteger idx, BOOL *stop) { 223 | return ((PSProc *)proc).pid == pid; 224 | }]; 225 | return idx == NSNotFound ? nil : (PSProc *)self.procs[idx]; 226 | } 227 | 228 | - (void)filter:(NSString *)text column:(PSColumn *)col 229 | { 230 | if (text && text.length) { 231 | self.procsFiltered = [self.procs mutableCopy]; 232 | if (col.getFloatData != nil) { 233 | double minValue = [text doubleValue]; 234 | switch([text characterAtIndex:text.length-1]) { 235 | case 'k': case 'K': minValue *= 1024; break; 236 | case 'm': case 'M': minValue *= 1024*1024; break; 237 | case 'g': case 'G': minValue *= 1024*1024*1024; break; 238 | } 239 | [self.procsFiltered filterUsingPredicate:[NSPredicate predicateWithBlock: ^BOOL(PSProc *proc, NSDictionary *bind) { 240 | return col.getFloatData(proc) >= minValue; 241 | }]]; 242 | } else 243 | [self.procsFiltered filterUsingPredicate:[NSPredicate predicateWithBlock: ^BOOL(PSProc *proc, NSDictionary *bind) { 244 | return [col.getData(proc) rangeOfString:text options:NSCaseInsensitiveSearch].location != NSNotFound; 245 | }]]; 246 | } else 247 | self.procsFiltered = self.procs; 248 | } 249 | 250 | @end 251 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # TODO: 2 | 3 | * Add a how-to for searching in specific columns. 4 | * Put object counters (how many threads/handles/ports etc.) in the popup menu. 5 | * Color-coding (highlighting) values by their magnitude (like Windows Task manager). 6 | * Add nice graphs! 7 | * Smooth row transitions. This is hard. 8 | 9 | # Maybe also: 10 | * Color-coding different processes by their type: app, service, 32-bit, zombie/stuck... 11 | * Smooth transition during orientation change. 12 | * Tap file to view. Useful for logs. 13 | -------------------------------------------------------------------------------- /src/RootViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "GridCell.h" 3 | #import "PopupMenuView.h" 4 | 5 | @interface RootViewController : UITableViewControllerWithMenu 6 | @end 7 | -------------------------------------------------------------------------------- /src/Setup.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface SetupViewController : UITableViewController 4 | @end 5 | -------------------------------------------------------------------------------- /src/Setup.m: -------------------------------------------------------------------------------- 1 | #import "Compat.h" 2 | #import "Setup.h" 3 | 4 | @interface SelectFromList : UITableViewController 5 | @property (strong) NSArray *list; 6 | @property (strong) NSString *option; 7 | @property (strong) NSString *value; 8 | @end 9 | 10 | @implementation SelectFromList 11 | 12 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 13 | { 14 | return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown; 15 | } 16 | 17 | - (instancetype)initWithList:(NSArray *)list option:(NSString *)option 18 | { 19 | self = [super initWithStyle:UITableViewStyleGrouped]; 20 | self.list = list; 21 | self.option = option; 22 | self.value = [[NSUserDefaults standardUserDefaults] stringForKey:option]; 23 | return self; 24 | } 25 | 26 | + (instancetype)selectFromList:(NSArray *)list option:(NSString *)option 27 | { 28 | return [[SelectFromList alloc] initWithList:list option:option]; 29 | } 30 | 31 | - (void)viewWillAppear:(BOOL)animated 32 | { 33 | [super viewWillAppear:animated]; 34 | self.navigationItem.title = @"Settings"; 35 | } 36 | 37 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 38 | { 39 | return 1; 40 | } 41 | 42 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 43 | { 44 | return @"Choose"; 45 | } 46 | 47 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 48 | { 49 | return self.list.count; 50 | } 51 | 52 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 53 | { 54 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Setup"]; 55 | if (cell == nil) 56 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Setup"]; 57 | cell.textLabel.text = self.list[indexPath.row]; 58 | cell.accessoryType = [self.value isEqualToString:cell.textLabel.text] ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 59 | return cell; 60 | } 61 | 62 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 63 | { 64 | self.value = [tableView cellForRowAtIndexPath:indexPath].textLabel.text; 65 | [[NSUserDefaults standardUserDefaults] setObject:self.value forKey:self.option]; 66 | [self.navigationController popViewControllerAnimated:YES]; 67 | } 68 | 69 | @end 70 | 71 | @interface OptionItem : NSObject 72 | + (instancetype)withAccessory:(id)accessory key:(NSString *)optionKey label:(NSString *)label chooseFrom:(NSArray *)choose; 73 | @property (assign) id accessory; 74 | @property (strong) NSString *optionKey; 75 | @property (strong) NSString *label; 76 | @property (strong) NSArray *choose; 77 | @end 78 | 79 | @implementation OptionItem 80 | + (instancetype)withAccessory:(id)accessory key:(NSString *)optionKey label:(NSString *)label chooseFrom:(NSArray *)choose 81 | { 82 | OptionItem *item = [OptionItem new]; 83 | item.accessory = accessory; 84 | item.optionKey = optionKey; 85 | item.label = label; 86 | item.choose = choose; 87 | return item; 88 | } 89 | @end 90 | 91 | @implementation SetupViewController 92 | { 93 | NSArray *optionsList; 94 | } 95 | 96 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 97 | { 98 | return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown; 99 | } 100 | 101 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 102 | { 103 | if (buttonIndex == 1) { 104 | [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]]; 105 | [self.tableView reloadData]; 106 | } 107 | } 108 | 109 | - (IBAction)factoryReset 110 | { 111 | [[[UIAlertView alloc] initWithTitle:@"Reset" message:@"Reset settings to default values?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil] show]; 112 | } 113 | 114 | - (void)viewDidLoad 115 | { 116 | [super viewDidLoad]; 117 | self.navigationItem.title = @"Settings"; 118 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Reset" style:UIBarButtonItemStylePlain 119 | target:self action:@selector(factoryReset)]; 120 | optionsList = @[ 121 | [OptionItem withAccessory:[UILabel class] key:@"UpdateInterval" label:@"Update interval (seconds)" chooseFrom:@[@"0.5",@"1",@"2",@"3",@"5",@"10",@"Never"]], 122 | [OptionItem withAccessory:[UILabel class] key:@"FirstColumnStyle" label:@"First column style" chooseFrom:@[@"Bundle Identifier",@"Bundle Name",@"Bundle Display Name",@"Executable Name",@"Executable With Args"]], 123 | [OptionItem withAccessory:[UISwitch class] key:@"FullWidthCommandLine" label:@"Full width command line" chooseFrom:nil], 124 | [OptionItem withAccessory:[UISwitch class] key:@"ShortenPaths" label:@"Show short (symlinked) paths" chooseFrom:nil], 125 | [OptionItem withAccessory:[UISwitch class] key:@"AutoJumpNewProcess" label:@"Auto scroll to new/terminated processes" chooseFrom:nil], 126 | [OptionItem withAccessory:[UISwitch class] key:@"ShowHeader" label:@"Show column sort header" chooseFrom:nil], 127 | [OptionItem withAccessory:[UISwitch class] key:@"ShowFooter" label:@"Show column totals (footer)" chooseFrom:nil], 128 | [OptionItem withAccessory:[UISwitch class] key:@"ColorDiffs" label:@"Highlight changing values" chooseFrom:nil], 129 | ]; 130 | } 131 | 132 | - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 133 | { 134 | [self.tableView reloadData]; 135 | } 136 | 137 | - (void)viewWillAppear:(BOOL)animated 138 | { 139 | [super viewWillAppear:animated]; 140 | [self.tableView reloadData]; 141 | } 142 | 143 | #pragma mark - UITableViewDataSource, UITableViewDelegate 144 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 145 | { 146 | return 1; 147 | } 148 | 149 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 150 | { 151 | return @"General"; 152 | } 153 | 154 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 155 | { 156 | return optionsList.count; 157 | } 158 | 159 | - (void)flipSwitch:(id)sender 160 | { 161 | UISwitch *onOff = (UISwitch *)sender; 162 | OptionItem *option = optionsList[onOff.tag - 1]; 163 | [[NSUserDefaults standardUserDefaults] setBool:onOff.on forKey:option.optionKey]; 164 | } 165 | 166 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 167 | { 168 | NSString *rid = indexPath.section ? @"SetupHelp" : @"Setup"; 169 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:rid]; 170 | if (cell == nil) 171 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:rid]; 172 | OptionItem *option = optionsList[indexPath.row]; 173 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 174 | cell.textLabel.text = option.label; 175 | if (option.accessory == [UISwitch class]) { 176 | UISwitch *onOff = [[UISwitch alloc] initWithFrame:CGRectZero]; 177 | [onOff addTarget:self action:@selector(flipSwitch:) forControlEvents:UIControlEventValueChanged]; 178 | onOff.on = [[NSUserDefaults standardUserDefaults] boolForKey:option.optionKey]; 179 | // onOff.onTintColor = [UIColor redColor]; 180 | onOff.tag = indexPath.row + 1; 181 | cell.accessoryView = onOff; 182 | } else { 183 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 184 | cell.accessoryView = nil; 185 | if (option.accessory == [UILabel class]) { 186 | cell.selectionStyle = UITableViewCellSelectionStyleBlue; 187 | cell.contentView.autoresizesSubviews = YES; 188 | UILabel *label = (UILabel *)[cell viewWithTag:indexPath.row + 1]; 189 | if (!label) { 190 | label = [[UILabel alloc] initWithFrame:CGRectZero]; 191 | label.textAlignment = NSTextAlignmentRight; 192 | label.font = [UIFont systemFontOfSize:16.0]; 193 | label.textColor = [UIColor grayColor]; 194 | label.backgroundColor = [UIColor clearColor]; 195 | label.text = [[NSUserDefaults standardUserDefaults] stringForKey:option.optionKey]; 196 | label.tag = indexPath.row + 1; 197 | label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth; 198 | [cell.contentView addSubview:label]; 199 | } else 200 | label.text = [[NSUserDefaults standardUserDefaults] stringForKey:option.optionKey]; 201 | } 202 | } 203 | return cell; 204 | } 205 | 206 | - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 207 | { 208 | OptionItem *option = optionsList[indexPath.row]; 209 | if (option.accessory == [UILabel class]) { 210 | UIView *label = [cell viewWithTag:indexPath.row + 1]; 211 | [cell.textLabel sizeToFit]; 212 | CGFloat labelstart = cell.textLabel.frame.size.width + 20; 213 | CGSize size = cell.contentView.frame.size; 214 | label.frame = CGRectMake(labelstart, 0, size.width - labelstart, size.height); 215 | } 216 | } 217 | 218 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 219 | { 220 | OptionItem *option = optionsList[indexPath.row]; 221 | if (option.accessory == [UILabel class]) { 222 | SelectFromList* selectView = [SelectFromList selectFromList:option.choose option:option.optionKey]; 223 | [self.navigationController pushViewController:selectView animated:YES]; 224 | } 225 | } 226 | 227 | @end 228 | -------------------------------------------------------------------------------- /src/SetupColumns.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface SetupColsViewController : UITableViewController 4 | @end 5 | -------------------------------------------------------------------------------- /src/Sock.h: -------------------------------------------------------------------------------- 1 | #import "Compat.h" 2 | #import "Column.h" 3 | #import "Proc.h" 4 | 5 | #define KEV_ANY_VENDOR 0 6 | #define KEV_ANY_CLASS 0 7 | #define KEV_ANY_SUBCLASS 0 8 | 9 | // All kernel event classes and subclasses. Thanks, Google! 10 | #define KEV_VENDOR_APPLE 1 11 | #define KEV_NETWORK_CLASS 1 12 | #define KEV_INET_SUBCLASS 1 13 | #define KEV_DL_SUBCLASS 2 14 | #define KEV_NETPOLICY_SUBCLASS 3 15 | #define KEV_SOCKET_SUBCLASS 4 16 | #define KEV_ATALK_SUBCLASS 5 17 | #define KEV_INET6_SUBCLASS 6 18 | #define KEV_ND6_SUBCLASS 7 19 | #define KEV_NECP_SUBCLASS 8 20 | #define KEV_NETAGENT_SUBCLASS 9 21 | #define KEV_LOG_SUBCLASS 10 22 | #define KEV_IOKIT_CLASS 2 23 | #define KEV_SYSTEM_CLASS 3 24 | #define KEV_CTL_SUBCLASS 2 25 | #define KEV_MEMORYSTATUS_SUBCLASS 3 26 | #define KEV_APPLESHARE_CLASS 4 27 | #define KEV_FIREWALL_CLASS 5 28 | #define KEV_IPFW_SUBCLASS 1 29 | #define KEV_IP6FW_SUBCLASS 2 30 | #define KEV_IEEE80211_CLASS 6 31 | #define KEV_APPLE80211_EVENT_SUBCLASS 1 32 | 33 | #define PIPE_ASYNC 0x004 /* Async? I/O. */ 34 | #define PIPE_WANTR 0x008 /* Reader wants some characters. */ 35 | #define PIPE_WANTW 0x010 /* Writer wants space to put characters. */ 36 | #define PIPE_WANT 0x020 /* Pipe is wanted to be run-down. */ 37 | #define PIPE_SEL 0x040 /* Pipe has a select active. */ 38 | #define PIPE_EOF 0x080 /* Pipe is in EOF condition. */ 39 | #define PIPE_LOCKFL 0x100 /* Process has exclusive access to pointers/data. */ 40 | #define PIPE_LWANT 0x200 /* Process wants exclusive access to pointers/data. */ 41 | #define PIPE_DIRECTW 0x400 /* Pipe direct write active. */ 42 | #define PIPE_DIRECTOK 0x800 /* Direct mode ok. */ 43 | #define PIPE_KNOTE 0x1000 /* Pipe has kernel events activated */ 44 | #define PIPE_DRAIN 0x2000 /* Waiting for I/O to drop for a close. Treated like EOF; only separate for easier debugging. */ 45 | #define PIPE_WSELECT 0x4000 /* Some thread has done an FWRITE select on the pipe */ 46 | #define PIPE_DEAD 0x8000 /* Pipe is dead and needs garbage collection */ 47 | 48 | @class PSSockArray; 49 | 50 | @interface PSSock : NSObject 51 | @property (assign) display_t display; 52 | @property (strong) NSString *name; 53 | @property (strong) UIColor *color; 54 | @property (assign) uint64_t node; 55 | + (int)refreshArray:(PSSockArray *)socks; 56 | - (NSString *)description; 57 | @end 58 | 59 | @interface PSSockSummary : PSSock 60 | @property (strong) PSProc *proc; 61 | @property (strong) PSColumn *col; 62 | @end 63 | 64 | @interface PSSockThreads : PSSock 65 | { @public struct thread_basic_info tbi; } 66 | @property (assign) uint64_t tid; 67 | @property (assign) uint64_t ptime; // 0.01's of a second 68 | @property (assign) unsigned int prio; 69 | @end 70 | 71 | @interface PSSockFiles : PSSock 72 | @property (assign) int32_t fd; 73 | @property (assign) uint32_t type; 74 | @property (assign) uint32_t flags; 75 | @property (assign) char *stype; 76 | @end 77 | 78 | @interface PSSockPorts : PSSock 79 | @property (strong) NSMutableString *connect; 80 | @property (assign) mach_port_name_t port; 81 | @property (assign) mach_port_type_t type; 82 | @property (assign) natural_t object; 83 | @end 84 | 85 | @interface PSSockModules : PSSock 86 | @property (strong) NSString *bundle; 87 | @property (assign) mach_vm_address_t addr; 88 | @property (assign) size_t size; 89 | @property (assign) uint32_t ref; 90 | @property (assign) uint32_t dev; 91 | @property (assign) uint32_t ino; 92 | @end 93 | 94 | @interface PSSockArray : NSObject 95 | @property (strong) PSProc *proc; 96 | @property (strong) NSMutableArray *socks; 97 | @property (strong) NSMutableDictionary *objects; // Kernel objects for communication between processes (ports, pipes, sockets) 98 | + (instancetype)psSockArrayWithProc:(PSProc *)proc; 99 | - (int)refreshWithMode:(column_mode_t)mode; 100 | - (void)sortUsingComparator:(NSComparator)comp desc:(BOOL)desc; 101 | - (void)setAllDisplayed:(display_t)display; 102 | - (NSUInteger)indexOfDisplayed:(display_t)display; 103 | - (NSUInteger)count; 104 | - (PSSock *)objectAtIndexedSubscript:(NSUInteger)idx; 105 | - (PSSock *)objectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate; 106 | @end 107 | -------------------------------------------------------------------------------- /src/SockViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "GridCell.h" 3 | #import "PopupMenuView.h" 4 | 5 | @interface SockViewController : UITableViewControllerWithMenu 6 | - (instancetype)initWithProc:(PSProc *)proc; 7 | @end 8 | -------------------------------------------------------------------------------- /src/THtmlViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface HtmlViewController : UIViewController 4 | @property(strong) NSURL *url; 5 | @property(strong) NSString *pageTitle; 6 | @property(strong) UIActivityIndicatorView *indicator; 7 | - (id)initWithURL:(NSString *)url title:(NSString *)title; 8 | @end 9 | -------------------------------------------------------------------------------- /src/THtmlViewController.m: -------------------------------------------------------------------------------- 1 | #import "THtmlViewController.h" 2 | #import "BackButtonHandler.h" 3 | 4 | @implementation HtmlViewController 5 | 6 | - (void)viewDidLoad 7 | { 8 | [super viewDidLoad]; 9 | self.navigationItem.title = self.pageTitle; 10 | self.indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 11 | self.indicator.color = [UIColor blackColor]; 12 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.indicator]; 13 | 14 | UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero]; 15 | webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 16 | webView.dataDetectorTypes = UIDataDetectorTypeNone; 17 | webView.scalesPageToFit = YES; 18 | webView.delegate = self; 19 | 20 | [webView loadRequest:[[NSURLRequest alloc] initWithURL:self.url]]; 21 | self.view = webView; 22 | } 23 | 24 | - (BOOL)navigationShouldPopOnBackButton 25 | { 26 | UIWebView *webView = (UIWebView *)self.view; 27 | if (webView.canGoBack) { 28 | [webView goBack]; 29 | return NO; 30 | } 31 | return YES; 32 | } 33 | 34 | - (void)webViewDidStartLoad:(UIWebView *)webView 35 | { 36 | [self.indicator startAnimating]; 37 | } 38 | 39 | - (void)webViewDidFinishLoad:(UIWebView *)webView 40 | { 41 | [self.indicator stopAnimating]; 42 | } 43 | 44 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 45 | { 46 | return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown; 47 | } 48 | 49 | - (id)initWithURL:(NSString *)url title:(NSString *)title; 50 | { 51 | self = [super init]; 52 | if (self != nil) { 53 | self.url = [[NSBundle mainBundle] URLForResource:url withExtension:@"html"]; 54 | self.pageTitle = title; 55 | } 56 | return self; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /src/TextViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface TextViewController : UIViewController 4 | @property(strong) NSString *textString; 5 | @property(strong) NSString *titleString; 6 | @property(strong) UITapGestureRecognizer *tapBehind; 7 | + (void)showText:(NSString *)text withTitle:(NSString *)title inViewController:(UIViewController *)parent; 8 | @end 9 | -------------------------------------------------------------------------------- /src/TextViewController.m: -------------------------------------------------------------------------------- 1 | #import "Compat.h" 2 | #import "TextViewController.h" 3 | 4 | @implementation TextViewController 5 | 6 | - (void)loadView 7 | { 8 | [super loadView]; 9 | // Text and title 10 | self.title = self.titleString; 11 | UITextView* textView = [[UITextView alloc] initWithFrame:CGRectZero]; 12 | textView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 13 | textView.editable = NO; 14 | textView.font = [UIFont systemFontOfSize:16.0]; 15 | textView.text = self.textString; 16 | self.view = textView; 17 | // Done button 18 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone 19 | target:self action:@selector(dismissViewController)]; 20 | } 21 | 22 | - (void)dismissViewController 23 | { 24 | [self dismissViewControllerAnimated:NO completion:nil]; 25 | } 26 | 27 | - (void)handleTapBehind:(UITapGestureRecognizer *)sender 28 | { 29 | if (sender.state == UIGestureRecognizerStateEnded) 30 | if (![self.view pointInside:[sender locationInView:self.view] withEvent:nil]) 31 | [self dismissViewControllerAnimated:NO completion:nil]; 32 | } 33 | 34 | - (void)viewDidAppear:(BOOL)animated 35 | { 36 | [super viewDidAppear:animated]; 37 | self.tapBehind = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapBehind:)]; 38 | [self.tapBehind setNumberOfTapsRequired:1]; 39 | self.tapBehind.cancelsTouchesInView = NO; 40 | self.tapBehind.delegate = self; 41 | [self.view.window addGestureRecognizer:self.tapBehind]; 42 | } 43 | 44 | - (void)viewWillDisappear:(BOOL)animated 45 | { 46 | [super viewWillDisappear:animated]; 47 | [self.view.window removeGestureRecognizer:self.tapBehind]; 48 | self.tapBehind = nil; 49 | } 50 | 51 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 52 | { return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown; } 53 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 54 | { return YES; } 55 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 56 | { return YES; } 57 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 58 | { return YES; } 59 | 60 | + (void)showText:(NSString *)text withTitle:(NSString *)title inViewController:(UIViewController *)parent 61 | { 62 | TextViewController *controller = [TextViewController new]; 63 | controller.textString = text; 64 | controller.titleString = title; 65 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller]; 66 | navController.modalPresentationStyle = UIModalPresentationFormSheet; 67 | // navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 68 | [parent presentViewController:navController animated:NO completion:nil]; 69 | if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone) { 70 | //#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0 71 | if (@available(iOS 7, *)) { 72 | navController.view.superview.layer.cornerRadius = 10.0; 73 | navController.view.superview.layer.borderColor = [UIColor clearColor].CGColor; 74 | } 75 | //#endif 76 | // navController.view.superview.layer.borderWidth = 2; 77 | navController.view.superview.clipsToBounds = YES; 78 | } 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /src/kern/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | 29 | #ifndef _KERN_DEBUG_H_ 30 | #define _KERN_DEBUG_H_ 31 | 32 | #include 33 | #include 34 | 35 | struct thread_snapshot { 36 | uint32_t snapshot_magic; 37 | uint32_t nkern_frames; 38 | uint32_t nuser_frames; 39 | uint64_t wait_event; 40 | uint64_t continuation; 41 | uint64_t thread_id; 42 | uint64_t user_time; 43 | uint64_t system_time; 44 | int32_t state; 45 | int32_t sched_pri; // scheduled (current) priority * 46 | int32_t sched_flags; // scheduler flags * 47 | char ss_flags; 48 | } __attribute__((packed)); 49 | 50 | struct task_snapshot { 51 | uint32_t snapshot_magic; 52 | int32_t pid; 53 | uint32_t nloadinfos; 54 | uint64_t user_time_in_terminated_threads; 55 | uint64_t system_time_in_terminated_threads; 56 | int suspend_count; 57 | int task_size; // pages 58 | int faults; // number of page faults 59 | int pageins; // number of actual pageins 60 | int cow_faults; // number of copy-on-write faults 61 | char spare[227]; 62 | char ss_flags; 63 | char p_comm[17]; 64 | } __attribute__((packed)); 65 | 66 | struct mem_snapshot { 67 | uint32_t snapshot_magic; 68 | uint32_t free_pages; 69 | uint32_t active_pages; 70 | uint32_t inactive_pages; 71 | uint32_t purgeable_pages; 72 | uint32_t wired_pages; 73 | uint32_t speculative_pages; 74 | uint32_t throttled_pages; 75 | } __attribute__((packed)); 76 | 77 | struct mem_and_io_snapshot { 78 | uint32_t snapshot_magic; 79 | uint32_t free_pages; 80 | uint32_t active_pages; 81 | uint32_t inactive_pages; 82 | uint32_t purgeable_pages; 83 | uint32_t wired_pages; 84 | uint32_t speculative_pages; 85 | uint32_t throttled_pages; 86 | int busy_buffer_count; 87 | uint32_t pages_wanted; 88 | uint32_t pages_reclaimed; 89 | uint8_t pages_wanted_reclaimed_valid; // did mach_vm_pressure_monitor succeed? 90 | } __attribute__((packed)); 91 | 92 | 93 | enum { 94 | kUser64_p = 0x1, 95 | kKernel64_p = 0x2, 96 | kHasDispatchSerial = 0x4, 97 | kTerminatedSnapshot = 0x8, 98 | kPidSuspended = 0x10, // true for suspended task 99 | kFrozen = 0x20 // true for hibernated task (along with pidsuspended) 100 | }; 101 | 102 | #define VM_PRESSURE_TIME_WINDOW 5 /* seconds */ 103 | 104 | enum { 105 | STACKSHOT_GET_DQ = 0x1, 106 | STACKSHOT_SAVE_LOADINFO = 0x2, 107 | STACKSHOT_GET_GLOBAL_MEM_STATS = 0x4 108 | }; 109 | 110 | #define STACKSHOT_THREAD_SNAPSHOT_MAGIC 0xfeedface 111 | #define STACKSHOT_TASK_SNAPSHOT_MAGIC 0xdecafbad 112 | #define STACKSHOT_MEM_SNAPSHOT_MAGIC 0xabcddcba 113 | #define STACKSHOT_MEM_AND_IO_SNAPSHOT_MAGIC 0xbfcabcde 114 | 115 | #endif /* _KERN_DEBUG_H_ */ 116 | -------------------------------------------------------------------------------- /src/layout/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: ru.domo.cocoatop64 2 | Name: CocoaTop 3 | Depends: 4 | Conflicts: ru.domo.cocoatop 5 | Version: 2.2.3 6 | Architecture: iphoneos-arm 7 | Description: Process Viewer for iOS GUI, updated for iOS 13 by SXX. 8 | Maintainer: SXX, Domo 9 | Author: Domo, SXX 10 | Section: Utilities 11 | -------------------------------------------------------------------------------- /src/layout/DEBIAN/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | chown root.wheel /Applications/CocoaTop.app/CocoaTop 3 | chmod +s /Applications/CocoaTop.app/CocoaTop 4 | -------------------------------------------------------------------------------- /src/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #include 3 | #import "AppDelegate.h" 4 | 5 | @interface CRJailbreakUtility : NSObject 6 | 7 | +(NSDictionary *_Nullable)tfp0:(NSError *_Nullable __autoreleasing* _Nullable)error; 8 | 9 | +(bool)sandboxEscape:(NSDictionary * _Nonnull)task_info; 10 | 11 | +(bool)setUid0:(NSDictionary * _Nonnull)task_info; 12 | 13 | @end 14 | 15 | int sandbox_container_path_for_pid(pid_t, char * _Nonnull buffer, size_t bufsize); 16 | 17 | static bool 18 | HelperIsRunningInSandbox(void) { 19 | char *buffer = malloc(MAXPATHLEN); 20 | bool buffer_should_free = true; 21 | if (buffer == NULL) { 22 | static char _b[MAXPATHLEN]; 23 | buffer = _b; 24 | buffer_should_free = false; 25 | } 26 | int isSandbox = sandbox_container_path_for_pid(getpid(), buffer, MAXPATHLEN); 27 | if (buffer_should_free) { 28 | free(buffer); 29 | } 30 | return isSandbox == 0; 31 | } 32 | struct _os_alloc_once_s { 33 | long once; 34 | void **ptr; 35 | }; 36 | 37 | int main(int argc, char *argv[]) { 38 | @autoreleasepool { 39 | if (HelperIsRunningInSandbox()) { 40 | NSBundle *utility = [[NSBundle alloc] initWithPath:@"/Library/Frameworks/CRJailbreakUtilities.framework"]; 41 | if (utility == nil || ![utility load]) { 42 | goto normal; 43 | } 44 | Class _CRJailbreakUtility = [utility principalClass]; 45 | NSError *error = nil; 46 | NSDictionary *dict = [_CRJailbreakUtility tfp0:&error]; 47 | if (error == nil) { 48 | [_CRJailbreakUtility sandboxEscape:dict]; 49 | //[_CRJailbreakUtility setUid0:dict]; 50 | } 51 | } 52 | normal: 53 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([TopAppDelegate class])); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/net/ntstat_16xx_ios5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2011 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | #ifndef __NTSTAT_H__ 29 | #define __NTSTAT_H__ 30 | #include 31 | 32 | #ifdef PRIVATE 33 | #pragma pack(push, 4) 34 | #pragma mark -- Common Data Structures -- 35 | 36 | #define __NSTAT_REVISION__ 1 37 | 38 | typedef u_int32_t nstat_provider_id_t; 39 | typedef u_int32_t nstat_src_ref_t; 40 | 41 | typedef struct nstat_counts 42 | { 43 | /* Counters */ 44 | u_int64_t nstat_rxpackets __attribute__((aligned(8))); 45 | u_int64_t nstat_rxbytes __attribute__((aligned(8))); 46 | u_int64_t nstat_txpackets __attribute__((aligned(8))); 47 | u_int64_t nstat_txbytes __attribute__((aligned(8))); 48 | 49 | u_int32_t nstat_rxduplicatebytes; 50 | u_int32_t nstat_rxoutoforderbytes; 51 | u_int32_t nstat_txretransmit; 52 | 53 | u_int32_t nstat_connectattempts; 54 | u_int32_t nstat_connectsuccesses; 55 | 56 | u_int32_t nstat_min_rtt; 57 | u_int32_t nstat_avg_rtt; 58 | u_int32_t nstat_var_rtt; 59 | } nstat_counts; 60 | 61 | #pragma mark -- Network Statistics Providers -- 62 | 63 | enum 64 | { 65 | NSTAT_PROVIDER_ROUTE = 1 66 | ,NSTAT_PROVIDER_TCP = 2 67 | ,NSTAT_PROVIDER_UDP = 3 68 | }; 69 | 70 | typedef struct nstat_route_add_param 71 | { 72 | union 73 | { 74 | struct sockaddr_in v4; 75 | struct sockaddr_in6 v6; 76 | } dst; 77 | union 78 | { 79 | struct sockaddr_in v4; 80 | struct sockaddr_in6 v6; 81 | } mask; 82 | u_int32_t ifindex; 83 | } nstat_route_add_param; 84 | 85 | typedef struct nstat_tcp_add_param 86 | { 87 | union 88 | { 89 | struct sockaddr_in v4; 90 | struct sockaddr_in6 v6; 91 | } local; 92 | union 93 | { 94 | struct sockaddr_in v4; 95 | struct sockaddr_in6 v6; 96 | } remote; 97 | } nstat_tcp_add_param; 98 | 99 | typedef struct nstat_tcp_descriptor 100 | { 101 | union 102 | { 103 | struct sockaddr_in v4; 104 | struct sockaddr_in6 v6; 105 | } local; 106 | 107 | union 108 | { 109 | struct sockaddr_in v4; 110 | struct sockaddr_in6 v6; 111 | } remote; 112 | 113 | u_int32_t ifindex; 114 | 115 | u_int32_t state; 116 | 117 | u_int32_t sndbufsize; 118 | u_int32_t sndbufused; 119 | u_int32_t rcvbufsize; 120 | u_int32_t rcvbufused; 121 | u_int32_t txunacked; 122 | u_int32_t txwindow; 123 | u_int32_t txcwindow; 124 | 125 | u_int64_t upid; 126 | u_int32_t pid; 127 | char pname[64]; 128 | } nstat_tcp_descriptor; 129 | 130 | typedef struct nstat_tcp_add_param nstat_udp_add_param; 131 | 132 | typedef struct nstat_udp_descriptor 133 | { 134 | union 135 | { 136 | struct sockaddr_in v4; 137 | struct sockaddr_in6 v6; 138 | } local; 139 | 140 | union 141 | { 142 | struct sockaddr_in v4; 143 | struct sockaddr_in6 v6; 144 | } remote; 145 | 146 | u_int32_t ifindex; 147 | 148 | u_int32_t rcvbufsize; 149 | u_int32_t rcvbufused; 150 | 151 | u_int64_t upid; 152 | u_int32_t pid; 153 | char pname[64]; 154 | } nstat_udp_descriptor; 155 | 156 | typedef struct nstat_route_descriptor 157 | { 158 | u_int64_t id; 159 | u_int64_t parent_id; 160 | u_int64_t gateway_id; 161 | 162 | union 163 | { 164 | struct sockaddr_in v4; 165 | struct sockaddr_in6 v6; 166 | struct sockaddr sa; 167 | } dst; 168 | 169 | union 170 | { 171 | struct sockaddr_in v4; 172 | struct sockaddr_in6 v6; 173 | struct sockaddr sa; 174 | } mask; 175 | 176 | union 177 | { 178 | struct sockaddr_in v4; 179 | struct sockaddr_in6 v6; 180 | struct sockaddr sa; 181 | } gateway; 182 | 183 | u_int32_t ifindex; 184 | u_int32_t flags; 185 | 186 | } nstat_route_descriptor; 187 | 188 | #pragma mark -- Network Statistics User Client -- 189 | 190 | #define NET_STAT_CONTROL_NAME "com.apple.network.statistics" 191 | 192 | enum 193 | { 194 | // generice respnse messages 195 | NSTAT_MSG_TYPE_SUCCESS = 0 196 | ,NSTAT_MSG_TYPE_ERROR = 1 197 | 198 | // Requests 199 | ,NSTAT_MSG_TYPE_ADD_SRC = 1001 200 | ,NSTAT_MSG_TYPE_ADD_ALL_SRCS = 1002 201 | ,NSTAT_MSG_TYPE_REM_SRC = 1003 202 | ,NSTAT_MSG_TYPE_QUERY_SRC = 1004 203 | ,NSTAT_MSG_TYPE_GET_SRC_DESC = 1005 204 | 205 | // Responses/Notfications 206 | ,NSTAT_MSG_TYPE_SRC_ADDED = 10001 207 | ,NSTAT_MSG_TYPE_SRC_REMOVED = 10002 208 | ,NSTAT_MSG_TYPE_SRC_DESC = 10003 209 | ,NSTAT_MSG_TYPE_SRC_COUNTS = 10004 210 | }; 211 | 212 | enum 213 | { 214 | NSTAT_SRC_REF_ALL = 0xffffffff 215 | ,NSTAT_SRC_REF_INVALID = 0 216 | }; 217 | 218 | typedef struct nstat_msg_hdr 219 | { 220 | u_int64_t context; 221 | u_int32_t type; 222 | u_int32_t pad; // unused for now 223 | } nstat_msg_hdr; 224 | 225 | typedef struct nstat_msg_error 226 | { 227 | nstat_msg_hdr hdr; 228 | u_int32_t error; // errno error 229 | } nstat_msg_error; 230 | 231 | typedef struct nstat_msg_add_src 232 | { 233 | nstat_msg_hdr hdr; 234 | nstat_provider_id_t provider; 235 | u_int8_t param[]; 236 | } nstat_msg_add_src_req; 237 | 238 | typedef struct nstat_msg_add_all_srcs 239 | { 240 | nstat_msg_hdr hdr; 241 | nstat_provider_id_t provider; 242 | } nstat_msg_add_all_srcs; 243 | 244 | typedef struct nstat_msg_src_added 245 | { 246 | nstat_msg_hdr hdr; 247 | nstat_provider_id_t provider; 248 | nstat_src_ref_t srcref; 249 | } nstat_msg_src_added; 250 | 251 | typedef struct nstat_msg_rem_src 252 | { 253 | nstat_msg_hdr hdr; 254 | nstat_src_ref_t srcref; 255 | } nstat_msg_rem_src_req; 256 | 257 | typedef struct nstat_msg_get_src_description 258 | { 259 | nstat_msg_hdr hdr; 260 | nstat_src_ref_t srcref; 261 | } nstat_msg_get_src_description; 262 | 263 | typedef struct nstat_msg_src_description 264 | { 265 | nstat_msg_hdr hdr; 266 | nstat_src_ref_t srcref; 267 | nstat_provider_id_t provider; 268 | u_int8_t data[]; 269 | } nstat_msg_src_description; 270 | 271 | typedef struct nstat_msg_query_src 272 | { 273 | nstat_msg_hdr hdr; 274 | nstat_src_ref_t srcref; 275 | } nstat_msg_query_src_req; 276 | 277 | typedef struct nstat_msg_src_counts 278 | { 279 | nstat_msg_hdr hdr; 280 | nstat_src_ref_t srcref; 281 | nstat_counts counts; 282 | } nstat_msg_src_counts; 283 | 284 | typedef struct nstat_msg_src_removed 285 | { 286 | nstat_msg_hdr hdr; 287 | nstat_src_ref_t srcref; 288 | } nstat_msg_src_removed; 289 | 290 | #pragma pack(pop) 291 | 292 | #endif /* PRIVATE */ 293 | 294 | #ifdef XNU_KERNEL_PRIVATE 295 | #include 296 | 297 | #pragma mark -- Generic Network Statistics Provider -- 298 | 299 | typedef void * nstat_provider_cookie_t; 300 | 301 | #pragma mark -- Route Statistics Gathering Functions -- 302 | struct rtentry; 303 | 304 | enum 305 | { 306 | NSTAT_TX_FLAG_RETRANSMIT = 1 307 | }; 308 | 309 | enum 310 | { 311 | NSTAT_RX_FLAG_DUPLICATE = 1, 312 | NSTAT_RX_FLAG_OUT_OF_ORDER = 2 313 | }; 314 | 315 | // indicates whether or not collection of statistics is enabled 316 | extern int nstat_collect; 317 | 318 | // Route collection routines 319 | void nstat_route_connect_attempt(struct rtentry *rte); 320 | void nstat_route_connect_success(struct rtentry *rte); 321 | void nstat_route_tx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 322 | void nstat_route_rx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 323 | void nstat_route_rtt(struct rtentry *rte, u_int32_t rtt, u_int32_t rtt_var); 324 | void nstat_route_detach(struct rtentry *rte); 325 | 326 | // watcher support 327 | struct inpcb; 328 | void nstat_tcp_new_pcb(struct inpcb *inp); 329 | void nstat_udp_new_pcb(struct inpcb *inp); 330 | void nstat_route_new_entry(struct rtentry *rt); 331 | 332 | // locked_add_64 uses atomic operations on 32bit so the 64bit 333 | // value can be properly read. The values are only ever incremented 334 | // while under the socket lock, so on 64bit we don't actually need 335 | // atomic operations to increment. 336 | #if defined(__LP64__) 337 | #define locked_add_64(__addr, __count) do { \ 338 | *(__addr) += (__count); \ 339 | } while (0) 340 | #else 341 | #define locked_add_64(__addr, __count) do { \ 342 | atomic_add_64((__addr), (__count)); \ 343 | } while (0) 344 | #endif 345 | 346 | #endif /* XNU_KERNEL_PRIVATE */ 347 | 348 | #endif /* __NTSTAT_H__ */ 349 | -------------------------------------------------------------------------------- /src/net/ntstat_20xx_ios6.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2011 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | #ifndef __NTSTAT_H__ 29 | #define __NTSTAT_H__ 30 | #include 31 | 32 | #ifdef PRIVATE 33 | #pragma pack(push, 4) 34 | #pragma mark -- Common Data Structures -- 35 | 36 | #define __NSTAT_REVISION__ 1 37 | 38 | typedef u_int32_t nstat_provider_id_t; 39 | typedef u_int32_t nstat_src_ref_t; 40 | 41 | typedef struct nstat_counts 42 | { 43 | /* Counters */ 44 | u_int64_t nstat_rxpackets __attribute__((aligned(8))); 45 | u_int64_t nstat_rxbytes __attribute__((aligned(8))); 46 | u_int64_t nstat_txpackets __attribute__((aligned(8))); 47 | u_int64_t nstat_txbytes __attribute__((aligned(8))); 48 | 49 | u_int32_t nstat_rxduplicatebytes; 50 | u_int32_t nstat_rxoutoforderbytes; 51 | u_int32_t nstat_txretransmit; 52 | 53 | u_int32_t nstat_connectattempts; 54 | u_int32_t nstat_connectsuccesses; 55 | 56 | u_int32_t nstat_min_rtt; 57 | u_int32_t nstat_avg_rtt; 58 | u_int32_t nstat_var_rtt; 59 | } nstat_counts; 60 | 61 | #pragma mark -- Network Statistics Providers -- 62 | 63 | enum 64 | { 65 | NSTAT_PROVIDER_ROUTE = 1 66 | ,NSTAT_PROVIDER_TCP = 2 67 | ,NSTAT_PROVIDER_UDP = 3 68 | }; 69 | 70 | typedef struct nstat_route_add_param 71 | { 72 | union 73 | { 74 | struct sockaddr_in v4; 75 | struct sockaddr_in6 v6; 76 | } dst; 77 | union 78 | { 79 | struct sockaddr_in v4; 80 | struct sockaddr_in6 v6; 81 | } mask; 82 | u_int32_t ifindex; 83 | } nstat_route_add_param; 84 | 85 | typedef struct nstat_tcp_add_param 86 | { 87 | union 88 | { 89 | struct sockaddr_in v4; 90 | struct sockaddr_in6 v6; 91 | } local; 92 | union 93 | { 94 | struct sockaddr_in v4; 95 | struct sockaddr_in6 v6; 96 | } remote; 97 | } nstat_tcp_add_param; 98 | 99 | typedef struct nstat_tcp_descriptor 100 | { 101 | union 102 | { 103 | struct sockaddr_in v4; 104 | struct sockaddr_in6 v6; 105 | } local; 106 | 107 | union 108 | { 109 | struct sockaddr_in v4; 110 | struct sockaddr_in6 v6; 111 | } remote; 112 | 113 | u_int32_t ifindex; 114 | 115 | u_int32_t state; 116 | 117 | u_int32_t sndbufsize; 118 | u_int32_t sndbufused; 119 | u_int32_t rcvbufsize; 120 | u_int32_t rcvbufused; 121 | u_int32_t txunacked; 122 | u_int32_t txwindow; 123 | u_int32_t txcwindow; 124 | u_int32_t traffic_class; 125 | 126 | u_int64_t upid; 127 | u_int32_t pid; 128 | char pname[64]; 129 | } nstat_tcp_descriptor; 130 | 131 | typedef struct nstat_tcp_add_param nstat_udp_add_param; 132 | 133 | typedef struct nstat_udp_descriptor 134 | { 135 | union 136 | { 137 | struct sockaddr_in v4; 138 | struct sockaddr_in6 v6; 139 | } local; 140 | 141 | union 142 | { 143 | struct sockaddr_in v4; 144 | struct sockaddr_in6 v6; 145 | } remote; 146 | 147 | u_int32_t ifindex; 148 | 149 | u_int32_t rcvbufsize; 150 | u_int32_t rcvbufused; 151 | u_int32_t traffic_class; 152 | 153 | u_int64_t upid; 154 | u_int32_t pid; 155 | char pname[64]; 156 | } nstat_udp_descriptor; 157 | 158 | typedef struct nstat_route_descriptor 159 | { 160 | u_int64_t id; 161 | u_int64_t parent_id; 162 | u_int64_t gateway_id; 163 | 164 | union 165 | { 166 | struct sockaddr_in v4; 167 | struct sockaddr_in6 v6; 168 | struct sockaddr sa; 169 | } dst; 170 | 171 | union 172 | { 173 | struct sockaddr_in v4; 174 | struct sockaddr_in6 v6; 175 | struct sockaddr sa; 176 | } mask; 177 | 178 | union 179 | { 180 | struct sockaddr_in v4; 181 | struct sockaddr_in6 v6; 182 | struct sockaddr sa; 183 | } gateway; 184 | 185 | u_int32_t ifindex; 186 | u_int32_t flags; 187 | 188 | } nstat_route_descriptor; 189 | 190 | #pragma mark -- Network Statistics User Client -- 191 | 192 | #define NET_STAT_CONTROL_NAME "com.apple.network.statistics" 193 | 194 | enum 195 | { 196 | // generic response messages 197 | NSTAT_MSG_TYPE_SUCCESS = 0 198 | ,NSTAT_MSG_TYPE_ERROR = 1 199 | 200 | // Requests 201 | ,NSTAT_MSG_TYPE_ADD_SRC = 1001 202 | ,NSTAT_MSG_TYPE_ADD_ALL_SRCS = 1002 203 | ,NSTAT_MSG_TYPE_REM_SRC = 1003 204 | ,NSTAT_MSG_TYPE_QUERY_SRC = 1004 205 | ,NSTAT_MSG_TYPE_GET_SRC_DESC = 1005 206 | 207 | // Responses/Notfications 208 | ,NSTAT_MSG_TYPE_SRC_ADDED = 10001 209 | ,NSTAT_MSG_TYPE_SRC_REMOVED = 10002 210 | ,NSTAT_MSG_TYPE_SRC_DESC = 10003 211 | ,NSTAT_MSG_TYPE_SRC_COUNTS = 10004 212 | }; 213 | 214 | enum 215 | { 216 | NSTAT_SRC_REF_ALL = 0xffffffff 217 | ,NSTAT_SRC_REF_INVALID = 0 218 | }; 219 | 220 | typedef struct nstat_msg_hdr 221 | { 222 | u_int64_t context; 223 | u_int32_t type; 224 | u_int32_t pad; // unused for now 225 | } nstat_msg_hdr; 226 | 227 | typedef struct nstat_msg_error 228 | { 229 | nstat_msg_hdr hdr; 230 | u_int32_t error; // errno error 231 | } nstat_msg_error; 232 | 233 | typedef struct nstat_msg_add_src 234 | { 235 | nstat_msg_hdr hdr; 236 | nstat_provider_id_t provider; 237 | u_int8_t param[]; 238 | } nstat_msg_add_src_req; 239 | 240 | typedef struct nstat_msg_add_all_srcs 241 | { 242 | nstat_msg_hdr hdr; 243 | nstat_provider_id_t provider; 244 | } nstat_msg_add_all_srcs; 245 | 246 | typedef struct nstat_msg_src_added 247 | { 248 | nstat_msg_hdr hdr; 249 | nstat_provider_id_t provider; 250 | nstat_src_ref_t srcref; 251 | } nstat_msg_src_added; 252 | 253 | typedef struct nstat_msg_rem_src 254 | { 255 | nstat_msg_hdr hdr; 256 | nstat_src_ref_t srcref; 257 | } nstat_msg_rem_src_req; 258 | 259 | typedef struct nstat_msg_get_src_description 260 | { 261 | nstat_msg_hdr hdr; 262 | nstat_src_ref_t srcref; 263 | } nstat_msg_get_src_description; 264 | 265 | typedef struct nstat_msg_src_description 266 | { 267 | nstat_msg_hdr hdr; 268 | nstat_src_ref_t srcref; 269 | nstat_provider_id_t provider; 270 | u_int8_t data[]; 271 | } nstat_msg_src_description; 272 | 273 | typedef struct nstat_msg_query_src 274 | { 275 | nstat_msg_hdr hdr; 276 | nstat_src_ref_t srcref; 277 | } nstat_msg_query_src_req; 278 | 279 | typedef struct nstat_msg_src_counts 280 | { 281 | nstat_msg_hdr hdr; 282 | nstat_src_ref_t srcref; 283 | nstat_counts counts; 284 | } nstat_msg_src_counts; 285 | 286 | typedef struct nstat_msg_src_removed 287 | { 288 | nstat_msg_hdr hdr; 289 | nstat_src_ref_t srcref; 290 | } nstat_msg_src_removed; 291 | 292 | #pragma pack(pop) 293 | 294 | #endif /* PRIVATE */ 295 | 296 | #ifdef XNU_KERNEL_PRIVATE 297 | #include 298 | 299 | #pragma mark -- Generic Network Statistics Provider -- 300 | 301 | typedef void * nstat_provider_cookie_t; 302 | 303 | #pragma mark -- Route Statistics Gathering Functions -- 304 | struct rtentry; 305 | 306 | enum 307 | { 308 | NSTAT_TX_FLAG_RETRANSMIT = 1 309 | }; 310 | 311 | enum 312 | { 313 | NSTAT_RX_FLAG_DUPLICATE = 1, 314 | NSTAT_RX_FLAG_OUT_OF_ORDER = 2 315 | }; 316 | 317 | // indicates whether or not collection of statistics is enabled 318 | extern int nstat_collect; 319 | 320 | void nstat_init(void); 321 | 322 | // Route collection routines 323 | void nstat_route_connect_attempt(struct rtentry *rte); 324 | void nstat_route_connect_success(struct rtentry *rte); 325 | void nstat_route_tx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 326 | void nstat_route_rx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 327 | void nstat_route_rtt(struct rtentry *rte, u_int32_t rtt, u_int32_t rtt_var); 328 | void nstat_route_detach(struct rtentry *rte); 329 | 330 | // watcher support 331 | struct inpcb; 332 | void nstat_tcp_new_pcb(struct inpcb *inp); 333 | void nstat_udp_new_pcb(struct inpcb *inp); 334 | void nstat_route_new_entry(struct rtentry *rt); 335 | void nstat_pcb_detach(struct inpcb *inp); 336 | 337 | // locked_add_64 uses atomic operations on 32bit so the 64bit 338 | // value can be properly read. The values are only ever incremented 339 | // while under the socket lock, so on 64bit we don't actually need 340 | // atomic operations to increment. 341 | #if defined(__LP64__) 342 | #define locked_add_64(__addr, __count) do { \ 343 | *(__addr) += (__count); \ 344 | } while (0) 345 | #else 346 | #define locked_add_64(__addr, __count) do { \ 347 | atomic_add_64((__addr), (__count)); \ 348 | } while (0) 349 | #endif 350 | 351 | #endif /* XNU_KERNEL_PRIVATE */ 352 | 353 | #endif /* __NTSTAT_H__ */ 354 | -------------------------------------------------------------------------------- /src/net/ntstat_24xx_ios7.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | #ifndef __NTSTAT_H__ 29 | #define __NTSTAT_H__ 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef PRIVATE 35 | #pragma pack(push, 4) 36 | #pragma mark -- Common Data Structures -- 37 | 38 | #define __NSTAT_REVISION__ 4 39 | 40 | typedef u_int32_t nstat_provider_id_t; 41 | typedef u_int32_t nstat_src_ref_t; 42 | 43 | typedef struct nstat_counts 44 | { 45 | /* Counters */ 46 | u_int64_t nstat_rxpackets __attribute__((aligned(8))); 47 | u_int64_t nstat_rxbytes __attribute__((aligned(8))); 48 | u_int64_t nstat_txpackets __attribute__((aligned(8))); 49 | u_int64_t nstat_txbytes __attribute__((aligned(8))); 50 | 51 | u_int32_t nstat_rxduplicatebytes; 52 | u_int32_t nstat_rxoutoforderbytes; 53 | u_int32_t nstat_txretransmit; 54 | 55 | u_int32_t nstat_connectattempts; 56 | u_int32_t nstat_connectsuccesses; 57 | 58 | u_int32_t nstat_min_rtt; 59 | u_int32_t nstat_avg_rtt; 60 | u_int32_t nstat_var_rtt; 61 | 62 | u_int64_t nstat_cell_rxbytes __attribute__((aligned(8))); 63 | u_int64_t nstat_cell_txbytes __attribute__((aligned(8))); 64 | u_int64_t nstat_wifi_rxbytes __attribute__((aligned(8))); 65 | u_int64_t nstat_wifi_txbytes __attribute__((aligned(8))); 66 | } nstat_counts; 67 | 68 | #pragma mark -- Network Statistics Providers -- 69 | 70 | enum 71 | { 72 | NSTAT_PROVIDER_ROUTE = 1 73 | ,NSTAT_PROVIDER_TCP = 2 74 | ,NSTAT_PROVIDER_UDP = 3 75 | ,NSTAT_PROVIDER_IFNET = 4 76 | }; 77 | 78 | typedef struct nstat_route_add_param 79 | { 80 | union 81 | { 82 | struct sockaddr_in v4; 83 | struct sockaddr_in6 v6; 84 | } dst; 85 | union 86 | { 87 | struct sockaddr_in v4; 88 | struct sockaddr_in6 v6; 89 | } mask; 90 | u_int32_t ifindex; 91 | } nstat_route_add_param; 92 | 93 | typedef struct nstat_tcp_add_param 94 | { 95 | union 96 | { 97 | struct sockaddr_in v4; 98 | struct sockaddr_in6 v6; 99 | } local; 100 | union 101 | { 102 | struct sockaddr_in v4; 103 | struct sockaddr_in6 v6; 104 | } remote; 105 | } nstat_tcp_add_param; 106 | 107 | typedef struct nstat_tcp_descriptor 108 | { 109 | union 110 | { 111 | struct sockaddr_in v4; 112 | struct sockaddr_in6 v6; 113 | } local; 114 | 115 | union 116 | { 117 | struct sockaddr_in v4; 118 | struct sockaddr_in6 v6; 119 | } remote; 120 | 121 | u_int32_t ifindex; 122 | 123 | u_int32_t state; 124 | 125 | u_int32_t sndbufsize; 126 | u_int32_t sndbufused; 127 | u_int32_t rcvbufsize; 128 | u_int32_t rcvbufused; 129 | u_int32_t txunacked; 130 | u_int32_t txwindow; 131 | u_int32_t txcwindow; 132 | u_int32_t traffic_class; 133 | 134 | u_int64_t upid; 135 | u_int32_t pid; 136 | char pname[64]; 137 | u_int64_t eupid; 138 | u_int32_t epid; 139 | 140 | uint8_t uuid[16]; 141 | uint8_t euuid[16]; 142 | } nstat_tcp_descriptor; 143 | 144 | typedef struct nstat_tcp_add_param nstat_udp_add_param; 145 | 146 | typedef struct nstat_udp_descriptor 147 | { 148 | union 149 | { 150 | struct sockaddr_in v4; 151 | struct sockaddr_in6 v6; 152 | } local; 153 | 154 | union 155 | { 156 | struct sockaddr_in v4; 157 | struct sockaddr_in6 v6; 158 | } remote; 159 | 160 | u_int32_t ifindex; 161 | 162 | u_int32_t rcvbufsize; 163 | u_int32_t rcvbufused; 164 | u_int32_t traffic_class; 165 | 166 | u_int64_t upid; 167 | u_int32_t pid; 168 | char pname[64]; 169 | u_int64_t eupid; 170 | u_int32_t epid; 171 | 172 | uint8_t uuid[16]; 173 | uint8_t euuid[16]; 174 | } nstat_udp_descriptor; 175 | 176 | typedef struct nstat_route_descriptor 177 | { 178 | u_int64_t id; 179 | u_int64_t parent_id; 180 | u_int64_t gateway_id; 181 | 182 | union 183 | { 184 | struct sockaddr_in v4; 185 | struct sockaddr_in6 v6; 186 | struct sockaddr sa; 187 | } dst; 188 | 189 | union 190 | { 191 | struct sockaddr_in v4; 192 | struct sockaddr_in6 v6; 193 | struct sockaddr sa; 194 | } mask; 195 | 196 | union 197 | { 198 | struct sockaddr_in v4; 199 | struct sockaddr_in6 v6; 200 | struct sockaddr sa; 201 | } gateway; 202 | 203 | u_int32_t ifindex; 204 | u_int32_t flags; 205 | 206 | } nstat_route_descriptor; 207 | 208 | typedef struct nstat_ifnet_add_param 209 | { 210 | u_int32_t ifindex; 211 | u_int64_t threshold; 212 | } nstat_ifnet_add_param; 213 | 214 | #ifndef IF_DESCSIZE 215 | #define IF_DESCSIZE 128 216 | #endif 217 | typedef struct nstat_ifnet_descriptor 218 | { 219 | char name[IFNAMSIZ+1]; 220 | u_int32_t ifindex; 221 | u_int64_t threshold; 222 | unsigned int type; 223 | char description[IF_DESCSIZE]; 224 | } nstat_ifnet_descriptor; 225 | 226 | #pragma mark -- Network Statistics User Client -- 227 | 228 | #define NET_STAT_CONTROL_NAME "com.apple.network.statistics" 229 | 230 | enum 231 | { 232 | // generic response messages 233 | NSTAT_MSG_TYPE_SUCCESS = 0 234 | ,NSTAT_MSG_TYPE_ERROR = 1 235 | 236 | // Requests 237 | ,NSTAT_MSG_TYPE_ADD_SRC = 1001 238 | ,NSTAT_MSG_TYPE_ADD_ALL_SRCS = 1002 239 | ,NSTAT_MSG_TYPE_REM_SRC = 1003 240 | ,NSTAT_MSG_TYPE_QUERY_SRC = 1004 241 | ,NSTAT_MSG_TYPE_GET_SRC_DESC = 1005 242 | ,NSTAT_MSG_TYPE_SET_FILTER = 1006 243 | 244 | // Responses/Notfications 245 | ,NSTAT_MSG_TYPE_SRC_ADDED = 10001 246 | ,NSTAT_MSG_TYPE_SRC_REMOVED = 10002 247 | ,NSTAT_MSG_TYPE_SRC_DESC = 10003 248 | ,NSTAT_MSG_TYPE_SRC_COUNTS = 10004 249 | }; 250 | 251 | enum 252 | { 253 | NSTAT_SRC_REF_ALL = 0xffffffff 254 | ,NSTAT_SRC_REF_INVALID = 0 255 | }; 256 | 257 | enum 258 | { 259 | NSTAT_FILTER_NOZEROBYTES = 0x01, 260 | }; 261 | 262 | typedef struct nstat_msg_hdr 263 | { 264 | u_int64_t context; 265 | u_int32_t type; 266 | u_int32_t pad; // unused for now 267 | } nstat_msg_hdr; 268 | 269 | typedef struct nstat_msg_error 270 | { 271 | nstat_msg_hdr hdr; 272 | u_int32_t error; // errno error 273 | } nstat_msg_error; 274 | 275 | typedef struct nstat_msg_add_src 276 | { 277 | nstat_msg_hdr hdr; 278 | nstat_provider_id_t provider; 279 | u_int8_t param[]; 280 | } nstat_msg_add_src_req; 281 | 282 | typedef struct nstat_msg_add_all_srcs 283 | { 284 | nstat_msg_hdr hdr; 285 | nstat_provider_id_t provider; 286 | } nstat_msg_add_all_srcs; 287 | 288 | typedef struct nstat_msg_src_added 289 | { 290 | nstat_msg_hdr hdr; 291 | nstat_provider_id_t provider; 292 | nstat_src_ref_t srcref; 293 | } nstat_msg_src_added; 294 | 295 | typedef struct nstat_msg_rem_src 296 | { 297 | nstat_msg_hdr hdr; 298 | nstat_src_ref_t srcref; 299 | } nstat_msg_rem_src_req; 300 | 301 | typedef struct nstat_msg_get_src_description 302 | { 303 | nstat_msg_hdr hdr; 304 | nstat_src_ref_t srcref; 305 | } nstat_msg_get_src_description; 306 | 307 | typedef struct nstat_msg_set_filter 308 | { 309 | nstat_msg_hdr hdr; 310 | nstat_src_ref_t srcref; 311 | u_int32_t filter; 312 | } nstat_msg_set_filter; 313 | 314 | typedef struct nstat_msg_src_description 315 | { 316 | nstat_msg_hdr hdr; 317 | nstat_src_ref_t srcref; 318 | nstat_provider_id_t provider; 319 | u_int8_t data[]; 320 | } nstat_msg_src_description; 321 | 322 | typedef struct nstat_msg_query_src 323 | { 324 | nstat_msg_hdr hdr; 325 | nstat_src_ref_t srcref; 326 | } nstat_msg_query_src_req; 327 | 328 | typedef struct nstat_msg_src_counts 329 | { 330 | nstat_msg_hdr hdr; 331 | nstat_src_ref_t srcref; 332 | nstat_counts counts; 333 | } nstat_msg_src_counts; 334 | 335 | typedef struct nstat_msg_src_removed 336 | { 337 | nstat_msg_hdr hdr; 338 | nstat_src_ref_t srcref; 339 | } nstat_msg_src_removed; 340 | 341 | #pragma pack(pop) 342 | 343 | #endif /* PRIVATE */ 344 | 345 | #ifdef XNU_KERNEL_PRIVATE 346 | #include 347 | 348 | #pragma mark -- Generic Network Statistics Provider -- 349 | 350 | typedef void * nstat_provider_cookie_t; 351 | 352 | #pragma mark -- Route Statistics Gathering Functions -- 353 | struct rtentry; 354 | 355 | enum 356 | { 357 | NSTAT_TX_FLAG_RETRANSMIT = 1 358 | }; 359 | 360 | enum 361 | { 362 | NSTAT_RX_FLAG_DUPLICATE = 1, 363 | NSTAT_RX_FLAG_OUT_OF_ORDER = 2 364 | }; 365 | 366 | // indicates whether or not collection of statistics is enabled 367 | extern int nstat_collect; 368 | 369 | void nstat_init(void); 370 | 371 | // Route collection routines 372 | void nstat_route_connect_attempt(struct rtentry *rte); 373 | void nstat_route_connect_success(struct rtentry *rte); 374 | void nstat_route_tx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 375 | void nstat_route_rx(struct rtentry *rte, u_int32_t packets, u_int32_t bytes, u_int32_t flags); 376 | void nstat_route_rtt(struct rtentry *rte, u_int32_t rtt, u_int32_t rtt_var); 377 | void nstat_route_detach(struct rtentry *rte); 378 | 379 | // watcher support 380 | struct inpcb; 381 | void nstat_tcp_new_pcb(struct inpcb *inp); 382 | void nstat_udp_new_pcb(struct inpcb *inp); 383 | void nstat_route_new_entry(struct rtentry *rt); 384 | void nstat_pcb_detach(struct inpcb *inp); 385 | 386 | 387 | void nstat_ifnet_threshold_reached(unsigned int ifindex); 388 | 389 | // locked_add_64 uses atomic operations on 32bit so the 64bit 390 | // value can be properly read. The values are only ever incremented 391 | // while under the socket lock, so on 64bit we don't actually need 392 | // atomic operations to increment. 393 | #if defined(__LP64__) 394 | #define locked_add_64(__addr, __count) do { \ 395 | *(__addr) += (__count); \ 396 | } while (0) 397 | #else 398 | #define locked_add_64(__addr, __count) do { \ 399 | atomic_add_64((__addr), (__count)); \ 400 | } while (0) 401 | #endif 402 | 403 | #endif /* XNU_KERNEL_PRIVATE */ 404 | 405 | #endif /* __NTSTAT_H__ */ 406 | -------------------------------------------------------------------------------- /src/netinet/tcp_fsm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. All advertising materials mentioning features or use of this software 14 | * must display the following acknowledgement: 15 | * This product includes software developed by the University of 16 | * California, Berkeley and its contributors. 17 | * 4. Neither the name of the University nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | * 33 | * @(#)tcp_fsm.h 8.1 (Berkeley) 6/10/93 34 | */ 35 | 36 | /* 37 | * TCP FSM state definitions. 38 | * Per RFC793, September, 1981. 39 | */ 40 | 41 | #define TCP_NSTATES 11 42 | 43 | #define TCPS_CLOSED 0 /* closed */ 44 | #define TCPS_LISTEN 1 /* listening for connection */ 45 | #define TCPS_SYN_SENT 2 /* active, have sent syn */ 46 | #define TCPS_SYN_RECEIVED 3 /* have send and received syn */ 47 | /* states < TCPS_ESTABLISHED are those where connections not established */ 48 | #define TCPS_ESTABLISHED 4 /* established */ 49 | #define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */ 50 | /* states > TCPS_CLOSE_WAIT are those where user has closed */ 51 | #define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */ 52 | #define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */ 53 | #define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */ 54 | /* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */ 55 | #define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */ 56 | #define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */ 57 | 58 | #define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED) 59 | #define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT) 60 | 61 | #ifdef TCPOUTFLAGS 62 | /* 63 | * Flags used when sending segments in tcp_output. 64 | * Basic flags (TH_RST,TH_ACK,TH_SYN,TH_FIN) are totally 65 | * determined by state, with the proviso that TH_FIN is sent only 66 | * if all data queued for output is included in the segment. 67 | */ 68 | u_char tcp_outflags[TCP_NSTATES] = { 69 | TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, 70 | TH_ACK, TH_ACK, 71 | TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK, 72 | }; 73 | #endif 74 | 75 | #ifdef KPROF 76 | int tcp_acounts[TCP_NSTATES][PRU_NREQ]; 77 | #endif 78 | 79 | #ifdef TCPSTATES 80 | char *tcpstates[] = { 81 | "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", 82 | "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING", 83 | "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", 84 | }; 85 | #endif 86 | -------------------------------------------------------------------------------- /src/postinst/Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = armv7 arm64 2 | TARGET = iphone:clang:13.0:6.0 3 | include $(THEOS)/makefiles/common.mk 4 | 5 | TOOL_NAME = postinst 6 | 7 | postinst_FILES = main.m 8 | postinst_CFLAGS += -fvisibility=hidden -DPOSTINST -fobjc-arc 9 | postinst_INSTALL_PATH = /DEBIAN 10 | postinst_CODESIGN_FLAGS = -Stask.xml 11 | 12 | include $(THEOS_MAKE_PATH)/tool.mk 13 | 14 | include $(THEOS_MAKE_PATH)/aggregate.mk 15 | -------------------------------------------------------------------------------- /src/postinst/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CocoaTop 4 | // 5 | // Created by SXX on 2021/1/4. 6 | // Copyright © 2021 SXX. All rights reserved. 7 | // 8 | 9 | #import 10 | #include 11 | 12 | #define APP_PATH_PREFIX "/Applications/CocoaTop.app" 13 | 14 | int 15 | main(int argc, char *argv[], char *envp[]) { 16 | if (geteuid() != 0) { 17 | printf("ERROR: This tool needs to be run as root.\n"); 18 | return 1; 19 | } 20 | chown(APP_PATH_PREFIX "/CocoaTop", 0, 0); 21 | chmod(APP_PATH_PREFIX "/CocoaTop", 04755); 22 | if (@available(iOS 10, *)) { 23 | } else { 24 | chmod(APP_PATH_PREFIX "/CocoaTop_", 0755); 25 | rename(APP_PATH_PREFIX "/CocoaTop", APP_PATH_PREFIX "/CocoaTop1"); 26 | rename(APP_PATH_PREFIX "/CocoaTop_", APP_PATH_PREFIX "/CocoaTop"); 27 | rename(APP_PATH_PREFIX "/CocoaTop1", APP_PATH_PREFIX "/CocoaTop_"); 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /src/postinst/task.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | com.apple.private.skip-library-validation 8 | 9 | com.apple.private.security.no-container 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/res/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib -------------------------------------------------------------------------------- /src/res/Base.lproj/LaunchScreen.storyboardc/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Base.lproj/LaunchScreen.storyboardc/Info.plist -------------------------------------------------------------------------------- /src/res/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib -------------------------------------------------------------------------------- /src/res/CocoaTop_: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | C=/${0} 3 | C=${C%/*} 4 | exec "${C:-.}"/CocoaTop_ 5 | if test -e /System/Library/Frameworks/GameController.framework; then 6 | exec "${C:-.}"/CocoaTop 7 | elif test -e /System/Library/Frameworks/MediaToolbox.framework; then 8 | exec "${C:-.}"/CocoaTop6 9 | else 10 | exec "${C:-.}"/CocoaTop5 11 | fi 12 | -------------------------------------------------------------------------------- /src/res/Default-1024h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Default-1024h.png -------------------------------------------------------------------------------- /src/res/Default-1024h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Default-1024h@2x.png -------------------------------------------------------------------------------- /src/res/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Default-568h@2x.png -------------------------------------------------------------------------------- /src/res/Default-667h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Default-667h@2x.png -------------------------------------------------------------------------------- /src/res/Default-736h@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Default-736h@3x.png -------------------------------------------------------------------------------- /src/res/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Default.png -------------------------------------------------------------------------------- /src/res/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Default@2x.png -------------------------------------------------------------------------------- /src/res/Icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon-60.png -------------------------------------------------------------------------------- /src/res/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon-72.png -------------------------------------------------------------------------------- /src/res/Icon-76~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon-76~ipad.png -------------------------------------------------------------------------------- /src/res/Icon-Small-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon-Small-40.png -------------------------------------------------------------------------------- /src/res/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon-Small-50.png -------------------------------------------------------------------------------- /src/res/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon-Small.png -------------------------------------------------------------------------------- /src/res/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon-Small@2x.png -------------------------------------------------------------------------------- /src/res/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon.png -------------------------------------------------------------------------------- /src/res/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/Icon@2x.png -------------------------------------------------------------------------------- /src/res/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UILaunchStoryboardName 6 | LaunchScreen 7 | UISupportedInterfaceOrientations~ipad 8 | 9 | UIInterfaceOrientationLandscapeRight 10 | UIInterfaceOrientationLandscapeLeft 11 | UIInterfaceOrientationPortraitUpsideDown 12 | UIInterfaceOrientationPortrait 13 | 14 | CFBundleDevelopmentRegion 15 | English 16 | CFBundleDisplayName 17 | CocoaTop 18 | CFBundleExecutable 19 | CocoaTop 20 | CFBundleIdentifier 21 | ru.domo.cocoatop64 22 | CFBundleInfoDictionaryVersion 23 | 6.0 24 | CFBundleName 25 | CocoaTop 26 | CFBundlePackageType 27 | APPL 28 | CFBundleSignature 29 | ???? 30 | CFBundleVersion 31 | 1.0 32 | UIDeviceFamily 33 | 34 | 1 35 | 2 36 | 37 | CFBundleIconFiles 38 | 39 | Icon.png 40 | Icon@2x.png 41 | Icon-72.png 42 | Icon-60 43 | Icon-76 44 | Icon-Small-40 45 | Icon-Small 46 | Icon-Small@2x 47 | Icon-Small-50 48 | 49 | UILaunchImages 50 | 51 | 52 | UILaunchImageMinimumOSVersion 53 | 7.0 54 | UILaunchImageName 55 | Default 56 | UILaunchImageOrientation 57 | Portrait 58 | UILaunchImageSize 59 | {320, 480} 60 | 61 | 62 | UILaunchImageMinimumOSVersion 63 | 7.0 64 | UILaunchImageName 65 | Default 66 | UILaunchImageOrientation 67 | Landscape 68 | UILaunchImageSize 69 | {320, 480} 70 | 71 | 72 | UILaunchImageMinimumOSVersion 73 | 7.0 74 | UILaunchImageName 75 | Default-568h 76 | UILaunchImageOrientation 77 | Portrait 78 | UILaunchImageSize 79 | {320, 568} 80 | 81 | 82 | UILaunchImageMinimumOSVersion 83 | 7.0 84 | UILaunchImageName 85 | Default-568h 86 | UILaunchImageOrientation 87 | Landscape 88 | UILaunchImageSize 89 | {320, 568} 90 | 91 | 92 | UILaunchImageMinimumOSVersion 93 | 7.0 94 | UILaunchImageName 95 | Default-667h 96 | UILaunchImageOrientation 97 | Portrait 98 | UILaunchImageSize 99 | {375, 667} 100 | 101 | 102 | UILaunchImageMinimumOSVersion 103 | 7.0 104 | UILaunchImageName 105 | Default-667h 106 | UILaunchImageOrientation 107 | Landscape 108 | UILaunchImageSize 109 | {375, 667} 110 | 111 | 112 | UILaunchImageMinimumOSVersion 113 | 7.0 114 | UILaunchImageName 115 | Default-736h 116 | UILaunchImageOrientation 117 | Portrait 118 | UILaunchImageSize 119 | {414, 736} 120 | 121 | 122 | UILaunchImageMinimumOSVersion 123 | 7.0 124 | UILaunchImageName 125 | Default-736h 126 | UILaunchImageOrientation 127 | Landscape 128 | UILaunchImageSize 129 | {414, 736} 130 | 131 | 132 | UILaunchImageMinimumOSVersion 133 | 7.0 134 | UILaunchImageName 135 | Default-1024h 136 | UILaunchImageOrientation 137 | Portrait 138 | UILaunchImageSize 139 | {768, 1024} 140 | 141 | 142 | UILaunchImageMinimumOSVersion 143 | 7.0 144 | UILaunchImageName 145 | Default-1024h 146 | UILaunchImageOrientation 147 | Landscape 148 | UILaunchImageSize 149 | {768, 1024} 150 | 151 | 152 | UISupportedInterfaceOrientations 153 | 154 | UIInterfaceOrientationPortrait 155 | UIInterfaceOrientationPortraitUpsideDown 156 | UIInterfaceOrientationLandscapeLeft 157 | UIInterfaceOrientationLandscapeRight 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /src/res/UIButtonBarHamburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/UIButtonBarHamburger.png -------------------------------------------------------------------------------- /src/res/UIButtonBarHamburger@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/UIButtonBarHamburger@2x.png -------------------------------------------------------------------------------- /src/res/UIButtonBarRefresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/UIButtonBarRefresh.png -------------------------------------------------------------------------------- /src/res/UIButtonBarRefresh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/UIButtonBarRefresh@2x.png -------------------------------------------------------------------------------- /src/res/guide.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Quick Guide 11 | 12 | 13 | 14 | Tap on a process to view its details, including threads, open files & sockets, loaded modules, and summary. 15 | Tap on a column header to sort by that column. Tap again to sort backwards. 16 | Switch to fullscreen view and back by touching the display with two fingers. 17 | Processes on a green background were recently created. 18 | Processes on a red background have recently terminated. 19 | To terminate (TERM) or kill a process (KILL) swipe to the left. A SIGTERM signal gives the process an option 20 | to terminate voluntarily. A SIGKILL kills the process immediately, that's why it's a red button. 21 | Numeric values are highlighted red when they increase, and blue when they decrease. 22 | Descriptions for all columns and their totals (the values at the bottom) are available in the column configuration 23 | pane – just tap the (i) icon. 24 | 25 | 26 | 27 | Process Details: Threads 28 | 29 | 30 | Threads are displayed with the following color coding: 31 | ■ - a thread is currently running. 32 | ■ - a thread is waiting on I/O in a system call (uninterruptible). 33 | ■ - a thread is halted or stopped. 34 | ■ - a thread is suspended. 35 | ■ - a thread is idle (sleeping). 36 | ■ - thread state is unknown. 37 | 38 | A small 'i' in thread state column indicates that the thread is running an idle loop (used for putting a CPU core into 39 | sleep mode). Such threads can be seen in the kernel task. 40 | 41 | 42 | Process Details: Open Files & Sockets 43 | 44 | 45 | Open file descriptors are displayed with the following color coding: 46 | ■ - this is a regular file. 47 | ■ - this is a network socket (TCP or UDP). 48 | ■ - this is a UNIX pipe. 49 | ■ - this is a UNIX socket or a kernel queue. 50 | ■ - this is a kernel control descriptor. 51 | ■ - this is a kernel event descriptor. 52 | 53 | 54 | 55 | Process Details: Mach Ports 56 | 57 | 58 | Open ports are displayed with the following color coding: 59 | ■ - this port has SEND and RECEIVE rights. 60 | ■ - this port has a RECEIVE right. 61 | ■ - this port has a SEND right. 62 | 63 | 64 | 65 | Process Details: Loaded Modules 66 | 67 | 68 | Loaded modules are displayed with the following color coding: 69 | ■ - this module is loaded from a .dylib file. Mapped size and reference count are provided. 70 | ■ - this module is loaded from the dynamic library cache – a large file 71 | where all built-in system libraries (private and public) are combined to improve performance. 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/res/ios7-chevron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/ios7-chevron.png -------------------------------------------------------------------------------- /src/res/ios7-chevron@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D0m0/CocoaTop/30746da61413f9474badd98e3d9757978c524649/src/res/ios7-chevron@2x.png -------------------------------------------------------------------------------- /src/res/story.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Developers 11 | 12 | 13 | ★ Domo (the original author) 14 | ★ SongXiaoXi aka SXX (iOS 13 support and lots of improvements) 15 | ★ Randomblock1 aka Benjamin G. (automatic .deb package assembly) 16 | ★ @DylanDuff3 (application icon) 17 | 18 | 19 | The Story 20 | 21 | 22 | Hello, friends! 23 | This text should clarify some questionable concepts implemented in CocoaTop, the ideas behind those concepts, 24 | and the idea behind the application itself. Also, it should be a fun read, at least for some ;) 25 | Before we begin I would like to thank Luis Finke for making miniCode 26 | (available in Cydia) – a nice alternative to XCode that became an IDE for my first iOS app, which is also my first 27 | Objective C app. (Hey, if you think I typed the whole thing on the iPad, you're wrong. I even used 28 | Theos, goddamit, okay! But that's not the point! 29 | Update: One of the most controversial topics concerning CocoaTop was the icon ;) . The original one, which I drew myself rather 30 | hastily, became the target of criticism on almost every forum or blog, not excluding Chinese, Korean, or some Hindu ones. 31 | That's when @DylanDuff3 kindly offered me his own version of the icon, which is 32 | used currently. 33 | Now, you could say that the purpose of CocoaTop is to replace the original terminal 'top' 34 | – but it is not. First of all, the UNIX terminal is a thing in itself: every iPad user has to have a terminal 35 | installed, otherwise (s)he can be mistaken for a dork, or worse – a humanitarian. Also, 'top' executed on an iPad 36 | always attracts people's attention. So the idea behind CocoaTop is this: I wanted to create something nice, 37 | gaining knowledge in the process. If you find it useful, well, you're in luck! 38 | While working on CocoaTop I found a book, a site, 39 | and a forum by a man named Jonathan Levin. I don't know how I managed to overlook this hilarious stuff. It gave me 40 | a great inspiration boost, not to mention loads of bad-quality source code to ponder on. Thanks to Jonathan's in-depth 41 | coverage of hidden and undocumented APIs this version of CocoaTop features real-time per-process network statistics! 42 | Also, if you're into console utilities & SSH, try his Process 43 | Explorer for iOS and Mac OS X. 44 | Ok, on to the fun facts: 45 | ★ CPU usage sums up not to 100% but to cores×100%. Moreover, it can actually exceed this value, and it surely 46 | will when the cores are doing the real stuff: protein folding and shit like that. CPU exceeds 100% not for your amusement, 47 | but due to a scheduling policy of the Mach Kernel, which is called decay-usage scheduling. When a thread acquires CPU 48 | time, its priority is continually being depressed: this ensures short response times of interactive jobs, which 49 | do not always have a high initial priority, especially on weaker mobile platforms. The decayed CPU usage of a running 50 | thread increases in a linearly proportional fashion with CPU time obtained, and is periodically divided by the decay 51 | factor, which is a constant larger than one. Thus, the Mach CPU utilization of the process is a decaying average over 52 | up to a minute of previous (real) time. Since the time base over which this is computed varies (since processes may be 53 | very young) it is possible for the sum of all %CPU fields to exceed 100%. And this is why Android sucks. Also, because 54 | of Java, which isn't bad by itself, but... the mobile world? 55 | Update: You may have noticed that on older versions of CocoaTop the kernel task (pid 0) took 56 | up a lot of %CPU, in fact it took up all unused CPU power. This is because for every CPU core there's a kernel thread which 57 | halts the core when it's not used to save battery life, effectively eating up remaining CPU cycles. You can actually find 58 | these threads when you switch to process details, thread mode: they will have a small 'i' for 'idle' in the state column. 59 | Newer versions of CocoaTop no longer include there threads in kernel CPU usage. Unfortunately, on 64-bit devices information 60 | on kernel threads is substantially limited. 61 | ★ Everyone knows about processes, but what about Mach tasks? These are actually different things. In fact, it is 62 | technically possible to create a Mach task without a BSD process. A Mach task can actually be created without threads 63 | and memory (ah, the benefits of The Microkernel, my love). Mach tasks do not have parent-child relationships, those are 64 | implemented at the BSD level. This implies that BSD (or, generally, POSIX) has more morale, but not really. In UNIX, it 65 | is actually the norm for the parent to outlive its children. Furthermore, a parent actually expects their children to die, 66 | otherwise they rise as zombies. This is why I love pure microkernels. 67 | Update: A barebone task cannot be created in iOS usermode, because the corresponding API task_create() 68 | is removed. But the underlying kernel function task_create_internal() still exists and creates a task 69 | when a BSD process is launched. 70 | ★ You can kill processes by swiping to the left, but this seems cruel. One thing I would really prefer is killing 71 | zombies, but not sure if that fits with the iOS philosophy. 72 | Update: Actually, a zombie is not a process, but rather just a kernel entry for a process which no longer exists. 73 | So you can't kill it. The only reason for keeping it is to remind a parent process of a child's previous existence and save 74 | any bits of data left over by the child, i.e. an exit code. When the parent process finally collects these data (or dies), 75 | the zombie disappears. 76 | ★ There's no such thing as a running process, because it is the threads that run, not processes. So why is there a 77 | 'Process running' state? Well, this is done to simplify the output, and actually taken from the original 'top' source 78 | code. Most process states are calculated from thread states using a simple rule of precedence: i.e. if at least one thread 79 | is running, the process state is presumed 'R', and so on. The complete list is provided in the column info: 80 | just tap (i) at the 'Process state' item while managing columns. 81 | ★ There is also a column called 'Mach Actual Threads Priority'. What it actually contains is the highest priority of 82 | a thread within the process. This is also the way original 'top' works. Also, there are several scheduling schemes 83 | supported by Mach, but only one of them is actually used in iOS – 'Time Sharing'. The other two, 'Round-Robin' 84 | and 'FIFO', will be marked in this column using prefixes R: and F: respectively, but I've never seen them. I added 85 | those marks out of curiosity - write me a letter. 86 | Update: Round-robin scheduling is actually used for certain threads throughout the OS, especially kernel threads. 87 | In fact, all kernel threads default to the round-robin scheme: see for yourself! (If you're lucky to see kernel task details) 88 | ★ Apple tightens up security with each new version of iOS, so CocoaTop can no longer show details about task 0 89 | (the kernel task) on iOS 8. You can still enjoy this data if you have iOS 7! Actually, the iOS could be considered the 90 | most secure public platform of all times, only if it wasn't so stuffed with backdoors, at least in v.7 ;) Anyway, 91 | it's better than the other non-evil company ;) 92 | Update: It seems that details about the kernel task are available on some platforms, while absent on others. 93 | Maybe this depends on the jailbreak method used. I'm glad to inform you that this info is once more available on some devices 94 | running iOS 9! 95 | ★ There's a 'Mach Task Role' column which actually shows the assigned role for GUI apps, like in OS X. I've noticed 96 | this works only on iOS 8+. 97 | 98 | 99 | 100 | 101 | Donate via PayPal, if you like this stuff 102 | 103 | 104 | Email for feedback and suggestions 105 | 106 | 107 | CocoaTop on Reddit 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /src/res/style.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | margin-left:15px; 3 | font-size: 1.5em; 4 | } 5 | 6 | .note { 7 | color: blue; 8 | } 9 | 10 | body { 11 | margin: 9px auto; 12 | width: device-width; 13 | font-family: sans-serif; 14 | background-color: #efeff4; 15 | } 16 | 17 | body > panel { 18 | display: block; 19 | width: 100%; 20 | margin: 0; 21 | border:0; 22 | border-top: 1px solid #c8c7cc; 23 | border-bottom: 1px solid #c8c7cc; 24 | margin-top:9px; 25 | margin-bottom:9px; 26 | background-color: white; 27 | text-align:left; 28 | } 29 | 30 | body > panel > fieldset { 31 | display: block; 32 | padding: 0 15px; 33 | background-color: white; 34 | color: #666; 35 | line-height: 18px; 36 | border:0; 37 | } 38 | 39 | body > panel > fieldset > ul { 40 | padding-left:15px; 41 | } 42 | 43 | body > panel > fieldset+fieldset { 44 | margin-left:15px; 45 | padding-left: 0; 46 | border-top: 1px solid #c8c7cc; 47 | } 48 | 49 | body > panel > fieldset:last-child { 50 | padding-bottom:1px; 51 | } 52 | 53 | body > panel > fieldset > a.button:link, body > panel > fieldset > a.button:visited { 54 | text-decoration:none; 55 | color: #0076ff; 56 | } 57 | 58 | body > panel > fieldset > a.button { 59 | display: block; 60 | width: 100%; 61 | font-size: 17px; 62 | display: block; 63 | color:black; 64 | position:relative; 65 | padding-left: 0; 66 | padding-right: 0; 67 | padding-top: 11.5px; 68 | padding-bottom: 12px; 69 | margin-top:2px; 70 | margin-bottom:2px; 71 | background-repeat: no-repeat; 72 | background-image: url(ios7-chevron.png); 73 | background-position: right; 74 | } 75 | 76 | @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 77 | body > panel > fieldset > a.button { 78 | background-image: url(ios7-chevron@2x.png); 79 | background-size:8px 13px; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/sys/dyld64.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__ 2 | #define CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__ 3 | 4 | #include 5 | #include 6 | 7 | struct dyld_uuid_info64 { 8 | mach_vm_address_t imageLoadAddress; /* base address image is mapped into */ 9 | uuid_t imageUUID; /* UUID of image */ 10 | }; 11 | 12 | struct dyld_image_info64 { 13 | mach_vm_address_t imageLoadAddress; /* base address image is mapped into */ 14 | mach_vm_address_t imageFilePath; /* path dyld used to load the image */ 15 | mach_vm_size_t imageFileModDate; /* time_t of image file */ 16 | /* if stat().st_mtime of imageFilePath does not match imageFileModDate, */ 17 | /* then file has been modified since dyld loaded it */ 18 | }; 19 | 20 | struct dyld_all_image_infos64 { 21 | uint32_t version; 22 | uint32_t infoArrayCount; 23 | mach_vm_address_t infoArray; // struct dyld_image_info64* 24 | dyld_image_notifier notification; 25 | bool processDetachedFromSharedRegion; 26 | bool libSystemInitialized; 27 | mach_vm_address_t dyldImageLoadAddress; 28 | mach_vm_address_t jitInfo; 29 | mach_vm_address_t dyldVersion; // char* 30 | mach_vm_address_t errorMessage; // char* 31 | uint64_t terminationFlags; 32 | mach_vm_address_t coreSymbolicationShmPage; 33 | uint64_t systemOrderFlag; 34 | uint64_t uuidArrayCount; 35 | mach_vm_address_t uuidArray; // struct dyld_uuid_info* 36 | mach_vm_address_t dyldAllImageInfosAddress; // struct dyld_all_image_infos64* 37 | uint64_t initialImageCount; 38 | uint64_t errorKind; 39 | mach_vm_address_t errorClientOfDylibPath; // char* 40 | mach_vm_address_t errorTargetDylibPath; // char* 41 | mach_vm_address_t errorSymbol; // char* 42 | uint64_t sharedCacheSlide; 43 | }; 44 | 45 | #endif /* !CLIENT_MAC_HANDLER_DYNAMIC_IMAGES_H__ */ 46 | -------------------------------------------------------------------------------- /src/sys/libproc.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_LIBPROC_H_ 2 | #define _SYS_LIBPROC_H_ 3 | 4 | #include 5 | #include 6 | 7 | extern kern_return_t task_for_pid(task_port_t task, pid_t pid, task_port_t *target); 8 | extern kern_return_t task_info(task_port_t task, unsigned int info_num, task_info_t info, unsigned int *info_count); 9 | extern int proc_pidpath(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 10 | extern int proc_pid_rusage(int pid, int flavor, struct rusage_info_v2 *rusage);// __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); 11 | //extern int proc_listpidspath(uint32_t type, uint32_t typeinfo, const char *path, uint32_t pathflags, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 12 | //extern int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 13 | //extern int proc_listallpids(void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); 14 | //extern int proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); 15 | //extern int proc_listchildpids(pid_t ppid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); 16 | extern int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 17 | extern int proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 18 | //extern int proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 19 | //extern int proc_name(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 20 | //extern int proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 21 | //extern int proc_kmsgbuf(void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 22 | //extern int proc_libversion(int *major, int * minor) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); 23 | extern kern_return_t mach_vm_read(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_offset_t *data, mach_msg_type_number_t *dataCnt); 24 | extern kern_return_t mach_vm_read_overwrite(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, mach_vm_address_t data, mach_vm_size_t *outsize); 25 | 26 | #endif /* !_SYS_LIBPROC_H_ */ 27 | -------------------------------------------------------------------------------- /src/sys/resource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2008 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 29 | /* 30 | * Copyright (c) 1982, 1986, 1993 31 | * The Regents of the University of California. All rights reserved. 32 | * 33 | * Redistribution and use in source and binary forms, with or without 34 | * modification, are permitted provided that the following conditions 35 | * are met: 36 | * 1. Redistributions of source code must retain the above copyright 37 | * notice, this list of conditions and the following disclaimer. 38 | * 2. Redistributions in binary form must reproduce the above copyright 39 | * notice, this list of conditions and the following disclaimer in the 40 | * documentation and/or other materials provided with the distribution. 41 | * 3. All advertising materials mentioning features or use of this software 42 | * must display the following acknowledgement: 43 | * This product includes software developed by the University of 44 | * California, Berkeley and its contributors. 45 | * 4. Neither the name of the University nor the names of its contributors 46 | * may be used to endorse or promote products derived from this software 47 | * without specific prior written permission. 48 | * 49 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 | * SUCH DAMAGE. 60 | * 61 | * @(#)resource.h 8.2 (Berkeley) 1/4/94 62 | */ 63 | 64 | #ifndef _SYS_RESOURCEEX_H_ 65 | #define _SYS_RESOURCEEX_H_ 66 | 67 | #include 68 | #include 69 | 70 | 71 | /***** 72 | * RESOURCE USAGE 73 | */ 74 | 75 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 76 | /* 77 | * Flavors for proc_pid_rusage(). 78 | */ 79 | #define RUSAGE_INFO_V0 0 80 | #define RUSAGE_INFO_V1 1 81 | #define RUSAGE_INFO_V2 2 82 | #define RUSAGE_INFO_V3 3 83 | 84 | #ifndef RUSAGE_INFO_CURRENT 85 | #define RUSAGE_INFO_CURRENT RUSAGE_INFO_V3 86 | 87 | typedef void *rusage_info_t; 88 | 89 | struct rusage_info_v0 { 90 | uint8_t ri_uuid[16]; 91 | uint64_t ri_user_time; 92 | uint64_t ri_system_time; 93 | uint64_t ri_pkg_idle_wkups; 94 | uint64_t ri_interrupt_wkups; 95 | uint64_t ri_pageins; 96 | uint64_t ri_wired_size; 97 | uint64_t ri_resident_size; 98 | uint64_t ri_phys_footprint; 99 | uint64_t ri_proc_start_abstime; 100 | uint64_t ri_proc_exit_abstime; 101 | }; 102 | 103 | struct rusage_info_v1 { 104 | uint8_t ri_uuid[16]; 105 | uint64_t ri_user_time; 106 | uint64_t ri_system_time; 107 | uint64_t ri_pkg_idle_wkups; 108 | uint64_t ri_interrupt_wkups; 109 | uint64_t ri_pageins; 110 | uint64_t ri_wired_size; 111 | uint64_t ri_resident_size; 112 | uint64_t ri_phys_footprint; 113 | uint64_t ri_proc_start_abstime; 114 | uint64_t ri_proc_exit_abstime; 115 | uint64_t ri_child_user_time; 116 | uint64_t ri_child_system_time; 117 | uint64_t ri_child_pkg_idle_wkups; 118 | uint64_t ri_child_interrupt_wkups; 119 | uint64_t ri_child_pageins; 120 | uint64_t ri_child_elapsed_abstime; 121 | }; 122 | 123 | struct rusage_info_v2 { 124 | uint8_t ri_uuid[16]; 125 | uint64_t ri_user_time; 126 | uint64_t ri_system_time; 127 | uint64_t ri_pkg_idle_wkups; 128 | uint64_t ri_interrupt_wkups; 129 | uint64_t ri_pageins; 130 | uint64_t ri_wired_size; 131 | uint64_t ri_resident_size; 132 | uint64_t ri_phys_footprint; 133 | uint64_t ri_proc_start_abstime; 134 | uint64_t ri_proc_exit_abstime; 135 | uint64_t ri_child_user_time; 136 | uint64_t ri_child_system_time; 137 | uint64_t ri_child_pkg_idle_wkups; 138 | uint64_t ri_child_interrupt_wkups; 139 | uint64_t ri_child_pageins; 140 | uint64_t ri_child_elapsed_abstime; 141 | uint64_t ri_diskio_bytesread; 142 | uint64_t ri_diskio_byteswritten; 143 | }; 144 | 145 | struct rusage_info_v3 { 146 | uint8_t ri_uuid[16]; 147 | uint64_t ri_user_time; 148 | uint64_t ri_system_time; 149 | uint64_t ri_pkg_idle_wkups; 150 | uint64_t ri_interrupt_wkups; 151 | uint64_t ri_pageins; 152 | uint64_t ri_wired_size; 153 | uint64_t ri_resident_size; 154 | uint64_t ri_phys_footprint; 155 | uint64_t ri_proc_start_abstime; 156 | uint64_t ri_proc_exit_abstime; 157 | uint64_t ri_child_user_time; 158 | uint64_t ri_child_system_time; 159 | uint64_t ri_child_pkg_idle_wkups; 160 | uint64_t ri_child_interrupt_wkups; 161 | uint64_t ri_child_pageins; 162 | uint64_t ri_child_elapsed_abstime; 163 | uint64_t ri_diskio_bytesread; 164 | uint64_t ri_diskio_byteswritten; 165 | uint64_t ri_cpu_time_qos_default; 166 | uint64_t ri_cpu_time_qos_maintenance; 167 | uint64_t ri_cpu_time_qos_background; 168 | uint64_t ri_cpu_time_qos_utility; 169 | uint64_t ri_cpu_time_qos_legacy; 170 | uint64_t ri_cpu_time_qos_user_initiated; 171 | uint64_t ri_cpu_time_qos_user_interactive; 172 | uint64_t ri_billed_system_time; 173 | uint64_t ri_serviced_system_time; 174 | }; 175 | 176 | typedef struct rusage_info_v3 rusage_info_current; 177 | 178 | #endif 179 | 180 | #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ 181 | 182 | #endif /* !_SYS_RESOURCEEX_H_ */ 183 | -------------------------------------------------------------------------------- /src/sys/sys_domain.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2005, 2012, 2014 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | 29 | 30 | #ifndef _SYSTEM_DOMAIN_H_ 31 | #define _SYSTEM_DOMAIN_H_ 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #ifdef KERNEL_PRIVATE 38 | #include 39 | #endif /* KERNEL_PRIVATE */ 40 | 41 | /* Kernel Events Protocol */ 42 | #define SYSPROTO_EVENT 1 /* kernel events protocol */ 43 | 44 | /* Kernel Control Protocol */ 45 | #define SYSPROTO_CONTROL 2 /* kernel control protocol */ 46 | #define AF_SYS_CONTROL 2 /* corresponding sub address type */ 47 | 48 | /* System family socket address */ 49 | struct sockaddr_sys { 50 | u_char ss_len; /* sizeof(struct sockaddr_sys) */ 51 | u_char ss_family; /* AF_SYSTEM */ 52 | u_int16_t ss_sysaddr; /* protocol address in AF_SYSTEM */ 53 | u_int32_t ss_reserved[7]; /* reserved to the protocol use */ 54 | }; 55 | 56 | #ifdef PRIVATE 57 | struct xsystmgen { 58 | u_int32_t xg_len; /* length of this structure */ 59 | u_int32_t xg_count; /* number of PCBs at this time */ 60 | u_int64_t xg_gen; /* generation count at this time */ 61 | u_int64_t xg_sogen; /* current socket generation count */ 62 | }; 63 | #endif /* PRIVATE */ 64 | 65 | #ifdef KERNEL_PRIVATE 66 | 67 | extern struct domain *systemdomain; 68 | 69 | SYSCTL_DECL(_net_systm); 70 | 71 | /* built in system domain protocols init function */ 72 | __BEGIN_DECLS 73 | void kern_event_init(struct domain *); 74 | void kern_control_init(struct domain *); 75 | __END_DECLS 76 | #endif /* KERNEL_PRIVATE */ 77 | 78 | #endif /* _SYSTEM_DOMAIN_H_ */ 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/task.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | get-task-allow 8 | 9 | proc_info-allow 10 | 11 | task_for_pid-allow 12 | 13 | com.apple.private.network.statistics 14 | 15 | com.apple.private.security.sandbox.debug-mode 16 | 17 | com.apple.security.temporary-exception.sbpl 18 | 19 | (allow signal) 20 | (allow process-info-listpids) 21 | (allow process-info*) 22 | 23 | com.apple.security.exception.process-info 24 | 25 | com.apple.system-task-ports 26 | 27 | com.apple.managedconfiguration.profiled-access 28 | 29 | dynamic-codesigning 30 | 31 | com.apple.private.security.no-container 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/xpc/base.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2011 Apple Inc. All rights reserved. 2 | 3 | #ifndef __XPC_BASE_H__ 4 | #define __XPC_BASE_H__ 5 | 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | #if !defined(__has_include) 11 | #define __has_include(x) 0 12 | #endif // !defined(__has_include) 13 | 14 | #if !defined(__has_attribute) 15 | #define __has_attribute(x) 0 16 | #endif // !defined(__has_attribute) 17 | 18 | #if !defined(__has_feature) 19 | #define __has_feature(x) 0 20 | #endif // !defined(__has_feature) 21 | 22 | #if !defined(__has_extension) 23 | #define __has_extension(x) 0 24 | #endif // !defined(__has_extension) 25 | 26 | #if __has_include() 27 | #include 28 | #else // __has_include() 29 | #include 30 | #endif // __has_include() 31 | 32 | #if XPC_SERVICE_MAIN_IN_LIBXPC 33 | #define XPC_HOSTING_OLD_MAIN 1 34 | #else // XPC_SERVICE_MAIN_IN_LIBXPC 35 | #define XPC_HOSTING_OLD_MAIN 0 36 | #endif // XPC_SERVICE_MAIN_IN_LIBXPC 37 | 38 | #ifndef __XPC_INDIRECT__ 39 | #error "Please #include instead of this file directly." 40 | #endif // __XPC_INDIRECT__ 41 | 42 | #pragma mark Attribute Shims 43 | #ifdef __GNUC__ 44 | #define XPC_CONSTRUCTOR __attribute__((constructor)) 45 | #define XPC_NORETURN __attribute__((__noreturn__)) 46 | #define XPC_NOTHROW __attribute__((__nothrow__)) 47 | #define XPC_NONNULL1 __attribute__((__nonnull__(1))) 48 | #define XPC_NONNULL2 __attribute__((__nonnull__(2))) 49 | #define XPC_NONNULL3 __attribute__((__nonnull__(3))) 50 | #define XPC_NONNULL4 __attribute__((__nonnull__(4))) 51 | #define XPC_NONNULL5 __attribute__((__nonnull__(5))) 52 | #define XPC_NONNULL6 __attribute__((__nonnull__(6))) 53 | #define XPC_NONNULL7 __attribute__((__nonnull__(7))) 54 | #define XPC_NONNULL8 __attribute__((__nonnull__(8))) 55 | #define XPC_NONNULL9 __attribute__((__nonnull__(9))) 56 | #define XPC_NONNULL10 __attribute__((__nonnull__(10))) 57 | #define XPC_NONNULL11 __attribute__((__nonnull__(11))) 58 | #define XPC_NONNULL_ALL __attribute__((__nonnull__)) 59 | #define XPC_SENTINEL __attribute__((__sentinel__)) 60 | #define XPC_PURE __attribute__((__pure__)) 61 | #define XPC_WARN_RESULT __attribute__((__warn_unused_result__)) 62 | #define XPC_MALLOC __attribute__((__malloc__)) 63 | #define XPC_UNUSED __attribute__((__unused__)) 64 | #define XPC_USED __attribute__((__used__)) 65 | #define XPC_PACKED __attribute__((__packed__)) 66 | #define XPC_PRINTF(m, n) __attribute__((format(printf, m, n))) 67 | #define XPC_INLINE static __inline__ __attribute__((__always_inline__)) 68 | #define XPC_NOINLINE __attribute__((noinline)) 69 | #define XPC_NOIMPL __attribute__((unavailable)) 70 | 71 | #if __has_extension(attribute_unavailable_with_message) 72 | #define XPC_UNAVAILABLE(m) __attribute__((unavailable(m))) 73 | #else // __has_extension(attribute_unavailable_with_message) 74 | #define XPC_UNAVAILABLE(m) XPC_NOIMPL 75 | #endif // __has_extension(attribute_unavailable_with_message) 76 | 77 | #define XPC_EXPORT extern __attribute__((visibility("default"))) 78 | #define XPC_NOEXPORT __attribute__((visibility("hidden"))) 79 | #define XPC_WEAKIMPORT extern __attribute__((weak_import)) 80 | #define XPC_DEBUGGER_EXCL XPC_NOEXPORT XPC_USED 81 | #define XPC_TRANSPARENT_UNION __attribute__((transparent_union)) 82 | #if __clang__ 83 | #define XPC_DEPRECATED(m) __attribute__((deprecated(m))) 84 | #else // __clang__ 85 | #define XPC_DEPRECATED(m) __attribute__((deprecated)) 86 | #endif // __clang 87 | 88 | #if __has_feature(objc_arc) 89 | #define XPC_GIVES_REFERENCE __strong 90 | #define XPC_UNRETAINED __unsafe_unretained 91 | #define XPC_BRIDGE(xo) ((__bridge void *)(xo)) 92 | #define XPC_BRIDGEREF_BEGIN(xo) ((__bridge_retained void *)(xo)) 93 | #define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) ((__bridge void *)(xo)) 94 | #define XPC_BRIDGEREF_MIDDLE(xo) ((__bridge id)(xo)) 95 | #define XPC_BRIDGEREF_END(xo) ((__bridge_transfer id)(xo)) 96 | #else // __has_feature(objc_arc) 97 | #define XPC_GIVES_REFERENCE 98 | #define XPC_UNRETAINED 99 | #define XPC_BRIDGE(xo) 100 | #define XPC_BRIDGEREF_BEGIN(xo) (xo) 101 | #define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) (xo) 102 | #define XPC_BRIDGEREF_MIDDLE(xo) (xo) 103 | #define XPC_BRIDGEREF_END(xo) (xo) 104 | #endif // __has_feature(objc_arc) 105 | 106 | #define _xpc_unreachable() __builtin_unreachable() 107 | #else // __GNUC__ 108 | /*! @parseOnly */ 109 | #define XPC_CONSTRUCTOR 110 | /*! @parseOnly */ 111 | #define XPC_NORETURN 112 | /*! @parseOnly */ 113 | #define XPC_NOTHROW 114 | /*! @parseOnly */ 115 | #define XPC_NONNULL1 116 | /*! @parseOnly */ 117 | #define XPC_NONNULL2 118 | /*! @parseOnly */ 119 | #define XPC_NONNULL3 120 | /*! @parseOnly */ 121 | #define XPC_NONNULL4 122 | /*! @parseOnly */ 123 | #define XPC_NONNULL5 124 | /*! @parseOnly */ 125 | #define XPC_NONNULL6 126 | /*! @parseOnly */ 127 | #define XPC_NONNULL7 128 | /*! @parseOnly */ 129 | #define XPC_NONNULL8 130 | /*! @parseOnly */ 131 | #define XPC_NONNULL9 132 | /*! @parseOnly */ 133 | #define XPC_NONNULL10 134 | /*! @parseOnly */ 135 | #define XPC_NONNULL11 136 | /*! @parseOnly */ 137 | #define XPC_NONNULL(n) 138 | /*! @parseOnly */ 139 | #define XPC_NONNULL_ALL 140 | /*! @parseOnly */ 141 | #define XPC_SENTINEL 142 | /*! @parseOnly */ 143 | #define XPC_PURE 144 | /*! @parseOnly */ 145 | #define XPC_WARN_RESULT 146 | /*! @parseOnly */ 147 | #define XPC_MALLOC 148 | /*! @parseOnly */ 149 | #define XPC_UNUSED 150 | /*! @parseOnly */ 151 | #define XPC_PACKED 152 | /*! @parseOnly */ 153 | #define XPC_PRINTF(m, n) 154 | /*! @parseOnly */ 155 | #define XPC_INLINE static inline 156 | /*! @parseOnly */ 157 | #define XPC_NOINLINE 158 | /*! @parseOnly */ 159 | #define XPC_NOIMPL 160 | /*! @parseOnly */ 161 | #define XPC_EXPORT extern 162 | /*! @parseOnly */ 163 | #define XPC_WEAKIMPORT 164 | /*! @parseOnly */ 165 | #define XPC_DEPRECATED 166 | /*! @parseOnly */ 167 | #define XPC_UNAVAILABLE(m) 168 | #endif // __GNUC__ 169 | 170 | __END_DECLS 171 | 172 | #endif // __XPC_BASE_H__ 173 | -------------------------------------------------------------------------------- /src/xpc/xpc.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2011 Apple Inc. All rights reserved. 2 | 3 | #ifndef __XPC_H__ 4 | #define __XPC_H__ 5 | 6 | //#include "xpc/base.h" 7 | 8 | typedef void *xpc_object_t; 9 | typedef void *xpc_pipe_t; 10 | typedef void *xpc_connection_t; 11 | 12 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 13 | //XPC_EXPORT XPC_NONNULL1 14 | void 15 | xpc_release(xpc_object_t object); 16 | 17 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 18 | //XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL_ALL 19 | xpc_connection_t 20 | xpc_dictionary_get_remote_connection(xpc_object_t xdict); 21 | 22 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 23 | //XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 24 | const char * 25 | xpc_connection_get_name(xpc_connection_t connection); 26 | 27 | //XPC_EXPORT XPC_MALLOC XPC_WARN_RESULT XPC_NONNULL1 28 | char* xpc_copy_description(xpc_object_t object); 29 | 30 | 31 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 32 | //XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT 33 | xpc_object_t 34 | xpc_dictionary_create(const char * const *keys, const xpc_object_t *values, size_t count); 35 | 36 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 37 | //XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 38 | void 39 | xpc_dictionary_set_uint64(xpc_object_t xdict, const char *key, uint64_t value); 40 | 41 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 42 | //XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 43 | void 44 | xpc_dictionary_set_fd(xpc_object_t xdict, const char *key, int fd); 45 | 46 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 47 | //XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL_ALL 48 | int64_t 49 | xpc_dictionary_get_int64(xpc_object_t xdict, const char *key); 50 | 51 | __attribute__((weak_import)) 52 | xpc_pipe_t xpc_pipe_create(const char *name, uint64_t flags); 53 | 54 | __attribute__((weak_import)) 55 | void xpc_pipe_invalidate(xpc_pipe_t pipe); 56 | 57 | __attribute__((weak_import)) 58 | int xpc_pipe_routine(xpc_pipe_t pipe, xpc_object_t message, xpc_object_t *reply); 59 | 60 | // struct _os_alloc_once_s { 61 | // long once; 62 | // u_int64_t *ptr; 63 | // }; 64 | 65 | // extern struct _os_alloc_once_s _os_alloc_once_table[]; 66 | 67 | extern mach_port_t bootstrap_port; 68 | 69 | xpc_pipe_t xpc_pipe_create_from_port(mach_port_t port, int flags); 70 | 71 | #endif // __XPC_H__ 72 | --------------------------------------------------------------------------------
Threads are displayed with the following color coding: 31 | ■ - a thread is currently running. 32 | ■ - a thread is waiting on I/O in a system call (uninterruptible). 33 | ■ - a thread is halted or stopped. 34 | ■ - a thread is suspended. 35 | ■ - a thread is idle (sleeping). 36 | ■ - thread state is unknown. 37 |
A small 'i' in thread state column indicates that the thread is running an idle loop (used for putting a CPU core into 39 | sleep mode). Such threads can be seen in the kernel task.
Open file descriptors are displayed with the following color coding: 46 | ■ - this is a regular file. 47 | ■ - this is a network socket (TCP or UDP). 48 | ■ - this is a UNIX pipe. 49 | ■ - this is a UNIX socket or a kernel queue. 50 | ■ - this is a kernel control descriptor. 51 | ■ - this is a kernel event descriptor. 52 |
Open ports are displayed with the following color coding: 59 | ■ - this port has SEND and RECEIVE rights. 60 | ■ - this port has a RECEIVE right. 61 | ■ - this port has a SEND right. 62 |
Loaded modules are displayed with the following color coding: 69 | ■ - this module is loaded from a .dylib file. Mapped size and reference count are provided. 70 | ■ - this module is loaded from the dynamic library cache – a large file 71 | where all built-in system libraries (private and public) are combined to improve performance. 72 |
★ Domo (the original author)
★ SongXiaoXi aka SXX (iOS 13 support and lots of improvements)
★ Randomblock1 aka Benjamin G. (automatic .deb package assembly)
★ @DylanDuff3 (application icon)
Hello, friends!
This text should clarify some questionable concepts implemented in CocoaTop, the ideas behind those concepts, 24 | and the idea behind the application itself. Also, it should be a fun read, at least for some ;)
Before we begin I would like to thank Luis Finke for making miniCode 26 | (available in Cydia) – a nice alternative to XCode that became an IDE for my first iOS app, which is also my first 27 | Objective C app. (Hey, if you think I typed the whole thing on the iPad, you're wrong. I even used 28 | Theos, goddamit, okay! But that's not the point!
Update: One of the most controversial topics concerning CocoaTop was the icon ;) . The original one, which I drew myself rather 30 | hastily, became the target of criticism on almost every forum or blog, not excluding Chinese, Korean, or some Hindu ones. 31 | That's when @DylanDuff3 kindly offered me his own version of the icon, which is 32 | used currently.
Now, you could say that the purpose of CocoaTop is to replace the original terminal 'top' 34 | – but it is not. First of all, the UNIX terminal is a thing in itself: every iPad user has to have a terminal 35 | installed, otherwise (s)he can be mistaken for a dork, or worse – a humanitarian. Also, 'top' executed on an iPad 36 | always attracts people's attention. So the idea behind CocoaTop is this: I wanted to create something nice, 37 | gaining knowledge in the process. If you find it useful, well, you're in luck!
While working on CocoaTop I found a book, a site, 39 | and a forum by a man named Jonathan Levin. I don't know how I managed to overlook this hilarious stuff. It gave me 40 | a great inspiration boost, not to mention loads of bad-quality source code to ponder on. Thanks to Jonathan's in-depth 41 | coverage of hidden and undocumented APIs this version of CocoaTop features real-time per-process network statistics! 42 | Also, if you're into console utilities & SSH, try his Process 43 | Explorer for iOS and Mac OS X.
Ok, on to the fun facts:
★ CPU usage sums up not to 100% but to cores×100%. Moreover, it can actually exceed this value, and it surely 46 | will when the cores are doing the real stuff: protein folding and shit like that. CPU exceeds 100% not for your amusement, 47 | but due to a scheduling policy of the Mach Kernel, which is called decay-usage scheduling. When a thread acquires CPU 48 | time, its priority is continually being depressed: this ensures short response times of interactive jobs, which 49 | do not always have a high initial priority, especially on weaker mobile platforms. The decayed CPU usage of a running 50 | thread increases in a linearly proportional fashion with CPU time obtained, and is periodically divided by the decay 51 | factor, which is a constant larger than one. Thus, the Mach CPU utilization of the process is a decaying average over 52 | up to a minute of previous (real) time. Since the time base over which this is computed varies (since processes may be 53 | very young) it is possible for the sum of all %CPU fields to exceed 100%. And this is why Android sucks. Also, because 54 | of Java, which isn't bad by itself, but... the mobile world?
Update: You may have noticed that on older versions of CocoaTop the kernel task (pid 0) took 56 | up a lot of %CPU, in fact it took up all unused CPU power. This is because for every CPU core there's a kernel thread which 57 | halts the core when it's not used to save battery life, effectively eating up remaining CPU cycles. You can actually find 58 | these threads when you switch to process details, thread mode: they will have a small 'i' for 'idle' in the state column. 59 | Newer versions of CocoaTop no longer include there threads in kernel CPU usage. Unfortunately, on 64-bit devices information 60 | on kernel threads is substantially limited.
★ Everyone knows about processes, but what about Mach tasks? These are actually different things. In fact, it is 62 | technically possible to create a Mach task without a BSD process. A Mach task can actually be created without threads 63 | and memory (ah, the benefits of The Microkernel, my love). Mach tasks do not have parent-child relationships, those are 64 | implemented at the BSD level. This implies that BSD (or, generally, POSIX) has more morale, but not really. In UNIX, it 65 | is actually the norm for the parent to outlive its children. Furthermore, a parent actually expects their children to die, 66 | otherwise they rise as zombies. This is why I love pure microkernels.
Update: A barebone task cannot be created in iOS usermode, because the corresponding API task_create() 68 | is removed. But the underlying kernel function task_create_internal() still exists and creates a task 69 | when a BSD process is launched.
★ You can kill processes by swiping to the left, but this seems cruel. One thing I would really prefer is killing 71 | zombies, but not sure if that fits with the iOS philosophy.
Update: Actually, a zombie is not a process, but rather just a kernel entry for a process which no longer exists. 73 | So you can't kill it. The only reason for keeping it is to remind a parent process of a child's previous existence and save 74 | any bits of data left over by the child, i.e. an exit code. When the parent process finally collects these data (or dies), 75 | the zombie disappears.
★ There's no such thing as a running process, because it is the threads that run, not processes. So why is there a 77 | 'Process running' state? Well, this is done to simplify the output, and actually taken from the original 'top' source 78 | code. Most process states are calculated from thread states using a simple rule of precedence: i.e. if at least one thread 79 | is running, the process state is presumed 'R', and so on. The complete list is provided in the column info: 80 | just tap (i) at the 'Process state' item while managing columns.
★ There is also a column called 'Mach Actual Threads Priority'. What it actually contains is the highest priority of 82 | a thread within the process. This is also the way original 'top' works. Also, there are several scheduling schemes 83 | supported by Mach, but only one of them is actually used in iOS – 'Time Sharing'. The other two, 'Round-Robin' 84 | and 'FIFO', will be marked in this column using prefixes R: and F: respectively, but I've never seen them. I added 85 | those marks out of curiosity - write me a letter.
Update: Round-robin scheduling is actually used for certain threads throughout the OS, especially kernel threads. 87 | In fact, all kernel threads default to the round-robin scheme: see for yourself! (If you're lucky to see kernel task details)
★ Apple tightens up security with each new version of iOS, so CocoaTop can no longer show details about task 0 89 | (the kernel task) on iOS 8. You can still enjoy this data if you have iOS 7! Actually, the iOS could be considered the 90 | most secure public platform of all times, only if it wasn't so stuffed with backdoors, at least in v.7 ;) Anyway, 91 | it's better than the other non-evil company ;)
Update: It seems that details about the kernel task are available on some platforms, while absent on others. 93 | Maybe this depends on the jailbreak method used. I'm glad to inform you that this info is once more available on some devices 94 | running iOS 9!
★ There's a 'Mach Task Role' column which actually shows the assigned role for GUI apps, like in OS X. I've noticed 96 | this works only on iOS 8+.