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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.3 */ 31 32 /* 33 * acctprc 34 * reads std. input (acct.h format), 35 * writes std. output (tacct format) 36 * sorted by uid 37 * adds login names 38 */ 39 40 #include <stdio.h> 41 #include <sys/types.h> 42 #include <sys/param.h> 43 #include "acctdef.h" 44 #include <sys/acct.h> 45 #include <string.h> 46 #include <search.h> 47 48 struct acct ab; 49 struct ptmp pb; 50 struct tacct tb; 51 52 struct utab { 53 uid_t ut_uid; 54 char ut_name[NSZ]; 55 float ut_cpu[2]; /* cpu time (mins) */ 56 float ut_kcore[2]; /* kcore-mins */ 57 long ut_pc; /* # processes */ 58 } * ub; 59 static usize; 60 char *strncpy(); 61 void **root = NULL; 62 63 main() 64 { 65 long elaps[2]; 66 ulong_t etime, stime; 67 unsigned long mem; 68 #ifdef uts 69 float expand(); 70 #else 71 ulong_t expand(); 72 #endif 73 74 while (fread(&ab, sizeof(ab), 1, stdin) == 1) { 75 if (!MYKIND(ab.ac_flag)) 76 continue; 77 pb.pt_uid = ab.ac_uid; 78 CPYN(pb.pt_name, NULL); 79 /* 80 * approximate cpu P/NP split as same as elapsed time 81 */ 82 if ((etime = SECS(expand(ab.ac_etime))) == 0) 83 etime = 1; 84 stime = expand(ab.ac_stime) + expand(ab.ac_utime); 85 mem = expand(ab.ac_mem); 86 if(pnpsplit(ab.ac_btime, etime, elaps) == 0) { 87 fprintf(stderr, "acctprc: could not calculate prime/non-prime hours\n"); 88 89 exit(1); 90 } 91 pb.pt_cpu[0] = (double)stime * (double)elaps[0] / etime; 92 pb.pt_cpu[1] = (stime > pb.pt_cpu[0])? stime - pb.pt_cpu[0] : 0; 93 pb.pt_cpu[1] = stime - pb.pt_cpu[0]; 94 if (stime) 95 pb.pt_mem = (mem + stime - 1) / stime; 96 else 97 pb.pt_mem = 0; /* unlikely */ 98 enter(&pb); 99 } 100 output(); 101 exit(0); 102 } 103 104 int node_compare(const void *node1, const void *node2) 105 { 106 if (((const struct utab *)node1)->ut_uid > \ 107 ((const struct utab *)node2)->ut_uid) 108 return(1); 109 else if (((const struct utab *)node1)->ut_uid < \ 110 ((const struct utab *)node2)->ut_uid) 111 return(-1); 112 else return(0); 113 } 114 115 enter(p) 116 register struct ptmp *p; 117 { 118 double memk; 119 struct utab **pt; 120 121 if ((ub = (struct utab *)malloc(sizeof (struct utab))) == NULL) { 122 fprintf(stderr, "acctprc: malloc fail!\n"); 123 exit(2); 124 } 125 126 ub->ut_uid = p->pt_uid; 127 CPYN(ub->ut_name, p->pt_name); 128 ub->ut_cpu[0] = MINT(p->pt_cpu[0]); 129 ub->ut_cpu[1] = MINT(p->pt_cpu[1]); 130 memk = KCORE(pb.pt_mem); 131 ub->ut_kcore[0] = memk * MINT(p->pt_cpu[0]); 132 ub->ut_kcore[1] = memk * MINT(p->pt_cpu[1]); 133 ub->ut_pc = 1; 134 135 if (*(pt = (struct utab **)tsearch((void *)ub, (void **)&root, \ 136 node_compare)) == NULL) { 137 fprintf(stderr, "Not enough space available to build tree\n"); 138 exit(1); 139 } 140 141 if (*pt != ub) { 142 (*pt)->ut_cpu[0] += MINT(p->pt_cpu[0]); 143 (*pt)->ut_cpu[1] += MINT(p->pt_cpu[1]); 144 (*pt)->ut_kcore[0] += memk * MINT(p->pt_cpu[0]); 145 (*pt)->ut_kcore[1] += memk * MINT(p->pt_cpu[1]); 146 (*pt)->ut_pc++; 147 free(ub); 148 } 149 } 150 151 void print_node(const void *node, VISIT order, int level) { 152 153 if (order == postorder || order == leaf) { 154 tb.ta_uid = (*(struct utab **)node)->ut_uid; 155 CPYN(tb.ta_name, (char *)uidtonam((*(struct utab **)node)->ut_uid)); 156 tb.ta_cpu[0] = (*(struct utab **)node)->ut_cpu[0]; 157 tb.ta_cpu[1] = (*(struct utab **)node)->ut_cpu[1]; 158 tb.ta_kcore[0] = (*(struct utab **)node)->ut_kcore[0]; 159 tb.ta_kcore[1] = (*(struct utab **)node)->ut_kcore[1]; 160 tb.ta_pc = (*(struct utab **)node)->ut_pc; 161 fwrite(&tb, sizeof(tb), 1, stdout); 162 } 163 } 164 165 output() 166 { 167 twalk((struct utab *)root, print_node); 168 } 169