static int epollfd = -1;
static bool sigint = false;
-static void job_wipe(job_t *job)
-{
- if (job->fd >= 0) {
- close(job->fd);
- job->fd = -1;
- }
-}
-DO_DELETE(job_t, job);
-
-void job_release(job_t **job)
+void job_delete(job_t **job)
{
if (*job) {
if ((*job)->stop) {
(*job)->stop(*job);
}
- job_delete(job);
+ if ((*job)->fd >= 0) {
+ close((*job)->fd);
+ }
+ p_delete(job);
}
}
{
struct epoll_event event = { .data.ptr = job, .events = EPOLLRDHUP };
- if (job->state & JOB_READ || job->state & JOB_LISTEN) {
+ if (job->state & (JOB_READ | JOB_LISTEN)) {
event.events |= EPOLLIN;
}
- if (job->state & JOB_WRITE || job->state & JOB_CONN) {
- event.events |= EPOLLIN;
+ if (job->state & (JOB_WRITE | JOB_CONN)) {
+ event.events |= EPOLLOUT;
}
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, job->fd, &event) < 0) {
syslog(LOG_ERR, "epoll_ctl error: %m");
job->error = true;
- job_release(&job);
+ job_delete(&job);
}
return job;
return;
job->state = state;
-
- if (job->state & JOB_READ || job->state & JOB_LISTEN) {
+ if (job->state & (JOB_READ | JOB_LISTEN)) {
event.events |= EPOLLIN;
}
- if (job->state & JOB_WRITE || job->state & JOB_CONN) {
- event.events |= EPOLLIN;
+ if (job->state & (JOB_WRITE | JOB_CONN)) {
+ event.events |= EPOLLOUT;
}
- epoll_ctl(epollfd, EPOLL_CTL_MOD, job->fd, &event);
+ if (epoll_ctl(epollfd, EPOLL_CTL_MOD, job->fd, &event) < 0) {
+ syslog(LOG_ERR, "epoll_ctl error: %m");
+ job->error = true;
+ }
}
job_t *job_accept(job_t *listener, int state)
return job_register_fd(res);
}
-static void job_handler(int sig)
+static void job_sighandler(int sig)
{
static time_t lastintr = 0;
time_t now = time(NULL);
void job_initialize(void)
{
signal(SIGPIPE, SIG_IGN);
- signal(SIGINT, &job_handler);
- signal(SIGTERM, &job_handler);
+ signal(SIGINT, &job_sighandler);
+ signal(SIGTERM, &job_sighandler);
epollfd = epoll_create(128);
if (epollfd < 0) {
job->process(job);
if (job->error || job->done) {
- job_release(&job);
+ job_delete(&job);
}
}
}
JOB_READ = 0x01,
JOB_WRITE = 0x02,
JOB_RDWR = 0x03,
- JOB_CONN = 0x04,
- JOB_LISTEN = 0x08,
+ JOB_LISTEN = 0x04,
+ JOB_CONN = 0x08,
};
enum smtp_state {
STATE_ETRN,
};
-typedef struct job_t job_t;
typedef struct jpriv_t jpriv_t;
-struct job_t {
+typedef struct job_t {
unsigned state : 6;
unsigned done : 1;
unsigned error : 1;
int fd;
- void (*process)(job_t *);
- void (*stop)(job_t *);
+ void (*process)(struct job_t *);
+ void (*stop)(struct job_t *);
jpriv_t *jdata;
-};
+} job_t;
-static inline job_t *job_init(job_t *job) {
- p_clear(job, 1);
+static inline job_t *job_new(void) {
+ job_t *job = p_new(job_t, 1);
job->fd = -1;
return job;
}
-DO_NEW(job_t, job);
-void job_release(job_t **job);
+void job_delete(job_t **job);
+
void job_update_state(job_t *job, int state);
job_t *job_accept(job_t *listener, int state);
buffer_t obuf;
};
-jpriv_t *postfix_jpriv_init(jpriv_t *jp)
+static jpriv_t *postfix_jpriv_init(jpriv_t *jp)
{
buffer_init(&jp->ibuf);
buffer_init(&jp->obuf);
return jp;
}
-void postfix_jpriv_wipe(jpriv_t *jp)
+static void postfix_jpriv_wipe(jpriv_t *jp)
{
buffer_wipe(&jp->ibuf);
buffer_wipe(&jp->obuf);
DO_NEW(jpriv_t, postfix_jpriv);
DO_DELETE(jpriv_t, postfix_jpriv);
-
-void postfix_start(job_t *listener)
-{
- job_t *job;
-
- job = job_accept(listener, JOB_READ);
- if (!job)
- return;
-
- job->jdata = postfix_jpriv_new();
-}
-
-void postfix_stop(job_t *job)
+static void postfix_stop(job_t *job)
{
postfix_jpriv_delete(&job->jdata);
}
-void postfix_process(job_t *job)
+static void postfix_process(job_t *job)
{
int nb;
switch (job->state) {
case JOB_LISTEN:
- return postfix_start(job);
+ if ((job = job_accept(job, JOB_READ))) {
+ job->jdata = postfix_jpriv_new();
+ job->process = &postfix_process;
+ job->stop = &postfix_stop;
+ }
+ return;
case JOB_WRITE:
nb = write(job->fd, job->jdata->obuf.data, job->jdata->obuf.len);