Show
Ignore:
Timestamp:
11/14/03 18:04:15 (20 years ago)
Author:
jalet
Message:

More (untested) work on the CUPS backend.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/cupspykota

    r1180 r1182  
    2424# 
    2525# $Log$ 
     26# Revision 1.4  2003/11/14 17:04:15  jalet 
     27# More (untested) work on the CUPS backend. 
     28# 
    2629# Revision 1.3  2003/11/12 23:27:44  jalet 
    2730# More work on new backend. This commit may be unstable. 
     
    3841import sys 
    3942import os 
     43import popen2 
    4044import time 
    4145import cStringIO 
    4246import shlex 
     47import select 
     48import signal 
    4349 
    4450from pykota.tool import PyKotaTool, PyKotaToolError 
     
    4854from pykota.requester import openRequester, PyKotaRequesterError 
    4955 
     56class PyKotaPopen3(popen2.Popen3) : 
     57    """Our own class to execute real backends. 
     58     
     59       Their first argument is different from their path so using 
     60       native popen2.Popen3 would not be feasible. 
     61    """ 
     62    def __init__(self, cmd, capturestderr=False, bufsize=-1, arg0=None) : 
     63        self.arg0 = arg0 
     64        popen2.Popen3.__init__(self, cmd, capturestderr, bufsize) 
     65         
     66    def _run_child(self, cmd): 
     67        for i in range(3, MAXFD): 
     68            try: 
     69                os.close(i) 
     70            except OSError: 
     71                pass 
     72        try: 
     73            os.execvpe(cmd[0], [self.arg0 or cmd[0]] + cmd[1:], os.environ) 
     74        finally: 
     75            os._exit(1) 
     76     
    5077class PyKotaBackend(PyKotaTool) :     
    5178    """Class for the PyKota backend.""" 
     
    114141    return "%s >/dev/null" % (cmdline % locals()) 
    115142 
     143def sigterm_handler(signum, frame) : 
     144    """Handler for SIGTERM.""" 
     145    sys.exit(1) 
     146     
    116147def main(thebackend) :     
    117148    """Do it, and do it right !""" 
     149    # first deal with signals 
     150    # CUPS backends ignore SIGPIPE and exit(1) on SIGTERM 
     151    # Fortunately SIGPIPE is already ignored by Python 
     152    # It's there just in case this changes in the future 
     153    signal.signal(signal.SIGPIPE, signal.SIG_IGN) 
     154    signal.signal(signal.SIGTERM, sigterm_handler) 
     155     
    118156    # 
    119157    # Get the last page counter and last username from the Quota Storage backend 
     
    182220         
    183221        # executes original backend 
    184         #mustclose = 0     
    185         #if thebackend.inputfile is not None :     
    186         #    if hasattr(thebackend.inputfile, "read") : 
    187         #        infile = thebackend.inputfile 
    188         #    else :     
    189         #        infile = open(thebackend.inputfile, "rb") 
    190         #    mustclose = 1 
    191         #else :     
    192         #    infile = sys.stdin 
    193              
    194         realbackend = os.path.join(os.path.split(sys.argv[0])[0], thebackend.originalbackend) 
    195         retcode = os.spawnve(os.P_WAIT, realbackend, [os.environ["DEVICE_URI"]] + sys.argv[1:], os.environ) 
     222        mustclose = 0     
     223        if thebackend.inputfile is not None :     
     224            if hasattr(thebackend.inputfile, "read") : 
     225                infile = thebackend.inputfile 
     226            else :     
     227                infile = open(thebackend.inputfile, "rb") 
     228            mustclose = 1 
     229        else :     
     230            infile = sys.stdin 
     231        subprocess = PyKotaPopen3([realbackend] + sys.argv[1:], capturestderr=1, arg0=os.environ["DEVICE_URI"]) 
     232        pollster = select.poll() 
     233        pollster.register(subprocess.fromchild, select.POLLIN) 
     234        pollster.register(subprocess.childerr, select.POLLIN) 
     235        pollster.register(subprocess.tochild, select.POLLOUT) 
     236        end = 0 
     237        while not end : 
     238            availablestreams = pollster.poll() 
     239            for (stream, mask) in availablestreams : 
     240                if mask & select.POLLOUT : 
     241                    data = infile.read(256 * 1024) 
     242                    if data : 
     243                        os.write(stream, data)     
     244                    else :     
     245                        end = 1 
     246                if mask & select.POLLIN :      
     247                    data = os.read(stream, 256 * 1024) 
     248                    if stream == pollster.fromchild.fileno() : 
     249                        sys.stdout.write(data) 
     250                    elif stream == pollster.childerr.fileno() :     
     251                        sys.stderr.write(data) 
     252        subprocess.fromchild.close() 
     253        subprocess.childerr.close() 
     254        subprocess.tochild.close() 
     255        if mustclose : 
     256            infile.close() 
     257        status = subprocess.wait() 
     258        if os.WIFEXITED(status) : 
     259            retcode = os.WEXITSTATUS(status) 
     260        else :     
     261            thebackend.logger.log_message(_("CUPS backend %s died abnormally.") % realbackend, "error") 
     262            retcode = -1 
     263         
     264        #realbackend = os.path.join(os.path.split(sys.argv[0])[0], thebackend.originalbackend) 
     265        #retcode = os.spawnve(os.P_WAIT, realbackend, [os.environ["DEVICE_URI"]] + sys.argv[1:], os.environ) 
    196266     
    197267    # stops accounting.