2 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * This routine simulates
24 * It is a demo program which does the copy by memory mapping each of the
25 * files and then doing a byte at a time memory copy.
37 #include <sys/types.h>
39 #include <sys/fcntl.h>
48 off_t len; /* length of file 1 */
50 int print_flags_set = 1;
52 typedef struct fflag {
53 int arg; /* != 0 if ars specified */
54 int value; /* flags value */
58 typedef enum ftype { /* flag bit types */
59 FL_MAP, FL_PROT, FL_OPEN, FL_MAX
62 typedef struct mfile {
63 fflag_t flags[FL_MAX];
75 #define FLAG(symbol,type) { # symbol , symbol, type }
83 FLAG(O_RDONLY, FL_OPEN),
84 FLAG(O_WRONLY, FL_OPEN),
85 FLAG(O_RDWR, FL_OPEN),
86 FLAG(O_NDELAY, FL_OPEN),
87 FLAG(O_NONBLOCK, FL_OPEN),
88 FLAG(O_APPEND, FL_OPEN),
89 FLAG(O_SYNC, FL_OPEN),
90 FLAG(O_TRUNC, FL_OPEN),
91 FLAG(O_CREAT, FL_OPEN),
92 FLAG(O_DIRECT, FL_OPEN),
93 FLAG(PROT_NONE, FL_PROT),
94 FLAG(PROT_READ, FL_PROT),
95 FLAG(PROT_WRITE, FL_PROT),
96 FLAG(PROT_EXEC, FL_PROT),
98 FLAG(PROT_EXECUTE, FL_PROT),
100 FLAG(MAP_SHARED, FL_MAP),
101 FLAG(MAP_PRIVATE, FL_MAP),
102 FLAG(MAP_FIXED, FL_MAP),
104 FLAG(MAP_RENAME, FL_MAP),
105 FLAG(MAP_AUTOGROW, FL_MAP),
106 FLAG(MAP_LOCAL, FL_MAP),
107 FLAG(MAP_AUTORESRV, FL_MAP),
109 FLAG(MAP_NONE, FL_MAP),
112 int num_Flags = sizeof(Flags)/sizeof(Flags[0]);
115 mfile_t *ifile, *ofile;
116 mfile_t *hfile; /* Hack job */
119 static mfile_t *new_mfile(void);
120 static int mfile_opt(char * s, mfile_t * f);
121 static void print_flags(char *s, mfile_t *f);
122 static void Usage(void);
125 main(int argc, char * argv[])
129 Progname = strrchr(argv[0], '/');
130 if (Progname == NULL)
138 if (ifile == NULL || ofile == NULL || hfile == NULL) {
139 fprintf(stderr,"%s: malloc failure.\n", Progname);
143 /* Set default flags */
144 ifile->flags[FL_MAP].value = MAP_PRIVATE;
145 ifile->flags[FL_PROT].value = PROT_READ;
146 ifile->flags[FL_OPEN].value = O_RDONLY;
147 ofile->flags[FL_MAP].value = MAP_SHARED;
149 ofile->flags[FL_MAP].value = MAP_AUTOGROW;
151 ofile->flags[FL_PROT].value = PROT_WRITE;
152 ofile->flags[FL_OPEN].value = O_RDWR|O_CREAT;
154 while ((opt = getopt(argc, argv, "i:o:h:d")) != EOF) {
157 if (mfile_opt(optarg, ifile) != 0) {
158 fprintf(stderr, "%s: Invalid -i option %s\n",
165 if (mfile_opt(optarg, ofile) != 0) {
166 fprintf(stderr, "%s: Invalid -o option %s\n",
173 if (mfile_opt(optarg, hfile) != 0) {
174 fprintf(stderr, "%s: Invalid -h option %s\n",
182 print_flags_set ^= 1;
192 ifile->path = argv[optind++];
193 ofile->path = argv[optind++];
195 if (optind != argc) /* Extra args on command line */
198 if (stat(ifile->path, &(ifile->st)) < 0) {
199 fprintf(stderr,"%s: stat of %s failed.\n",
200 Progname, ifile->path);
205 len = ifile->st.st_size;
207 ifile->fd = open(ifile->path, ifile->flags[FL_OPEN].value);
209 fprintf(stderr,"%s: cannot open %s\n", Progname, ifile->path);
215 ofile->fd = open(ofile->path, ofile->flags[FL_OPEN].value, 0644);
217 fprintf(stderr,"%s: cannot open %s\n", Progname, ofile->path);
222 if (print_flags_set) {
223 print_flags("Input ", ifile);
224 print_flags("Output", ofile);
226 print_flags("Hack ", hfile);
230 ifile->p = mmap(NULL, len, ifile->flags[FL_PROT].value,
231 ifile->flags[FL_MAP].value, ifile->fd, 0);
232 if (ifile->p == MAP_FAILED) {
233 fprintf(stderr,"%s: cannot mmap %s\n", Progname, ifile->path);
238 ofile->p = mmap(NULL, len, ofile->flags[FL_PROT].value,
239 ofile->flags[FL_MAP].value , ofile->fd, 0);
240 if (ofile->p == MAP_FAILED) {
241 fprintf(stderr,"%s: cannot mmap %s\n", Progname, ofile->path);
249 error = mprotect(ofile->p, len, hfile->flags[FL_PROT].value);
251 fprintf(stderr,"%s: mprotect call failed.\n", Progname);
257 bcopy(ifile->p, ofile->p, len);
259 printf("%s complete.\n", Progname);
266 mfile_t *ptr = (mfile_t *)malloc(sizeof(*ptr));
268 bzero(ptr, sizeof *ptr);
275 mfile_opt(char * s, mfile_t *f)
280 for (i = 0; i < num_Flags; i++) {
281 if(!strcasecmp(Flags[i].name, s)) {
283 /* Zero value if this is 1st arg of this type */
285 type = Flags[i].type;
286 if (f->flags[type].arg++ == 0)
287 f->flags[type].value = 0;
288 f->flags[type].value |= Flags[i].value;
292 return -1; /* error - string not found */
301 "Usage: %s [-d] [-i flag] [-i flag] [-o flag] ... file1 file2\n",
303 fprintf(stderr, "Valid flag values are:\n");
305 for (i = 0; i < num_Flags; i++) {
306 fprintf(stderr,"%15s",Flags[i].name);
307 if ((i+1)%4 == 0 || i == num_Flags-1)
308 fprintf(stderr,"\n");
316 print_flags(char *s, mfile_t *f)
321 printf("DEBUG - %s flags:\n", s);
322 for (i = 0; i < num_Flags; i++) {
323 type = Flags[i].type;
324 if (type == FL_OPEN && Flags[i].value == O_RDONLY &&
325 ((f->flags[type].value) & 3) == 0)
326 /* Hack to print out O_RDONLY */
327 printf("\t%s\n", Flags[i].name);
328 else if ((Flags[i].value & (f->flags[type].value)) != 0)
329 printf("\t%s\n", Flags[i].name);