test-suite-pull-tools-directly-in-20020114
[openafs.git] / src / tests / xf_profile.c
1 /*
2  * CMUCS AFStools
3  * dumpscan - routines for scanning and manipulating AFS volume dumps
4  *
5  * Copyright (c) 1998 Carnegie Mellon University
6  * All Rights Reserved.
7  * 
8  * Permission to use, copy, modify and distribute this software and its
9  * documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie Mellon
26  * the rights to redistribute these changes.
27  */
28
29 /* xf_profile.c - XFILE routines for read/write profiling */
30
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <fcntl.h>
36 #include <errno.h>
37
38 #include "xfiles.h"
39 #include "xf_errs.h"
40
41 #define O_MODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
42
43 typedef struct {
44   XFILE content;
45   XFILE profile;
46 } PFILE;
47
48
49 /* do_read for profiled xfiles */
50 static afs_uint32 xf_PROFILE_do_read(XFILE *X, void *buf, afs_uint32 count)
51 {
52   PFILE *PF = X->refcon;
53   afs_uint32 err;
54
55   err = xfread(&PF->content, buf, count);
56   xfprintf(&PF->profile, "R %ld =%ld\n", (long)count, (long)err);
57   return err;
58 }
59
60
61 /* do_write for profiled xfiles */
62 static afs_uint32 xf_PROFILE_do_write(XFILE *X, void *buf, afs_uint32 count)
63 {
64   PFILE *PF = X->refcon;
65   afs_uint32 err;
66
67   err = xfwrite(&PF->content, buf, count);
68   xfprintf(&PF->profile, "W %ld =%ld\n", (long)count, (long)err);
69   return err;
70 }
71
72
73 /* do_tell for profiled xfiles */
74 static afs_uint32 xf_PROFILE_do_tell(XFILE *X, u_int64 *offset)
75 {
76   PFILE *PF = X->refcon;
77   afs_uint32 err;
78
79   err = xftell(&PF->content, offset);
80   if (err) xfprintf(&PF->profile, "TELL ERR =%ld\n", (long)err);
81   else     xfprintf(&PF->profile, "TELL %s =0\n", hexify_int64(offset, 0));
82   return err;
83 }
84
85
86 /* do_seek for profiled xfiles */
87 static afs_uint32 xf_PROFILE_do_seek(XFILE *X, u_int64 *offset)
88 {
89   PFILE *PF = X->refcon;
90   afs_uint32 err;
91
92   err = xfseek(&PF->content, offset);
93   xfprintf(&PF->profile, "SEEK %s =%ld\n", hexify_int64(offset, 0), (long)err);
94   return err;
95 }
96
97
98 /* do_skip for profiled xfiles */
99 static afs_uint32 xf_PROFILE_do_skip(XFILE *X, afs_uint32 count)
100 {
101   PFILE *PF = X->refcon;
102   afs_uint32 err;
103
104   err = xfskip(&PF->content, count);
105   xfprintf(&PF->profile, "SKIP %ld =%ld\n", (long)count, (long)err);
106   return err;
107 }
108
109
110 /* do_close for profiled xfiles */
111 static afs_uint32 xf_PROFILE_do_close(XFILE *X)
112 {
113   PFILE *PF = X->refcon;
114   afs_uint32 err, err2;
115
116   err = xfclose(&PF->content);
117   err2 = xfclose(&PF->profile);
118   free(PF);
119   return err ? err : err2;
120 }
121
122
123 /* Open a profiled XFILE */
124 afs_uint32 xfopen_profile(XFILE *X, int flag, char *xname, char *profile)
125 {
126   PFILE *PF;
127   afs_uint32 err;
128
129   PF = malloc(sizeof(*PF));
130   if (!PF) return ENOMEM;
131   memset(PF, 0, sizeof(*PF));
132
133   err = xfopen(&PF->profile, O_RDWR|O_CREAT|O_TRUNC, profile);
134   if (err) {
135     free(PF);
136     return err;
137   }
138
139   err = xfopen(&PF->content, flag, xname);
140   if (err) {
141     xfclose(&PF->profile);
142     free(PF);
143     return err;
144   }
145
146   memset(X, 0, sizeof(*X));
147   X->refcon = PF;
148   X->do_read  = xf_PROFILE_do_read;
149   X->do_write = xf_PROFILE_do_write;
150   X->do_tell  = xf_PROFILE_do_tell;
151   X->do_close = xf_PROFILE_do_close;
152   X->is_writable = PF->content.is_writable;
153   if (PF->content.is_seekable) {
154     X->is_seekable;
155     X->do_seek  = xf_PROFILE_do_seek;
156     X->do_skip  = xf_PROFILE_do_skip;
157   }
158   xfprintf(&PF->profile, "OPEN %s\n", xname);
159   return 0;
160 }
161
162
163 afs_uint32 xfon_profile(XFILE *X, int flag, char *name)
164 {
165   char *x, *profile, *xname;
166   afs_uint32 err;
167
168   if (!(name = strdup(name))) return ENOMEM;
169
170   profile = "-";
171   xname = name;
172   for (x = name; *x; x++) {
173     if (x[0] == ':' && x[1] == ':') {
174       *x = 0;
175       profile = name;
176       xname = x + 2;
177       break;
178     }
179   }
180   if (!*name) profile = "-";
181   err = xfopen_profile(X, flag, xname, profile);
182   free(name);
183   return err;
184 }