]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/mainloop.c
lxc: child failing before container rename
[mirror_lxc.git] / src / lxc / mainloop.c
CommitLineData
b0a33c1e 1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26#include <errno.h>
91480a0f 27#include <fcntl.h>
b0a33c1e 28#include <unistd.h>
29#include <sys/epoll.h>
30
31#include "mainloop.h"
32
9227a12a 33struct mainloop_handler {
b0a33c1e 34 lxc_mainloop_callback_t callback;
35 int fd;
36 void *data;
37};
38
5df6b18f
CC
39#define MAX_EVENTS 10
40
b0a33c1e 41int lxc_mainloop(struct lxc_epoll_descr *descr)
42{
5df6b18f 43 int i, nfds;
9227a12a 44 struct mainloop_handler *handler;
5df6b18f 45 struct epoll_event events[MAX_EVENTS];
b0a33c1e 46
47 for (;;) {
48
5df6b18f 49 nfds = epoll_wait(descr->epfd, events, MAX_EVENTS, -1);
b0a33c1e 50 if (nfds < 0) {
51 if (errno == EINTR)
52 continue;
53 return -1;
54 }
55
5df6b18f 56 for (i = 0; i < nfds; i++) {
9227a12a 57 handler =
5df6b18f 58 (struct mainloop_handler *) events[i].data.ptr;
b0a33c1e 59
60 /* If the handler returns a positive value, exit
61 the mainloop */
62 if (handler->callback(handler->fd, handler->data,
63 descr) > 0)
64 return 0;
b0a33c1e 65 }
66
d066f3b8 67 if (lxc_list_empty(&descr->handlers))
b0a33c1e 68 return 0;
69 }
70}
71
72int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
73 lxc_mainloop_callback_t callback, void *data)
74{
d066f3b8 75 struct epoll_event ev;
9227a12a 76 struct mainloop_handler *handler;
d066f3b8 77 struct lxc_list *item;
b0a33c1e 78
79 handler = malloc(sizeof(*handler));
80 if (!handler)
81 return -1;
82
83 handler->callback = callback;
84 handler->fd = fd;
85 handler->data = data;
86
d066f3b8
CC
87 ev.events = EPOLLIN;
88 ev.data.ptr = handler;
b0a33c1e 89
d066f3b8
CC
90 if (epoll_ctl(descr->epfd, EPOLL_CTL_ADD, fd, &ev) < 0)
91 goto out_free_handler;
b0a33c1e 92
d066f3b8
CC
93 item = malloc(sizeof(*item));
94 if (!item)
95 goto out_free_handler;
b0a33c1e 96
d066f3b8
CC
97 item->elem = handler;
98 lxc_list_add(&descr->handlers, item);
3ce45e64 99 return 0;
b0a33c1e 100
d066f3b8 101out_free_handler:
b0a33c1e 102 free(handler);
3ce45e64 103 return -1;
b0a33c1e 104}
105
106int lxc_mainloop_del_handler(struct lxc_epoll_descr *descr, int fd)
107{
9227a12a 108 struct mainloop_handler *handler;
d066f3b8 109 struct lxc_list *iterator;
b0a33c1e 110
d066f3b8
CC
111 lxc_list_for_each(iterator, &descr->handlers) {
112 handler = iterator->elem;
b0a33c1e 113
d066f3b8
CC
114 if (handler->fd == fd) {
115 /* found */
116 if (epoll_ctl(descr->epfd, EPOLL_CTL_DEL, fd, NULL))
117 return -1;
b0a33c1e 118
d066f3b8
CC
119 lxc_list_del(iterator);
120 free(iterator->elem);
121 free(iterator);
122 return 0;
b0a33c1e 123 }
b0a33c1e 124 }
125
126 return -1;
127}
128
a9e61274 129int lxc_mainloop_open(struct lxc_epoll_descr *descr)
b0a33c1e 130{
a9e61274
DL
131 /* hint value passed to epoll create */
132 descr->epfd = epoll_create(2);
b0a33c1e 133 if (descr->epfd < 0)
134 return -1;
135
91480a0f
DL
136 if (fcntl(descr->epfd, F_SETFD, FD_CLOEXEC)) {
137 close(descr->epfd);
138 return -1;
139 }
140
d066f3b8 141 lxc_list_init(&descr->handlers);
b0a33c1e 142 return 0;
143}
144
145int lxc_mainloop_close(struct lxc_epoll_descr *descr)
146{
d066f3b8
CC
147 struct lxc_list *iterator, *next;
148
149 iterator = descr->handlers.next;
150 while (iterator != &descr->handlers) {
151 next = iterator->next;
b0a33c1e 152
d066f3b8
CC
153 lxc_list_del(iterator);
154 free(iterator->elem);
155 free(iterator);
156 iterator = next;
157 }
b0a33c1e 158
159 return close(descr->epfd);
160}
161