Tizen 2.1 base
[external/acpid.git] / connection_list.c
1 /*
2  *  connection_list.c - ACPI daemon connection list
3  *
4  *  Copyright (C) 2008, Ted Felix (www.tedfelix.com)
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  Tabs at 4
21  */
22
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "acpid.h"
29 #include "log.h"
30
31 #include "connection_list.h"
32
33 #define max(a, b)  (((a)>(b))?(a):(b))
34
35 /*---------------------------------------------------------------*/
36 /* private objects */
37
38 #define MAX_CONNECTIONS 20
39
40 static struct connection connection_list[MAX_CONNECTIONS];
41
42 static int nconnections = 0;
43
44 /* fd_set containing all the fd's that come in */
45 static fd_set allfds;
46
47 /* highest fd that is opened */
48 /* (-2 + 1) causes select() to return immediately */
49 static int highestfd = -2;
50
51 /*---------------------------------------------------------------*/
52 /* public functions */
53
54 void
55 add_connection(struct connection *p)
56 {
57         if (nconnections < 0)
58                 return;
59         if (nconnections >= MAX_CONNECTIONS) {
60                 acpid_log(LOG_ERR, "Too many connections.");
61                 /* ??? This routine should return -1 in this situation so that */
62                 /*   callers can clean up any open fds and whatnot.  */
63                 return;
64         }
65
66         if (nconnections == 0)
67                 FD_ZERO(&allfds);
68         
69         /* add the connection to the connection list */
70         connection_list[nconnections] = *p;
71         ++nconnections;
72         
73         /* add to the fd set */
74         FD_SET(p->fd, &allfds);
75         highestfd = max(highestfd, p->fd);
76 }
77
78 /*---------------------------------------------------------------*/
79
80 void
81 delete_connection(int fd)
82 {
83         int i;
84
85         close(fd);
86
87         /* remove from the fd set */
88         FD_CLR(fd, &allfds);
89
90         for (i = 0; i < nconnections; ++i) {
91                 /* if the file descriptors match, delete the connection */
92                 if (connection_list[i].fd == fd) {
93                         free(connection_list[i].pathname);
94                         
95                         --nconnections;
96                         connection_list[i] = connection_list[nconnections];
97                         
98                         break;
99                 }
100         }
101         
102         /* prepare for recalculation of highestfd */
103         highestfd = -2;
104         
105         /* recalculate highestfd */
106         for (i = 0; i < nconnections; ++i) {
107                 highestfd = max(highestfd, connection_list[i].fd);
108         }
109 }
110
111 /*---------------------------------------------------------------*/
112
113 struct connection *
114 find_connection(int fd)
115 {
116         int i;
117
118         /* for each connection */
119         for (i = 0; i < nconnections; ++i) {
120                 /* if the file descriptors match, return the connection */
121                 if (connection_list[i].fd == fd)
122                         return &connection_list[i];
123         }
124
125         return NULL;
126 }
127
128 /*---------------------------------------------------------------*/
129
130 struct connection *
131 find_connection_name(char *pathname)
132 {
133         int i;
134
135         /* for each connection */
136         for (i = 0; i < nconnections; ++i) {
137                 /* skip null pathnames */
138                 if (connection_list[i].pathname == NULL)
139                         continue;
140
141                 /* if the pathname matches, return the connection */
142                 if (strcmp(connection_list[i].pathname, pathname) == 0)
143                         return &connection_list[i];
144         }
145
146         return NULL;
147 }
148
149 /*---------------------------------------------------------------*/
150
151 int 
152 get_number_of_connections()
153 {
154         return nconnections;
155 }
156
157 /*---------------------------------------------------------------*/
158
159 struct connection *
160 get_connection(int i)
161 {
162         if (i < 0  ||  i >= nconnections)
163                 return NULL;
164
165         return &connection_list[i];
166 }
167
168 /*---------------------------------------------------------------*/
169
170 const fd_set *
171 get_fdset()
172 {
173         return &allfds;
174 }
175
176 /*---------------------------------------------------------------*/
177
178 int
179 get_highestfd()
180 {
181         return highestfd;
182 }