message queue & fp 연관문제 입니다..

shiny의 이미지

커널에서 메시지 큐를 생성하여 메시지를 송신하면 아래 유저

프로그램에서는 그 메시지를 처리하는 (fp를 이용하여 'back.dat'에 저장하는)

프로그램을 짰는데 문제는 fp를 사용하지 않으면 제대로 동작이 되거든여..

근데 fp를 사용하여 돌려보면 딱 두번만 실행되고 이런 메시지가 나옵니다.

msgrcv error

msgrcv: No message of desired type

물론 백그라운드로 실행되고 있구여..

다른곳에서 에러가 나는지 확인해 봤는데 다 멀쩡하구

꼭 fp만 사용하면 에러메시지가 나오더라구여..

메시지큐와 fp간에 무슨 충돌이 일어나는지.....ㅠ,.ㅠ

고수님들의 답변 부탁드립니다..

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include </root/linux/include/linux/ipc.h>
#include </root/linux/include/linux/msg_song.h>
#include </root/linux/include/linux/stat.h>
#include </root/linux/include/linux/types.h>
#include </root/linux/include/linux/linkage.h>

#define MAXDATASIZE 4096
#define END 4

static void quit(char *call, int end)
{
	perror(call);
	exit(end);
}
struct umsg
{
	long mtype;
	char mtext[4096];
};
main()
{

	unsigned char pathfile[256];
	char buf[MAXDATASIZE], name[2];	
	struct umsg mymsg;
	int size, j=0, i=0;
	int qid1;
	FILE *fp;

	mymsg.mtype = (long)1;

	if((qid1 = msgget((key_t)1, IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1)
	{
		printf("msgget err\n\r");
		quit("msgget", 2);
	}
		
	while(1)			
	{		
		if((size = msgrcv(qid1, &mymsg, 4096, (long)1)) == -1)
		{
			printf("msgrcv err\n\r");
			quit("msgrcv", 3);
		}
		else
		{
			printf("received\n\r");
			printf("mymsg.mtext->%s\n\r",mymsg.mtext);				

			i=0;
			while(mymsg.mtext[i] != '\0')
			{
				buf[i] = mymsg.mtext[i];
				i++;
			}
			buf[i] = '\0';
			printf("buf->%s\n\r",buf);				
		

			/*******문제제기된 부분*********/
			fp = fopen("back.dat","w");
			fputs(buf, fp);
			fclose(fp);	
			/*******************************/
		}
	}
}
alsong의 이미지

man msgrcv wrote:
If no message of the requested type is available and
IPC_NOWAIT isn't asserted in msgflg, the calling process
is blocked until one of the following conditions occurs:

A message of the desired type is placed on the
queue.

The message queue is removed from the system. In
such a case the system call fails with errno set to
EIDRM.
The calling process receives a signal that has to
be caught. In such a case the system call fails
with errno set to EINTR.

버퍼크기를 메시지큐 크기와 일치 시켜보세요.( 혹시나 ^^; )
strncpy도 쓸 수 있겠네요.

         printf("received\n\r"); 
         printf("mymsg.mtext->%s\n\r",mymsg.mtext);             

         i=0; 
         while(mymsg.mtext[i] != '\0') 
         { 
            buf[i] = mymsg.mtext[i]; 
            i++; 
         } 
         buf[i] = '\0'; 
         printf("buf->%s\n\r",buf);             
       

         /*******문제제기된 부분*********/ 
         fp = fopen("back.dat","w"); 
         fputs(buf, fp); 
         fclose(fp);    
         /*******************************/ 

최소한의 코드로 줄이면(테스트 안해봐서 아래비스무리하게)
         
         printf("received\n\r"); 
         printf("mymsg.mtext->%s\n\r",mymsg.mtext); 

         mymsg.mtext[4095] = '\0';
         fp = fopen("back.dat","w");
         fputs(mymsg.mtext, fp); 
         fclose(fp);

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

shiny의 이미지

답변 정말루 감솨~~~

제가 소스를 잘못올렸군여,,, 버퍼사이즈와 큐사이즈를 같게 했구여..

버퍼를 쓴이유는 계속 메시지큐 포인터를 참조하서 에러가 나는지

확인차 했던겁니다...

그리고 메시지가 항상 4096개가 아니라 최대 4096개고염...

가변하기 때문에

mymsg.mtext[4095] = '\0';

이부분은 소용없을 듯 하네여...

대신

buf[i] = '\0';

를 썼구여..

문제는 왜 fp를 같이 쓰면 안되냐졍..ㅠ,.ㅠ

꿈은 이루어진다.
그렇지 않다면 신이 우리에게 꿈을 꾸게 만들었을 리가 없다.

alsong의 이미지

혹시나 key값을 다른 데몬이나 시스템이 쓰고 있는지 확인해보세요.
그냥봐서는 오류가 없네요. ^^;
어떤 못된 프로세스가 쓰고 있을지도..... ㅎㅎ

mymsg.mtext[4095] = '\0'; 는 메시지의 가변과는 상관없습니다. 프로그램의 작동상...... 오류가 발생할 소지는 버퍼의 최대 크기일때까지 널이 없을경우만 발생하므로 막아 준겁니다. (그외에는 널처리가 필요 없어 보이는군요.)

그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.

shiny의 이미지

static void eint1_int(int irq, void *dev_id, struct pt_regs *regs)
{
	int tempsi;
	
	if(IS_SET(SCC_RD(LSR0),RCV_ready) != 0)
	{
		mymsg.mtype = (long int)1;
		mymsg.mtext[si]=SCC_RD(RHR0);
		si++;
		
		if(si>=1024)
		{
			if(sys_msgsnd(qid, (void *)&mymsg, 1024, IPC_NOWAIT) != -1)
			{			
				si = 0;		
			}
			else		
				printk("msgsnd error");
		} 		
		else if(si > 2)
		{
			if(mymsg.mtext[si-2] == (char)0x04) 
			{	
				mymsg.mtext[si-1]='\0';
				
				if(sys_msgsnd(qid, (void *)&mymsg, si, IPC_NOWAIT) != -1)
				{			
					printk("%d\n\r",si);
					si = 0;		
					
				}
				else		
					printk("msgsnd error");
			}
		}
	}
}

int rs7312_init(void)
{ 
	int	i;
	struct 	uport	*up;

	memset(&rs_driver,0,sizeof(rs_driver));
	rs_driver.magic=TTY_DRIVER_MAGIC;
	rs_driver.driver_name="serial_7312";
	rs_driver.name="ttyS"; 
	rs_driver.major=TTY_MAJOR;
	rs_driver.minor_start=SERIAL_7312_MINOR_START;
	rs_driver.num=SERIAL_7312_NPORT;
	rs_driver.type=TTY_DRIVER_TYPE_SERIAL;
	rs_driver.subtype=SERIAL_TYPE_NORMAL;
	rs_driver.init_termios=tty_std_termios;
	rs_driver.init_termios.c_cflag=B19200|CS8|CREAD|HUPCL|CLOCAL;
	rs_driver.flags=TTY_DRIVER_REAL_RAW;
	rs_driver.refcount=&rs_refcount; 
	rs_driver.table=rs_table;
	rs_driver.termios=rs_termios;
	rs_driver.termios_locked=rs_termios_locked;

	rs_driver.open=rs_open;
	rs_driver.close=rs_close;
	rs_driver.write=rs_write;
	rs_driver.put_char=rs_put_char;
	rs_driver.flush_chars=NULL;
	rs_driver.write_room=rs_write_room;
	rs_driver.chars_in_buffer=rs_chars_in_buffer;
	rs_driver.flush_buffer=rs_flush_buffer;
	rs_driver.ioctl=NULL; 
	rs_driver.throttle=rs_throttle;
	rs_driver.unthrottle=rs_unthrottle;
	rs_driver.send_xchar=rs_send_xchar;
	rs_driver.set_termios=rs_set_termios;
	rs_driver.stop=rs_stop;
	rs_driver.start=rs_start;
	rs_driver.hangup=NULL;
	rs_driver.break_ctl=NULL;
	rs_driver.wait_until_sent=rs_wait_until_sent; 
	rs_driver.read_proc=NULL;

	for ( i=0; i<SERIAL_7312_NPORT; i++ )  {
	    up = &uports[i];
	    up->syscon = SYSCON1 | (i*0x1000);
	    up->sysflg = SYSFLG1 | (i*0x1000);
	    up->intsr  = INTSR1  | (i*0x1000);
	    up->intmr  = INTMR1  | (i*0x1000);
	    up->uartdr = UARTDR1 | (i*0x1000);
	    up->ubrlcr = UBRLCR1 | (i*0x1000);
	    up->tx_irq = IRQ_UTXINT1 + 16*i;
	    up->rx_irq = IRQ_URXINT1 + 16*i;
	    up->use_count = 0;
	    up->flag = 0;
	    up->putp = up->getp = up->wbuf;
	    up->xchar = 0;
	    if( request_irq(up->rx_irq,rs_rx_int,0,"rs7312rx",(void *)i) )
		panic("Couldn't get rx irq %d for rs7312", up->rx_irq); 
	    if( request_irq(up->tx_irq,rs_tx_int,0,"rs7312tx",(void *)i) )
		panic("Couldn't get tx irq %d for rs7312", up->tx_irq); 
		rs_set_cflag(up, rs_driver.init_termios.c_cflag);
	}

	if(tty_register_driver(&rs_driver))
	{
		panic("Couldn't register CL-PS7312 serial driver\n");
		printk("***** error register rs7312 *****\n");
	}
	printk("******* End of serial7312 initialize \n");

	i = 2;
	if( request_irq(IRQ_EINT1,eint1_int,0,"eint1_int",(void *) i))
		panic("***** Couldn't get eint1 %d for eint1 *****\n",IRQ_EINT1);

	if( request_irq(IRQ_EINT2,eint2_int,0,"eint2_int",(void *) i))
		panic("***** Couldn't get eint1 %d for eint1 *****\n",IRQ_EINT2);
	
	/**************큐 생성******************/
	if((qid = sys_msgget((key_t)1, IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1)
	{
		printk("msgget error");
		return;
	}
	/***************************************/				
	return 0;
}

커널소스입니당..

참고하셔셔 답변 좀 부탁...

꿈은 이루어진다.
그렇지 않다면 신이 우리에게 꿈을 꾸게 만들었을 리가 없다.

shiny의 이미지

fp만 사용하지 않으면 아주 잘~ 동작되거는여.. 성실하게..

근데 fp만 사용하면 두번 실행후 프로그램 종료...

버퍼 내용을 꼭 파일로 저장해둬야는데 다른방법이

없을까여???? :cry:

꿈은 이루어진다.
그렇지 않다면 신이 우리에게 꿈을 꾸게 만들었을 리가 없다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.