/***************************************************
* Creat : 2001. 02. 10 (programed by Cori-Young)
* Site: http://www.byoneself.co.kr
* Update :
***************************************************/
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define MAXnap 4
static ask();
static void catcher();
extern void exit();
static good_addr();
extern void perror();
extern char *shmat();
static struct state{
int shmid;
char *shmaddr;
int shmflg;
} ap[MAXnap];
static int nap;
static jmp_buf segvbuf;
main()
{
register int action;
char *addr;
register int i;
register struct state *p;
void (*savefunc)();
(void) fprintf(stderr, "All numeric input is expected to follow C conventions:n");
(void) fprintf(stderr, "t0x... is interpreted as hexadecimal,n");
(void) fprintf(stderr, "t0... is interpreted as octal,n");
(void) fprintf(stderr, "totherwise, decimal.n");
while (action = ask()) {
if (nap) {
(void) fprintf(stderr, "nCurrently attached segment(s):n");
(void) fprintf(stderr, " shmid addressn");
(void) fprintf(stderr, "------ ----------n");
p = &ap[nap];
while (p-- != ap) {
(void) fprintf(stderr, "%6d", p->shmid);
(void) fprintf(stderr, "%#11x", p->shmaddr);
(void) fprintf(stderr, " Read%sn", (p->shmflg & SHM_RDONLY) ?"-Only" : "/Write");
}
}
else
(void) fprintf(stderr, "nNo segments are currently attached.n");
switch (action) {
case 1:
if (nap == MAXnap) {
(void) fprintf(stderr, "%s %d %sn", "This simple example will only allow", MAXnap, "attached segments.");
break;
}
p = &ap[nap++];
(void) fprintf(stderr,"Enter shmid of segment to attach: ");
(void) scanf("%i", &p->shmid);
(void) fprintf(stderr, "Enter shmaddr: ");
(void) scanf("%i", &p->shmaddr);
(void) fprintf(stderr, "Meaningful shmflg values are:n");
(void) fprintf(stderr, "tSHM_RDONLY = t%#8.8on", SHM_RDONLY);
(void) fprintf(stderr, "tSHM_RND = t%#8.8on", SHM_RND);
(void) fprintf(stderr, "Enter shmflg value: ");
(void) scanf("%i", &p->shmflg);
(void) fprintf(stderr,"shmop: Calling shmat(%d, %#x, %#o)n", p->shmid, p->shmaddr, p->shmflg);
p->shmaddr = shmat(p->shmid, p->shmaddr, p->shmflg);
if(p->shmaddr == (char *)-1) {
perror("shmop: shmat failed");
nap--;
}
else {
(void) fprintf(stderr,"shmop: shmat returned %#8.8xn", p->shmaddr);
}
break;
case 2: /* Shmdt requested. */
(void) fprintf(stderr, "Enter detach shmaddr: ");
(void) scanf("%i", &addr);
i = shmdt(addr);
if(i == -1)
{
perror("shmop: shmdt failed");
}
else {
(void) fprintf(stderr, "shmop: shmdt returned %dn", i);
for (p = ap, i = nap; i--; p++) {
if (p->shmaddr == addr)
*p = ap[--nap];
}
}
break;
case 3: /* Read from segment requested. */
if (nap == 0)
break;
(void) fprintf(stderr, "Enter address of an %s","attached segment: ");
(void) scanf("%i", &addr);
if (good_addr(addr))
(void) fprintf(stderr, "String @ %#x is `%s'n", addr, addr);
break;
case 4: /* Write to segment requested. */
if (nap == 0)
break;
(void) fprintf(stderr, "Enter address of an %s", "attached segment: ");
(void) scanf("%i", &addr);
/* Set up SIGSEGV catch routine to trap attempts to write into a read-only attached segment. */
savefunc = signal(SIGSEGV, catcher);
if (setjmp(segvbuf)) {
(void) fprintf(stderr, "shmop: %s: %sn","SIGSEGV signal caught","Write aborted.");
}
else {
if (good_addr(addr)) {
(void) fflush(stdin);
(void) fprintf(stderr, "%s %s %#x:n", "Enter one line to be copied", "to shared segment attached @",addr);
(void) gets(addr);
}
}
(void) fflush(stdin);
(void) signal(SIGSEGV, savefunc);
break;
}
}
exit(0);
/*NOTREACHED*/
}
static
ask()
{
int response;
do {
(void) fprintf(stderr, "Your options are:n");
(void) fprintf(stderr, "t^D = exitn");
(void) fprintf(stderr, "t 0 = exitn");
(void) fprintf(stderr, "t 1 = shmatn");
(void) fprintf(stderr, "t 2 = shmdtn");
(void) fprintf(stderr, "t 3 = read from segmentn");
(void) fprintf(stderr, "t 4 = write to segmentn");
(void) fprintf(stderr, "Enter the number corresponding to your choice: ");
response = 0;
(void) scanf("%i", &response);
} while (response < 0 || response > 4);
return (response);
}
static void catcher(sig)
{
longjmp(segvbuf, 1);
}
static
good_addr(address)
char *address;
{
register struct state *p;
for (p = ap; p != &ap[nap]; p++)
if (p->shmaddr == address)
return(1);
return(0);
} |
|