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:
parent
a94ce1c912
commit
7727e08e5f
@ -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)))
|
||||
|
||||
|
||||
// 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 */
|
||||
|
||||
|
@ -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,
|
||||
const iovec *msgVecs, size_t vecCount,
|
||||
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
|
||||
}
|
||||
|
@ -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,
|
||||
const struct iovec *msgVecs, size_t vecCount,
|
||||
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
|
||||
extern void _kern_debugger(const char *message);
|
||||
|
@ -40,6 +40,9 @@ typedef struct port_msg {
|
||||
int32 code;
|
||||
cbuf *buffer_chain;
|
||||
size_t size;
|
||||
uid_t sender;
|
||||
gid_t sender_group;
|
||||
team_id sender_team;
|
||||
} port_msg;
|
||||
|
||||
struct port_entry {
|
||||
@ -811,11 +814,22 @@ port_buffer_size(port_id id)
|
||||
ssize_t
|
||||
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;
|
||||
sem_id cachedSem;
|
||||
status_t status;
|
||||
port_msg *msg;
|
||||
ssize_t size;
|
||||
int32 slot;
|
||||
|
||||
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
|
||||
status_t error = B_OK;
|
||||
msg = (port_msg*)list_get_first_item(&sPorts[slot].msg_queue);
|
||||
if (msg == NULL) {
|
||||
if (status == B_OK)
|
||||
panic("port %ld: no messages found\n", sPorts[slot].id);
|
||||
|
||||
size = B_BAD_PORT_ID;
|
||||
} else
|
||||
size = msg->size;
|
||||
error = B_BAD_PORT_ID;
|
||||
} else {
|
||||
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]);
|
||||
restore_interrupts(state);
|
||||
@ -876,7 +895,7 @@ port_buffer_size_etc(port_id id, uint32 flags, bigtime_t timeout)
|
||||
release_sem(cachedSem);
|
||||
|
||||
// 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)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// sender credentials
|
||||
msg->sender = geteuid();
|
||||
msg->sender_group = getegid();
|
||||
msg->sender_team = team_get_current_team_id();
|
||||
|
||||
if (bufferSize > 0) {
|
||||
uint32 i;
|
||||
if (userCopy) {
|
||||
@ -1418,3 +1442,26 @@ _user_writev_port_etc(port_id port, int32 messageCode, const iovec *userVecs,
|
||||
free(vecs);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user