1 //---------------------------------------------------------------------- 2 // This software is part of the OpenBeOS distribution and is covered 3 // by the OpenBeOS license. 4 //--------------------------------------------------------------------- 5 6 #include <AppMisc.h> 7 #include <Looper.h> 8 #include <Messenger.h> 9 #include <NodeMonitor.h> 10 11 #include <syscalls.h> 12 13 // TODO: Tests! 14 15 16 // watch_node 17 /*! \brief Subscribes a target to node and/or mount watching, or unsubscribes 18 it from node watching. 19 20 Depending of \a flags the action performed by this function varies: 21 - \a flags is \c 0: The target is unsubscribed from watching the node. 22 \a node must not be \c NULL in this case. 23 - \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount 24 watching. 25 - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, 26 \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to 27 watching the specified aspects of the node. \a node must not be \c NULL 28 in this case. 29 30 Note, that the latter two cases are not mutual exlusive, i.e. mount and 31 node watching can be requested with a single call. 32 33 \param node node_ref referring to the node to be watched. May be \c NULL, 34 if only mount watching is requested. 35 \param flags Flags indicating the actions to be performed. 36 \param target Messenger referring to the target. Must be valid. 37 \return \c B_OK, if everything went fine, another error code otherwise. 38 */ 39 status_t 40 watch_node(const node_ref *node, uint32 flags, BMessenger target) 41 { 42 status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE); 43 if (error == B_OK) { 44 BLooper *looper = NULL; 45 BHandler *handler = target.Target(&looper); 46 error = watch_node(node, flags, handler, looper); 47 } 48 return error; 49 } 50 51 // watch_node 52 /*! \brief Subscribes a target to node and/or mount watching, or unsubscribes 53 it from node watching. 54 55 Depending of \a flags the action performed by this function varies: 56 - \a flags is \c 0: The target is unsubscribed from watching the node. 57 \a node must not be \c NULL in this case. 58 - \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount 59 watching. 60 - \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT, 61 \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to 62 watching the specified aspects of the node. \a node must not be \c NULL 63 in this case. 64 65 Note, that the latter two cases are not mutual exlusive, i.e. mount and 66 node watching can be requested with a single call. 67 68 \param node node_ref referring to the node to be watched. May be \c NULL, 69 if only mount watching is requested. 70 \param flags Flags indicating the actions to be performed. 71 \param handler The target handler. May be \c NULL, if \a looper is not 72 \c NULL. Then the preferred handler of the looper is targeted. 73 \param looper The target looper. May be \c NULL, if \a handler is not 74 \c NULL. Then the handler's looper is the target looper. 75 \return \c B_OK, if everything went fine, another error code otherwise. 76 */ 77 status_t 78 watch_node(const node_ref *node, uint32 flags, const BHandler *handler, 79 const BLooper *looper) 80 { 81 status_t error = B_OK; 82 // check looper and handler and get the handler token 83 int32 handlerToken = -2; 84 if (handler) { 85 handlerToken = _get_object_token_(handler); 86 if (looper) { 87 if (looper != handler->Looper()) 88 error = B_BAD_VALUE; 89 } else { 90 looper = handler->Looper(); 91 if (!looper) 92 error = B_BAD_VALUE; 93 } 94 } else if (!looper) 95 error = B_BAD_VALUE; 96 if (error == B_OK) { 97 port_id port = _get_looper_port_(looper); 98 if (flags == B_STOP_WATCHING) { 99 // unsubscribe from node node watching 100 if (node) 101 error = _kern_stop_watching(node->device, node->node, flags, port, handlerToken); 102 else 103 error = B_BAD_VALUE; 104 } else { 105 // subscribe to... 106 // mount watching 107 if (flags & B_WATCH_MOUNT) { 108 error = _kern_start_watching((dev_t)-1, (ino_t)-1, 0, port, handlerToken); 109 flags &= ~B_WATCH_MOUNT; 110 } 111 // node watching 112 if (error == B_OK && flags) 113 error = _kern_start_watching(node->device, node->node, flags, port, handlerToken); 114 } 115 } 116 return error; 117 } 118 119 // stop_watching 120 /*! \brief Unsubscribes a target from node and mount monitoring. 121 \param target Messenger referring to the target. Must be valid. 122 \return \c B_OK, if everything went fine, another error code otherwise. 123 */ 124 status_t 125 stop_watching(BMessenger target) 126 { 127 status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE); 128 if (error == B_OK) { 129 BLooper *looper = NULL; 130 BHandler *handler = target.Target(&looper); 131 error = stop_watching(handler, looper); 132 } 133 return error; 134 } 135 136 // stop_watching 137 /*! \brief Unsubscribes a target from node and mount monitoring. 138 \param handler The target handler. May be \c NULL, if \a looper is not 139 \c NULL. Then the preferred handler of the looper is targeted. 140 \param looper The target looper. May be \c NULL, if \a handler is not 141 \c NULL. Then the handler's looper is the target looper. 142 \return \c B_OK, if everything went fine, another error code otherwise. 143 */ 144 status_t 145 stop_watching(const BHandler *handler, const BLooper *looper) 146 { 147 status_t error = B_OK; 148 // check looper and handler and get the handler token 149 int32 handlerToken = -2; 150 if (handler) { 151 handlerToken = _get_object_token_(handler); 152 if (looper) { 153 if (looper != handler->Looper()) 154 error = B_BAD_VALUE; 155 } else { 156 looper = handler->Looper(); 157 if (!looper) 158 error = B_BAD_VALUE; 159 } 160 } else if (!looper) 161 error = B_BAD_VALUE; 162 // unsubscribe 163 if (error == B_OK) { 164 port_id port = _get_looper_port_(looper); 165 error = _kern_stop_notifying(port, handlerToken); 166 } 167 return error; 168 } 169 170