92 lines
1.6 KiB
C
92 lines
1.6 KiB
C
|
#include <sys/types.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdint.h>
|
||
|
#include <syscall.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
DEFN_SYSCALL2(shm_obtain, 35, char *, int)
|
||
|
DEFN_SYSCALL1(shm_release, 36, char *)
|
||
|
|
||
|
|
||
|
int main_server(volatile char *shm);
|
||
|
int main_client(volatile char *shm);
|
||
|
|
||
|
|
||
|
|
||
|
int main (int argc, char ** argv) {
|
||
|
if (argc < 2) {
|
||
|
fprintf(stderr, "%s: expected argument\n", argv[0]);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
printf("(This should fork and the child process (but not the parent) should segfault)\n");
|
||
|
|
||
|
volatile char * shm = (char *)syscall_shm_obtain(argv[1], 27);
|
||
|
if (shm == NULL) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int pid = getpid();
|
||
|
uint32_t f = fork();
|
||
|
if (getpid() != pid) {
|
||
|
// Child: client
|
||
|
return main_client(shm);
|
||
|
} else {
|
||
|
// Parent: server
|
||
|
return main_server(shm);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
int main_server(volatile char *shm) {
|
||
|
char c;
|
||
|
volatile char *s;
|
||
|
|
||
|
/*
|
||
|
* Now put some things into the memory for the
|
||
|
* other process to read.
|
||
|
*/
|
||
|
s = shm;
|
||
|
|
||
|
for (c = 'a'; c <= 'z'; c++)
|
||
|
*s++ = c;
|
||
|
*s = '\0';
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Finally, we wait until the other process
|
||
|
* changes the first character of our memory
|
||
|
* to '*', indicating that it has read what
|
||
|
* we put there.
|
||
|
*/
|
||
|
while (*shm != '*') {}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int main_client(volatile char *shm) {
|
||
|
int shmid;
|
||
|
volatile char *s;
|
||
|
|
||
|
/*
|
||
|
* Now read what the server put in the memory.
|
||
|
*/
|
||
|
while (*shm != 'a');
|
||
|
for (s = shm; *s != '\0'; s++)
|
||
|
printf("%c", *s);
|
||
|
printf("\n");
|
||
|
|
||
|
/*
|
||
|
* Finally, change the first character of the
|
||
|
* segment to '*', indicating we have read
|
||
|
* the segment.
|
||
|
*/
|
||
|
*shm = '*';
|
||
|
|
||
|
return 0;
|
||
|
}
|