@@ -638,6 +638,113 @@ + (NSString*)descriptionOfPid:(pid_t)pid {
638
638
return answer ;
639
639
}
640
640
641
+ + (NSString *)humanReadableElapsedRunningTimeOfPid : (pid_t )pid {
642
+ NSArray * args = [NSArray arrayWithObjects:
643
+ @" -www" , // Allow 4x the normal column width. Should be enough!!
644
+
645
+ @" -o" , // Print the following column (= means to suppress header line)
646
+ @" etime=" , // elapsed running time
647
+
648
+ @" -p" , // subject pid follows
649
+ [NSString stringWithFormat: @" %ld " , (long )pid],
650
+ nil ] ;
651
+
652
+ NSString * answer = nil ;
653
+ NSData * stdoutData ;
654
+ [SSYShellTasker doShellTaskCommand: @" /bin/ps"
655
+ arguments: args
656
+ inDirectory: nil
657
+ stdinData: nil
658
+ stdoutData_p: &stdoutData
659
+ stderrData_p: NULL
660
+ timeout: 5.0
661
+ error_p: NULL ] ;
662
+ if (stdoutData) {
663
+ NSString * raw = [[NSString alloc ] initWithData: stdoutData
664
+ encoding: NSUTF8StringEncoding];
665
+ /* raw can be one of several forms. Here is what I got in
666
+ macOS 10.14.2, 2018-12-29:
667
+ 02-02:57:50 means 2 days, 2 hours, 57 minutes and 50 seconds
668
+ 19:29 means 19 minutes and 29 seconds
669
+ 00:22 means 0 minutes and 22 seconds */
670
+
671
+ NSString * trimmed = [raw stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet ]];
672
+ [raw release ];
673
+ NSArray * comps = [trimmed componentsSeparatedByString: @" -" ];
674
+ NSString * days;
675
+ NSString * hms;
676
+ if (comps.count > 1 ) {
677
+ days = [comps objectAtIndex: 0 ];
678
+ hms = [comps objectAtIndex: 1 ];
679
+ } else {
680
+ days = nil ;
681
+ hms = [comps objectAtIndex: 0 ];
682
+ }
683
+
684
+ comps = [hms componentsSeparatedByString: @" :" ];
685
+ NSString * hours;
686
+ NSString * minutes;
687
+ NSString * seconds;
688
+ if (comps.count > 2 ) {
689
+ hours = [comps objectAtIndex: 0 ];
690
+ minutes = [comps objectAtIndex: 1 ];
691
+ seconds = [comps objectAtIndex: 0 ];
692
+ } else if (comps.count > 1 ) {
693
+ hours = nil ;
694
+ minutes = [comps objectAtIndex: 0 ];
695
+ seconds = [comps objectAtIndex: 1 ];
696
+ } else {
697
+ hours = nil ;
698
+ minutes = nil ;
699
+ seconds = [comps objectAtIndex: 0 ];
700
+ }
701
+
702
+ if (hours.integerValue == 0 ) {
703
+ /* This branch will never occur with the year 2018 implementation
704
+ of `ps` because 0 hours are omitted. But just in case. */
705
+ hours = nil ;
706
+ }
707
+ if (minutes.integerValue == 0 ) {
708
+ /* This branch *will* occur with the year 2018 implementation
709
+ of `ps` because 0 minutes are returned by `ps` as "00". */
710
+ minutes = nil ;
711
+ }
712
+
713
+ NSMutableString * string = [[NSMutableString alloc ] init ];
714
+ if (days) {
715
+ [string appendString: days];
716
+ [string appendString: @" dayss" ];
717
+ }
718
+ if (hours) {
719
+ if (string.length > 0 ) {
720
+ [string appendString: @" " ];
721
+ }
722
+ [string appendString: hours];
723
+ [string appendString: @" hours" ];
724
+ }
725
+ if (minutes) {
726
+ if (string.length > 0 ) {
727
+ [string appendString: @" " ];
728
+ }
729
+ [string appendString: minutes];
730
+ [string appendString: @" minutes" ];
731
+ }
732
+ if (seconds) {
733
+ if (string.length > 0 ) {
734
+ [string appendString: @" " ];
735
+ }
736
+ [string appendString: seconds];
737
+ [string appendString: @" seconds" ];
738
+ }
739
+
740
+ answer = [string copy ];
741
+ [string release ];
742
+ }
743
+
744
+ [answer autorelease ];
745
+ return answer ;
746
+ }
747
+
641
748
+ (BOOL )isProcessRunningPid : (pid_t )pid
642
749
thisUserOnly : (BOOL )thisUserOnly {
643
750
BOOL answer = NO ;
0 commit comments