14eeeeea9SAxel Dörfler/*
2a30a4a41SJohn Scipione * Copyright 2001-2010 Haiku, Inc. All rights reserved.
34eeeeea9SAxel Dörfler * Distributed under the terms of the MIT License.
44eeeeea9SAxel Dörfler *
54eeeeea9SAxel Dörfler * Authors:
64eeeeea9SAxel Dörfler *		Ingo Weinhold, bonefish@@users.sf.net
74eeeeea9SAxel Dörfler *		Axel D��rfler, axeld@pinc-software.de
84a5a077fSClemens Zeidler *		Clemens Zeidler <haiku@clemens-zeidler.de>
94eeeeea9SAxel Dörfler */
104eeeeea9SAxel Dörfler
11150bfa37SIngo Weinhold
12150bfa37SIngo Weinhold#include <Messenger.h>
13150bfa37SIngo Weinhold#include <NodeMonitor.h>
14150bfa37SIngo Weinhold
154eeeeea9SAxel Dörfler#include <MessengerPrivate.h>
164eeeeea9SAxel Dörfler
171f5d3007SAxel Dörfler#include <syscalls.h>
18150bfa37SIngo Weinhold
19bfff9df5SClemens Zeidler#include "node_monitor_private.h"
20bfff9df5SClemens Zeidler
21bfff9df5SClemens Zeidler
221f5d3007SAxel Dörfler// TODO: Tests!
23150bfa37SIngo Weinhold
24150bfa37SIngo Weinhold
25fc982701SJohn Scipione// Subscribes a target to watch node changes on a volume.
264d476e46SClemens Zeidlerstatus_t
27bfff9df5SClemens Zeidlerwatch_volume(dev_t volume, uint32 flags, BMessenger target)
284d476e46SClemens Zeidler{
294d5d8090SPhilippe Saint-Pierre	if ((flags & (B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR)) == 0)
304d476e46SClemens Zeidler		return B_BAD_VALUE;
314d476e46SClemens Zeidler
32bfff9df5SClemens Zeidler	flags |= B_WATCH_VOLUME;
33bfff9df5SClemens Zeidler
344d476e46SClemens Zeidler	BMessenger::Private messengerPrivate(target);
354d476e46SClemens Zeidler	port_id port = messengerPrivate.Port();
364d476e46SClemens Zeidler	int32 token = messengerPrivate.Token();
374d476e46SClemens Zeidler	return _kern_start_watching(volume, (ino_t)-1, flags, port, token);
384d476e46SClemens Zeidler}
394d476e46SClemens Zeidler
404d476e46SClemens Zeidler
414d476e46SClemens Zeidlerstatus_t
42a30a4a41SJohn Scipionewatch_volume(dev_t volume, uint32 flags, const BHandler* handler,
43a30a4a41SJohn Scipione	const BLooper* looper)
444d476e46SClemens Zeidler{
454d476e46SClemens Zeidler	return watch_volume(volume, flags, BMessenger(handler, looper));
464d476e46SClemens Zeidler}
474d476e46SClemens Zeidler
484d476e46SClemens Zeidler
49fc982701SJohn Scipione// Subscribes or unsubscribes a target to node and/or mount watching.
50150bfa37SIngo Weinholdstatus_t
51a30a4a41SJohn Scipionewatch_node(const node_ref* node, uint32 flags, BMessenger target)
52150bfa37SIngo Weinhold{
534eeeeea9SAxel Dörfler	if (!target.IsValid())
544eeeeea9SAxel Dörfler		return B_BAD_VALUE;
554eeeeea9SAxel Dörfler
564eeeeea9SAxel Dörfler	BMessenger::Private messengerPrivate(target);
574eeeeea9SAxel Dörfler	port_id port = messengerPrivate.Port();
584eeeeea9SAxel Dörfler	int32 token = messengerPrivate.Token();
594eeeeea9SAxel Dörfler
604eeeeea9SAxel Dörfler	if (flags == B_STOP_WATCHING) {
614eeeeea9SAxel Dörfler		// unsubscribe from node node watching
624eeeeea9SAxel Dörfler		if (node == NULL)
634eeeeea9SAxel Dörfler			return B_BAD_VALUE;
644eeeeea9SAxel Dörfler
65edb15b55SAxel Dörfler		return _kern_stop_watching(node->device, node->node, port, token);
66150bfa37SIngo Weinhold	}
674eeeeea9SAxel Dörfler
684eeeeea9SAxel Dörfler	// subscribe to...
694eeeeea9SAxel Dörfler	// mount watching
704eeeeea9SAxel Dörfler	if (flags & B_WATCH_MOUNT) {
71bb674499SAxel Dörfler		status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1,
72bb674499SAxel Dörfler			B_WATCH_MOUNT, port, token);
734eeeeea9SAxel Dörfler		if (status < B_OK)
744eeeeea9SAxel Dörfler			return status;
754eeeeea9SAxel Dörfler
764eeeeea9SAxel Dörfler		flags &= ~B_WATCH_MOUNT;
774eeeeea9SAxel Dörfler	}
784eeeeea9SAxel Dörfler
794eeeeea9SAxel Dörfler	// node watching
804eeeeea9SAxel Dörfler	if (flags != 0) {
814eeeeea9SAxel Dörfler		if (node == NULL)
824eeeeea9SAxel Dörfler			return B_BAD_VALUE;
834eeeeea9SAxel Dörfler
844eeeeea9SAxel Dörfler		return _kern_start_watching(node->device, node->node, flags, port,
854eeeeea9SAxel Dörfler			token);
864eeeeea9SAxel Dörfler	}
874eeeeea9SAxel Dörfler
884eeeeea9SAxel Dörfler	return B_OK;
89150bfa37SIngo Weinhold}
90150bfa37SIngo Weinhold
91fc982701SJohn Scipione
92fc982701SJohn Scipione// Subscribes or unsubscribes a handler or looper to node and/or mount
93fc982701SJohn Scipione// watching.
94150bfa37SIngo Weinholdstatus_t
95a30a4a41SJohn Scipionewatch_node(const node_ref* node, uint32 flags, const BHandler* handler,
96a30a4a41SJohn Scipione	const BLooper* looper)
97150bfa37SIngo Weinhold{
984eeeeea9SAxel Dörfler	return watch_node(node, flags, BMessenger(handler, looper));
99150bfa37SIngo Weinhold}
100150bfa37SIngo Weinhold
1014eeeeea9SAxel Dörfler
102fc982701SJohn Scipione// Unsubscribes a target from node and mount monitoring.
103150bfa37SIngo Weinholdstatus_t
104150bfa37SIngo Weinholdstop_watching(BMessenger target)
105150bfa37SIngo Weinhold{
1064eeeeea9SAxel Dörfler	if (!target.IsValid())
1074eeeeea9SAxel Dörfler		return B_BAD_VALUE;
1084eeeeea9SAxel Dörfler
1094eeeeea9SAxel Dörfler	BMessenger::Private messengerPrivate(target);
1104eeeeea9SAxel Dörfler	port_id port = messengerPrivate.Port();
1114eeeeea9SAxel Dörfler	int32 token = messengerPrivate.Token();
1124eeeeea9SAxel Dörfler
1134eeeeea9SAxel Dörfler	return _kern_stop_notifying(port, token);
114150bfa37SIngo Weinhold}
115150bfa37SIngo Weinhold
1164eeeeea9SAxel Dörfler
117fc982701SJohn Scipione// Unsubscribes a target from node and mount monitoring.
118150bfa37SIngo Weinholdstatus_t
119a30a4a41SJohn Scipionestop_watching(const BHandler* handler, const BLooper* looper)
120150bfa37SIngo Weinhold{
1214eeeeea9SAxel Dörfler	return stop_watching(BMessenger(handler, looper));
122150bfa37SIngo Weinhold}
123150bfa37SIngo Weinhold