Fawkes API Fawkes Development Version
qa_ipc_shmem_lowlevel.cpp
1
2/***************************************************************************
3 * qa_ipc_shmem_lowlevel.cpp - lowlevel shared memory qa
4 *
5 * Generated: Sun Oct 22 23:43:36 2006
6 * Copyright 2006 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24/// @cond QA
25
26/* This program reveals a problem with the shmat shmaddr parameter. It shows
27 * that this cannot be reliably used to map the shared memory to a specific
28 * address even if the REMAP flag has been set. Maybe this just shows a fundamental
29 * misunderstanding on my side. Have to study more literature, kernel source did
30 * not reveal the problem in an obvious manner to me.
31 */
32
33#include <sys/ipc.h>
34#include <sys/shm.h>
35
36#include <errno.h>
37#include <iostream>
38#include <signal.h>
39
40using namespace std;
41using namespace fawkes;
42
43#define SHMEM_SIZE 2048
44#define SHMEM_TOKEN "JustSomeDumbQA"
45
46typedef struct
47{
48 void *ptr;
49} header_t;
50
51bool quit = false;
52
53void
54signal_handler(int signum)
55{
56 quit = true;
57}
58
59int
60main(int argc, char **argv)
61{
62 signal(SIGINT, signal_handler);
63
64 key_t key = ftok(".", 'b');
65 printf("Key: 0x%x\n", key);
66
67 if (argc == 1) {
68 // master
69 int shmid = shmget(key, SHMEM_SIZE, IPC_CREAT | 0666);
70 if (shmid == -1) {
71 perror("M: Could not get ID");
72 exit(1);
73 }
74
75 void *shmem = shmat(shmid, NULL, 0);
76 if (shmem == (void *)-1) {
77 perror("M: Could not attach");
78 exit(2);
79 }
80
81 memset(shmem, 0, SHMEM_SIZE);
82
83 header_t *header = (header_t *)shmem;
84 header->ptr = shmem;
85
86 printf("M: ptr=0x%lx\n", (long unsigned int)shmem);
87
88 while (!quit) {
89 usleep(100000);
90 }
91
92 shmctl(shmid, IPC_RMID, NULL);
93 shmdt(shmem);
94
95 } else {
96 // slave
97 int shmid = shmget(key, SHMEM_SIZE, 0);
98
99 if (shmid == -1) {
100 perror("S: Could not get ID");
101 exit(1);
102 }
103
104 void *shmem = shmat(shmid, NULL, 0);
105 if (shmem == (void *)-1) {
106 perror("S: Could not attach");
107 exit(2);
108 }
109
110 header_t *header = (header_t *)shmem;
111
112 printf("S: ptr=0x%lx header->ptr=0x%lx\n",
113 (long unsigned int)shmem,
114 (long unsigned int)header->ptr);
115
116 if (shmem != header->ptr) {
117 printf("S: pointers differ, re-attaching\n");
118 void *ptr = header->ptr;
119 shmdt(shmem);
120 shmem = shmat(shmid, ptr, SHM_REMAP);
121 if (shmem == (void *)-1) {
122 perror("S: Could not re-attach");
123 exit(3);
124 }
125 header = (header_t *)shmem;
126 printf("S: after re-attach: ptr=0x%lx header->ptr=0x%lx\n",
127 (long unsigned int)shmem,
128 (long unsigned int)header->ptr);
129 }
130
131 /*
132 while ( ! quit ) {
133 usleep(100000);
134 }
135 */
136
137 shmdt(shmem);
138 }
139
140 return 0;
141}
142
143/// @endcond
Fawkes library namespace.