/* $XFree86: xc/programs/Xserver/hw/xfree86/etc/mmapw.c,v 1.4 2003/04/24 15:20:41 tsi Exp $ */ /* * Copyright 2002 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of Marc Aurele La France not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Marc Aurele La France makes no representations * about the suitability of this software for any purpose. It is provided * "as-is" without express or implied warranty. * * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #define _LARGEFILE_SOURCE 1 #define _FILE_OFFSET_BITS 64 #undef __STRICT_ANSI__ #include #include #include #include #include #include #include #include #include #ifndef MAP_FAILED # define MAP_FAILED ((void *)(-1)) #endif #if defined(_SCO_DS) && !defined(_SCO_DS_LL) #define strtoull (unsigned long long)strtoul #endif #if !defined(strtoull) && \ (defined(CSRG_BASED) || \ (defined(__GNU_LIBRARY__) && \ (__GNU_LIBRARY__ < 6))) # define strtoull strtouq #endif static unsigned char datab; static unsigned short dataw; static unsigned int datal; static unsigned long dataL; static unsigned long long dataq; static void usage(void) { fprintf(stderr, "\n" "mmapw [-{bwlqL}] \n\n" "endianness flags:\n\n" " -b write one byte\n" " -w write two aligned bytes\n" " -l write four aligned bytes (default)\n" " -q write eight aligned bytes\n"); switch (sizeof(dataL)) { case sizeof(datab): fprintf(stderr, " -L same as -b\n\n"); break; case sizeof(dataw): fprintf(stderr, " -L same as -w\n\n"); break; case sizeof(datal): fprintf(stderr, " -L same as -l\n\n"); break; case sizeof(dataq): fprintf(stderr, " -L same as -q\n\n"); break; default: fprintf(stderr, "\n"); break; } exit(1); } int main(int argc, char **argv) { unsigned long long data; off_t Offset = 0, offset; size_t length; char *BadString; void *buffer; int fd, pagesize; char size = sizeof(datal); switch (argc) { case 4: break; case 5: if (argv[1][0] != '-') usage(); switch (argv[1][1]) { case 'b': size = sizeof(datab); break; case 'w': size = sizeof(dataw); break; case 'l': size = sizeof(datal); break; case 'L': size = sizeof(dataL); break; case 'q': size = sizeof(dataq); break; default: usage(); } if (argv[1][2]) usage(); argc--; argv++; break; default: usage(); } BadString = (char *)0; Offset = strtoull(argv[2], &BadString, 0); if (errno || (BadString && *BadString) || (Offset & (size - 1))) usage(); BadString = (char *)0; data = strtoull(argv[3], &BadString, 0); if (errno || (BadString && *BadString)) usage(); if ((fd = open(argv[1], O_RDWR)) < 0) { fprintf(stderr, "mmapr: Unable to open \"%s\": %s.\n", argv[1], strerror(errno)); exit(1); } pagesize = getpagesize(); offset = Offset & (off_t)(-pagesize); length = ((Offset + size + pagesize - 1) & (off_t)(-pagesize)) - offset; buffer = mmap((caddr_t)0, length, PROT_WRITE, MAP_SHARED, fd, offset); close(fd); if (buffer == MAP_FAILED) { fprintf(stderr, "mmapr: Unable to mmap \"%s\": %s.\n", argv[1], strerror(errno)); exit(1); } Offset -= offset; if (size == sizeof(datab)) *(volatile unsigned char *)((char *)buffer + Offset) = (unsigned char)data; else if (size == sizeof(dataw)) *(volatile unsigned short *)((char *)buffer + Offset) = (unsigned short)data; else if (size == sizeof(datal)) *(volatile unsigned int *)((char *)buffer + Offset) = (unsigned int)data; else if (size == sizeof(dataL)) *(volatile unsigned long *)((char *)buffer + Offset) = (unsigned long)data; else if (size == sizeof(dataq)) *(volatile unsigned long long *)((char *)buffer + Offset) = (unsigned long long)data; munmap(buffer, length); return 0; }