Added experimental public API get_port_message_info_etc(). It is similar
to port_buffer_size_etc(), but returns the info through a structure, which also identifies the sender (uid, gid, team ID) of the message. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25003 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -135,6 +135,25 @@ extern status_t _get_next_port_info(team_id team, int32 *cookie, port_info *port
|
|||||||
_get_next_port_info((team), (cookie), (info), sizeof(*(info)))
|
_get_next_port_info((team), (cookie), (info), sizeof(*(info)))
|
||||||
|
|
||||||
|
|
||||||
|
// WARNING: The following is Haiku experimental API. It might be removed or
|
||||||
|
// changed in the future.
|
||||||
|
|
||||||
|
typedef struct port_message_info {
|
||||||
|
size_t size;
|
||||||
|
uid_t sender;
|
||||||
|
gid_t sender_group;
|
||||||
|
team_id sender_team;
|
||||||
|
} port_message_info;
|
||||||
|
|
||||||
|
// similar to port_buffer_size_etc(), but returns (more) info
|
||||||
|
extern status_t _get_port_message_info_etc(port_id port,
|
||||||
|
port_message_info *info, size_t infoSize, uint32 flags,
|
||||||
|
bigtime_t timeout);
|
||||||
|
|
||||||
|
#define get_port_message_info_etc(port, info, flags, timeout) \
|
||||||
|
_get_port_message_info_etc((port), (info), sizeof(*(info)), flags, \
|
||||||
|
timeout)
|
||||||
|
|
||||||
/*-------------------------------------------------------------*/
|
/*-------------------------------------------------------------*/
|
||||||
/* Semaphores */
|
/* Semaphores */
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ status_t _user_write_port_etc(port_id port, int32 msgCode,
|
|||||||
status_t _user_writev_port_etc(port_id id, int32 msgCode,
|
status_t _user_writev_port_etc(port_id id, int32 msgCode,
|
||||||
const iovec *msgVecs, size_t vecCount,
|
const iovec *msgVecs, size_t vecCount,
|
||||||
size_t bufferSize, uint32 flags, bigtime_t timeout);
|
size_t bufferSize, uint32 flags, bigtime_t timeout);
|
||||||
|
status_t _user_get_port_message_info_etc(port_id port,
|
||||||
|
port_message_info *info, size_t infoSize, uint32 flags,
|
||||||
|
bigtime_t timeout);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,6 +318,9 @@ extern status_t _kern_write_port_etc(port_id port, int32 msgCode, const void *m
|
|||||||
extern status_t _kern_writev_port_etc(port_id id, int32 msgCode,
|
extern status_t _kern_writev_port_etc(port_id id, int32 msgCode,
|
||||||
const struct iovec *msgVecs, size_t vecCount,
|
const struct iovec *msgVecs, size_t vecCount,
|
||||||
size_t bufferSize, uint32 flags, bigtime_t timeout);
|
size_t bufferSize, uint32 flags, bigtime_t timeout);
|
||||||
|
extern status_t _kern_get_port_message_info_etc(port_id port,
|
||||||
|
port_message_info *info, size_t infoSize, uint32 flags,
|
||||||
|
bigtime_t timeout);
|
||||||
|
|
||||||
// debug support functions
|
// debug support functions
|
||||||
extern void _kern_debugger(const char *message);
|
extern void _kern_debugger(const char *message);
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ typedef struct port_msg {
|
|||||||
int32 code;
|
int32 code;
|
||||||
cbuf *buffer_chain;
|
cbuf *buffer_chain;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
uid_t sender;
|
||||||
|
gid_t sender_group;
|
||||||
|
team_id sender_team;
|
||||||
} port_msg;
|
} port_msg;
|
||||||
|
|
||||||
struct port_entry {
|
struct port_entry {
|
||||||
@@ -811,11 +814,22 @@ port_buffer_size(port_id id)
|
|||||||
ssize_t
|
ssize_t
|
||||||
port_buffer_size_etc(port_id id, uint32 flags, bigtime_t timeout)
|
port_buffer_size_etc(port_id id, uint32 flags, bigtime_t timeout)
|
||||||
{
|
{
|
||||||
|
port_message_info info;
|
||||||
|
status_t error = get_port_message_info_etc(id, &info, flags, timeout);
|
||||||
|
return error != B_OK ? error : info.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
_get_port_message_info_etc(port_id id, port_message_info *info,
|
||||||
|
size_t infoSize, uint32 flags, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
if (info == NULL || infoSize != sizeof(port_message_info))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
cpu_status state;
|
cpu_status state;
|
||||||
sem_id cachedSem;
|
sem_id cachedSem;
|
||||||
status_t status;
|
status_t status;
|
||||||
port_msg *msg;
|
port_msg *msg;
|
||||||
ssize_t size;
|
|
||||||
int32 slot;
|
int32 slot;
|
||||||
|
|
||||||
if (!sPortsActive || id < 0)
|
if (!sPortsActive || id < 0)
|
||||||
@@ -860,14 +874,19 @@ port_buffer_size_etc(port_id id, uint32 flags, bigtime_t timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// determine tail & get the length of the message
|
// determine tail & get the length of the message
|
||||||
|
status_t error = B_OK;
|
||||||
msg = (port_msg*)list_get_first_item(&sPorts[slot].msg_queue);
|
msg = (port_msg*)list_get_first_item(&sPorts[slot].msg_queue);
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
panic("port %ld: no messages found\n", sPorts[slot].id);
|
panic("port %ld: no messages found\n", sPorts[slot].id);
|
||||||
|
|
||||||
size = B_BAD_PORT_ID;
|
error = B_BAD_PORT_ID;
|
||||||
} else
|
} else {
|
||||||
size = msg->size;
|
info->size = msg->size;
|
||||||
|
info->sender = msg->sender;
|
||||||
|
info->sender_group = msg->sender_group;
|
||||||
|
info->sender_team = msg->sender_team;
|
||||||
|
}
|
||||||
|
|
||||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
RELEASE_PORT_LOCK(sPorts[slot]);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
@@ -876,7 +895,7 @@ port_buffer_size_etc(port_id id, uint32 flags, bigtime_t timeout)
|
|||||||
release_sem(cachedSem);
|
release_sem(cachedSem);
|
||||||
|
|
||||||
// return length of item at end of queue
|
// return length of item at end of queue
|
||||||
return size;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1119,6 +1138,11 @@ writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
|
|||||||
if (msg == NULL)
|
if (msg == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
// sender credentials
|
||||||
|
msg->sender = geteuid();
|
||||||
|
msg->sender_group = getegid();
|
||||||
|
msg->sender_team = team_get_current_team_id();
|
||||||
|
|
||||||
if (bufferSize > 0) {
|
if (bufferSize > 0) {
|
||||||
uint32 i;
|
uint32 i;
|
||||||
if (userCopy) {
|
if (userCopy) {
|
||||||
@@ -1418,3 +1442,26 @@ _user_writev_port_etc(port_id port, int32 messageCode, const iovec *userVecs,
|
|||||||
free(vecs);
|
free(vecs);
|
||||||
return syscall_restart_handle_timeout_post(status, timeout);
|
return syscall_restart_handle_timeout_post(status, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
_user_get_port_message_info_etc(port_id port, port_message_info *userInfo,
|
||||||
|
size_t infoSize, uint32 flags, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
if (userInfo == NULL || infoSize != sizeof(port_message_info))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
syscall_restart_handle_timeout_pre(flags, timeout);
|
||||||
|
|
||||||
|
port_message_info info;
|
||||||
|
status_t error = _get_port_message_info_etc(port, &info, sizeof(info),
|
||||||
|
flags | B_CAN_INTERRUPT, timeout);
|
||||||
|
|
||||||
|
// copy info to userland
|
||||||
|
if (error == B_OK && (!IS_USER_ADDRESS(userInfo)
|
||||||
|
|| user_memcpy(userInfo, &info, sizeof(info)) != B_OK)) {
|
||||||
|
error = B_BAD_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return syscall_restart_handle_timeout_post(error, timeout);
|
||||||
|
}
|
||||||
|
|||||||
@@ -110,3 +110,11 @@ _get_port_info(port_id port, port_info *info, size_t size)
|
|||||||
return _kern_get_port_info(port, info);
|
return _kern_get_port_info(port, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
_get_port_message_info_etc(port_id port, port_message_info *info,
|
||||||
|
size_t infoSize, uint32 flags, bigtime_t timeout)
|
||||||
|
{
|
||||||
|
return _kern_get_port_message_info_etc(port, info, infoSize, flags,
|
||||||
|
timeout);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user