chiefbutz
11-20-2008, 11:37 PM
I am working on an exercise for a Linux programming class I am taking, I am having some trouble. I have 2 semaphores inside a memory segment and when the second semaphore is initialized I get a seg fault. Here is the file and the header. Any help would be appreciated.
master.cpp:
#include "msg.h"
#include <cstdio>
#include <ctime>
#include <fcntl.h>
#include <iostream>
#include <istream>
#include <mqueue.h>
#include <semaphore.h>
#include <signal.h>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <sys/ipc.h>
#include <sys/mman.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
// I hate to do it, but i need to...
mqd_t mq_id;
string mq_name, shm_name, srvstr;
msg srvmsg;
//
bool mainLoop(int sig);
void ouch(int sig);
//
int main(int argc, char *argv[])
{
// Vars and Such
srvmsg.type = SRVMSG;
mq_name = "/jb373-MQ";
shm_name = "/jb373-MSEG";
bool done = false;
// Setup
struct sigaction act;
act.sa_handler = ouch;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGINT, &act, 0);
// Message Queue
struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 1;
attr.mq_msgsize = sizeof(srvmsg);
mq_id = mq_open(mq_name.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600, &attr);
// Shared Memory
int mfd = shm_open(shm_name.c_str(), O_RDWR | O_CREAT, 0600);
ftruncate(mfd, sizeof(struct memseg));
// Map the file to a shared memory segment
struct memseg* shared_memory = (struct memseg*)mmap(0, sizeof(struct memseg),
PROT_READ | PROT_WRITE, MAP_SHARED,
mfd, 0);
// We can close the file descriptor.
close(mfd);
// Semaphores
cout << "trying to init semaphores\n";
try
{
if(sem_init(((struct memseg*)&shared_memory)->r_to_u, 1, 0) != 0)
{
cout << "Sem init error\n";
}
// \/\/\/\/\/\/\/\/\/\/ PROBLEM CAUSER
if(sem_init(((struct memseg*)&shared_memory)->u_to_r, 1, 0) != 0)
{
cout << "Sem init error\n";
}
}
catch(...)
{
cout << "semaphore got mad!\n";
}
cout << "done initing semaphores\n";
// Run reverse
int pid = fork();
if(pid == 0)
{
execl("reverse", "reverse", mq_name.c_str(), shm_name.c_str(), 0);
exit(0);
}
// Run Upper
int pid2 = fork();
if(pid2 == 0)
{
execl("upper", "upper", shm_name.c_str(), 0);
exit(0);
}
// Main Loop
while(!done)
{
done = mainLoop(0);
}
// Closing Stuff
mq_close(mq_id);
mq_unlink(mq_name.c_str());
shm_unlink(shm_name.c_str());
}
bool mainLoop(int sig)
{
char str[MAXLEN];
cout << " >";
// Get the string
cin.getline(str, MAXLEN);
srvstr = str;
// Setup the string for sending
srvstr += '\0';
srvstr.copy(srvmsg.data,MAXLEN-1);
srvmsg.data[MAXLEN-1] = '\0';
// Send the string
mq_send(mq_id, (const char *)&srvmsg, sizeof(srvmsg), 1);
if(srvstr.find("-END-") != string::npos)
{
cout << "Exiting...\n";
//done = true;
return true;
}
else
return false;
}
void ouch(int sig)
{
cout << endl;
// Tells reverse to shutdown
srvstr = "-END-";
srvstr += '\0';
srvstr.copy(srvmsg.data,MAXLEN-1);
srvmsg.data[MAXLEN-1] = '\0';
mq_send(mq_id, (const char *)&srvmsg, sizeof(srvmsg), 1);
// Closing Stuff
mq_close(mq_id);
mq_unlink(mq_name.c_str());
shm_unlink(shm_name.c_str());
exit(0);
}
msg.h:
#include <semaphore.h>
const int MAXLEN = 256;
enum msgtype { SRVMSG=1, CLIMSG };
struct msg { long type; char data[MAXLEN];};
struct memseg
{
sem_t *r_to_u;
sem_t *u_to_r;
char data[MAXLEN]; // when doing stuff make sure the end is \0
};
master.cpp:
#include "msg.h"
#include <cstdio>
#include <ctime>
#include <fcntl.h>
#include <iostream>
#include <istream>
#include <mqueue.h>
#include <semaphore.h>
#include <signal.h>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <sys/ipc.h>
#include <sys/mman.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
// I hate to do it, but i need to...
mqd_t mq_id;
string mq_name, shm_name, srvstr;
msg srvmsg;
//
bool mainLoop(int sig);
void ouch(int sig);
//
int main(int argc, char *argv[])
{
// Vars and Such
srvmsg.type = SRVMSG;
mq_name = "/jb373-MQ";
shm_name = "/jb373-MSEG";
bool done = false;
// Setup
struct sigaction act;
act.sa_handler = ouch;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGINT, &act, 0);
// Message Queue
struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 1;
attr.mq_msgsize = sizeof(srvmsg);
mq_id = mq_open(mq_name.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600, &attr);
// Shared Memory
int mfd = shm_open(shm_name.c_str(), O_RDWR | O_CREAT, 0600);
ftruncate(mfd, sizeof(struct memseg));
// Map the file to a shared memory segment
struct memseg* shared_memory = (struct memseg*)mmap(0, sizeof(struct memseg),
PROT_READ | PROT_WRITE, MAP_SHARED,
mfd, 0);
// We can close the file descriptor.
close(mfd);
// Semaphores
cout << "trying to init semaphores\n";
try
{
if(sem_init(((struct memseg*)&shared_memory)->r_to_u, 1, 0) != 0)
{
cout << "Sem init error\n";
}
// \/\/\/\/\/\/\/\/\/\/ PROBLEM CAUSER
if(sem_init(((struct memseg*)&shared_memory)->u_to_r, 1, 0) != 0)
{
cout << "Sem init error\n";
}
}
catch(...)
{
cout << "semaphore got mad!\n";
}
cout << "done initing semaphores\n";
// Run reverse
int pid = fork();
if(pid == 0)
{
execl("reverse", "reverse", mq_name.c_str(), shm_name.c_str(), 0);
exit(0);
}
// Run Upper
int pid2 = fork();
if(pid2 == 0)
{
execl("upper", "upper", shm_name.c_str(), 0);
exit(0);
}
// Main Loop
while(!done)
{
done = mainLoop(0);
}
// Closing Stuff
mq_close(mq_id);
mq_unlink(mq_name.c_str());
shm_unlink(shm_name.c_str());
}
bool mainLoop(int sig)
{
char str[MAXLEN];
cout << " >";
// Get the string
cin.getline(str, MAXLEN);
srvstr = str;
// Setup the string for sending
srvstr += '\0';
srvstr.copy(srvmsg.data,MAXLEN-1);
srvmsg.data[MAXLEN-1] = '\0';
// Send the string
mq_send(mq_id, (const char *)&srvmsg, sizeof(srvmsg), 1);
if(srvstr.find("-END-") != string::npos)
{
cout << "Exiting...\n";
//done = true;
return true;
}
else
return false;
}
void ouch(int sig)
{
cout << endl;
// Tells reverse to shutdown
srvstr = "-END-";
srvstr += '\0';
srvstr.copy(srvmsg.data,MAXLEN-1);
srvmsg.data[MAXLEN-1] = '\0';
mq_send(mq_id, (const char *)&srvmsg, sizeof(srvmsg), 1);
// Closing Stuff
mq_close(mq_id);
mq_unlink(mq_name.c_str());
shm_unlink(shm_name.c_str());
exit(0);
}
msg.h:
#include <semaphore.h>
const int MAXLEN = 256;
enum msgtype { SRVMSG=1, CLIMSG };
struct msg { long type; char data[MAXLEN];};
struct memseg
{
sem_t *r_to_u;
sem_t *u_to_r;
char data[MAXLEN]; // when doing stuff make sure the end is \0
};