Sorry for the duplicate, for some reasons gmail doesn't show the email as a reply to the first email sent.
Amine. On Mon, Dec 19, 2016 at 10:30 AM, amine.ahd <amine....@gmail.com> wrote: > Signed-off-by: amine.ahd <amine....@gmail.com> > --- > libubus-internal.h | 4 +++- > libubus-obj.c | 24 ++++++++++++++++-------- > libubus-req.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- > libubus.c | 2 +- > libubus.h | 19 +++++++++++++++++++ > ubusd_proto.c | 6 +++++- > 6 files changed, 91 insertions(+), 14 deletions(-) > > diff --git a/libubus-internal.h b/libubus-internal.h > index f62edc3..c4067d3 100644 > --- a/libubus-internal.h > +++ b/libubus-internal.h > @@ -24,7 +24,9 @@ int ubus_send_msg(struct ubus_context *ctx, uint32_t seq, > void ubus_process_msg(struct ubus_context *ctx, struct ubus_msghdr_buf *buf, > int fd); > int __hidden ubus_start_request(struct ubus_context *ctx, struct > ubus_request *req, > struct blob_attr *msg, int cmd, uint32_t > peer); > -void ubus_process_obj_msg(struct ubus_context *ctx, struct ubus_msghdr_buf > *buf); > +int __hidden __ubus_start_request(struct ubus_context *ctx, struct > ubus_request *req, > + struct blob_attr *msg, int cmd, uint32_t > peer); > +void ubus_process_obj_msg(struct ubus_context *ctx, struct ubus_msghdr_buf > *buf, int fd); > void ubus_process_req_msg(struct ubus_context *ctx, struct ubus_msghdr_buf > *buf, int fd); > void __hidden ubus_poll_data(struct ubus_context *ctx, int timeout); > > diff --git a/libubus-obj.c b/libubus-obj.c > index 990d04b..a9972c5 100644 > --- a/libubus-obj.c > +++ b/libubus-obj.c > @@ -11,12 +11,13 @@ > * GNU General Public License for more details. > */ > > +#include <unistd.h> > #include "libubus.h" > #include "libubus-internal.h" > > static void > ubus_process_unsubscribe(struct ubus_context *ctx, struct ubus_msghdr *hdr, > - struct ubus_object *obj, struct blob_attr **attrbuf) > + struct ubus_object *obj, struct blob_attr **attrbuf, > int fd) > { > struct ubus_subscriber *s; > > @@ -29,11 +30,13 @@ ubus_process_unsubscribe(struct ubus_context *ctx, struct > ubus_msghdr *hdr, > s = container_of(obj, struct ubus_subscriber, obj); > if (s->remove_cb) > s->remove_cb(ctx, s, blob_get_u32(attrbuf[UBUS_ATTR_TARGET])); > + > + close(fd); > } > > static void > ubus_process_notify(struct ubus_context *ctx, struct ubus_msghdr *hdr, > - struct ubus_object *obj, struct blob_attr **attrbuf) > + struct ubus_object *obj, struct blob_attr **attrbuf, int > fd) > { > if (!obj || !attrbuf[UBUS_ATTR_ACTIVE]) > return; > @@ -41,14 +44,18 @@ ubus_process_notify(struct ubus_context *ctx, struct > ubus_msghdr *hdr, > obj->has_subscribers = blob_get_u8(attrbuf[UBUS_ATTR_ACTIVE]); > if (obj->subscribe_cb) > obj->subscribe_cb(ctx, obj); > + > + close(fd); > } > static void > ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr, > - struct ubus_object *obj, struct blob_attr **attrbuf) > + struct ubus_object *obj, struct blob_attr **attrbuf, int > fd) > { > struct ubus_request_data req = { > .fd = -1, > + .req_fd = fd, > }; > + > int method; > int ret; > bool no_reply = false; > @@ -65,7 +72,7 @@ ubus_process_invoke(struct ubus_context *ctx, struct > ubus_msghdr *hdr, > > if (attrbuf[UBUS_ATTR_NO_REPLY]) > no_reply = blob_get_int8(attrbuf[UBUS_ATTR_NO_REPLY]); > - > + > req.peer = hdr->peer; > req.seq = hdr->seq; > req.object = obj->id; > @@ -88,6 +95,7 @@ found: > ret = obj->methods[method].handler(ctx, obj, &req, > > blob_data(attrbuf[UBUS_ATTR_METHOD]), > attrbuf[UBUS_ATTR_DATA]); > + close(req.req_fd); > if (req.deferred || no_reply) > return; > > @@ -95,16 +103,16 @@ send: > ubus_complete_deferred_request(ctx, &req, ret); > } > > -void __hidden ubus_process_obj_msg(struct ubus_context *ctx, struct > ubus_msghdr_buf *buf) > + > +void __hidden ubus_process_obj_msg(struct ubus_context *ctx, struct > ubus_msghdr_buf *buf, int fd) > { > void (*cb)(struct ubus_context *, struct ubus_msghdr *, > - struct ubus_object *, struct blob_attr **); > + struct ubus_object *, struct blob_attr **, int fd); > struct ubus_msghdr *hdr = &buf->hdr; > struct blob_attr **attrbuf; > struct ubus_object *obj; > uint32_t objid; > void *prev_data = NULL; > - > attrbuf = ubus_parse_msg(buf->data); > if (!attrbuf[UBUS_ATTR_OBJID]) > return; > @@ -131,7 +139,7 @@ void __hidden ubus_process_obj_msg(struct ubus_context > *ctx, struct ubus_msghdr_ > buf->data = NULL; > } > > - cb(ctx, hdr, obj, attrbuf); > + cb(ctx, hdr, obj, attrbuf, fd); > > if (prev_data) { > if (buf->data) > diff --git a/libubus-req.c b/libubus-req.c > index 416adab..5180a6f 100644 > --- a/libubus-req.c > +++ b/libubus-req.c > @@ -49,10 +49,9 @@ static void __ubus_process_req_data(struct ubus_request > *req) > } > } > > -int __hidden ubus_start_request(struct ubus_context *ctx, struct > ubus_request *req, > +int __hidden __ubus_start_request(struct ubus_context *ctx, struct > ubus_request *req, > struct blob_attr *msg, int cmd, uint32_t peer) > { > - memset(req, 0, sizeof(*req)); > > if (msg && blob_pad_len(msg) > UBUS_MAX_MSGLEN) > return -1; > @@ -62,9 +61,21 @@ int __hidden ubus_start_request(struct ubus_context *ctx, > struct ubus_request *r > req->ctx = ctx; > req->peer = peer; > req->seq = ++ctx->request_seq; > - return ubus_send_msg(ctx, req->seq, msg, cmd, peer, -1); > + > + return ubus_send_msg(ctx, req->seq, msg, cmd, peer, req->fd); > } > > +int __hidden ubus_start_request(struct ubus_context *ctx, struct > ubus_request *req, > + struct blob_attr *msg, int cmd, uint32_t peer) > +{ > + memset(req, 0, sizeof(*req)); > + > + req->fd = -1; > + > + return __ubus_start_request(ctx, req, msg, cmd, peer); > +} > + > + > void ubus_abort_request(struct ubus_context *ctx, struct ubus_request *req) > { > if (list_empty(&req->list)) > @@ -224,6 +235,23 @@ int ubus_invoke_async(struct ubus_context *ctx, uint32_t > obj, const char *method > return 0; > } > > + > +int ubus_invoke_async_fd(struct ubus_context *ctx, uint32_t obj, const char > *method, > + struct blob_attr *msg, struct ubus_request *req, int > fd) > +{ > + blob_buf_init(&b, 0); > + blob_put_int32(&b, UBUS_ATTR_OBJID, obj); > + blob_put_string(&b, UBUS_ATTR_METHOD, method); > + if (msg) > + blob_put(&b, UBUS_ATTR_DATA, blob_data(msg), blob_len(msg)); > + > + memset(req, 0, sizeof(*req)); > + req->fd = fd; > + if (__ubus_start_request(ctx, req, b.head, UBUS_MSG_INVOKE, obj) < 0) > + return UBUS_STATUS_INVALID_ARGUMENT; > + return 0; > +} > + > int ubus_invoke(struct ubus_context *ctx, uint32_t obj, const char *method, > struct blob_attr *msg, ubus_data_handler_t cb, void *priv, > int timeout) > @@ -240,6 +268,22 @@ int ubus_invoke(struct ubus_context *ctx, uint32_t obj, > const char *method, > return ubus_complete_request(ctx, &req, timeout); > } > > +int ubus_invoke_fd(struct ubus_context *ctx, uint32_t obj, const char > *method, > + struct blob_attr *msg, ubus_data_handler_t cb, void *priv, > + int timeout, int fd) > +{ > + struct ubus_request req; > + int rc; > + > + rc = ubus_invoke_async_fd(ctx, obj, method, msg, &req, fd); > + if (rc) > + return rc; > + > + req.data_cb = cb; > + req.priv = priv; > + return ubus_complete_request(ctx, &req, timeout); > +} > + > static void > ubus_notify_complete_cb(struct ubus_request *req, int ret) > { > diff --git a/libubus.c b/libubus.c > index 8163ff7..b25d8b0 100644 > --- a/libubus.c > +++ b/libubus.c > @@ -103,7 +103,7 @@ ubus_process_msg(struct ubus_context *ctx, struct > ubus_msghdr_buf *buf, int fd) > break; > } > > - ubus_process_obj_msg(ctx, buf); > + ubus_process_obj_msg(ctx, buf, fd); > break; > case UBUS_MSG_MONITOR: > if (ctx->monitor_cb) > diff --git a/libubus.h b/libubus.h > index 07239d6..350e694 100644 > --- a/libubus.h > +++ b/libubus.h > @@ -188,6 +188,7 @@ struct ubus_request_data { > /* internal use */ > bool deferred; > int fd; > + int req_fd; /* fd received from the initial request */ > }; > > struct ubus_request { > @@ -208,6 +209,8 @@ struct ubus_request { > ubus_fd_handler_t fd_cb; > ubus_complete_handler_t complete_cb; > > + int fd; > + > struct ubus_context *ctx; > void *priv; > }; > @@ -336,6 +339,14 @@ int ubus_invoke(struct ubus_context *ctx, uint32_t obj, > const char *method, > int ubus_invoke_async(struct ubus_context *ctx, uint32_t obj, const char > *method, > struct blob_attr *msg, struct ubus_request *req); > > +int ubus_invoke_fd(struct ubus_context *ctx, uint32_t obj, const char > *method, > + struct blob_attr *msg, ubus_data_handler_t cb, void *priv, > + int timeout, int fd); > + > +/* asynchronous version of ubus_invoke() */ > +int ubus_invoke_async_fd(struct ubus_context *ctx, uint32_t obj, const char > *method, > + struct blob_attr *msg, struct ubus_request *req, int > fd); > + > /* send a reply to an incoming object method call */ > int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req, > struct blob_attr *msg); > @@ -356,6 +367,14 @@ static inline void ubus_request_set_fd(struct > ubus_context *ctx, > req->fd = fd; > } > > +static inline int ubus_request_get_caller_fd(struct ubus_request_data *req) > +{ > + int fd = req->req_fd; > + req->req_fd = -1; > + > + return fd; > +} > + > void ubus_complete_deferred_request(struct ubus_context *ctx, > struct ubus_request_data *req, int ret); > > diff --git a/ubusd_proto.c b/ubusd_proto.c > index b591384..49b4ea9 100644 > --- a/ubusd_proto.c > +++ b/ubusd_proto.c > @@ -80,11 +80,15 @@ void > ubus_proto_send_msg_from_blob(struct ubus_client *cl, struct ubus_msg_buf > *ub, > uint8_t type) > { > + /* keep the fd to be passed if it is UBUS_MSG_INVOKE */ > + int fd = ub->fd; > ub = ubus_reply_from_blob(ub, true); > if (!ub) > return; > > ub->hdr.type = type; > + ub->fd = fd; > + > ubus_msg_send(cl, ub, true); > } > > @@ -446,7 +450,7 @@ void ubusd_proto_receive_message(struct ubus_client *cl, > struct ubus_msg_buf *ub > if (ub->hdr.type < __UBUS_MSG_LAST) > cb = handlers[ub->hdr.type]; > > - if (ub->hdr.type != UBUS_MSG_STATUS) > + if (ub->hdr.type != UBUS_MSG_STATUS && ub->hdr.type != > UBUS_MSG_INVOKE) > ubus_msg_close_fd(ub); > > if (cb) > -- > 2.6.6 > _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev