-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy path_util.pyx
More file actions
101 lines (87 loc) · 3.18 KB
/
_util.pyx
File metadata and controls
101 lines (87 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""
General PyAFS utilities, such as error handling
"""
# cython: c_string_type=str, c_string_encoding=ascii
import sys
import logging
log = logging.getLogger('afs._util')
# otherwise certain headers are unhappy
cdef extern from "netinet/in.h": pass
cdef extern from "afs/vice.h": pass
cdef int _init = 0
# pioctl convenience wrappers
# Function for "reading" data from a pioctl
# "outbuffer" will get populated with the data in question
cdef int pioctl_read(char *path, afs_int32 op, void *outbuffer,
unsigned short size, afs_int32 follow) except -1:
cdef ViceIoctl blob
cdef afs_int32 code
log.debug("pioctl_read() on %s with operation %d and size %d",
path, op, size)
blob.in_size = 0
blob.out_size = size
blob.out = outbuffer
code = pioctl(path, op, &blob, follow)
# If we don't save errno here, logging scribbles over it
save_errno = errno
log.debug("pioctl_read() returned %d (save_errno %d)", code, save_errno)
# This might work with the rest of OpenAFS, but I'm not convinced
# the rest of it is consistent
if code == -1:
raise OSError(save_errno, strerror(save_errno))
pyafs_error(code)
return code
# Function for "writing" data to a pioctl
# "outbuffer" will get populated with the data in question
# Pass NULL for outbuffer in cases where we don't get anything
# back (e.g. VIOCSETAL)
# "outsize" will be ignored (forced to 0) if "outbuffer" is NULL
cdef int pioctl_write(char *path, afs_int32 op, char *inbuffer,
void *outbuffer, afs_int32 outsize,
afs_int32 follow) except -1:
cdef ViceIoctl blob
cdef afs_int32 code
blob.cin = inbuffer
blob.in_size = 1 + strlen(inbuffer)
log.debug("pioctl_write() on %s with operation %d, and input '%s'",
path, op, inbuffer)
if outbuffer == NULL:
log.debug("No output desired from pioctl_write()")
blob.out_size = 0
else:
blob.out_size = outsize
blob.out = outbuffer
code = pioctl(path, op, &blob, follow)
# If we don't save errno here, logging scribbles over it
save_errno = errno
log.debug("pioctl_write() returned %d (errno %d)", code, save_errno)
# This might work with the rest of OpenAFS, but I'm not convinced
# the rest of it is consistent
if code == -1:
raise OSError(save_errno, strerror(save_errno))
pyafs_error(code)
return code
# Error handling
class AFSException(Exception):
def __init__(self, errno):
self.errno = errno
self.strerror = afs_error_message(errno)
def __repr__(self):
return "AFSException(%s)" % (self.errno)
def __str__(self):
return "[%s] %s" % (self.errno, self.strerror)
def pyafs_error(code):
global _init
if not _init:
initialize_ACFG_error_table()
initialize_KTC_error_table()
initialize_PT_error_table()
initialize_RXK_error_table()
initialize_U_error_table()
_init = 1
if code != 0:
raise AFSException(code)
def path_to_bytes(path):
if isinstance(path, unicode):
return path.encode(sys.getfilesystemencoding(), 'surrogateescape')
return path