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; } |
|
来自: champion_xu > 《my yc》