分享

cgi控制OK6410板子LED(YC)

 champion_xu 2012-04-22
cgi意思为通用网关接口,是服务器与浏览器动作相互通信的一种方式和桥梁。我们通过浏览器网页收集动作并触发cgi程序可以处理自己在cgi程序中定义的需要处理的过程。
这里写了一个简单的通过网页控制目标板LED的程序,进程间通信方式为共享内存,有点铺张,可以使用FIFO更简单,但是追求的就是一个折腾的过程,于是乎各种蛋疼菊紧扑面而来,还好最后以极强的心理战术解决困境。花了一天时间啊!!!(初学留个记录,看以后回过来头再看有多可笑)
指的提醒的是IPC机制中的信号量是不会随进程结束而自动消除的,除非进程中自己有显示的消除,不然任何进程都可以用,不管其中是否由退出的,只要不删除都可以用,共享内存也是一样。

以下是led对应的接收cgi数据的程序:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<sys/sem.h>
#include<sys/shm.h>
#include<sys/ipc.h>


#define LED_ON 1
#define LED_OFF 0

int main(int argc, char **argv)
{
  int fd = -1;
  unsigned int led_no;
  struct sembuf sem_led;
  int semid,shmid,i=0,val;
  char *shmdat_r,led_status[3];
  int position;

  sem_led.sem_num = 0;

  fd = open("/dev/s3c6410leds",0);
  if(fd<0)
  {
    printf("Can not open device leds\n");
    return -1;
  }

  semid=semget((key_t)12345,1,0666|IPC_CREAT);
  if(semid==-1) {
    printf("sem get error\n");    
    return -1;
  }

  if(semctl(semid,0,SETVAL,0)==-1) {
    printf("sem set val error\n");
    return -1;
  }

  shmid=shmget((key_t)54321,512,0666|IPC_CREAT);
  if(shmid==-1) {
    printf("shm get error \n");
    return -1;
  }

  shmdat_r = shmat(shmid,NULL,0);
  if(shmdat_r==NULL) {
    printf("shm map error\n");
    if(shmctl(shmid,IPC_RMID,NULL)==-1) {
        printf("rm shm error\n");
        return -1;
    }
     return -1;
  }

  printf("shamdat:%s\n",shmdat_r);
 
  while(1) {
  if((val=semctl(semid,0,GETVAL))==1) {
    printf("%s\n",shmdat_r);
      led_no = *shmdat_r-'0'-1;
      printf("ledno=%d\n",led_no);
      shmdat_r++;//在这里内存地址加1,由于进程不会退出,是一个无限循环的过程,所以后面要记得减1
      if(!strcmp(shmdat_r,"ON"))
      {
        ioctl(fd,LED_ON,led_no);
      }

      else if(!strcmp(shmdat_r,"OFF"))
      {
        ioctl(fd,LED_OFF,led_no);
     }
    
    shmdat_r--;//这里内存地址减1,对应的前面的加1,以保护现场,不至于一直往后移
      sem_led.sem_op = -1;
      if(semop(semid,&sem_led,1)==-1) {
          printf("sem -1 failed\n");
        return -1;
      }
  }
 
 
 }

  close(fd);
  shmdt(shmdat_r);
  printf("removing the shm\n");
  if(shmctl(shmid,IPC_RMID,0)!=0) {
    printf("remove shm error\n");
    return -1;
  }

  if(semctl(semid,0,IPC_RMID,0)!=0) {
    printf("rm sem error\n");
    return -1;
  }
  printf("deleting the sem\n");

  return 0;
 


err:
  if(fd>0) close(fd);
  return -1;

}

以下是cgi程序:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<sys/ipc.h>

//打印网页信息的头
void print_head(void)
{
    printf("Content-type: text/html\n\n");
    printf("<html>\n");
    printf("<head><title>CGI Output</title></head>\n");
    printf("<body>\n");
}

//打印网页信息的尾
void print_tail(void)
{
    printf("<body>\n");
    printf("</html>\n");
}   


int main(void)
{
    char *input_tmp,inputstr[30],*method,tmp1[20],tmp2[20],tmp3[20];
    int i=0,ledno,length;
      struct sembuf sem_led;
      int semid,shmid,val;
    char *shmdat;

    sem_led.sem_num = 0;
   
    method=getenv("REQUEST_METHOD");
    input_tmp=getenv("QUERY_STRING");
//以下开始对数据进行URL解码
    while(*input_tmp!='\0') {
        if(*input_tmp=='%') {
            inputstr[i]='\0';
            break;
        }
        else {
            inputstr[i] = *input_tmp;
            input_tmp++;
            i++;
        }
    }
    length = i;
    inputstr[length] = '\0';
    i = 0;
    sscanf(inputstr,"%[^&]",tmp1);
    while(tmp1[i]!='\0') i++;
    length = i;
    i = 0;    
    ledno = tmp1[length-1];

    while(inputstr[i+length+1]!='\0') {
        tmp2[i] = inputstr[i+length+1];
        i++;
    }
    length = i;
    tmp2[length] = '\0';
    i = 0;
    sscanf(tmp2,"%[^&]",tmp2);
    sscanf(tmp2,"%[^=]",tmp3);
    while(tmp3[i]!='\0') i++;
    length = i;
    i = 0;
    while(tmp2[i+length+1]!='\0') {
        tmp3[i] = tmp2[i+length+1];
        i++;
    }
    length = i;
    tmp3[length]='\0';
    i = 0;
//到此结束对数据URL解码
     semid=semget((key_t)12345,1,0666|IPC_CREAT);
      if(semid==-1) {
        printf("sem get error\n");   
        return -1;
      }

      if(semctl(semid,0,SETVAL,0)==-1) {
        printf("sem set val error\n");
        return -1;
      }


      shmid=shmget((key_t)54321,512,0666|IPC_CREAT);
      if(shmid==-1) {
        printf("shm get error \n");
        return -1;
      }

      shmdat = shmat(shmid,NULL,0);

     if(shmdat==NULL) {
        printf("shm map error\n");
        if(shmctl(shmid,IPC_RMID,NULL)==-1) {
            printf("rm shm error\n");
            return -1;
        }
         return -1;
      }

    print_head();
    printf("<h1>method:%s</h1>\n",method);
    printf("<h1>inputstr:%s</h1>\n",inputstr);
    printf("<h1>tmp1:%s</h1>\n",tmp1);
    printf("<h1>tmp2:%s</h1>\n",tmp2);
    printf("<h1>ledno=%d</h1>\n",(ledno-'0'));
    printf("<h1>status=%s</h1>\n",tmp3);
    print_tail();   

    if((val=semctl(semid,0,GETVAL))==0) {
        print_head();
        printf("<h1>sem val 0<h1>\n");
        print_tail();       
        *shmdat = ledno;
        shmdat++;
        while(tmp3[i]!='\0') {
            *shmdat = tmp3[i];
            shmdat++;
            i++;
        }
        *shmdat='\0'; //由于可能出现ON,OFF字符长度不一的情况,这里需要及时在结尾加上字符串结束符
        i=0;
        sem_led.sem_op = 1;
        if(semop(semid,&sem_led,1)==-1) {
            print_head();
            printf("<h1>sem +1 error<h1>\n");
            print_tail();
            return -1;
        }
        val=semctl(semid,0,GETVAL);
        print_head();
        printf("<h1>sem val %d<h1>\n",val);
        print_tail();
    }

    return 0;
}




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多