LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   massage structure? (https://www.linuxquestions.org/questions/programming-9/massage-structure-142913/)

kalleanka 02-06-2004 05:45 AM

massage structure?
 
Hi,

I need some info to be past from one process to another. And my idea was to send a message and then a signal to notify the other process.

In http://www.cs.cf.ac.uk/Dave/C/node25...00000000000000 it says:

The structure below is an example of what this user-defined buffer might look like:

struct mymsg {
long mtype; /* message type */
char mtext[MSGSZ]; /* message text of length MSGSZ */
}

So can I change this to:
typedef struct msgbuf {
int mSlots[5];
int mError[5];
char mtext[MSGSZ];
} message_buf;

or is the struct unchangeble.

The man in linux gives:

the calling process allocates a structure of the following general form :
struct msgbuf {
long mtype; /* message type must be >0*/
char mtext[1]; /* message data */
}


any idees?

eshwar_ind 02-06-2004 06:40 AM

Yah You can change, but first member should be Long int ( mtype).
Speciality in Linux message Queues is that Mtype. It allows Multiplexing of messages into a message queue.
But at the other end while you are reading you should use the same Format structure. Other wise logically you may face problems.
I hope this clarifies your doubt.
Bye,
Eshwar.

eshwar_ind 02-06-2004 06:41 AM

By the by what do u want to do really?
I didnt get what you are willing to do with that.

Can you explain it a little?

kalleanka 02-06-2004 06:59 AM

I want to send info from one process to another in this form:
struct msgbuf {
int mSlots[5];
int mError[5];
char mtext[MSGSZ];
} message_buf;

so I dont have to pack and sort to an string or char array.

eshwar_ind 02-06-2004 07:05 AM

Ya you can send but add long mtype as the first element of your message.
Recieve that data at the other end with the same structure format. It has to work try it.
bye,
Eshwar.

eshwar_ind 02-06-2004 07:11 AM

1 st method:

struct msgbuf{
long mtype;
int mSlots[5];
int mError[5];
char mtext[MSGSZ];
} message_buf;

or

SEcond method:

struct mymessage{
int mSlots[5];
int mError[5];
char mtext[MSGSZ];
};

struct msgbuf {
long mtype;
struct mymessage message;
} message_buf;


Use any of above two methods. But read the data in to the same format structure variable ( sturcture used for writing).

eshwar_ind 02-06-2004 07:12 AM

If u have any questions ask me on tomorrow. Its late i am leaving.
bye,
Eshwar.

kalleanka 02-06-2004 07:15 AM

Thanks eshwar

Hko 02-06-2004 11:32 AM

Here's the message queue part of a program I wrote to switch on/off two LED's connected to a serial port. Maybe you can use this. Your thing sound similar to me. If you would like to see the entire program, just send me an e-mail through my forum profile, and I'll mail you back with the .tar.gz of the program attached.

It has one daemon process that sits waiting for a SIGUSR1 signal from the client program. The client process puts a message on the queue, and then kills the daemon with SIGUSR1, The signal handler of the daemon gets the message from the queue and sets/unsets the lines of the serial port. This way the daemon uses exactly 0% CPU when there's nothing to do.

Code:

Note that:
 - Both my client and the daemon link with this, each calling only the functions
  useful for them. (the daemon creates and remove the queue, the client
  "connects")
 - functions like out_error() used here are in some other c-file of my program,
  which just send the string either to syslog or stderr depending on some
  flag set somewhere else in the program.
 - I used ftok() to generate a IPC key in getipckey(). This needs a path to
  some file unique for the project.  I used a lockfile here that my program
  uses.  The function getlockfilename() is in another c-file in my project.
  It just returns the path of the lock-file.
 - The size parameter for the syscalls msgrcv() and msgsnd() should not
  include the long int message type identifier.  I solved this here using a
  struct inside the actual message-struct.

Code:

/* msgq.h  */

#ifndef MSGQ_H
#define MSGQ_H

#define MSGTYPE 19031968
#define MSGSIZE (sizeof(action_t))

/* LED actions */
#define NONE 0
#define OFF  1
#define ON  2

typedef struct {
    unsigned int led1 :2;
    unsigned int led2 :2;
} action_t;


typedef struct {
    long int message_type;
    action_t action;
} msg_t;


int  connect_new_msg_queue(void);
int  connect_msg_queue(void);
void remove_msg_queue(void);
int  get_message(action_t *action);
int  put_message(const action_t *action);

#endif

Code:

/* msgq.c */

#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include "msgq.h"
#include "output.h"


static int msgq_id = -1;


key_t getipckey(void)
{
    key_t key;

    key = ftok(getlockfilename(), 19);
    if (key < 0) {
          out_perror(errno, "ftok()");
    }
    return key;
}


int connect_new_msg_queue(void)
{
    key_t key;

    key = getipckey();
    if (key < 0) {
          out_error("Could not get IPC key for message queue.");
          return 0;
    }
    if (msgq_id >= 0) {
          out_warn("connect_new_msg_queue(): already connected");
    }
    msgq_id = msgget(key,  0660 | IPC_CREAT);
    if (msgq_id < 0 ) {
          out_perror(errno, "connect_new_msg_queue()");
          msgq_id = -1;
          return 0;
    }
    atexit(remove_msg_queue);
    return 1;
}


int connect_msg_queue(void)
{
    key_t key;

    key = getipckey();
    if (key < 0) {
          return 0;
    }
    if (msgq_id >= 0) {
          out_warn("connect_msg_queue(): already connected");
    }
    msgq_id = msgget(key,  0660);
    if (msgq_id < 0 ) {
          out_perror(errno, "connect_new_msg_queue()");
          msgq_id = -1;
          return 0;
    }
    return 1;
}


void remove_msg_queue(void)
{
    if (msgq_id < 0) return;
    if (msgctl(msgq_id, IPC_RMID, NULL) < 0) {
          out_perror(errno, "remove_msg_queue()");
          return;
    }
    msgq_id = -1;
}


int get_message(action_t *action)
{
    msg_t msg;

    if (msgq_id < 0) {
          out_error("get_message(): not connected to message queue");
          return 0;
    }
    if (msgrcv(msgq_id, &msg, MSGSIZE, MSGTYPE, IPC_NOWAIT) < 0) {
          if (errno == ENOMSG) {
              action->led1 = action->led2 = NONE;
              return 0;
          } else {
              out_perror(errno, "get_messgage(): msgrcv()");
              return 0;
          }
    }

    *action = msg.action;
    return 1;
}


int put_message(const action_t *action)
{
    msg_t msg;
   
    if (msgq_id < 0) {
          out_error("put_message(): not connected to message queue");
          return 0;
    }
    msg.message_type = MSGTYPE;
    msg.action = *action;
    if (msgsnd(msgq_id, &msg, MSGSIZE, IPC_NOWAIT) < 0) {
          out_perror(errno, "put_message(): msgsnd()");
          return 0;
    }
    return 1;
}


kalleanka 02-07-2004 12:48 PM

hko thats exacly what im doing.

Hko 02-07-2004 07:17 PM

Nice!
I received your e-mail and I've send you the tar.gz with the sources of the client and daemon programs. Hope you can use this.


All times are GMT -5. The time now is 05:53 AM.