1 /* @(#)getrusage.c 1.31 21/07/22 Copyright 1987-2021 J. Schilling */
2 #undef USE_LARGEFILES /* XXX Tempor�rer Hack f�r Solaris */
3 #include <schily/mconfig.h>
4 #ifndef lint
5 static UConst char sccsid[] =
6 "@(#)getrusage.c 1.31 21/07/22 Copyright 1987-2021 J. Schilling";
7 #endif
8 /*
9 * getrusage() emulation for SVr4
10 *
11 * Copyright (c) 1987-2021 J. Schilling
12 */
13 /*
14 * The contents of this file are subject to the terms of the
15 * Common Development and Distribution License, Version 1.0 only
16 * (the "License"). You may not use this file except in compliance
17 * with the License.
18 *
19 * See the file CDDL.Schily.txt in this distribution for details.
20 * A copy of the CDDL is also available via the Internet at
21 * http://www.opensource.org/licenses/cddl1.txt
22 *
23 * When distributing Covered Code, include this CDDL HEADER in each
24 * file and include the License file CDDL.Schily.txt from this distribution.
25 */
26
27 /*
28 * XXX Solaris kann kein 64 bit proc file (LF32)
29 */
30 #undef USE_LARGEFILES /* XXX Tempor�rer Hack f�r Solaris */
31
32 #include <schily/stdio.h>
33 #include "bsh.h"
34 #include <schily/unistd.h>
35 #include <schily/fcntl.h>
36 #include <schily/time.h>
37 #include <schily/resource.h>
38 #include <schily/procfs.h>
39 #include <schily/times.h>
40 #include "limit.h"
41
42
43 /*#undef HAVE_GETRUSAGE*/
44
45 #ifndef HAVE_GETRUSAGE
46 EXPORT int getrusage __PR((int who, struct rusage *rusage));
47 #endif
48
49 #ifndef HAVE_GETRUSAGE
50 /*
51 * XXX who wird nicht untersteutzt!
52 */
53 EXPORT int
getrusage(who,rusage)54 getrusage(who, rusage)
55 int who;
56 struct rusage *rusage;
57 {
58 #if defined(PIOCUSAGE) || _STRUCTURED_PROC == 1
59 int f;
60 char cproc[32];
61 prusage_t prusage;
62 #endif
63 #if _STRUCTURED_PROC == 1
64 pstatus_t pstatus;
65 #endif
66
67 if (rusage)
68 fillbytes((void *)rusage, sizeof (struct rusage), 0);
69
70 #if defined(PIOCUSAGE) || _STRUCTURED_PROC == 1
71 #define DID_RUSAGE
72
73 #if _STRUCTURED_PROC == 1
74 if (who == RUSAGE_CHILDREN)
75 sprintf(cproc, "/proc/%ld/status", (long)getpid());
76 else
77 sprintf(cproc, "/proc/%ld/usage", (long)getpid());
78 if ((f = open(cproc, O_RDONLY)) < 0)
79 return (-1);
80 if (who == RUSAGE_CHILDREN) {
81 if (read(f, &pstatus, sizeof (pstatus)) < 0) {
82 close(f);
83 return (-1);
84 }
85 } else {
86 if (read(f, &prusage, sizeof (prusage)) < 0) {
87 close(f);
88 return (-1);
89 }
90 }
91 #else
92 if (who == RUSAGE_CHILDREN)
93 return (-1);
94 sprintf(cproc, "/proc/%ld", (long)getpid());
95 if ((f = open(cproc, O_RDONLY)) < 0)
96 return (-1);
97 if (ioctl(f, PIOCUSAGE, &prusage) < 0) {
98 close(f);
99 return (-1);
100 }
101 #endif
102 close(f);
103 if (rusage) {
104 #if _STRUCTURED_PROC == 1
105 if (who == RUSAGE_CHILDREN) {
106 rusage->ru_utime.tv_sec = pstatus.pr_cutime.tv_sec;
107 rusage->ru_utime.tv_usec = pstatus.pr_cutime.tv_nsec/1000;
108 rusage->ru_stime.tv_sec = pstatus.pr_cstime.tv_sec;
109 rusage->ru_stime.tv_usec = pstatus.pr_cstime.tv_nsec/1000;
110 return (0);
111 }
112 #endif
113 rusage->ru_utime.tv_sec = prusage.pr_utime.tv_sec;
114 rusage->ru_utime.tv_usec = prusage.pr_utime.tv_nsec/1000;
115 rusage->ru_stime.tv_sec = prusage.pr_stime.tv_sec;
116 rusage->ru_stime.tv_usec = prusage.pr_stime.tv_nsec/1000;
117
118 /* Missing fields: */
119 /* rusage->ru_maxrss = XXX;*/
120 /* rusage->ru_ixrss = XXX;*/
121 /* rusage->ru_idrss = XXX;*/
122 /* rusage->ru_isrss = XXX;*/
123
124 rusage->ru_minflt = prusage.pr_minf;
125 rusage->ru_majflt = prusage.pr_majf;
126 rusage->ru_nswap = prusage.pr_nswap;
127 rusage->ru_inblock = prusage.pr_inblk;
128 rusage->ru_oublock = prusage.pr_oublk;
129 rusage->ru_msgsnd = prusage.pr_msnd;
130 rusage->ru_msgrcv = prusage.pr_mrcv;
131 rusage->ru_nsignals = prusage.pr_sigs;
132 rusage->ru_nvcsw = prusage.pr_vctx;
133 rusage->ru_nivcsw = prusage.pr_ictx;
134 }
135 #endif /* PIOCUSAGE */
136 #if !defined(DID_RUSAGE) && defined(HAVE_TIMES)
137 #define DID_RUSAGE
138 #define NEED_CLOCK2TV
139 {
140 struct tms tms;
141 LOCAL void clock2tv __PR((clock_t t, struct timeval *tp));
142
143 times(&tms);
144
145 if (who == RUSAGE_SELF) {
146 clock2tv(tms.tms_utime, &rusage->ru_utime);
147 clock2tv(tms.tms_stime, &rusage->ru_stime);
148 } else if (who == RUSAGE_CHILDREN) {
149 clock2tv(tms.tms_cutime, &rusage->ru_utime);
150 clock2tv(tms.tms_cstime, &rusage->ru_stime);
151 }
152 }
153 #endif
154 return (0);
155 }
156
157 #ifdef NEED_CLOCK2TV
158 #ifndef HZ
159 #define HZ sysconf(_SC_CLK_TCK)
160 #endif
161
162 LOCAL void
clock2tv(t,tp)163 clock2tv(t, tp)
164 clock_t t;
165 struct timeval *tp;
166 {
167 int _hz = HZ; /* HZ may be a macro to a sysconf() call */
168
169 tp->tv_sec = t / _hz;
170 tp->tv_usec = t % _hz;
171 if (_hz <= 1000000)
172 tp->tv_usec *= 1000000 / _hz;
173 else
174 tp->tv_usec /= _hz / 1000000;
175 }
176 #endif
177
178 #endif /* HAVE_GETRUSAGE */
179