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) == 0 && (flags | B_WATCH_STAT) 42 && (flags | B_WATCH_ATTR)) 43 return B_BAD_VALUE; 44 45 flags |= B_WATCH_VOLUME; 46 47 BMessenger::Private messengerPrivate(target); 48 port_id port = messengerPrivate.Port(); 49 int32 token = messengerPrivate.Token(); 50 return _kern_start_watching(volume, (ino_t)-1, flags, port, token); 51 } 52 53 54 status_t 55 watch_volume(dev_t volume, uint32 flags, const BHandler *handler, 56 const BLooper *looper) 57 { 58 return watch_volume(volume, flags, BMessenger(handler, looper)); 59 } 60 61 62 // watch_node 63 /*! \brief Subscribes a target to node and/or mount watching, or unsubscribes 64 it from node watching. 65 66 Depending of \a flags the action performed by this function varies: 67 - \a flags is \c 0: The target is unsubscribed from watching the node. 68 \a node must not be \c NULL in this case. 69 - \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount 70 watching. 71 - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, 72 \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to 73 watching the specified aspects of the node. \a node must not be \c NULL 74 in this case. 75 76 Note, that the latter two cases are not mutual exlusive, i.e. mount and 77 node watching can be requested with a single call. 78 79 \param node node_ref referring to the node to be watched. May be \c NULL, 80 if only mount watching is requested. 81 \param flags Flags indicating the actions to be performed. 82 \param target Messenger referring to the target. Must be valid. 83 \return \c B_OK, if everything went fine, another error code otherwise. 84 */ 85 status_t 86 watch_node(const node_ref *node, uint32 flags, BMessenger target) 87 { 88 if (!target.IsValid()) 89 return B_BAD_VALUE; 90 91 BMessenger::Private messengerPrivate(target); 92 port_id port = messengerPrivate.Port(); 93 int32 token = messengerPrivate.Token(); 94 95 if (flags == B_STOP_WATCHING) { 96 // unsubscribe from node node watching 97 if (node == NULL) 98 return B_BAD_VALUE; 99 100 return _kern_stop_watching(node->device, node->node, port, token); 101 } 102 103 // subscribe to... 104 // mount watching 105 if (flags & B_WATCH_MOUNT) { 106 status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1, 107 B_WATCH_MOUNT, port, token); 108 if (status < B_OK) 109 return status; 110 111 flags &= ~B_WATCH_MOUNT; 112 } 113 114 // node watching 115 if (flags != 0) { 116 if (node == NULL) 117 return B_BAD_VALUE; 118 119 return _kern_start_watching(node->device, node->node, flags, port, 120 token); 121 } 122 123 return B_OK; 124 } 125 126 // watch_node 127 /*! \brief Subscribes a target to node and/or mount watching, or unsubscribes 128 it from node watching. 129 130 Depending of \a flags the action performed by this function varies: 131 - \a flags is \c 0: The target is unsubscribed from watching the node. 132 \a node must not be \c NULL in this case. 133 - \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount 134 watching. 135 - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, 136 \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to 137 watching the specified aspects of the node. \a node must not be \c NULL 138 in this case. 139 140 Note, that the latter two cases are not mutual exlusive, i.e. mount and 141 node watching can be requested with a single call. 142 143 \param node node_ref referring to the node to be watched. May be \c NULL, 144 if only mount watching is requested. 145 \param flags Flags indicating the actions to be performed. 146 \param handler The target handler. May be \c NULL, if \a looper is not 147 \c NULL. Then the preferred handler of the looper is targeted. 148 \param looper The target looper. May be \c NULL, if \a handler is not 149 \c NULL. Then the handler's looper is the target looper. 150 \return \c B_OK, if everything went fine, another error code otherwise. 151 */ 152 status_t 153 watch_node(const node_ref *node, uint32 flags, const BHandler *handler, 154 const BLooper *looper) 155 { 156 return watch_node(node, flags, BMessenger(handler, looper)); 157 } 158 159 160 /*! \brief Unsubscribes a target from node and mount monitoring. 161 \param target Messenger referring to the target. Must be valid. 162 \return \c B_OK, if everything went fine, another error code otherwise. 163 */ 164 status_t 165 stop_watching(BMessenger target) 166 { 167 if (!target.IsValid()) 168 return B_BAD_VALUE; 169 170 BMessenger::Private messengerPrivate(target); 171 port_id port = messengerPrivate.Port(); 172 int32 token = messengerPrivate.Token(); 173 174 return _kern_stop_notifying(port, token); 175 } 176 177 178 /*! \brief Unsubscribes a target from node and mount monitoring. 179 \param handler The target handler. May be \c NULL, if \a looper is not 180 \c NULL. Then the preferred handler of the looper is targeted. 181 \param looper The target looper. May be \c NULL, if \a handler is not 182 \c NULL. Then the handler's looper is the target looper. 183 \return \c B_OK, if everything went fine, another error code otherwise. 184 */ 185 status_t 186 stop_watching(const BHandler *handler, const BLooper *looper) 187 { 188 return stop_watching(BMessenger(handler, looper)); 189 } 190 191