I am writing a practise for using message queue in linux, there are a few mistries i can't seem to figure out. code are posted after this
i have two programs, ./server and ./client, when I do ./client <cmd>, ./client supposes to send the <cmd> to the queue and server will retrieve it, exec it and send the results back to the queue and client gets it, display it and quit.
when I do one ./client <cmd> and then do ipcs, it shows me there is no messages
i open another terminal and do it again, it shows me there is one message
i open another terminal and do it again, it shows me there is 2 messages
and so on, why the first one didn't get added to the queue, that's my biggest question right now
queue struct
Code:
const long int SERVER = 1L; //msg type for server
typedef struct {
long int msg_to;
long int msg_fm;
char buffer[BUFSIZ];
} MESSAGE;
[code]
client code
Code:
#include "local.h"
#include <stdio.h>
int main (int argc, char *argv[]) {
pid_t c_pid;
int mid, n=0, i, pos =0;
char *pch;
MESSAGE msg;
bzero(msg.buffer, BUFSIZ);
c_pid = getpid();
if ((mid=msgget(2,IPC_CREAT)) == -1) {
perror ("Server is not running");
return 1;
}
printf("mid is %d\n", mid);
while (1) {
msg.msg_to = SERVER;
msg.msg_fm = c_pid;
memset(msg.buffer, 0x0, BUFSIZ);
for(i=0; i<argc; i++) {
strcat(msg.buffer, argv[i]);
strcat(msg.buffer, " ");
printf("argv[%i] is %s and n is %d and str is %s and size %d\n", i, argv[i], n, msg.buffer, sizeof(msg.buffer));
}
n = sizeof(char) * strlen(msg.buffer);
n += sizeof(msg.msg_fm);
printf("n is %d\n", n);
if(msgsnd(mid, &msg, n, 0) == -1) {
perror ("Client: msgsnd");
return 3;
}
if ( (n=msgrcv(mid, &msg, BUFSIZ, c_pid, 0)) != -1 ) {
printf("Client MSQID: %d\n", c_pid);
write(fileno(stdout), msg.buffer, n);
break;
}
}
printf("Client exit\n");
return 0;
}
server code
Code:
#include "local.h"
#include <signal.h>
#include <fcntl.h>
int smid;
MESSAGE msg;
void server_cmd();
void sig_catch_u1(int);
int main (int argc, char *argv[]) {
int n,t=0;
FILE *fp;
signal(SIGUSR1, sig_catch_u1);
if ((smid=msgget(2, 0)) == -1) {
smid = msgget(2, IPC_CREAT | IPC_EXCL | 0660); //create msg queue
}
while (1) {
memset(msg.buffer, 0x0, BUFSIZ);
if ((n=msgrcv(smid, &msg, BUFSIZ, SERVER, 0)) == -1) {
perror("Server: msgrcv");
return 2;
}
else if (n == 0) {
break;
}
printf("server: get here and n is %d\n", n);
printf("server: msg.buffer is %s\n", msg.buffer);
switch(fork()) {
case -1:
perror("Fork error");
exit(1);
case 0:
server_cmd();
}
printf("server: after fork\n");
if ((fp = fopen("/tmp/server_tmp", "r")) == NULL) {
perror("Open file error");
exit(1);
}
do {
msg.buffer[t++] = getc(fp);
}while(msg.buffer[t] != EOF || t>= BUFSIZ);
msg.msg_to = msg.msg_fm;
msg.msg_fm = SERVER;
n = sizeof(char) * strlen(msg.buffer);
n += sizeof(msg.msg_fm);
if (msgsnd(smid, &msg, n, 0) == -1) {
perror("Server: msgsnd");
return 3;
}
}
}
void server_cmd() {
char *s_cmd, *new_args[20];
int s_fd, i=0;
if ((s_fd=open("/tmp/server_tmp", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR))==-1) {
perror ("Open error");
exit(0);
}
if (dup2(s_fd, fileno(stdout)) == -1) {
perror ("Dup2 erorr");
exit(0);
}
s_cmd = msg.buffer;
new_args[i] = strtok(s_cmd, " \t");
while (*new_args[i] != '\0'){
i++;
}
new_args[i] = NULL;
execvp(new_args[1], &new_args[1]);
perror("Execvp failure");
exit(1);
}
void sig_catch_u1 (int sig)
{
signal(sig, sig_catch_u1);
msgctl(smid, IPC_RMID, (struct msqid_ds *) 0);
exit(0);
}