2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
33 * This routine simulates
38 * It is a demo program which does the copy by memory mapping each of the
39 * files and then doing a byte at a time memory copy.
51 #include <sys/types.h>
53 #include <sys/fcntl.h>
61 off_t len; /* length of file 1 */
63 int print_flags_set = 1;
65 typedef struct fflag {
66 int arg; /* != 0 if ars specified */
67 int value; /* flags value */
71 typedef enum ftype { /* flag bit types */
72 FL_MAP, FL_PROT, FL_OPEN, FL_MAX
75 typedef struct mfile {
76 fflag_t flags[FL_MAX];
88 #define FLAG(symbol,type) { # symbol , symbol, type }
96 FLAG(O_RDONLY, FL_OPEN),
97 FLAG(O_WRONLY, FL_OPEN),
98 FLAG(O_RDWR, FL_OPEN),
99 FLAG(O_NDELAY, FL_OPEN),
100 FLAG(O_NONBLOCK, FL_OPEN),
101 FLAG(O_APPEND, FL_OPEN),
102 FLAG(O_SYNC, FL_OPEN),
103 FLAG(O_TRUNC, FL_OPEN),
104 FLAG(O_CREAT, FL_OPEN),
105 FLAG(O_DIRECT, FL_OPEN),
106 FLAG(PROT_NONE, FL_PROT),
107 FLAG(PROT_READ, FL_PROT),
108 FLAG(PROT_WRITE, FL_PROT),
109 FLAG(PROT_EXEC, FL_PROT),
111 FLAG(PROT_EXECUTE, FL_PROT),
113 FLAG(MAP_SHARED, FL_MAP),
114 FLAG(MAP_PRIVATE, FL_MAP),
115 FLAG(MAP_FIXED, FL_MAP),
117 FLAG(MAP_RENAME, FL_MAP),
118 FLAG(MAP_AUTOGROW, FL_MAP),
119 FLAG(MAP_LOCAL, FL_MAP),
120 FLAG(MAP_AUTORESRV, FL_MAP),
122 FLAG(MAP_NONE, FL_MAP),
125 int num_Flags = sizeof(Flags)/sizeof(Flags[0]);
128 mfile_t *ifile, *ofile;
129 mfile_t *hfile; /* Hack job */
132 static mfile_t *new_mfile(void);
133 static int mfile_opt(char * s, mfile_t * f);
134 static void print_flags(char *s, mfile_t *f);
135 static void Usage(void);
137 main(int argc, char * argv[])
141 if ((Progname = strrchr(argv[0], '/')) == NULL)
149 if (ifile == NULL || ofile == NULL || hfile == NULL) {
150 fprintf(stderr,"%s: malloc failure.\n", Progname);
154 /* Set default flags */
155 ifile->flags[FL_MAP].value = MAP_PRIVATE;
156 ifile->flags[FL_PROT].value = PROT_READ;
157 ifile->flags[FL_OPEN].value = O_RDONLY;
158 ofile->flags[FL_MAP].value = MAP_SHARED;
160 ofile->flags[FL_MAP].value = MAP_AUTOGROW;
162 ofile->flags[FL_PROT].value = PROT_WRITE;
163 ofile->flags[FL_OPEN].value = O_RDWR|O_CREAT;
165 while ((opt = getopt(argc, argv, "i:o:h:d")) != EOF) {
168 if (mfile_opt(optarg, ifile) != 0) {
169 fprintf(stderr, "%s: Invalid -i option %s\n",
176 if (mfile_opt(optarg, ofile) != 0) {
177 fprintf(stderr, "%s: Invalid -o option %s\n",
184 if (mfile_opt(optarg, hfile) != 0) {
185 fprintf(stderr, "%s: Invalid -h option %s\n",
193 print_flags_set ^= 1;
203 ifile->path = argv[optind++];
204 ofile->path = argv[optind++];
206 if (optind != argc) /* Extra args on command line */
209 if (stat(ifile->path, &(ifile->st)) < 0) {
210 fprintf(stderr,"%s: stat of %s failed.\n",
211 Progname, ifile->path);
216 len = ifile->st.st_size;
218 ifile->fd = open(ifile->path, ifile->flags[FL_OPEN].value);
220 fprintf(stderr,"%s: cannot open %s\n", Progname, ifile->path);
226 ofile->fd = open(ofile->path, ofile->flags[FL_OPEN].value, 0644);
228 fprintf(stderr,"%s: cannot open %s\n", Progname, ofile->path);
233 if (print_flags_set) {
234 print_flags("Input ", ifile);
235 print_flags("Output", ofile);
237 print_flags("Hack ", hfile);
241 ifile->p = mmap(NULL, len, ifile->flags[FL_PROT].value,
242 ifile->flags[FL_MAP].value, ifile->fd, 0);
243 if (ifile->p == MAP_FAILED) {
244 fprintf(stderr,"%s: cannot mmap %s\n", Progname, ifile->path);
249 ofile->p = mmap(NULL, len, ofile->flags[FL_PROT].value,
250 ofile->flags[FL_MAP].value , ofile->fd, 0);
251 if (ofile->p == MAP_FAILED) {
252 fprintf(stderr,"%s: cannot mmap %s\n", Progname, ofile->path);
260 error = mprotect(ofile->p, len, hfile->flags[FL_PROT].value);
262 fprintf(stderr,"%s: mprotect call failed.\n", Progname);
268 bcopy(ifile->p, ofile->p, len);
270 printf("%s complete.\n", Progname);
277 mfile_t *ptr = (mfile_t *)malloc(sizeof(*ptr));
279 bzero(ptr, sizeof *ptr);
286 mfile_opt(char * s, mfile_t *f)
291 for (i = 0; i < num_Flags; i++) {
292 if(!strcasecmp(Flags[i].name, s)) {
294 /* Zero value if this is 1st arg of this type */
296 type = Flags[i].type;
297 if (f->flags[type].arg++ == 0)
298 f->flags[type].value = 0;
299 f->flags[type].value |= Flags[i].value;
303 return -1; /* error - string not found */
312 "Usage: %s [-d] [-i flag] [-i flag] [-o flag] ... file1 file2\n",
314 fprintf(stderr, "Valid flag values are:\n");
316 for (i = 0; i < num_Flags; i++) {
317 fprintf(stderr,"%15s",Flags[i].name);
318 if ((i+1)%4 == 0 || i == num_Flags-1)
319 fprintf(stderr,"\n");
327 print_flags(char *s, mfile_t *f)
332 printf("DEBUG - %s flags:\n", s);
333 for (i = 0; i < num_Flags; i++) {
334 type = Flags[i].type;
335 if (type == FL_OPEN && Flags[i].value == O_RDONLY &&
336 ((f->flags[type].value) & 3) == 0)
337 /* Hack to print out O_RDONLY */
338 printf("\t%s\n", Flags[i].name);
339 else if ((Flags[i].value & (f->flags[type].value)) != 0)
340 printf("\t%s\n", Flags[i].name);