#!/usr/bin/env python
# -*- coding: utf-8 -*-
########## THIS NOW WORKS! ##########
UNSUITABLE_ENVIRONMENT_ERROR = \
"This program requires at least Python 2.6 and Linux"
import sys
import struct
import os
from array import array
# +++ Check environment
try:
import platform # Introduced in Python 2.3
except ImportError:
print >>sys.stderr, UNSUITABLE_ENVIRONMENT_ERROR
if platform.system() != "Linux":
print >>sys.stderr, UNSUITABLE_ENVIRONMENT_ERROR
if platform.python_version_tuple()[:2] < (2, 6):
print >>sys.stderr, UNSUITABLE_ENVIRONMENT_ERROR
# --- Check environment
HDIO_GETGEO = 0x301 # Linux
import fcntl
def get_disk_geometry(fd):
geometry = array('c',"XXXXXXXX")
fcntl.ioctl(fd, HDIO_GETGEO, geometry, True)
heads, sectors, cylinders, start = \
struct.unpack("BBHL",geometry.tostring())
return { 'heads' : heads, 'cylinders': cylinders, 'sectors': sectors, "start": start }
from pprint import pprint
fd=os.open("/dev/sdb", os.O_RDWR)
pprint(get_disk_geometry(fd))
Asked
Active
Viewed 1,013 times
0

user376403
- 1,085
- 2
- 9
- 18
-
Yeah, why doesn't this code work and a working example would be swell :D – user376403 Jun 27 '10 at 07:38
-
TypeError: ioctl requires a file or file descriptor, an integer and optionally an integer or buffer argument Uncaught exception. Entering post mortem debugging Running 'cont' or 'step' will restart the program > /home/rob/ricedisk(25)get_disk_geometry() -> fcntl.ioctl(fd, HDIO_GETGEO, geometry, True) (Pdb) p HDIO_GETGEO 769 (Pdb) p type(HDIO_GETGEO)
(Pdb) p type(fd) – user376403 Jun 27 '10 at 07:41 -
Placed it in the question for you – Ikke Jun 27 '10 at 07:43
-
Or a way telling me to turn /dev/sdb into the right place under /sys/firmware/edd is fine too. – user376403 Jun 27 '10 at 07:50
1 Answers
0
Nobody seems to be able to tell me why you can't do this, but you can do it with ctypes so it doesn't really matter.
#!/usr/bin/env python
from ctypes import *
import os
from pprint import pprint
libc = CDLL("libc.so.6")
HDIO_GETGEO = 0x301 # Linux
class HDGeometry(Structure):
_fields_ = (("heads", c_ubyte),
("sectors", c_ubyte),
("cylinders", c_ushort),
("start", c_ulong))
def __repr__(self):
return """Heads: %s, Sectors %s, Cylinders %s, Start %s""" % (
self.heads, self.sectors, self.cylinders, self.start)
def get_disk_geometry(fd):
""" Returns the heads, sectors, cylinders and start of disk as rerpoted by
BIOS. These us usually bogus, but we still need them"""
buffer = create_string_buffer(sizeof(HDGeometry))
g = cast(buffer, POINTER(HDGeometry))
result = libc.ioctl(fd, HDIO_GETGEO, byref(buffer))
assert result == 0
return g.contents
if __name__ == "__main__":
fd = os.open("/dev/sdb", os.O_RDWR)
print repr(get_disk_geometry(fd))

user376403
- 1,085
- 2
- 9
- 18
-
Using `import *` pollutes your namespace, making programs harder to read and debug. Consider using `import extralongmodulename as e` if you require conciseness. – Mike Graham Sep 03 '10 at 20:10
-
ctypes is the only module I ever do it with and I agree, but ctypes is a general pain in the ass. I suppose importing it as C or something would be ok. – user376403 Sep 03 '10 at 20:31