aboutsummaryrefslogtreecommitdiff
path: root/Foundation/GTMTimeUtils.m
blob: 2b551e415c2d6089fad4e5769290822bc0ea4364 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//
//  GTMTimeUtils.m
//
//  Copyright 2018 Google LLC
//
//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
//  use this file except in compliance with the License.  You may obtain a copy
//  of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
//  License for the specific language governing permissions and limitations under
//  the License.
//

#import "GTMTimeUtils.h"

#include <sys/sysctl.h>

#import "GTMDefines.h"

NSTimeInterval GTMTimeValToNSTimeInterval(struct timeval time) {
  return time.tv_sec + (time.tv_usec / (double)USEC_PER_SEC);
}

struct timeval GTMBootTimeRelativeTo1970(void) {
  struct timeval bootTime = { 0, 0 };
  int mib[2] = { CTL_KERN, KERN_BOOTTIME };
  size_t bootTimeSize = sizeof(bootTime);
  if (sysctl(mib, 2, &bootTime, &bootTimeSize, NULL, 0) != 0) {
    _GTMDevAssert(errno == 0, @"sysctl error - %d", errno);
    struct timeval invalid = { 0, 0 };
    return invalid;
  }
  return bootTime;
}

struct timeval GTMAppLaunchTimeRelativeTo1970(void) {
  id_t pid = getpid();
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid };
  const size_t mibSize = sizeof(mib) / sizeof(mib[0]);
  size_t infoSize = 0;

  // Get initial size of KERN_PROC data structure.
  if (sysctl(mib, mibSize, NULL, &infoSize, NULL, 0) != 0) {
    _GTMDevAssert(errno == 0, @"sysctl error - %d", errno);
    struct timeval invalid = { 0, 0 };
    return invalid;
  }
  struct kinfo_proc info;
  if (sysctl(mib, mibSize, &info, &infoSize, NULL, 0) != 0) {
    _GTMDevAssert(errno == 0, @"sysctl error - %d", errno);
    struct timeval invalid = { 0, 0 };
    return invalid;
  }
  return info.kp_proc.p_starttime;
}

NSDate *GTMAppLaunchDate() {
  NSTimeInterval ti =
      GTMTimeValToNSTimeInterval(GTMAppLaunchTimeRelativeTo1970());
  return [NSDate dateWithTimeIntervalSince1970:ti];
}

NSDate *GTMBootDate() {
  NSTimeInterval ti =
      GTMTimeValToNSTimeInterval(GTMBootTimeRelativeTo1970());
  return [NSDate dateWithTimeIntervalSince1970:ti];
}