1*d1e4d7ceSDavid van Moolenbroek /* $NetBSD: time.c,v 1.20 2013/07/16 17:47:43 christos Exp $ */
2*d1e4d7ceSDavid van Moolenbroek
3*d1e4d7ceSDavid van Moolenbroek /*-
4*d1e4d7ceSDavid van Moolenbroek * Copyright (c) 1980, 1991, 1993
5*d1e4d7ceSDavid van Moolenbroek * The Regents of the University of California. All rights reserved.
6*d1e4d7ceSDavid van Moolenbroek *
7*d1e4d7ceSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
8*d1e4d7ceSDavid van Moolenbroek * modification, are permitted provided that the following conditions
9*d1e4d7ceSDavid van Moolenbroek * are met:
10*d1e4d7ceSDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
11*d1e4d7ceSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
12*d1e4d7ceSDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
13*d1e4d7ceSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
14*d1e4d7ceSDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
15*d1e4d7ceSDavid van Moolenbroek * 3. Neither the name of the University nor the names of its contributors
16*d1e4d7ceSDavid van Moolenbroek * may be used to endorse or promote products derived from this software
17*d1e4d7ceSDavid van Moolenbroek * without specific prior written permission.
18*d1e4d7ceSDavid van Moolenbroek *
19*d1e4d7ceSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*d1e4d7ceSDavid van Moolenbroek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*d1e4d7ceSDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*d1e4d7ceSDavid van Moolenbroek * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*d1e4d7ceSDavid van Moolenbroek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*d1e4d7ceSDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*d1e4d7ceSDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*d1e4d7ceSDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*d1e4d7ceSDavid van Moolenbroek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*d1e4d7ceSDavid van Moolenbroek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*d1e4d7ceSDavid van Moolenbroek * SUCH DAMAGE.
30*d1e4d7ceSDavid van Moolenbroek */
31*d1e4d7ceSDavid van Moolenbroek
32*d1e4d7ceSDavid van Moolenbroek #include <sys/cdefs.h>
33*d1e4d7ceSDavid van Moolenbroek #ifndef lint
34*d1e4d7ceSDavid van Moolenbroek #if 0
35*d1e4d7ceSDavid van Moolenbroek static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 5/31/93";
36*d1e4d7ceSDavid van Moolenbroek #else
37*d1e4d7ceSDavid van Moolenbroek __RCSID("$NetBSD: time.c,v 1.20 2013/07/16 17:47:43 christos Exp $");
38*d1e4d7ceSDavid van Moolenbroek #endif
39*d1e4d7ceSDavid van Moolenbroek #endif /* not lint */
40*d1e4d7ceSDavid van Moolenbroek
41*d1e4d7ceSDavid van Moolenbroek #ifndef NOT_CSH
42*d1e4d7ceSDavid van Moolenbroek #include <sys/types.h>
43*d1e4d7ceSDavid van Moolenbroek #include <stdarg.h>
44*d1e4d7ceSDavid van Moolenbroek #include "csh.h"
45*d1e4d7ceSDavid van Moolenbroek #include "extern.h"
46*d1e4d7ceSDavid van Moolenbroek #endif
47*d1e4d7ceSDavid van Moolenbroek #include <util.h>
48*d1e4d7ceSDavid van Moolenbroek
49*d1e4d7ceSDavid van Moolenbroek /*
50*d1e4d7ceSDavid van Moolenbroek * C Shell - routines handling process timing and niceing
51*d1e4d7ceSDavid van Moolenbroek */
52*d1e4d7ceSDavid van Moolenbroek static void pdeltat(FILE *, struct timeval *, struct timeval *);
53*d1e4d7ceSDavid van Moolenbroek static void pcsecs(FILE *, long);
54*d1e4d7ceSDavid van Moolenbroek
55*d1e4d7ceSDavid van Moolenbroek #ifndef NOT_CSH
56*d1e4d7ceSDavid van Moolenbroek void
settimes(void)57*d1e4d7ceSDavid van Moolenbroek settimes(void)
58*d1e4d7ceSDavid van Moolenbroek {
59*d1e4d7ceSDavid van Moolenbroek struct rusage ruch;
60*d1e4d7ceSDavid van Moolenbroek
61*d1e4d7ceSDavid van Moolenbroek (void)clock_gettime(CLOCK_MONOTONIC, &time0);
62*d1e4d7ceSDavid van Moolenbroek (void)getrusage(RUSAGE_SELF, &ru0);
63*d1e4d7ceSDavid van Moolenbroek (void)getrusage(RUSAGE_CHILDREN, &ruch);
64*d1e4d7ceSDavid van Moolenbroek ruadd(&ru0, &ruch);
65*d1e4d7ceSDavid van Moolenbroek }
66*d1e4d7ceSDavid van Moolenbroek
67*d1e4d7ceSDavid van Moolenbroek /*
68*d1e4d7ceSDavid van Moolenbroek * dotime is only called if it is truly a builtin function and not a
69*d1e4d7ceSDavid van Moolenbroek * prefix to another command
70*d1e4d7ceSDavid van Moolenbroek */
71*d1e4d7ceSDavid van Moolenbroek void
72*d1e4d7ceSDavid van Moolenbroek /*ARGSUSED*/
dotime(Char ** v,struct command * t)73*d1e4d7ceSDavid van Moolenbroek dotime(Char **v, struct command *t)
74*d1e4d7ceSDavid van Moolenbroek {
75*d1e4d7ceSDavid van Moolenbroek struct rusage ru1, ruch;
76*d1e4d7ceSDavid van Moolenbroek struct timespec timedol;
77*d1e4d7ceSDavid van Moolenbroek
78*d1e4d7ceSDavid van Moolenbroek (void)getrusage(RUSAGE_SELF, &ru1);
79*d1e4d7ceSDavid van Moolenbroek (void)getrusage(RUSAGE_CHILDREN, &ruch);
80*d1e4d7ceSDavid van Moolenbroek ruadd(&ru1, &ruch);
81*d1e4d7ceSDavid van Moolenbroek (void)clock_gettime(CLOCK_MONOTONIC, &timedol);
82*d1e4d7ceSDavid van Moolenbroek prusage(cshout, &ru0, &ru1, &timedol, &time0);
83*d1e4d7ceSDavid van Moolenbroek }
84*d1e4d7ceSDavid van Moolenbroek
85*d1e4d7ceSDavid van Moolenbroek /*
86*d1e4d7ceSDavid van Moolenbroek * donice is only called when it on the line by itself or with a +- value
87*d1e4d7ceSDavid van Moolenbroek */
88*d1e4d7ceSDavid van Moolenbroek void
89*d1e4d7ceSDavid van Moolenbroek /*ARGSUSED*/
donice(Char ** v,struct command * t)90*d1e4d7ceSDavid van Moolenbroek donice(Char **v, struct command *t)
91*d1e4d7ceSDavid van Moolenbroek {
92*d1e4d7ceSDavid van Moolenbroek Char *cp;
93*d1e4d7ceSDavid van Moolenbroek int nval;
94*d1e4d7ceSDavid van Moolenbroek
95*d1e4d7ceSDavid van Moolenbroek nval = 0;
96*d1e4d7ceSDavid van Moolenbroek v++;
97*d1e4d7ceSDavid van Moolenbroek cp = *v++;
98*d1e4d7ceSDavid van Moolenbroek if (cp == 0)
99*d1e4d7ceSDavid van Moolenbroek nval = 4;
100*d1e4d7ceSDavid van Moolenbroek else if (*v == 0 && any("+-", cp[0]))
101*d1e4d7ceSDavid van Moolenbroek nval = getn(cp);
102*d1e4d7ceSDavid van Moolenbroek (void)setpriority(PRIO_PROCESS, 0, nval);
103*d1e4d7ceSDavid van Moolenbroek }
104*d1e4d7ceSDavid van Moolenbroek
105*d1e4d7ceSDavid van Moolenbroek void
ruadd(struct rusage * ru,struct rusage * ru2)106*d1e4d7ceSDavid van Moolenbroek ruadd(struct rusage *ru, struct rusage *ru2)
107*d1e4d7ceSDavid van Moolenbroek {
108*d1e4d7ceSDavid van Moolenbroek timeradd(&ru->ru_utime, &ru2->ru_utime, &ru->ru_utime);
109*d1e4d7ceSDavid van Moolenbroek timeradd(&ru->ru_stime, &ru2->ru_stime, &ru->ru_stime);
110*d1e4d7ceSDavid van Moolenbroek if (ru2->ru_maxrss > ru->ru_maxrss)
111*d1e4d7ceSDavid van Moolenbroek ru->ru_maxrss = ru2->ru_maxrss;
112*d1e4d7ceSDavid van Moolenbroek
113*d1e4d7ceSDavid van Moolenbroek ru->ru_ixrss += ru2->ru_ixrss;
114*d1e4d7ceSDavid van Moolenbroek ru->ru_idrss += ru2->ru_idrss;
115*d1e4d7ceSDavid van Moolenbroek ru->ru_isrss += ru2->ru_isrss;
116*d1e4d7ceSDavid van Moolenbroek ru->ru_minflt += ru2->ru_minflt;
117*d1e4d7ceSDavid van Moolenbroek ru->ru_majflt += ru2->ru_majflt;
118*d1e4d7ceSDavid van Moolenbroek ru->ru_nswap += ru2->ru_nswap;
119*d1e4d7ceSDavid van Moolenbroek ru->ru_inblock += ru2->ru_inblock;
120*d1e4d7ceSDavid van Moolenbroek ru->ru_oublock += ru2->ru_oublock;
121*d1e4d7ceSDavid van Moolenbroek ru->ru_msgsnd += ru2->ru_msgsnd;
122*d1e4d7ceSDavid van Moolenbroek ru->ru_msgrcv += ru2->ru_msgrcv;
123*d1e4d7ceSDavid van Moolenbroek ru->ru_nsignals += ru2->ru_nsignals;
124*d1e4d7ceSDavid van Moolenbroek ru->ru_nvcsw += ru2->ru_nvcsw;
125*d1e4d7ceSDavid van Moolenbroek ru->ru_nivcsw += ru2->ru_nivcsw;
126*d1e4d7ceSDavid van Moolenbroek }
127*d1e4d7ceSDavid van Moolenbroek #endif /* NOT_CSH */
128*d1e4d7ceSDavid van Moolenbroek
129*d1e4d7ceSDavid van Moolenbroek void
prusage(FILE * fp,struct rusage * r0,struct rusage * r1,struct timespec * e,struct timespec * b)130*d1e4d7ceSDavid van Moolenbroek prusage(FILE *fp, struct rusage *r0, struct rusage *r1, struct timespec *e,
131*d1e4d7ceSDavid van Moolenbroek struct timespec *b)
132*d1e4d7ceSDavid van Moolenbroek {
133*d1e4d7ceSDavid van Moolenbroek #ifndef NOT_CSH
134*d1e4d7ceSDavid van Moolenbroek struct varent *vp;
135*d1e4d7ceSDavid van Moolenbroek #endif
136*d1e4d7ceSDavid van Moolenbroek const char *cp;
137*d1e4d7ceSDavid van Moolenbroek long i;
138*d1e4d7ceSDavid van Moolenbroek time_t t;
139*d1e4d7ceSDavid van Moolenbroek time_t ms;
140*d1e4d7ceSDavid van Moolenbroek
141*d1e4d7ceSDavid van Moolenbroek cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
142*d1e4d7ceSDavid van Moolenbroek ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_nsec - b->tv_nsec) / 10000000;
143*d1e4d7ceSDavid van Moolenbroek t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 +
144*d1e4d7ceSDavid van Moolenbroek (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
145*d1e4d7ceSDavid van Moolenbroek (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 +
146*d1e4d7ceSDavid van Moolenbroek (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
147*d1e4d7ceSDavid van Moolenbroek #ifndef NOT_CSH
148*d1e4d7ceSDavid van Moolenbroek vp = adrof(STRtime);
149*d1e4d7ceSDavid van Moolenbroek
150*d1e4d7ceSDavid van Moolenbroek if (vp && vp->vec[0] && vp->vec[1])
151*d1e4d7ceSDavid van Moolenbroek cp = short2str(vp->vec[1]);
152*d1e4d7ceSDavid van Moolenbroek #endif
153*d1e4d7ceSDavid van Moolenbroek
154*d1e4d7ceSDavid van Moolenbroek for (; *cp; cp++)
155*d1e4d7ceSDavid van Moolenbroek if (*cp != '%')
156*d1e4d7ceSDavid van Moolenbroek (void) fputc(*cp, fp);
157*d1e4d7ceSDavid van Moolenbroek else if (cp[1])
158*d1e4d7ceSDavid van Moolenbroek switch (*++cp) {
159*d1e4d7ceSDavid van Moolenbroek case 'D': /* (average) unshared data size */
160*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", t == 0 ? 0L :
161*d1e4d7ceSDavid van Moolenbroek (long)((r1->ru_idrss + r1->ru_isrss -
162*d1e4d7ceSDavid van Moolenbroek (r0->ru_idrss + r0->ru_isrss)) / t));
163*d1e4d7ceSDavid van Moolenbroek break;
164*d1e4d7ceSDavid van Moolenbroek case 'E': /* elapsed (wall-clock) time */
165*d1e4d7ceSDavid van Moolenbroek pcsecs(fp, (long) ms);
166*d1e4d7ceSDavid van Moolenbroek break;
167*d1e4d7ceSDavid van Moolenbroek case 'F': /* page faults */
168*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_majflt - r0->ru_majflt);
169*d1e4d7ceSDavid van Moolenbroek break;
170*d1e4d7ceSDavid van Moolenbroek case 'I': /* FS blocks in */
171*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_inblock - r0->ru_inblock);
172*d1e4d7ceSDavid van Moolenbroek break;
173*d1e4d7ceSDavid van Moolenbroek case 'K': /* (average) total data memory used */
174*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", t == 0 ? 0L :
175*d1e4d7ceSDavid van Moolenbroek (long)(((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) -
176*d1e4d7ceSDavid van Moolenbroek (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t));
177*d1e4d7ceSDavid van Moolenbroek break;
178*d1e4d7ceSDavid van Moolenbroek case 'M': /* max. Resident Set Size */
179*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_maxrss / 2L);
180*d1e4d7ceSDavid van Moolenbroek break;
181*d1e4d7ceSDavid van Moolenbroek case 'O': /* FS blocks out */
182*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_oublock - r0->ru_oublock);
183*d1e4d7ceSDavid van Moolenbroek break;
184*d1e4d7ceSDavid van Moolenbroek case 'P': /* percent time spent running */
185*d1e4d7ceSDavid van Moolenbroek /* check if it did not run at all */
186*d1e4d7ceSDavid van Moolenbroek if (ms == 0) {
187*d1e4d7ceSDavid van Moolenbroek (void)fputs("0.0%", fp);
188*d1e4d7ceSDavid van Moolenbroek } else {
189*d1e4d7ceSDavid van Moolenbroek char pb[32];
190*d1e4d7ceSDavid van Moolenbroek (void)fputs(strpct(pb, sizeof(pb),
191*d1e4d7ceSDavid van Moolenbroek (uintmax_t)t, (uintmax_t)ms, 1), fp);
192*d1e4d7ceSDavid van Moolenbroek (void)fputc('%', fp);
193*d1e4d7ceSDavid van Moolenbroek }
194*d1e4d7ceSDavid van Moolenbroek break;
195*d1e4d7ceSDavid van Moolenbroek case 'R': /* page reclaims */
196*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_minflt - r0->ru_minflt);
197*d1e4d7ceSDavid van Moolenbroek break;
198*d1e4d7ceSDavid van Moolenbroek case 'S': /* system CPU time used */
199*d1e4d7ceSDavid van Moolenbroek pdeltat(fp, &r1->ru_stime, &r0->ru_stime);
200*d1e4d7ceSDavid van Moolenbroek break;
201*d1e4d7ceSDavid van Moolenbroek case 'U': /* user CPU time used */
202*d1e4d7ceSDavid van Moolenbroek pdeltat(fp, &r1->ru_utime, &r0->ru_utime);
203*d1e4d7ceSDavid van Moolenbroek break;
204*d1e4d7ceSDavid van Moolenbroek case 'W': /* number of swaps */
205*d1e4d7ceSDavid van Moolenbroek i = r1->ru_nswap - r0->ru_nswap;
206*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", i);
207*d1e4d7ceSDavid van Moolenbroek break;
208*d1e4d7ceSDavid van Moolenbroek case 'X': /* (average) shared text size */
209*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", t == 0 ? 0L :
210*d1e4d7ceSDavid van Moolenbroek (long)((r1->ru_ixrss - r0->ru_ixrss) / t));
211*d1e4d7ceSDavid van Moolenbroek break;
212*d1e4d7ceSDavid van Moolenbroek case 'c': /* num. involuntary context switches */
213*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_nivcsw - r0->ru_nivcsw);
214*d1e4d7ceSDavid van Moolenbroek break;
215*d1e4d7ceSDavid van Moolenbroek case 'k': /* number of signals received */
216*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_nsignals-r0->ru_nsignals);
217*d1e4d7ceSDavid van Moolenbroek break;
218*d1e4d7ceSDavid van Moolenbroek case 'r': /* socket messages received */
219*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_msgrcv - r0->ru_msgrcv);
220*d1e4d7ceSDavid van Moolenbroek break;
221*d1e4d7ceSDavid van Moolenbroek case 's': /* socket messages sent */
222*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_msgsnd - r0->ru_msgsnd);
223*d1e4d7ceSDavid van Moolenbroek break;
224*d1e4d7ceSDavid van Moolenbroek case 'w': /* num. voluntary context switches (waits) */
225*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", r1->ru_nvcsw - r0->ru_nvcsw);
226*d1e4d7ceSDavid van Moolenbroek break;
227*d1e4d7ceSDavid van Moolenbroek }
228*d1e4d7ceSDavid van Moolenbroek (void)fputc('\n', fp);
229*d1e4d7ceSDavid van Moolenbroek }
230*d1e4d7ceSDavid van Moolenbroek
231*d1e4d7ceSDavid van Moolenbroek static void
pdeltat(FILE * fp,struct timeval * t1,struct timeval * t0)232*d1e4d7ceSDavid van Moolenbroek pdeltat(FILE *fp, struct timeval *t1, struct timeval *t0)
233*d1e4d7ceSDavid van Moolenbroek {
234*d1e4d7ceSDavid van Moolenbroek struct timeval td;
235*d1e4d7ceSDavid van Moolenbroek
236*d1e4d7ceSDavid van Moolenbroek timersub(t1, t0, &td);
237*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld.%01ld", (long)td.tv_sec,
238*d1e4d7ceSDavid van Moolenbroek (long)(td.tv_usec / 100000));
239*d1e4d7ceSDavid van Moolenbroek }
240*d1e4d7ceSDavid van Moolenbroek
241*d1e4d7ceSDavid van Moolenbroek #define P2DIG(fp, i) (void)fprintf(fp, "%ld%ld", (i) / 10, (i) % 10)
242*d1e4d7ceSDavid van Moolenbroek
243*d1e4d7ceSDavid van Moolenbroek #ifndef NOT_CSH
244*d1e4d7ceSDavid van Moolenbroek void
psecs(long l)245*d1e4d7ceSDavid van Moolenbroek psecs(long l)
246*d1e4d7ceSDavid van Moolenbroek {
247*d1e4d7ceSDavid van Moolenbroek long i;
248*d1e4d7ceSDavid van Moolenbroek
249*d1e4d7ceSDavid van Moolenbroek i = l / 3600;
250*d1e4d7ceSDavid van Moolenbroek if (i) {
251*d1e4d7ceSDavid van Moolenbroek (void)fprintf(cshout, "%ld:", i);
252*d1e4d7ceSDavid van Moolenbroek i = l % 3600;
253*d1e4d7ceSDavid van Moolenbroek P2DIG(cshout, i / 60);
254*d1e4d7ceSDavid van Moolenbroek goto minsec;
255*d1e4d7ceSDavid van Moolenbroek }
256*d1e4d7ceSDavid van Moolenbroek i = l;
257*d1e4d7ceSDavid van Moolenbroek (void)fprintf(cshout, "%ld", i / 60);
258*d1e4d7ceSDavid van Moolenbroek minsec:
259*d1e4d7ceSDavid van Moolenbroek i %= 60;
260*d1e4d7ceSDavid van Moolenbroek (void)fputc(':', cshout);
261*d1e4d7ceSDavid van Moolenbroek P2DIG(cshout, i);
262*d1e4d7ceSDavid van Moolenbroek }
263*d1e4d7ceSDavid van Moolenbroek #endif
264*d1e4d7ceSDavid van Moolenbroek
265*d1e4d7ceSDavid van Moolenbroek static void
pcsecs(FILE * fp,long l)266*d1e4d7ceSDavid van Moolenbroek pcsecs(FILE *fp, long l) /* PWP: print mm:ss.dd, l is in sec*100 */
267*d1e4d7ceSDavid van Moolenbroek {
268*d1e4d7ceSDavid van Moolenbroek long i;
269*d1e4d7ceSDavid van Moolenbroek
270*d1e4d7ceSDavid van Moolenbroek i = l / 360000;
271*d1e4d7ceSDavid van Moolenbroek if (i) {
272*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld:", i);
273*d1e4d7ceSDavid van Moolenbroek i = (l % 360000) / 100;
274*d1e4d7ceSDavid van Moolenbroek P2DIG(fp, i / 60);
275*d1e4d7ceSDavid van Moolenbroek goto minsec;
276*d1e4d7ceSDavid van Moolenbroek }
277*d1e4d7ceSDavid van Moolenbroek i = l / 100;
278*d1e4d7ceSDavid van Moolenbroek (void)fprintf(fp, "%ld", i / 60);
279*d1e4d7ceSDavid van Moolenbroek minsec:
280*d1e4d7ceSDavid van Moolenbroek i %= 60;
281*d1e4d7ceSDavid van Moolenbroek (void)fputc(':', fp);
282*d1e4d7ceSDavid van Moolenbroek P2DIG(fp, i);
283*d1e4d7ceSDavid van Moolenbroek (void)fputc('.', fp);
284*d1e4d7ceSDavid van Moolenbroek P2DIG(fp, (l % 100));
285*d1e4d7ceSDavid van Moolenbroek }
286