libipm: Add support for sending file descriptors
This commit is contained in:
parent
02a3821f4d
commit
8a71322fe4
@ -32,6 +32,35 @@
|
||||
|
||||
const char *libipm_valid_type_chars = "ybnqiuxtsdhogB";
|
||||
|
||||
/**************************************************************************//**
|
||||
* Send function for a struct trans initialised with libipm_init_trans()
|
||||
*
|
||||
* @param trans Transport to send on
|
||||
* @param data pointer to data to send
|
||||
* @param len Length of data to send
|
||||
* @return As for write(2)
|
||||
*/
|
||||
static int
|
||||
libipm_trans_send_proc(struct trans *self, const char *data, int len)
|
||||
{
|
||||
int rv;
|
||||
struct libipm_priv *priv = (struct libipm_priv *)self->extra_data;
|
||||
if (priv != NULL && data == self->out_s->data)
|
||||
{
|
||||
/* We're sending the message header. Send any file descriptors
|
||||
* as ancillary data */
|
||||
rv = g_sck_send_fd_set(self->sck, data, len,
|
||||
priv->out_fds, priv->out_fd_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = g_sck_send(self->sck, data, len, 0);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Destructor for a struct trans initialised with libipm_init_trans()
|
||||
*
|
||||
@ -83,6 +112,7 @@ libipm_init_trans(struct trans *trans,
|
||||
priv->facility = facility;
|
||||
priv->msgno_to_str = msgno_to_str;
|
||||
|
||||
trans->trans_send = libipm_trans_send_proc;
|
||||
trans->extra_data = priv;
|
||||
trans->extra_destructor = libipm_trans_destructor;
|
||||
|
||||
|
@ -67,6 +67,7 @@ enum libipm_status
|
||||
E_LI_UNIMPLEMENTED_TYPE, /***< Specified type code is unimplemented */
|
||||
E_LI_UNEXPECTED_TYPE, /***< Encountered unexpected type on input */
|
||||
E_LI_BUFFER_OVERFLOW, /***< End of buffer reached unexpectedly */
|
||||
E_LI_TOO_MANY_FDS, /***< Too many file descriptors encountered */
|
||||
E_LI_BAD_VALUE, /***< Specified (or incoming) value is out of range */
|
||||
E_LI_BAD_HEADER, /***< Bad incoming message header */
|
||||
E_LI_TRANSPORT_ERROR /***< Error detected at the transport level */
|
||||
@ -154,14 +155,17 @@ libipm_msg_out_init(struct trans *trans, unsigned short msgno,
|
||||
* x |int64_t | Signed (two's complement) 64-bit integer
|
||||
* t |uint64_t | Unsigned 64-bit integer
|
||||
* s |char * | NULL-terminated string
|
||||
* h |int | File descriptor
|
||||
* d | - | (reserved)
|
||||
* h | - | (reserved)
|
||||
* o | - | (reserved)
|
||||
* g | - | (reserved)
|
||||
*
|
||||
* For the 'b' type, only values 0 and 1 are allowed. Other values
|
||||
* generate an error.
|
||||
*
|
||||
* The 'h' type can only be used where the underlying transport is a
|
||||
* UNIX domain socket.
|
||||
*
|
||||
* The following additions to the D-Bus type system are also supported:-
|
||||
*
|
||||
* Char |C Type | Description
|
||||
|
@ -39,7 +39,12 @@ enum
|
||||
/**
|
||||
* Size of libipm header
|
||||
*/
|
||||
HEADER_SIZE = 12
|
||||
HEADER_SIZE = 12,
|
||||
|
||||
/**
|
||||
* Max number of file descriptors in a message
|
||||
*/
|
||||
MAX_FD_PER_MSG = 8
|
||||
};
|
||||
|
||||
/**
|
||||
@ -52,6 +57,8 @@ struct libipm_priv
|
||||
const char *(*msgno_to_str)(unsigned short msgno);
|
||||
unsigned short out_msgno;
|
||||
unsigned short out_param_count;
|
||||
unsigned short out_fd_count;
|
||||
int out_fds[MAX_FD_PER_MSG];
|
||||
unsigned short in_msgno;
|
||||
unsigned short in_param_count;
|
||||
};
|
||||
|
@ -306,6 +306,47 @@ append_char_ptr_type(char c, struct trans *trans, va_list *argptr)
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Add a file descriptor to the output stream
|
||||
*
|
||||
* @param c Type letter which triggered the call
|
||||
* @param trans libipm transport
|
||||
* @param argptr Pointer to value in argument stack (promoted to int)
|
||||
* @return != 0 for error
|
||||
*/
|
||||
static enum libipm_status
|
||||
append_fd_type(char c, va_list *argptr, struct trans *trans)
|
||||
{
|
||||
enum libipm_status rv = E_LI_SUCCESS;
|
||||
struct stream *s = trans->out_s;
|
||||
struct libipm_priv *priv = (struct libipm_priv *)trans->extra_data;
|
||||
int fd = va_arg(*argptr, int);
|
||||
if (fd < 0)
|
||||
{
|
||||
log_append_error(trans, "File descriptor cannot be < 0");
|
||||
rv = E_LI_PROGRAM_ERROR;
|
||||
}
|
||||
else if (!s_check_rem_out(s, 1))
|
||||
{
|
||||
log_append_error(trans,
|
||||
"Not enough space in output buffer for '%c'", c);
|
||||
rv = E_LI_BUFFER_OVERFLOW;
|
||||
}
|
||||
else if (priv->out_fd_count >= MAX_FD_PER_MSG)
|
||||
{
|
||||
log_append_error(trans,
|
||||
"Too many file descriptors for '%c'", c);
|
||||
rv = E_LI_TOO_MANY_FDS;
|
||||
}
|
||||
else
|
||||
{
|
||||
out_uint8(s, c);
|
||||
priv->out_fds[priv->out_fd_count++] = fd;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Append a fixed size block to the output stream
|
||||
*
|
||||
@ -405,6 +446,10 @@ libipm_msg_out_appendv(struct trans *trans, const char *format, va_list *argptr)
|
||||
rv = append_char_ptr_type(c, trans, argptr);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
rv = append_fd_type(c, argptr, trans);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
rv = append_fsb_type(c, trans, argptr);
|
||||
break;
|
||||
@ -441,6 +486,7 @@ init_output_buffer(struct trans *trans, unsigned short msgno)
|
||||
|
||||
priv->out_msgno = msgno;
|
||||
priv->out_param_count = 0;
|
||||
priv->out_fd_count = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user