wht@tridom.uucp (Warren Tucker) (12/12/89)
This is a shared memory dump utility for System V. The compilation instructions for machines I've tested it on are in the source header and the usage can be obtained by running the program without arguments. This posting is related to a discussion of shared memory currently ongoing in comp.unix.wizards. #!/bin/sh # This is shmdump, a shell archive (shar 3.04) # made 12/12/1989 07:15 UTC by gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu) # Source directory /u1/src/src # # existing files will NOT be overwritten # # This shar contains: # shmdump.c # touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$ if [ -s /tmp/s3_touch$$ ] then TOUCH=can else TOUCH=cannot fi rm -f /tmp/s3_touch$$ if test -f shmdump.c; then echo "File shmdump.c exists"; else echo "x - extracting shmdump.c (Text)" sed 's/^X//' << 'SHAR_EOF' > shmdump.c && X/* CHK=0xE884 */ X/*+------------------------------------------------------------------------- X shmdump.c X ...gatech!kd4nc!n4hgf!wht (free to use as you please) X X Defined functions: X hex_dump(str,len) X hex_dump16(int16) X hex_dump32(int32) X hex_dump4(int4) X hex_dump8(int8) X main(argc,argv,envp) X str_to_INT32(str) X usage() X XSCO XENIX 286: cc -DLINT_ARGS -M2le shmdump.c -o shmdump XSCO U/X 386: cc -DLINT_ARGS shmdump.c -o shmdump XISC: cc shmdump.c -o shmdump XPyramid: att cc shmdump.c -o shmdump X X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:12-12-1989-01:50-wht-creation */ X X#include <stdio.h> X#include <ctype.h> X#include <signal.h> X#include <fcntl.h> X#include <sys/types.h> X#include <sys/ipc.h> X#include <sys/shm.h> X X#ifndef UINT8 X#define UINT8 unsigned char X#define INT8 char X#define UINT16 unsigned short X#define INT16 long X#define UINT32 unsigned long X#define INT32 long X#define UINT unsigned int X#endif X X#if defined(M_I286) X#define BIGPTR INT8 far * X#else X#define BIGPTR INT8 * X#endif X X#if defined(LINT_ARGS) Xint msgctl(int,int,struct msqid_ds *); Xint msgget(INT32 /* key_t */,int); Xint msgsnd(int,struct msgbuf *,int,int); Xint msgrcv(int,struct msgbuf *,int,INT32,int); Xint semctl(int,int,int,); Xint semget(INT32 /* key_t */,int,int); Xint semop(int,struct sembuf *,int); Xint shmctl(int,int,struct shmid_ds *); Xint shmget(INT32 /* key_t */,int,int); XBIGPTR shmat(int,BIGPTR ,int); Xint shmdt(char *); X#else XBIGPTR shmat(); X#endif X Xkey_t shmkey; Xint shmid; XBIGPTR shmaddr; X#if !defined(M_I286) Xint addr32 = 0; X#endif X XBIGPTR sbrk(); X X/*+------------------------------------------------------------------------- X usage() X--------------------------------------------------------------------------*/ Xvoid Xusage() X{ X fprintf(stderr,"dump shared memory segment\n"); X fprintf(stderr,"usage: shmdump [-f <offset>] [-l <len>] [-k] <ident>\n"); X fprintf(stderr,"where <ident> is a shared memory segment id, unless -k\n"); X fprintf(stderr,"is specified, in which case <ident> is a key.\n"); X fprintf(stderr,"-f (first), -l (length) allow partial dumps.\n"); X fprintf(stderr,"numeric params are decimal unless prefixed with '0x'.\n"); X exit(1); X} /* end of usage */ X X/*+------------------------------------------------------------------------- X str_to_INT32(str) X--------------------------------------------------------------------------*/ XINT32 Xstr_to_INT32(str) Xchar *str; X{ X INT32 ltmp; X X if(!strncmp(str,"0x",2)) X sscanf(str + 2,"%lx",<mp); X else X sscanf(str,"%ld",<mp); X return(ltmp); X X} /* end of str_to_INT32 */ X X/*+----------------------------------------------------------------------- X hex_dump#... subservient routines X------------------------------------------------------------------------*/ X#define dump_putc(ch) fputc((ch),stdout) X#define dump_puts(str) fputs(str,stdout) Xvoid Xhex_dump4(int4) XUINT8 int4; X{ X int4 &= 15; X dump_putc((int4 >= 10) ? (int4 + 'A' - 10) : (int4 + '0')); X} X Xvoid Xhex_dump8(int8) XUINT8 int8; X{ X hex_dump4(int8 >> 4); X hex_dump4(int8); X} X Xvoid Xhex_dump16(int16) XUINT16 int16; X{ X hex_dump8(int16 >> 8); X hex_dump8(int16); X} X Xvoid Xhex_dump32(int32) XUINT32 int32; X{ X hex_dump16((UINT16)(int32 >> 16)); X hex_dump16((UINT16)int32); X} X X/*+----------------------------------------------------------------- X hex_dump(str,len,offset) X------------------------------------------------------------------*/ Xvoid Xhex_dump(str,len,offset) XUINT8 *str; XUINT len; XUINT offset; X{ X register UINT itmp; X register UINT istr = 0; X X while(istr < len) X { X#if !defined(M_I286) X if(addr32) X hex_dump32(istr + offset); X else X#endif X hex_dump16(istr + offset); X X if(offset) X { X dump_putc('('); X hex_dump16(offset); X dump_putc(')'); X } X dump_putc(' '); X for(itmp = 0; itmp < 16; ++itmp) X { X dump_putc(' '); X if(istr + itmp >= len) X { X dump_putc(' '); X dump_putc(' '); X continue; X } X hex_dump8(str[istr + itmp]); X } X dump_puts(" | "); X for(itmp = 0; itmp < 16; ++itmp) X { X register char dchar; X if(istr + itmp >= len) X dump_putc(' '); X else X { X dchar = str[istr + itmp] & 0x7F; X dump_putc(((dchar >= ' ') && (dchar < 0x7f)) ? dchar : '.' ); X } X } X dump_puts(" |\n"); X istr += 16; X } /* end of while(istr < len) */ X X} /* end of hex_dump */ X X/*+------------------------------------------------------------------------- X main(argc,argv,envp) X--------------------------------------------------------------------------*/ Xmain(argc,argv,envp) Xint argc; Xchar **argv; Xchar **envp; X{ Xregister UINT first = 0; Xregister UINT len = 0; XUINT shmlen; Xint iargv; Xint posarg = 0; Xint key_flag = 0; XINT32 pos_ltmp; Xstruct shmid_ds sds; X X if(argc == 1) X usage(); X X for(iargv = 1; iargv < argc; iargv++) X { X if(*argv[iargv] == '-') X { X switch(*(argv[iargv] + 1)) X { X case 'k': /* pos arg is key, not id */ X key_flag++; X break; X case 'f': X first = str_to_INT32(argv[iargv] + 2); X break; X case 'l': X len = str_to_INT32(argv[iargv] + 2); X break; X default: X usage(); X } X } X else X { X switch(posarg++) X { X case 0: X pos_ltmp = str_to_INT32(argv[iargv]); X break; X default: X usage(); X } X } X } X X if(key_flag) X { X shmkey = pos_ltmp; X if((shmid = shmget(shmkey,0,0)) < 0) X { X perror("shmget"); X exit(1); X } X } X else X shmid = (int)pos_ltmp; X X if((shmaddr = shmat(shmid,(BIGPTR)0,SHM_RDONLY)) == (BIGPTR)-1) X { X perror("shmat"); X exit(1); X } X if(shmctl(shmid,IPC_STAT,&sds)) X { X perror("shmctl"); X exit(1); X } X X shmkey = sds.shm_perm.key; X printf(" id: %d key: %08lx size: %u (%04x) nattach: %d creator pid: %d\n", X shmid,sds.shm_perm.key,sds.shm_segsz,sds.shm_segsz, X sds.shm_nattch - 1, /* do not include this program */ X sds.shm_cpid); X X printf(" addresess: attach=%lx, sbrk()=%lx stack=%lx\n", X shmaddr,sbrk(0),&argv); X X#if !defined(M_I286) X if(sds.shm_segsz > 0xFFFF) X addr32 = 1; X#endif X X if(first > (UINT)sds.shm_segsz) X { X fprintf(stderr,"-f value > size of segment\n"); X exit(1); X } X if((len == 0) || (len > (UINT)sds.shm_segsz - first)) X len = (UINT)sds.shm_segsz - first; X X hex_dump(shmaddr,len,first); X exit(0); X} /* end of main */ SHAR_EOF chmod 0644 shmdump.c || echo "restore of shmdump.c fails" if [ $TOUCH = can ] then touch -m 1212021489 shmdump.c fi fi exit 0 -- ------------------------------------------------------------------ Warren Tucker, Tridom Corporation ...!gatech!emory!tridom!wht home address: ...!gatech!kd4nc!n4hgf!wht