Mercurial > illumos > onarm
comparison usr/src/cmd/lastcomm/lc_exacct.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
1 /* | |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
5 * Common Development and Distribution License, Version 1.0 only | |
6 * (the "License"). You may not use this file except in compliance | |
7 * with the License. | |
8 * | |
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 * or http://www.opensolaris.org/os/licensing. | |
11 * See the License for the specific language governing permissions | |
12 * and limitations under the License. | |
13 * | |
14 * When distributing Covered Code, include this CDDL HEADER in each | |
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 * If applicable, add the following below this CDDL HEADER, with the | |
17 * fields enclosed by brackets "[]" replaced with your own identifying | |
18 * information: Portions Copyright [yyyy] [name of copyright owner] | |
19 * | |
20 * CDDL HEADER END | |
21 */ | |
22 /* | |
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. | |
24 * Use is subject to license terms. | |
25 */ | |
26 | |
27 #pragma ident "@(#)lc_exacct.c 1.5 05/06/08 SMI" | |
28 | |
29 #include <sys/time.h> | |
30 #include <errno.h> | |
31 #include "lastcomm.h" | |
32 | |
33 /* ARGSUSED1 */ | |
34 static void | |
35 skip_group(ea_file_t *ef, uint_t nobjs) | |
36 { | |
37 ea_object_t curr_obj; | |
38 | |
39 if (ea_previous_object(ef, &curr_obj) == -1) { | |
40 (void) fprintf(stderr, gettext("lastcomm: " | |
41 "corrupted exacct file\n")); | |
42 exit(1); | |
43 } | |
44 } | |
45 | |
46 static int | |
47 ok(int argc, char *argv[], int index, uid_t uid, dev_t tty, char *command) | |
48 { | |
49 int j; | |
50 | |
51 for (j = index; j < argc; j++) | |
52 if (strcmp(getname(uid), argv[j]) && | |
53 strcmp(getdev(tty), argv[j]) && | |
54 strncmp(command, argv[j], fldsiz(acct, ac_comm))) | |
55 break; | |
56 return (j == argc); | |
57 } | |
58 | |
59 static void | |
60 disp_group(ea_file_t *ef, uint_t nobjs, int argc, char *argv[], int index) | |
61 { | |
62 uint_t i; | |
63 char *command = NULL; | |
64 double cpu_usr_secs = 0.; | |
65 double cpu_usr_nsecs = 0.; | |
66 double cpu_sys_secs = 0.; | |
67 double cpu_sys_nsecs = 0.; | |
68 double totalsecs; | |
69 dev_t tty = 0; | |
70 major_t tty_major = 0; | |
71 minor_t tty_minor = 0; | |
72 uid_t uid = 0; | |
73 time_t time = 0; | |
74 uint32_t flag = 0; | |
75 | |
76 for (i = 0; i < nobjs; i++) { | |
77 ea_object_t curr_obj; | |
78 | |
79 if (ea_get_object(ef, &curr_obj) == -1) { | |
80 (void) fprintf(stderr, gettext("lastcomm: " | |
81 "corrupted exacct file\n")); | |
82 exit(1); | |
83 } | |
84 | |
85 switch (curr_obj.eo_catalog) { | |
86 case EXT_STRING | EXC_DEFAULT | EXD_PROC_COMMAND: | |
87 command = curr_obj.eo_item.ei_string; | |
88 break; | |
89 case EXT_UINT32 | EXC_DEFAULT | EXD_PROC_UID: | |
90 uid = curr_obj.eo_item.ei_uint32; | |
91 break; | |
92 case EXT_UINT64 | EXC_DEFAULT | EXD_PROC_CPU_SYS_SEC: | |
93 cpu_sys_secs = curr_obj.eo_item.ei_uint64; | |
94 break; | |
95 case EXT_UINT64 | EXC_DEFAULT | EXD_PROC_CPU_USER_SEC: | |
96 cpu_usr_secs = curr_obj.eo_item.ei_uint64; | |
97 break; | |
98 case EXT_UINT64 | EXC_DEFAULT | EXD_PROC_CPU_SYS_NSEC: | |
99 cpu_sys_nsecs = curr_obj.eo_item.ei_uint64; | |
100 break; | |
101 case EXT_UINT64 | EXC_DEFAULT | EXD_PROC_CPU_USER_NSEC: | |
102 cpu_usr_nsecs = curr_obj.eo_item.ei_uint64; | |
103 break; | |
104 case EXT_UINT32 | EXC_DEFAULT | EXD_PROC_TTY_MAJOR: | |
105 tty_major = curr_obj.eo_item.ei_uint32; | |
106 break; | |
107 case EXT_UINT32 | EXC_DEFAULT | EXD_PROC_TTY_MINOR: | |
108 tty_minor = curr_obj.eo_item.ei_uint32; | |
109 break; | |
110 case EXT_UINT32 | EXC_DEFAULT | EXD_PROC_ACCT_FLAGS: | |
111 flag = curr_obj.eo_item.ei_uint32; | |
112 break; | |
113 case EXT_UINT64 | EXC_DEFAULT | EXD_PROC_START_SEC: | |
114 time = (uint32_t)curr_obj.eo_item.ei_uint64; | |
115 break; | |
116 default: | |
117 break; | |
118 } | |
119 | |
120 if (curr_obj.eo_type == EO_GROUP) | |
121 disp_group(ef, curr_obj.eo_group.eg_nobjs, | |
122 argc, argv, index); | |
123 } | |
124 | |
125 if (command == NULL) { | |
126 (void) fprintf(stderr, gettext("lastcomm: " | |
127 "corrupted exacct file\n")); | |
128 exit(1); | |
129 } | |
130 | |
131 /* | |
132 * If a 64-bit kernel returns a major or minor value that would exceed | |
133 * the capacity of a 32-bit dev_t (and these also become visible in the | |
134 * filesystem), then the 32-bit makedev may be inaccurate and return | |
135 * NODEV. When this occurs, we can remedy the problem by providing | |
136 * either a function which returns "dev64_t"'s or by providing an LP64 | |
137 * version of lastcomm. | |
138 */ | |
139 tty = makedev(tty_major, tty_minor); | |
140 | |
141 /* | |
142 * If this record doesn't match the optional arguments, go on to the | |
143 * next record. | |
144 */ | |
145 if (argc > index && !ok(argc, argv, index, uid, tty, command)) | |
146 return; | |
147 | |
148 totalsecs = | |
149 cpu_usr_secs + cpu_usr_nsecs / NANOSEC + | |
150 cpu_sys_secs + cpu_sys_nsecs / NANOSEC; | |
151 | |
152 (void) printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n", | |
153 fldsiz(acct, ac_comm), fldsiz(acct, ac_comm), command, | |
154 flagbits(flag), NMAX, getname(uid), LMAX, getdev(tty), | |
155 totalsecs, ctime(&time)); | |
156 } | |
157 | |
158 int | |
159 lc_exacct(char *filename, int argc, char *argv[], int index) | |
160 { | |
161 ea_file_t ef; | |
162 ea_object_t curr_obj; | |
163 | |
164 if (ea_open(&ef, filename, EXACCT_CREATOR, | |
165 EO_TAIL | EO_VALID_HDR, O_RDONLY, 0) < 0) { | |
166 switch (ea_error()) { | |
167 case EXR_CORRUPT_FILE: | |
168 (void) fprintf(stderr, gettext("lastcomm: " | |
169 "exacct file corrupted\n")); | |
170 break; | |
171 case EXR_SYSCALL_FAIL: | |
172 (void) fprintf(stderr, gettext("lastcomm: " | |
173 "cannot open %s: %s\n"), filename, | |
174 strerror(errno)); | |
175 break; | |
176 default: | |
177 break; | |
178 } | |
179 | |
180 return (1); | |
181 } | |
182 | |
183 while (ea_previous_object(&ef, &curr_obj) != -1) { | |
184 if (ea_get_object(&ef, &curr_obj) == -1) { | |
185 (void) fprintf(stderr, gettext("lastcomm: " | |
186 "exacct file corrupted\n")); | |
187 exit(1); | |
188 } | |
189 | |
190 /* | |
191 * lc_exacct(), in parsing the extended process accounting file, | |
192 * has knowledge of the fact that process records are top-level | |
193 * records. | |
194 */ | |
195 if ((curr_obj.eo_catalog & EXT_TYPE_MASK) == EXT_GROUP) { | |
196 if (curr_obj.eo_catalog == | |
197 (EXT_GROUP | EXC_DEFAULT | EXD_GROUP_PROC)) | |
198 disp_group(&ef, curr_obj.eo_group.eg_nobjs, | |
199 argc, argv, index); | |
200 else | |
201 skip_group(&ef, curr_obj.eo_group.eg_nobjs); | |
202 } | |
203 | |
204 /* | |
205 * Back up to the head of the object we just consumed. | |
206 */ | |
207 if (ea_previous_object(&ef, &curr_obj) == -1) { | |
208 if (ea_error() == EXR_EOF) | |
209 break; | |
210 | |
211 (void) fprintf(stderr, gettext("lastcomm: " | |
212 "exacct file corrupted\n")); | |
213 exit(1); | |
214 } | |
215 } | |
216 | |
217 if (ea_error() != EXR_EOF) { | |
218 (void) fprintf(stderr, gettext("lastcomm: " | |
219 "exacct file corrupted\n")); | |
220 exit(1); | |
221 } | |
222 | |
223 (void) ea_close(&ef); | |
224 | |
225 return (0); | |
226 } |