Mercurial > mplayer.hg
annotate input/lirc.c @ 28355:418d7d213966
Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
due to not freeing the lirc config on error.
| author | reimar |
|---|---|
| date | Fri, 30 Jan 2009 15:41:45 +0000 |
| parents | 5b1f6e52673b |
| children | 0f1b5b68af32 |
| rev | line source |
|---|---|
| 28112 | 1 /* |
| 2 * This file is part of MPlayer. | |
| 3 * | |
| 4 * MPlayer is free software; you can redistribute it and/or modify | |
| 5 * it under the terms of the GNU General Public License as published by | |
| 6 * the Free Software Foundation; either version 2 of the License, or | |
| 7 * (at your option) any later version. | |
| 8 * | |
| 9 * MPlayer is distributed in the hope that it will be useful, | |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 * GNU General Public License for more details. | |
| 13 * | |
| 14 * You should have received a copy of the GNU General Public License along | |
| 15 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
| 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 17 */ | |
| 4432 | 18 |
| 16860 | 19 #include "config.h" |
| 4432 | 20 |
| 21 #include <lirc/lirc_client.h> | |
| 22 #include <errno.h> | |
|
28345
3a08f32c8fa1
Do not use select n lirc code, instead set the fd non-blocking.
reimar
parents:
28321
diff
changeset
|
23 #include <fcntl.h> |
| 4432 | 24 #include <stdio.h> |
| 25 #include <string.h> | |
| 26 #include <unistd.h> | |
| 27 #include <stdlib.h> | |
| 28 | |
| 16860 | 29 #include "mp_msg.h" |
| 30 #include "help_mp.h" | |
| 7883 | 31 #include "input.h" |
| 4432 | 32 |
| 33 static struct lirc_config *lirc_config; | |
|
4823
d25b898c4c44
Make old and new lirc support independant from each other
albeu
parents:
4526
diff
changeset
|
34 char *lirc_configfile; |
| 4432 | 35 |
| 7883 | 36 static char* cmd_buf = NULL; |
| 4432 | 37 |
| 38 int | |
| 39 mp_input_lirc_init(void) { | |
| 40 int lirc_sock; | |
|
28345
3a08f32c8fa1
Do not use select n lirc code, instead set the fd non-blocking.
reimar
parents:
28321
diff
changeset
|
41 int mode; |
| 4432 | 42 |
| 20185 | 43 mp_msg(MSGT_LIRC,MSGL_V,MSGTR_SettingUpLIRC); |
| 4432 | 44 if((lirc_sock=lirc_init("mplayer",1))==-1){ |
| 20185 | 45 mp_msg(MSGT_LIRC,MSGL_ERR,MSGTR_LIRCopenfailed); |
| 4432 | 46 return -1; |
| 47 } | |
| 48 | |
|
28355
418d7d213966
Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
reimar
parents:
28354
diff
changeset
|
49 mode = fcntl(lirc_sock, F_GETFL); |
|
418d7d213966
Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
reimar
parents:
28354
diff
changeset
|
50 if (mode < 0 || fcntl(lirc_sock, F_SETFL, mode | O_NONBLOCK) < 0) { |
|
418d7d213966
Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
reimar
parents:
28354
diff
changeset
|
51 mp_msg(MSGT_LIRC, MSGL_ERR, "setting non-blocking mode failed: %s\n", |
|
418d7d213966
Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
reimar
parents:
28354
diff
changeset
|
52 strerror(errno)); |
| 4432 | 53 lirc_deinit(); |
| 54 return -1; | |
| 55 } | |
| 56 | |
|
28355
418d7d213966
Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
reimar
parents:
28354
diff
changeset
|
57 if(lirc_readconfig( lirc_configfile,&lirc_config,NULL )!=0 ){ |
|
418d7d213966
Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
reimar
parents:
28354
diff
changeset
|
58 mp_msg(MSGT_LIRC,MSGL_ERR,MSGTR_LIRCcfgerr, |
|
418d7d213966
Move setting of O_NONBLOCK before lirc_readconfig, this avoids a memleak
reimar
parents:
28354
diff
changeset
|
59 lirc_configfile == NULL ? "~/.lircrc" : lirc_configfile); |
|
28345
3a08f32c8fa1
Do not use select n lirc code, instead set the fd non-blocking.
reimar
parents:
28321
diff
changeset
|
60 lirc_deinit(); |
|
3a08f32c8fa1
Do not use select n lirc code, instead set the fd non-blocking.
reimar
parents:
28321
diff
changeset
|
61 return -1; |
|
3a08f32c8fa1
Do not use select n lirc code, instead set the fd non-blocking.
reimar
parents:
28321
diff
changeset
|
62 } |
|
3a08f32c8fa1
Do not use select n lirc code, instead set the fd non-blocking.
reimar
parents:
28321
diff
changeset
|
63 |
| 7883 | 64 return lirc_sock; |
| 4432 | 65 } |
| 66 | |
| 7883 | 67 int mp_input_lirc_read(int fd,char* dest, int s) { |
| 68 int r,cl = 0; | |
| 69 char *code = NULL,*c = NULL; | |
| 4432 | 70 |
| 7883 | 71 // We have something in the buffer return it |
| 72 if(cmd_buf != NULL) { | |
| 73 int l = strlen(cmd_buf), w = l > s ? s : l; | |
| 74 memcpy(dest,cmd_buf,w); | |
| 75 l -= w; | |
| 76 if(l > 0) | |
| 77 memmove(cmd_buf,&cmd_buf[w],l+1); | |
| 78 else { | |
| 79 free(cmd_buf); | |
| 80 cmd_buf = NULL; | |
| 81 } | |
| 82 return w; | |
| 83 } | |
| 84 | |
| 28321 | 85 // Nothing in the buffer, poll the lirc fd |
| 7883 | 86 if(lirc_nextcode(&code) != 0) { |
| 28354 | 87 mp_msg(MSGT_LIRC,MSGL_ERR,"Lirc error :(\n"); |
| 7883 | 88 return MP_INPUT_DEAD; |
| 89 } | |
| 4432 | 90 |
| 7883 | 91 if(!code) return MP_INPUT_NOTHING; |
| 92 | |
| 93 // We put all cmds in a single buffer separated by \n | |
| 94 while((r = lirc_code2char(lirc_config,code,&c))==0 && c!=NULL) { | |
| 95 int l = strlen(c); | |
| 96 if(l <= 0) | |
| 4432 | 97 continue; |
| 7883 | 98 cmd_buf = realloc(cmd_buf,cl+l+2); |
| 99 memcpy(&cmd_buf[cl],c,l); | |
| 100 cl += l+1; | |
| 101 cmd_buf[cl-1] = '\n'; | |
| 102 cmd_buf[cl] = '\0'; | |
| 4432 | 103 } |
| 7883 | 104 |
| 105 free(code); | |
| 106 | |
| 107 if(r < 0) | |
| 108 return MP_INPUT_DEAD; | |
| 109 else if(cmd_buf) // return the first command in the buffer | |
| 110 return mp_input_lirc_read(fd,dest,s); | |
| 111 else | |
| 15825 | 112 return MP_INPUT_RETRY; |
| 7883 | 113 |
| 4432 | 114 } |
| 115 | |
| 116 void | |
| 7883 | 117 mp_input_lirc_close(int fd) { |
| 118 if(cmd_buf) { | |
| 119 free(cmd_buf); | |
| 120 cmd_buf = NULL; | |
| 4432 | 121 } |
| 7883 | 122 lirc_freeconfig(lirc_config); |
| 123 lirc_deinit(); | |
| 4432 | 124 } |
