/*! \brief Remove a target from the list of targets to be notified on disk device events. \param target A BMessenger identifying the target to which notfication message shall not longer be sent. \return \c B_OK, if everything went fine, another error code otherwise. */ status_t BDiskDeviceRoster::StopWatching(BMessenger target) { BMessenger::Private messengerPrivate(target); port_id port = messengerPrivate.Port(); int32 token = messengerPrivate.Token(); return _kern_stop_watching_disks(port, token); }
/*! \brief Unsubscribes a target from node and mount monitoring. \param target Messenger referring to the target. Must be valid. \return \c B_OK, if everything went fine, another error code otherwise. */ status_t stop_watching(BMessenger target) { if (!target.IsValid()) return B_BAD_VALUE; BMessenger::Private messengerPrivate(target); port_id port = messengerPrivate.Port(); int32 token = messengerPrivate.Token(); return _kern_stop_notifying(port, token); }
/*! \brief Adds a target to the list of targets to be notified on disk device events. \todo List the event mask flags, the events and describe the layout of the notification message. If \a target is already listening to events, this method replaces the former event mask with \a eventMask. \param target A BMessenger identifying the target to which the events shall be sent. \param eventMask A mask specifying on which events the target shall be notified. \return \c B_OK, if everything went fine, another error code otherwise. */ status_t BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask) { if (eventMask == 0) return B_BAD_VALUE; BMessenger::Private messengerPrivate(target); port_id port = messengerPrivate.Port(); int32 token = messengerPrivate.Token(); return _kern_start_watching_disks(eventMask, port, token); }
/*! \brief Subscribes a target to watch node changes on a volume. Depending of \a flags the action performed by this function varies: - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, or \c B_WATCH_ATTR: The target is subscribed to watching the specified aspects of any node on the volume. \param volume dev_t referring to the volume to be watched. \param flags Flags indicating the actions to be performed. \param target Messenger referring to the target. Must be valid. \return \c B_OK, if everything went fine, another error code otherwise. */ status_t watch_volume(dev_t volume, uint32 flags, BMessenger target) { if ((flags & (B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR)) == 0) return B_BAD_VALUE; flags |= B_WATCH_VOLUME; BMessenger::Private messengerPrivate(target); port_id port = messengerPrivate.Port(); int32 token = messengerPrivate.Token(); return _kern_start_watching(volume, (ino_t)-1, flags, port, token); }
/*! \brief Subscribes a target to node and/or mount watching, or unsubscribes it from node watching. Depending of \a flags the action performed by this function varies: - \a flags is \c 0: The target is unsubscribed from watching the node. \a node must not be \c NULL in this case. - \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount watching. - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to watching the specified aspects of the node. \a node must not be \c NULL in this case. Note, that the latter two cases are not mutual exlusive, i.e. mount and node watching can be requested with a single call. \param node node_ref referring to the node to be watched. May be \c NULL, if only mount watching is requested. \param flags Flags indicating the actions to be performed. \param target Messenger referring to the target. Must be valid. \return \c B_OK, if everything went fine, another error code otherwise. */ status_t watch_node(const node_ref *node, uint32 flags, BMessenger target) { if (!target.IsValid()) return B_BAD_VALUE; BMessenger::Private messengerPrivate(target); port_id port = messengerPrivate.Port(); int32 token = messengerPrivate.Token(); if (flags == B_STOP_WATCHING) { // unsubscribe from node node watching if (node == NULL) return B_BAD_VALUE; return _kern_stop_watching(node->device, node->node, port, token); } // subscribe to... // mount watching if (flags & B_WATCH_MOUNT) { status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1, B_WATCH_MOUNT, port, token); if (status < B_OK) return status; flags &= ~B_WATCH_MOUNT; } // node watching if (flags != 0) { if (node == NULL) return B_BAD_VALUE; return _kern_start_watching(node->device, node->node, flags, port, token); } return B_OK; }
status_t swap_data(type_code type, void *_data, size_t length, swap_action action) { // is there anything to do? #if B_HOST_IS_LENDIAN if (action == B_SWAP_HOST_TO_LENDIAN || action == B_SWAP_LENDIAN_TO_HOST) return B_OK; #else if (action == B_SWAP_HOST_TO_BENDIAN || action == B_SWAP_BENDIAN_TO_HOST) return B_OK; #endif if (length == 0) return B_OK; if (_data == NULL) return B_BAD_VALUE; // ToDo: these are not safe. If the length is smaller than the size of // the type to be converted, too much data may be read. R5 behaves in the // same way though. switch (type) { // 16 bit types case B_INT16_TYPE: case B_UINT16_TYPE: { uint16 *data = (uint16 *)_data; uint16 *end = (uint16 *)((addr_t)_data + length); while (data < end) { *data = __swap_int16(*data); data++; } break; } // 32 bit types case B_FLOAT_TYPE: case B_INT32_TYPE: case B_UINT32_TYPE: case B_TIME_TYPE: case B_RECT_TYPE: case B_POINT_TYPE: #if B_HAIKU_32_BIT case B_SIZE_T_TYPE: case B_SSIZE_T_TYPE: case B_POINTER_TYPE: #endif { uint32 *data = (uint32 *)_data; uint32 *end = (uint32 *)((addr_t)_data + length); while (data < end) { *data = __swap_int32(*data); data++; } break; } // 64 bit types case B_DOUBLE_TYPE: case B_INT64_TYPE: case B_UINT64_TYPE: case B_OFF_T_TYPE: #if B_HAIKU_64_BIT case B_SIZE_T_TYPE: case B_SSIZE_T_TYPE: case B_POINTER_TYPE: #endif { uint64 *data = (uint64 *)_data; uint64 *end = (uint64 *)((addr_t)_data + length); while (data < end) { *data = __swap_int64(*data); data++; } break; } // special types case B_MESSENGER_TYPE: { BMessenger *messenger = (BMessenger *)_data; BMessenger *end = (BMessenger *)((addr_t)_data + length); while (messenger < end) { BMessenger::Private messengerPrivate(messenger); // ToDo: if the additional fields change, this function has to be updated! messengerPrivate.SetTo( __swap_int32(messengerPrivate.Team()), __swap_int32(messengerPrivate.Port()), __swap_int32(messengerPrivate.Token())); messenger++; } break; } default: // not swappable or recognized type! return B_BAD_VALUE; } return B_OK; }
status_t swap_data(type_code type, void *_data, size_t length, swap_action action) { if (_data == NULL || length == 0) return B_BAD_VALUE; switch (type) { // allowed types case B_INT16_TYPE: case B_UINT16_TYPE: case B_FLOAT_TYPE: case B_INT32_TYPE: case B_UINT32_TYPE: case B_SIZE_T_TYPE: case B_SSIZE_T_TYPE: case B_TIME_TYPE: case B_POINTER_TYPE: case B_RECT_TYPE: case B_POINT_TYPE: case B_DOUBLE_TYPE: case B_INT64_TYPE: case B_UINT64_TYPE: case B_OFF_T_TYPE: case B_MESSENGER_TYPE: break; default: // not swappable or recognized type! return B_BAD_VALUE; } // is there anything to do? #if B_HOST_IS_LENDIAN if (action == B_SWAP_HOST_TO_LENDIAN || action == B_SWAP_LENDIAN_TO_HOST) return B_OK; #else if (action == B_SWAP_HOST_TO_BENDIAN || action == B_SWAP_BENDIAN_TO_HOST) return B_OK; #endif switch (type) { // 16 bit types case B_INT16_TYPE: case B_UINT16_TYPE: { uint16 *data = (uint16 *)_data; uint16 *end = (uint16 *)((addr_t)_data + length); while (data < end) { *data = __swap_int16(*data); data++; } break; } // 32 bit types case B_FLOAT_TYPE: case B_INT32_TYPE: case B_UINT32_TYPE: case B_SIZE_T_TYPE: case B_SSIZE_T_TYPE: case B_TIME_TYPE: case B_POINTER_TYPE: case B_RECT_TYPE: case B_POINT_TYPE: { // ToDo: some of these types may not be 32-bit on 64-bit platforms! uint32 *data = (uint32 *)_data; uint32 *end = (uint32 *)((addr_t)_data + length); while (data < end) { *data = __swap_int32(*data); data++; } break; } // 64 bit types case B_DOUBLE_TYPE: case B_INT64_TYPE: case B_UINT64_TYPE: case B_OFF_T_TYPE: { uint64 *data = (uint64 *)_data; uint64 *end = (uint64 *)((addr_t)_data + length); while (data < end) { *data = __swap_int64(*data); data++; } break; } // special types case B_MESSENGER_TYPE: { BMessenger *messenger = (BMessenger *)_data; BMessenger *end = (BMessenger *)((addr_t)_data + length); while (messenger < end) { BMessenger::Private messengerPrivate(messenger); // ToDo: if the additional fields change, this function has to be updated! messengerPrivate.SetTo( __swap_int32(messengerPrivate.Team()), __swap_int32(messengerPrivate.Port()), __swap_int32(messengerPrivate.Token())); messenger++; } break; } } return B_OK; }