/Lib/plat-os2emx/_emx_link.py

http://unladen-swallow.googlecode.com/ · Python · 79 lines · 60 code · 3 blank · 16 comment · 2 complexity · 0fe72b7d87f7ac6e454d9845c782c660 MD5 · raw file

  1. # _emx_link.py
  2. # Written by Andrew I MacIntyre, December 2002.
  3. """_emx_link.py is a simplistic emulation of the Unix link(2) library routine
  4. for creating so-called hard links. It is intended to be imported into
  5. the os module in place of the unimplemented (on OS/2) Posix link()
  6. function (os.link()).
  7. We do this on OS/2 by implementing a file copy, with link(2) semantics:-
  8. - the target cannot already exist;
  9. - we hope that the actual file open (if successful) is actually
  10. atomic...
  11. Limitations of this approach/implementation include:-
  12. - no support for correct link counts (EMX stat(target).st_nlink
  13. is always 1);
  14. - thread safety undefined;
  15. - default file permissions (r+w) used, can't be over-ridden;
  16. - implemented in Python so comparatively slow, especially for large
  17. source files;
  18. - need sufficient free disk space to store the copy.
  19. Behaviour:-
  20. - any exception should propagate to the caller;
  21. - want target to be an exact copy of the source, so use binary mode;
  22. - returns None, same as os.link() which is implemented in posixmodule.c;
  23. - target removed in the event of a failure where possible;
  24. - given the motivation to write this emulation came from trying to
  25. support a Unix resource lock implementation, where minimal overhead
  26. during creation of the target is desirable and the files are small,
  27. we read a source block before attempting to create the target so that
  28. we're ready to immediately write some data into it.
  29. """
  30. import os
  31. import errno
  32. __all__ = ['link']
  33. def link(source, target):
  34. """link(source, target) -> None
  35. Attempt to hard link the source file to the target file name.
  36. On OS/2, this creates a complete copy of the source file.
  37. """
  38. s = os.open(source, os.O_RDONLY | os.O_BINARY)
  39. if os.isatty(s):
  40. raise OSError, (errno.EXDEV, 'Cross-device link')
  41. data = os.read(s, 1024)
  42. try:
  43. t = os.open(target, os.O_WRONLY | os.O_BINARY | os.O_CREAT | os.O_EXCL)
  44. except OSError:
  45. os.close(s)
  46. raise
  47. try:
  48. while data:
  49. os.write(t, data)
  50. data = os.read(s, 1024)
  51. except OSError:
  52. os.close(s)
  53. os.close(t)
  54. os.unlink(target)
  55. raise
  56. os.close(s)
  57. os.close(t)
  58. if __name__ == '__main__':
  59. import sys
  60. try:
  61. link(sys.argv[1], sys.argv[2])
  62. except IndexError:
  63. print 'Usage: emx_link <source> <target>'
  64. except OSError:
  65. print 'emx_link: %s' % str(sys.exc_info()[1])