Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
| Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
09-20-2005, 02:14 AM
|
#1
|
|
Member
Registered: Sep 2005
Location: austria
Distribution: fedora,backtrack
Posts: 31
Rep:
|
message queues - please some checkup from the pros
hi folks i hope, if some of you master-of-the-posix guys could look throught the program and say whats the problem.
the following happened:
i had to do a message queue:
prog1:
send lines from input via msq. to the next program
prog2:
change all input to big letters
and send to prog 3
prog3:
output the lines
in addition:
with quit all proggs. quit and implement a signal handler (sigint)
if someone could help with the following i would be very grateful:
1) i did this small prog. on debian
a friend of mine tried to run it on solaris and had some problems when trying to quit the proggs (it resultet in a loop)
2) i know of course this prog. can be done better faster intelligenter stronger ....  im not a pro (yet) ... but if there are some mistakes that just happened by luck to not result in an error ... please tell me
ok here is the code
msq.h
Code:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define key_in 1234
#define key_out 4321
#define size 1024
int msq_snd(int msq_id, char text[])
{
int send_id;
send_id=msgsnd(msq_id,text,strlen(text),0);
if (send_id < 0)
{
printf("Fehler bei senden einer Nachricht ...\n");
return -1;
}
}
int msq_rcv(int msq_id,char text[])
{
int receive_id;
receive_id=msgrcv(msq_id,text,size,0,0);
if(receive_id < 0)
{
printf("Fehler beim empfangen einer Nachricht ...\n");
return -1;
}
}
input.c
Code:
#include "./msq.h"
#include <signal.h>
static int input_id;
void term()
{
printf("Strg+c...sending quit to msq\n");
msq_snd(input_id,"quit");
msgctl(input_id,IPC_RMID,0);
exit(0);
}
int main()
{
int n;
char text[size];
signal(SIGINT,term);
input_id=msgget(key_in,IPC_CREAT);
if (input_id == -1)
{
printf("Fehler beim Einrichten der Msq.\n");
return -1;
}
while(1)
{
gets(text);
msq_snd(input_id,text);
if (strcmp(text,"quit") == 0)
{
printf("<<exiting>>\n");
msgctl(input_id,IPC_RMID,0);
return 0;
}
}
}
compute.c
Code:
#include "./msq.h"
int main()
{
int n,tooutput_id,toinput_id,receive_id,send_id;
char text[size];
toinput_id=msgget(key_in, 0);
if (toinput_id == -1)
{
printf("Fehler beim Einrichten der Msq.\n");
return -1;
}
tooutput_id=msgget(key_out, IPC_CREAT);
if (tooutput_id == -1)
{
printf("Fehler beim Einrichten der Msq.\n");
return -1;
}
printf("Server läuft...\n");
while(1)
{
msq_rcv(toinput_id,text);
if(strcmp(text,"quit")==0)
{
msq_snd(tooutput_id,text);
printf("<<exiting>>\n");
msgctl(toinput_id,IPC_RMID,0);
msgctl(tooutput_id,IPC_RMID,0);
return 0;
}
puts(text);
for (n=0;n<strlen(text);n++)
{
text[n]=toupper(text[n]);
}
printf("Changed to: ");
puts(text);
msq_snd(tooutput_id,text);
}
return 0;
}
output.c
Code:
#include "./msq.h"
int main()
{
int output_id,receive_id;
char text[size];
output_id=msgget(key_out,0);
if(output_id < 0)
{
printf("Fehler beim Einrichten der Msq.\n");
return -1;
}
while(1)
{
msq_rcv(output_id,text);
if(strcmp(text,"quit")==0)
{
printf("<<exiting>>\n");
msgctl(output_id,IPC_RMID,0);
return 0;
}
puts(text);
}
}
i have an exam in a few days and just dont want to miss some obvious mistakes
[edit]
oh btw. i am from austria ... so the error messages are written in german but i hope thats not a problem
[/edit]
Last edited by kirmet; 09-20-2005 at 02:21 AM.
|
|
|
|
09-20-2005, 04:49 AM
|
#2
|
|
Member
Registered: Oct 2003
Posts: 249
Rep:
|
hiho kermit
german:
griaß di *g*
also ich hab mal deinen code ausprobiert
hier was mir aufgefallen ist (ich weiß nicht ob es bei dir das gleiche problem ist!)
mir sind 2 dinge aufgefallen
1. bei input.c krieg ich einen compile warning
da du gets(); stat fgets(); verwendest
erklärung:
gets(); schaut nicht auf die puffer größe (bei dir variable text) und somit könnts zu einem puffer überlauf kommen
deshalb ist diese funktion unsicher!
lösung:
ganz oben füge hinzu
#include <stdio.h>
gets(text); ersetzen durch fgets(text,size,stdin);
2. bei mir hat gar nix funktioniert, weil die berichtigung für die message queue falsch war
PS: fall du irgendwo einen fehler hast (also die funktion liefert einen fehlercode) dann verwende
perror("ERROR");
die funktion perror gibt dir den fehlertext aus, des letzten fehlers
dadurch hab ich gekriegt:
ERROR: Permission denied
lösung:
in jedem code file außer msq.h
ändere die msgget funktion!
bei der msgget musst du noch die berechtigung angeben mit der die message queue geöffnet werden soll:
z.B. bei input.c --> input_id=msgget(key_in,IPC_CREAT|0666); // 0666 ist quasi standard berechtigung (-rw-rw-rw-)
output.c --> output_id=msgget(key_out,0|0666);
compute.c --> toinput_id=msgget(key_in, 0|0666);
das waren bei mir die probleme
hoffe du schaffst die prüfung
good luck ;-)
english:
the problems i've found:
1. gets(); is used in input.c
gets is unsafe because it can cause a buffer overflow because it
from the man page:
Never use gets(). Because it is impossible to tell withÂ_
out knowing the data in advance how many characters gets()
will read, and because gets() will continue to store charÂ_
acters past the end of the buffer, it is extremely dangerÂ_
ous to use. It has been used to break computer security.
Use fgets() instead.
so i changed input.c
1: #include <stdio.h>
2: fgets(text,size,stdin);
2.
the priviledge for the message queue isn't set
using perror("ERROR");
i got
ERROR: Permission denied
so i changed every msgget(); to
msgget(key,flag|0666);
where key is the key variable used in the code and flag the flags set (0 or IPC_CREAT)
now it works great
good luck for your exam
|
|
|
|
09-20-2005, 05:00 AM
|
#3
|
|
Member
Registered: Sep 2005
Location: austria
Distribution: fedora,backtrack
Posts: 31
Original Poster
Rep:
|
thx a lot thinking for the answer (for the german as well as for the english version)
first i used scanf but i couldnt solve the format problem. i guess it would have been a small syntax change but well ... works fine now.
thx even more to show me the permission error ... thats something my theacher likes to look at
ok im back to work
working on threads and semaphores now and im sure im coming back for some questions 
|
|
|
|
09-20-2005, 05:04 AM
|
#4
|
|
Member
Registered: Oct 2003
Posts: 249
Rep:
|
you're welcome
|
|
|
|
09-20-2005, 08:40 AM
|
#5
|
|
Member
Registered: Sep 2005
Location: austria
Distribution: fedora,backtrack
Posts: 31
Original Poster
Rep:
|
huhu i am back
i need some more help or verification for the following code please
ok this task was about threads and semaphores ... a better topic to do some mistakes i guess
the task just was to have
1file:
to read from stdin and write it in a message queue. then open a thread and let it read from the message queue and write the content in a file. in addition i had to do a semaphore for the second prog.
2file:
to read from the file (if the semaphore isnt set) and delete the file afterwards.
write_file (nice name or?  )
Code:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#define key_sem 5555L
#define key_msq 1111
#define size 1024
static int sem_id;
static struct sembuf semaphore;
static int init_semaphore(void)
{
sem_id = semget(key_sem,1,IPC_CREAT | 0666);
if(sem_id < 0)
{
perror("Fehler bei semget()");
return -1;
}
if (semctl(sem_id,0,SETVAL,(int) 1) < 0)
{
perror("Fehler bei semctl()");
return -1;
}
return 1;
}
static int op_semaphore(int stat)
{
semaphore.sem_op = stat;
semaphore.sem_flg = SEM_UNDO;
if (semop (sem_id,&semaphore,1) < 0)
{
perror("Fehler bei semop()");
return -1;
}
return 1;
}
static void function(void *file)
{
int msq_id,rcv_id,fd_file;
char text[size];
msq_id=msgget(key_msq,0|0666);
if(msq_id < 0)
{
perror("Fehler bei msgget()");
pthread_exit(NULL);
}
rcv_id=msgrcv(msq_id,text,size,0,0);
if (rcv_id < 0)
{
perror("Fehler bei msgrcv()");
pthread_exit(NULL);
}
op_semaphore(-1);
fd_file=open((char *) file,O_RDWR | O_EXCL | O_CREAT, 0666);
if (fd_file < 0)
{
perror("Fehler bei open()");
pthread_exit(NULL);
}
if (write(fd_file,text,strlen(text)) != strlen(text))
{
perror("Fehler bei write()");
pthread_exit(NULL);
}
op_semaphore(1);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
int msq_id,send_id;
int ress;
char text[size];
pthread_t th;
if (argc < 2)
{
printf("syntax %s <filename>\n",argv[0]);
return -1;
}
ress = init_semaphore();
if (ress < 0)
{
printf("Fehler bei init_semaphore()\n");
return -1;
}
if (pthread_create(&th,NULL,&function,argv[1]) < 0)
{
perror("Fehler bei pthread_create()");
return -1;
}
msq_id=msgget(key_msq,IPC_CREAT|0666);
if(msq_id < 0)
{
perror("Fehler bei msgget()");
return -1;
}
fgets(text,size,stdin);
send_id=msgsnd(msq_id,text,strlen(text),0);
if(send_id < 0)
{
perror("Fehler bei msgsnd()");
return -1;
}
pthread_join(th,NULL);
return 0;
}
read_file
Code:
#include <sys/types.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#define key_sem 5555L
#define size 1024
static int sem_id;
static struct sembuf semaphore;
static int init_semaphore(void)
{
sem_id = semget(key_sem,1,0 | 0666);
if(sem_id < 0)
{
perror("Fehler bei semget()");
return -1;
}
return 1;
}
static int op_semaphore(int stat)
{
semaphore.sem_op = stat;
semaphore.sem_flg = SEM_UNDO;
if (semop (sem_id,&semaphore,1) < 0)
{
perror("Fehler bei semop()");
return -1;
}
return 1;
}
int main(int argc, char *argv[])
{
int fd_file;
char text[size];
init_semaphore();
op_semaphore(-1);
fd_file=open(argv[1],O_RDONLY,0666);
if (fd_file < 0)
{
perror("Fehler bei open()");
return -1;
}
if (read(fd_file,text,size) < 0)
{
perror("Fehler bei read()");
return -1;
}
remove (argv[1]);
op_semaphore(1);
semctl(sem_id,0,IPC_RMID,0);
puts(text);
return 0;
}
i hope someone (thinking perhaps  ) could take a quick look at it to point to me to some mistakes.
thanks
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 05:20 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|