2 * ion/mod_statusbar/statusd-launch.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
10 #include <sys/types.h>
15 #include <libtu/minmax.h>
16 #include <libextl/readconfig.h>
17 #include <libmainloop/exec.h>
18 #include <libmainloop/select.h>
19 #include <libmainloop/signal.h>
20 #include <ioncore/saveload.h>
21 #include <ioncore/bindmaps.h>
22 #include <ioncore/global.h>
23 #include <ioncore/ioncore.h>
25 #include "statusbar.h"
28 #define CF_STATUSD_TIMEOUT_SEC 3
35 static bool process_pipe(int fd
, ExtlFn fn
,
36 bool *doneseen
, bool *eagain
)
44 n
=read(fd
, buf
, BL
-1);
47 if(errno
==EAGAIN
|| errno
==EINTR
){
48 *eagain
=(errno
==EAGAIN
);
51 warn_err_obj(TR("reading a pipe"));
56 return extl_call(fn
, "s", "b", &buf
, doneseen
);
63 static bool wait_statusd_init(int outfd
, int errfd
, ExtlFn dh
, ExtlFn eh
)
66 struct timeval tv
, endtime
, now
;
67 int nfds
=maxof(outfd
, errfd
);
69 bool dummy
, doneseen
, eagain
=FALSE
;
71 if(mainloop_gettime(&endtime
)!=0){
77 endtime
.tv_sec
+=CF_STATUSD_TIMEOUT_SEC
;
82 /* Calculate remaining time */
83 if(now
.tv_sec
>endtime
.tv_sec
){
85 }else if(now
.tv_sec
==endtime
.tv_sec
){
86 if(now
.tv_usec
>=endtime
.tv_usec
)
89 tv
.tv_usec
=endtime
.tv_usec
-now
.tv_usec
;
91 tv
.tv_usec
=USEC
+endtime
.tv_usec
-now
.tv_usec
;
92 tv
.tv_sec
=-1+endtime
.tv_sec
-now
.tv_sec
;
93 /* Kernel lameness tuner: */
94 tv
.tv_sec
+=tv
.tv_usec
/USEC
;
101 retval
=select(nfds
+1, &rfds
, NULL
, NULL
, &tv
);
103 if(FD_ISSET(errfd
, &rfds
)){
104 if(!process_pipe(errfd
, eh
, &dummy
, &eagain
))
107 if(FD_ISSET(outfd
, &rfds
)){
108 if(!process_pipe(outfd
, dh
, &doneseen
, &eagain
))
111 /* Read rest of errors. */
114 ok
=process_pipe(errfd
, eh
, &dummy
, &eagain
);
115 }while(ok
&& !eagain
);
123 if(mainloop_gettime(&now
)!=0){
132 /* Just complain to stderr, not startup error log, and do not fail.
133 * The system might just be a bit slow. We can continue, but without
134 * initial values for the meters, geometry adjustments may be necessary
135 * when we finally get that information.
137 ioncore_warn_nolog(TR("ion-statusd timed out."));
143 int mod_statusbar__launch_statusd(const char *cmd
,
144 ExtlFn initdatahandler
,
145 ExtlFn initerrhandler
,
150 int outfd
=-1, errfd
=-1;
155 pid
=mainloop_do_spawn(cmd
, NULL
, NULL
,
156 NULL
, &outfd
, &errfd
);
161 if(!wait_statusd_init(outfd
, errfd
, initdatahandler
, initerrhandler
))
164 if(!mainloop_register_input_fd_extlfn(outfd
, datahandler
))
167 if(!mainloop_register_input_fd_extlfn(errfd
, errhandler
))
173 mainloop_unregister_input_fd(outfd
);