faqts : Computers : Programming : Languages : Python : Snippets

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

3 of 4 people (75%) answered Yes
Recently 2 of 2 people (100%) answered Yes


Possix access() and ttyname() missing?

Jul 5th, 2000 09:59
Nathan Wallace, Hans Nowak, Snippet 32, Michael P. Reilly

Packages: operating_systems.unix
: Greetings.  It was recently brought to my attention that doing things like
: perl's "if (-x file)" are actually fairly hard to do in Python.  It seems
: that the access() Posix function is missing from the Posix module, as is
: ttyname().  If there's any objection to putting these in Python, let me
: know.  Otherwise, find a patch to source and documentation at
: ftp://ftp.tummy.com/pub/tummy/Python/Python-1.5.2b1-access.patch
: Also in that directory is a preliminary version of "fileinfo.py", a module
: full of convenience functions implementing most of the tests in the unix
: "test(1)" program for files (readable, writable, executable, empty,
: newer/older than, etc...) and then some.  However, this is a PRELIMINARY
: version, no documentation and I'd like to have some discussion on the
: module naming scheme.
Some time back I submitted a module, Os_path, to handle path searches
(like PATH, CDPATH, MANPATH, etc.) for UNIX and other systems.  The
test for executability wasn't all that complex.  Some of my reworked
code is below.
import os
if hasattr(os, 'getuid'):
  my_uid = apply(getattr(os, 'getuid'), ())
  my_uid = 0
if hasattr(os, 'getgid'):
  my_gid = apply(getattr(os, 'getgid'), ())
  my_gid = 0
def get_execfile(self, file):
  # if the file doesn't pass the test, then attempt platform specific
  # filenames
  if is_executable(file):
    return file
  elif os.name in ('posix', 'mac'):
    return None
  elif os.name in ('dos', 'nt'):
    if self._filetest(file + '.exe'):
      return file + '.exe'
    elif self._filetest(file + '.com'):
      return file + '.com'
    elif self._filetest(file + '.bat'):
      return file + '.bat'
  return None
def is_executable(file, stat=os.path.stat):
  statinfo = os.stat(file)
  mode = stat.S_IMODE(statinfo[stat.ST_MODE])
  if ((statinfo[stat.ST_UID] == my_uid and stat.S_IXUSR & mode) or
      (statinfo[stat.ST_GID] == my_gid and stat.S_IXGRP & mode) or
      stat.S_IXOTH & mode):
    return 1
  return 0
I think it might be useful to have some proper forms of "is_readable",
"is_writable" and "is_executable" functions.  But much more than that
may be too CISC oriented.  And much of the file-based info that test(1)
returns can be retrieved with os.stat().
As I believe Guido pointed out, the access() function isn't all that
useful to setxid programs - the effective ids are often more
appropriate for a running program.  The same information can be
retrieved from stat(2) with a little more logic (matched against either
effective or real ids).
As for ttyname(2), how often would ppl be using it, and how hard would
it be to run string.rstrip(os.popen('/bin/tty', 'r').readline()) to get
nearly the same value.  Again, this is a CISC oriented view (not
necessarily wrong... just cumbersome).