1 /* 2 * Copyright 2001-2010, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ingo Weinhold, bonefish@@users.sf.net 7 * Axel Dörfler, axeld@pinc-software.de 8 * Clemens Zeidler <haiku@clemens-zeidler.de> 9 */ 10 11 12 #include <Messenger.h> 13 #include <NodeMonitor.h> 14 15 #include <MessengerPrivate.h> 16 17 #include <syscalls.h> 18 19 #include "node_monitor_private.h" 20 21 22 // TODO: Tests! 23 24 25 // watch_volume 26 /*! \brief Subscribes a target to watch node changes on a volume. 27 28 Depending of \a flags the action performed by this function varies: 29 - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, 30 or \c B_WATCH_ATTR: The target is subscribed to 31 watching the specified aspects of any node on the volume. 32 33 \param volume dev_t referring to the volume to be watched. 34 \param flags Flags indicating the actions to be performed. 35 \param target Messenger referring to the target. Must be valid. 36 \return \c B_OK, if everything went fine, another error code otherwise. 37 */ 38 status_t 39 watch_volume(dev_t volume, uint32 flags, BMessenger target) 40 { 41 if ((flags & (B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR)) == 0) 42 return B_BAD_VALUE; 43 44 flags |= B_WATCH_VOLUME; 45 46 BMessenger::Private messengerPrivate(target); 47 port_id port = messengerPrivate.Port(); 48 int32 token = messengerPrivate.Token(); 49 return _kern_start_watching(volume, (ino_t)-1, flags, port, token); 50 } 51 52 53 status_t 54 watch_volume(dev_t volume, uint32 flags, const BHandler *handler, 55 const BLooper *looper) 56 { 57 return watch_volume(volume, flags, BMessenger(handler, looper)); 58 } 59 60 61 // watch_node 62 /*! \brief Subscribes a target to node and/or mount watching, or unsubscribes 63 it from node watching. 64 65 Depending of \a flags the action performed by this function varies: 66 - \a flags is \c 0: The target is unsubscribed from watching the node. 67 \a node must not be \c NULL in this case. 68 - \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount 69 watching. 70 - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, 71 \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to 72 watching the specified aspects of the node. \a node must not be \c NULL 73 in this case. 74 75 Note, that the latter two cases are not mutual exlusive, i.e. mount and 76 node watching can be requested with a single call. 77 78 \param node node_ref referring to the node to be watched. May be \c NULL, 79 if only mount watching is requested. 80 \param flags Flags indicating the actions to be performed. 81 \param target Messenger referring to the target. Must be valid. 82 \return \c B_OK, if everything went fine, another error code otherwise. 83 */ 84 status_t 85 watch_node(const node_ref *node, uint32 flags, BMessenger target) 86 { 87 if (!target.IsValid()) 88 return B_BAD_VALUE; 89 90 BMessenger::Private messengerPrivate(target); 91 port_id port = messengerPrivate.Port(); 92 int32 token = messengerPrivate.Token(); 93 94 if (flags == B_STOP_WATCHING) { 95 // unsubscribe from node node watching 96 if (node == NULL) 97 return B_BAD_VALUE; 98 99 return _kern_stop_watching(node->device, node->node, port, token); 100 } 101 102 // subscribe to... 103 // mount watching 104 if (flags & B_WATCH_MOUNT) { 105 status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1, 106 B_WATCH_MOUNT, port, token); 107 if (status < B_OK) 108 return status; 109 110 flags &= ~B_WATCH_MOUNT; 111 } 112 113 // node watching 114 if (flags != 0) { 115 if (node == NULL) 116 return B_BAD_VALUE; 117 118 return _kern_start_watching(node->device, node->node, flags, port, 119 token); 120 } 121 122 return B_OK; 123 } 124 125 // watch_node 126 /*! \brief Subscribes a target to node and/or mount watching, or unsubscribes 127 it from node watching. 128 129 Depending of \a flags the action performed by this function varies: 130 - \a flags is \c 0: The target is unsubscribed from watching the node. 131 \a node must not be \c NULL in this case. 132 - \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount 133 watching. 134 - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, 135 \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to 136 watching the specified aspects of the node. \a node must not be \c NULL 137 in this case. 138 139 Note, that the latter two cases are not mutual exlusive, i.e. mount and 140 node watching can be requested with a single call. 141 142 \param node node_ref referring to the node to be watched. May be \c NULL, 143 if only mount watching is requested. 144 \param flags Flags indicating the actions to be performed. 145 \param handler The target handler. May be \c NULL, if \a looper is not 146 \c NULL. Then the preferred handler of the looper is targeted. 147 \param looper The target looper. May be \c NULL, if \a handler is not 148 \c NULL. Then the handler's looper is the target looper. 149 \return \c B_OK, if everything went fine, another error code otherwise. 150 */ 151 status_t 152 watch_node(const node_ref *node, uint32 flags, const BHandler *handler, 153 const BLooper *looper) 154 { 155 return watch_node(node, flags, BMessenger(handler, looper)); 156 } 157 158 159 /*! \brief Unsubscribes a target from node and mount monitoring. 160 \param target Messenger referring to the target. Must be valid. 161 \return \c B_OK, if everything went fine, another error code otherwise. 162 */ 163 status_t 164 stop_watching(BMessenger target) 165 { 166 if (!target.IsValid()) 167 return B_BAD_VALUE; 168 169 BMessenger::Private messengerPrivate(target); 170 port_id port = messengerPrivate.Port(); 171 int32 token = messengerPrivate.Token(); 172 173 return _kern_stop_notifying(port, token); 174 } 175 176 177 /*! \brief Unsubscribes a target from node and mount monitoring. 178 \param handler The target handler. May be \c NULL, if \a looper is not 179 \c NULL. Then the preferred handler of the looper is targeted. 180 \param looper The target looper. May be \c NULL, if \a handler is not 181 \c NULL. Then the handler's looper is the target looper. 182 \return \c B_OK, if everything went fine, another error code otherwise. 183 */ 184 status_t 185 stop_watching(const BHandler *handler, const BLooper *looper) 186 { 187 return stop_watching(BMessenger(handler, looper)); 188 } 189 190