1# -*- coding: utf-8 -*-
2# This code is part of Ansible, but is an independent component.
3# This particular file snippet, and this file snippet only, is based on
4# Lib/posixpath.py of cpython
5# It is licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
6#
7# 1. This LICENSE AGREEMENT is between the Python Software Foundation
8# ("PSF"), and the Individual or Organization ("Licensee") accessing and
9# otherwise using this software ("Python") in source or binary form and
10# its associated documentation.
11#
12# 2. Subject to the terms and conditions of this License Agreement, PSF hereby
13# grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
14# analyze, test, perform and/or display publicly, prepare derivative works,
15# distribute, and otherwise use Python alone or in any derivative version,
16# provided, however, that PSF's License Agreement and PSF's notice of copyright,
17# i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
18# 2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved"
19# are retained in Python alone or in any derivative version prepared by Licensee.
20#
21# 3. In the event Licensee prepares a derivative work that is based on
22# or incorporates Python or any part thereof, and wants to make
23# the derivative work available to others as provided herein, then
24# Licensee hereby agrees to include in any such work a brief summary of
25# the changes made to Python.
26#
27# 4. PSF is making Python available to Licensee on an "AS IS"
28# basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
29# IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
30# DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
31# FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
32# INFRINGE ANY THIRD PARTY RIGHTS.
33#
34# 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
35# FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
36# A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
37# OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
38#
39# 6. This License Agreement will automatically terminate upon a material
40# breach of its terms and conditions.
41#
42# 7. Nothing in this License Agreement shall be deemed to create any
43# relationship of agency, partnership, or joint venture between PSF and
44# Licensee.  This License Agreement does not grant permission to use PSF
45# trademarks or trade name in a trademark sense to endorse or promote
46# products or services of Licensee, or any third party.
47#
48# 8. By copying, installing or otherwise using Python, Licensee
49# agrees to be bound by the terms and conditions of this License
50# Agreement.
51
52from __future__ import absolute_import, division, print_function
53
54__metaclass__ = type
55
56import os
57
58
59def ismount(path):
60    """Test whether a path is a mount point
61    This is a copy of the upstream version of ismount(). Originally this was copied here as a workaround
62    until Python issue 2466 was fixed. Now it is here so this will work on older versions of Python
63    that may not have the upstream fix.
64    https://github.com/ansible/ansible-modules-core/issues/2186
65    http://bugs.python.org/issue2466
66    """
67    try:
68        s1 = os.lstat(path)
69    except (OSError, ValueError):
70        # It doesn't exist -- so not a mount point. :-)
71        return False
72    else:
73        # A symlink can never be a mount point
74        if os.path.stat.S_ISLNK(s1.st_mode):
75            return False
76
77    if isinstance(path, bytes):
78        parent = os.path.join(path, b'..')
79    else:
80        parent = os.path.join(path, '..')
81    parent = os.path.realpath(parent)
82    try:
83        s2 = os.lstat(parent)
84    except (OSError, ValueError):
85        return False
86
87    dev1 = s1.st_dev
88    dev2 = s2.st_dev
89    if dev1 != dev2:
90        return True     # path/.. on a different device as path
91    ino1 = s1.st_ino
92    ino2 = s2.st_ino
93    if ino1 == ino2:
94        return True     # path/.. is the same i-node as path
95    return False
96