File: select.c

package info (click to toggle)
notion 4.0.2%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,676 kB
  • sloc: ansic: 47,508; sh: 2,096; makefile: 603; perl: 270
file content (107 lines) | stat: -rw-r--r-- 1,747 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * ion/libmainloop/mainloop.c
 *
 * Partly based on a contributed code.
 *
 * See the included file LICENSE for details.
 */

#include <libtu/types.h>
#include <libtu/misc.h>
#include <libtu/dlist.h>

#include "select.h"


/*{{{ File descriptor management */


static WInputFd *input_fds=NULL;

static WInputFd *find_input_fd(int fd)
{
    WInputFd *tmp=input_fds;

    while(tmp){
        if(tmp->fd==fd)
            break;
        tmp=tmp->next;
    }
    return tmp;
}

bool mainloop_register_input_fd(int fd, void *data,
                                void (*callback)(int fd, void *d))
{
    WInputFd *tmp;

    if(find_input_fd(fd)!=NULL)
        return FALSE;

    tmp=ALLOC(WInputFd);
    if(tmp==NULL)
        return FALSE;

    tmp->fd=fd;
    tmp->data=data;
    tmp->process_input_fn=callback;

    LINK_ITEM(input_fds, tmp, next, prev);

    return TRUE;
}

void mainloop_unregister_input_fd(int fd)
{
    WInputFd *tmp=find_input_fd(fd);

    if(tmp!=NULL){
        UNLINK_ITEM(input_fds, tmp, next, prev);
        free(tmp);
    }
}

static void set_input_fds(fd_set *rfds, int *nfds)
{
    WInputFd *tmp=input_fds;

    while(tmp){
        FD_SET(tmp->fd, rfds);
        if(tmp->fd>*nfds)
            *nfds=tmp->fd;
        tmp=tmp->next;
    }
}

static void check_input_fds(fd_set *rfds)
{
    WInputFd *tmp=input_fds, *next=NULL;

    while(tmp){
        next=tmp->next;
        if(FD_ISSET(tmp->fd, rfds))
            tmp->process_input_fn(tmp->fd, tmp->data);
        tmp=next;
    }
}

/*}}}*/


/*{{{ Select */

void mainloop_select()
{
    fd_set rfds;
    int nfds=0;

    FD_ZERO(&rfds);

    set_input_fds(&rfds, &nfds);

    if(select(nfds+1, &rfds, NULL, NULL, NULL)>0)
        check_input_fds(&rfds);
}


/*}}}*/