Message Queue - Solaris10 - Could not open - c

I want to write 2 programs that communicate with a message queue!
common.h
#ifndef COMMON_H
#define COMMON_H
#define QUEUE_NAME "/zq1"
#define MAX_SIZE 100
#define MSG_STOP "quit"
#endif
server
#include <stdio.h>
#include <strings.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "common.h"
int main(int argc,char **argv)
{
char buf[MAX_SIZE];
int size=0;
mqd_t mq;
int open_flags= O_CREAT | O_RDWR | O_EXCL;
mq=mq_open(QUEUE_NAME, open_flags, S_IRWXU | S_IRWXG, NULL);
if(mq ==(mqd_t)-1)
{
perror("Message Queue Open Failed");
return 1;
}
/* INPUT */
printf("Exit with 'quit' \n\n");
for(;;)
{
printf("Eingabe:");
fgets(buf,sizeof(buf),stdin);
size=strlen(buf);
buf[size-1]=0;
if(mq_send(mq,buf,strlen(buf),0)<0)
{
perror("Failure mq_send()");
}
if(strcmp(buf,MSG_STOP)==0) break;
}
/*
for(;;)
{
memset(&buf,0,sizeof(buf));
mq_receive(mq,buf,MAX_SIZE,NULL);
printf("%s ",buf);
if(strcmp(buf,MSG_STOP)==0) break;
}
*/
mq_close(mq);
// mq_unlink(QUEUE_NAME);
return 0;
}
i could read and write, but if i want to open the mq with the client:
"No such file or directory"
The server does not creat a file, but why?
client
#include <mqueue.h>
#include "common.h"
#include <stdio.h>
#include <strings.h>
int main()
{
mqd_t mq;
char buf[MAX_SIZE];
ssize_t bytes_read;
mq=mq_open(QUEUE_NAME,O_RDWR);
if((mqd_t)-1 == mq)
{
perror("Error mq_open()");
return 1;
}
for(;;)
{
bytes_read=mq_receive(mq,buf,MAX_SIZE,NULL);
if(bytes_read == -1) perror("Error Read")
printf("inhalt:%s",buf);
if(strncmp(buf,MSG_STOP,strlen(MSG_STOP))==0)
break;
}
return 0;
}

i found it, i wrote
if((mqd_t)-1 != mq)
I'am sorry!
But the problem ist still the same! client doesn't get any messages
Error: Message too long
The size of MAX_SIZE was too short, i raised it up to 1024 and it works well!

Related

msgget function is not implemented

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFF_SIZE 1024
typedef struct {
long data_type;
int data_num;
char data_buff[BUFF_SIZE];
} t_data;
int main(){
key_t msqid;
int ndx = 0;
t_data data;
msqid = msgget( (key_t)1234, IPC_CREAT | 0666);
if ( -1 == msqid)
{
perror( "msgget() fail");
exit( 1);
}
return 0;
}
and next, i do
gcc -o parent parent.c
and next,
./parent
but the result is
msgget() fail: Function not implemented
I don't know why the msgget function is not implemented even though this is just simple code.
How can i fix my code??

fifo linux - write() function terminates the program abruptly

I'm implementing a pipe in C, where multiples producer programs (9 in my case) write data to one single consumer program.
The problem is that some producers (some times one or two) exit the program abruptly when calling the write() function.
The code is simple, here is the producer code:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#define MSG_SIZE_BYTES 4
void send(unsigned int * msg){
int fd, msg_size;
int r;
char buffer [5];
char myfifo[50] = "/tmp/myfifo";
fd = open(myfifo, O_WRONLY);
if(fd == -1){
perror("error open SEND to fifo");
}
r = write(fd, msg, MSG_SIZE_BYTES);
if(r == -1){
perror("error writing to fifo");
}
close(fd);
printf("Message send\n");
}
int main(int argc, char *argv[]){
int cluster_id = atoi(argv[1]);
unsigned int msg[1];
msg[0] = cluster_id;
while(1){
printf("Press a key to continue...\n");
getchar();
send(msg);
}
}
And here is the consumer code
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#define MSG_SIZE_BYTES 4
int receive(unsigned int * received_msg){
int fd, msg_size;
int ret_code;
char buffer [5];
char myfifo[50] = "/tmp/myfifo";
fd = open(myfifo, O_RDONLY);
if(fd == -1)
perror("error open RECV to fifo");
ret_code = read(fd, received_msg, MSG_SIZE_BYTES);
close(fd);
if (ret_code == -1){
printf("\nERROR\n");
return 0;
}
return 1;
}
void main(){
mkfifo("/tmp/myfifo", 0666);
unsigned int msg[1];
while(1){
receive(msg);
printf("receive msg from id %d\n", msg[0]);
}
}
I'm compiling the producers and consumer with the following command: gcc -o my_progam my_program.c
To reproduce the problem, you need to open 9 terminals to run each producer and 1 terminal to run the consumer.
Execute the consumer: ./consumer
Execute the producer in all terminals simultaneously, passing to each execution an associated ID passed by command line. Ex: ./producer 0, ./producer 1.
After the producer send messages some times (10 in average), one arbitrary producer will abruptly stop its execution, showing the problem.
The following image depicts the execution:
Terminals ready to execute
The following image depicts the error on producer ID 3
Error on producer 3
Thanks in advance
It looks like the consumer program closes the reading end of the pipe after reading data:
fd = open(myfifo, O_RDONLY);
if(fd == -1){
perror("error open RECV to fifo");
}
ret_code = read(fd, received_msg, MSG_SIZE_BYTES);
close(fd);
All other writers, which are currently trying to write() data (i.e. are blocked in the write()-syscall) now receive a SIGPIPE, which leads to program termination (if no other signal handling is specified).
Your consumer program may not close the filedescriptor while producers are writing. Just read the next datum without closing.
Problem SOLVED:
The problem is that I was opening and closing the FIFO at each message, generating a Broken pipe in some write attempts. Removing the close() and inserting the open() function for BOTH producer and consumer at the begging of the code instead inside the loop solved the problem.
Here is the code of producer with the bug fixed:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#define MSG_SIZE_BYTES 4
int my_fd;
void send(unsigned int * msg){
int fd, msg_size;
int r;
char buffer [5];
char myfifo[50] = "/tmp/myfifo"
if(fd == -1){
perror("error open SEND to fifo");
}
r = write(my_fd, msg, MSG_SIZE_BYTES);
if(r == -1){
perror("error writing to fifo");
}
//close(fd);
printf("Message send\n");
}
int main(int argc, char *argv[]){
int cluster_id = atoi(argv[1]);
unsigned int msg[1];
msg[0] = cluster_id;
my_fd = open("/tmp/myfifo", O_WRONLY);
while(1){
printf("Press a key to continue...\n");
getchar();
send(msg);
}
}
And here is the consumer code:
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#define MSG_SIZE_BYTES 4
int my_fd;
int receive(unsigned int * received_msg){
int fd, msg_size;
int ret_code;
char buffer [5];
char myfifo[50] = "/tmp/myfifo";
if(fd == -1)
perror("error open RECV to fifo");
ret_code = read(my_fd, received_msg, MSG_SIZE_BYTES);
//close(fd);
if (ret_code == -1){
printf("\nERROR\n");
return 0;
}
return 1;
}
void main(){
mkfifo("/tmp/myfifo", 0666);
my_fd = open("/tmp/myfifo", O_RDONLY);
unsigned int msg[1];
while(1){
receive(msg);
printf("receive msg from id %d\n", msg[0]);
}
}
Thank you all!!

infinite loop in shared memory

Within a Ubuntu virtal machine, I have created two c programs called "server" and "client". When I run server with an input (some integer) and then run client afterwards, client will output the integer that I gave to server. This is working with shared memory. My problem is, after client receives the info, it sets a variable to "CONSUMED", and server has a loop that waits for that to happen, but it never seems to work correctly. This all works if I remove the loop altogether, but I need it in there to be able to ensure that client receives the integer and I don't just continue without it happening.
Here is my code for server.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include "shm.h"
int main(int argc, char* argv[]){
int retVal = 0;
ShmData *addr;
if(argc != 2){
printf("please enter 1 argument.\n");
return 0;
}
int fd = shm_open("shm.h", O_CREAT | O_RDWR , 0666);
if(fd == -1){
printf("!!!error with shm_open.\n");
}
if(ftruncate(fd, sizeof(ShmData)) == -1){
printf("!!!error with ftruncate.\n");
}
addr = mmap(0, sizeof(ShmData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(addr == MAP_FAILED){
printf("!!!error with mmap.\n");
}
addr->status = INVALID;
addr->data = atoi(argv[1]);
addr->status = VALID;
printf("[Server]: Server data Valid... waiting for client\n");
while(addr->status != CONSUMED){
sleep(1); //THIS LOOP NEVER EXITS
}
printf("[Server]: Server Data consumed!\n");
munmap(addr, 0);
if(close(fd) == -1){
printf("!!!error with close.\n");
}
shm_unlink("smh.h");
printf("[Server]: Server exiting...\n\n\n");
return(retVal);
}
Here is my code for client.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include "shm.h"
int main(int argc, char* argv[]){
int retVal = 0;
int fd = shm_open("shm.h", O_CREAT | O_RDWR , 0666);
if(fd == -1){
printf("!!!error with shm_open.\n");
}
ShmData *addr;
addr = mmap(0, sizeof(ShmData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
printf("[Client]: Waiting for valid data ...\n");
while(addr->status != VALID){
sleep(1);
}
printf("[Client]: Received %d\n", addr->data);
addr->status = CONSUMED;
munmap(addr, 0);
printf("[Client]: Client exiting...\n");
return(retVal);
}
And here is the shm.h file:
enum StatusEnum{INVALID, VALID, CONSUMED};
typedef struct{
enum StatusEnum status;
int data;
}ShmData;
I've been banging my head against the computer screen for a long time but I still don't see anything wrong with my code. How can I get this loop to succeed and exit?

Message Queue in C, mq returns -1 when creating message queue

When I create a message queue, mq always returns -1 and it gives an error message.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <mqueue.h>
#include <errno.h>
#include <pthread.h>
#include <ctype.h>
#include <time.h>
typedef int bool;
#define true 1
#define false 0
#define MIN_WORKERS 1
#define MAX_WORKERS 5
#define MAX_COUNT 200
#define BUF_SIZE 100
int main(int argc, char * argv[])
{
//Declaring Nodes
NODE * first;
NODE * current;
first=current=NULL;
//Message Queue
mqd_t mq;
//Declaring Variables
int pid;
int i;
char *buffer;
int bufferLength;
int index = 3;
//Declare message queue attributes
struct mq_attr mq_attr;
mq_attr.mq_flags = 0;
mq_attr.mq_maxmsg = 10;
mq_attr.mq_msgsize = 10;
mq_attr.mq_curmsgs = 0;
// initialize the queue attributes
mq_getattr(mq, &mq_attr);
bufferLength = mq_attr.mq_msgsize;
char serverName[128];
strcpy(serverName, argv[1]);
pid=fork();
printf("%d\n",pid );
//Parents message queue
if(pid!=0)
{
printf("%d\n",pid );
mq = mq_open(serverName, O_RDWR | O_CREAT, 0666, NULL);
if(mq==-1)
{
perror("Error: at creating PARENT server message queue\n");
exit(1);
}
}

close() on shared memory in osx causes invalid argument error

The following code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
int
main(int argc, char **argv)
{
char *p;
int shm_fd;
int error;
size_t len;
if ((shm_fd = shm_open("/somename", O_CREAT | O_RDWR, 0666)) < 0) {
perror("shm_open");
exit(1);
}
error = close(shm_fd);
if (error < 0) {
perror("close");
}
return 0;
}
Works fine on fedora22 x86_64, freebsd 10.2 x86_64. But it fails on OSX 10.10 with
close: Invalid argument
What is wrong with the call on OSX?

Resources