1# Copyright (c) 2017, Tomohiro Kusumi
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are met:
6#
7# 1. Redistributions of source code must retain the above copyright notice, this
8#    list of conditions and the following disclaimer.
9# 2. Redistributions in binary form must reproduce the above copyright notice,
10#    this list of conditions and the following disclaimer in the documentation
11#    and/or other materials provided with the distribution.
12#
13# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24from __future__ import with_statement
25import errno
26
27from . import libc
28from . import log
29from . import unix
30from . import util
31
32def get_blkdev_info(f):
33    with fopen(f) as fd:
34        return __get_blkdev_info(fd)
35
36def __get_blkdev_info(fd):
37    try:
38        DKIOC = (0x04 << 8)
39        DKIOCGMEDIAINFO = (DKIOC | 42)
40        sizeof_uint = libc.get_sizeof_uint()
41        sizeof_ulonglong = libc.get_sizeof_ulonglong()
42        size = sizeof_uint*2 + sizeof_ulonglong
43        b = unix.ioctl(fd, DKIOCGMEDIAINFO, size)
44
45        buf = b[sizeof_uint:sizeof_uint*2]
46        sector_size = util.host_to_int(buf)
47        buf = b[sizeof_uint*2:sizeof_uint*2 + sizeof_ulonglong]
48        size = util.host_to_int(buf) * sector_size
49        return size, sector_size, ''
50    except Exception as e:
51        log.error("ioctl({0}, DKIOCGMEDIAINFO) failed, {1}".format(fd.name, e))
52        raise
53
54def read_reg_size(f):
55    return unix.read_reg_size(f)
56
57def seek_end(f):
58    return unix.seek_end(f)
59
60def get_inode(f):
61    return unix.get_inode(f)
62
63def fopen(f, mode='r'):
64    return unix.fopen(f, mode)
65
66def fopen_text(f, mode='r'):
67    return unix.fopen_text(f, mode)
68
69def fcreat(f):
70    return unix.fcreat(f)
71
72def fcreat_text(f):
73    return unix.fcreat_text(f)
74
75def symlink(source, link_name):
76    return unix.symlink(source, link_name)
77
78def fsync(fd):
79    return unix.fsync(fd)
80
81def truncate(f, offset):
82    return unix.truncate(f, offset)
83
84def utime(f, st):
85    return unix.utime(f, st)
86
87def touch(f):
88    return unix.touch(f)
89
90def stat_type(f):
91    return unix.stat_type(f)
92
93def get_page_size():
94    return unix.get_page_size()
95
96def get_buffer_size():
97    return unix.get_buffer_size()
98
99def get_total_ram():
100    return __get_meminfo("physmem")
101
102def get_free_ram():
103    return __get_meminfo("freemem")
104
105def __get_meminfo(name):
106    ret = __get_kstat_system_pages(name)
107    if ret == -1:
108        return -1
109    return ret * get_page_size()
110
111def __get_kstat_system_pages(name):
112    """
113    [root@unknown ~]# kstat -n system_pages -p -s physmem
114    unix:0:system_pages:physmem     522126
115    """
116    try:
117        cmd = "kstat", "-n", "system_pages", "-p", "-s", name
118        s = util.execute(*cmd).stdout
119        x = s.split("\t")[-1]
120        return int(x)
121    except Exception as e:
122        log.error(e)
123        return -1
124
125def is_blkdev(f):
126    return unix.stat_is_chrdev(f)
127
128def is_blkdev_supported():
129    return True
130
131def mmap_full(fileno, readonly=False):
132    return unix.mmap_full(fileno, readonly)
133
134def mmap_partial(fileno, offset, length, readonly=False):
135    return unix.mmap_partial(fileno, offset, length, readonly)
136
137def has_mmap():
138    return True
139
140def has_mremap():
141    return False
142
143def test_mmap_resize(osiz, nsiz):
144    return unix.test_mmap_resize(osiz, nsiz)
145
146def has_pid_access(pid):
147    return unix.kill_sig_zero(pid)
148
149def has_pid(pid):
150    return unix.has_pid(pid)
151
152def get_pid_name(pid):
153    return unix.get_pid_name(pid)
154
155# The ptrace() function is available only with the 32-bit version of
156# libc(3LIB). It is not available with the 64-bit version of this library.
157def has_ptrace():
158    return False
159
160def ptrace_peektext(pid, addr):
161    return None, errno.EOPNOTSUPP
162
163def ptrace_peekdata(pid, addr):
164    return None, errno.EOPNOTSUPP
165
166def ptrace_poketext(pid, addr, data):
167    return None, errno.EOPNOTSUPP
168
169def ptrace_pokedata(pid, addr, data):
170    return None, errno.EOPNOTSUPP
171
172def ptrace_attach(pid):
173    return None, errno.EOPNOTSUPP
174
175def ptrace_detach(pid):
176    return None, errno.EOPNOTSUPP
177
178def get_ptrace_word_size():
179    return -1
180
181def waitpid(pid, opts):
182    return unix.waitpid(pid, opts)
183
184def parse_waitpid_result(status):
185    return unix.parse_waitpid_result(status)
186
187def init():
188    unix.init_procfs()
189