public void shutDown() { for (Port port : m_OpenPorts.values()) { try { log = log && log(1, "shutDown() closing port %d\n", port.m_FD); port.close(); } catch (Exception e) { // should never happen e.printStackTrace(); } } }
public int fcntl(int fd, int cmd, int arg) { Port port = getPort(fd); if (port == null) return -1; if (F_SETFL == cmd) port.m_OpenFlags = arg; else if (F_GETFL == cmd) return port.m_OpenFlags; else { m_ErrNo = ENOTSUP; return -1; } return 0; }
public int tcdrain(int fd) { Port port = getPort(fd); if (port == null) return -1; try { synchronized (port.m_WrBuffer) { if (!FlushFileBuffers(port.m_Comm)) port.fail(); return 0; } } catch (Fail f) { return -1; } }
public int tcsendbreak(int fd, int duration) { Port port = getPort(fd); if (port == null) return -1; try { if (!SetCommBreak(port.m_Comm)) port.fail(); nanoSleep(duration * 250000000); if (!ClearCommBreak(port.m_Comm)) port.fail(); return 0; } catch (Fail f) { return -1; } }
public void execute(ApplicationData MyApplicationData) { int port = MyApplicationData.getPort(); String note = (String) (MyApplicationData.getParameters()); Iterator PortIterator = super.getComputer().getPorts().entrySet().iterator(); while (PortIterator.hasNext()) { Port TempPort = (Port) (((Map.Entry) PortIterator.next()).getValue()); if (TempPort.getNumber() == port) { TempPort.setNote(note); } } }
private void build(Port port) { if (wsdlModeler.isProvider(port)) return; Binding binding = port.resolveBinding(wsdlDocument); SOAPBinding soapBinding = (SOAPBinding) getExtensionOfType(binding, SOAPBinding.class); // lets try and see if its SOAP 1.2. dont worry about extension flag, its // handled much earlier if (soapBinding == null) { soapBinding = (SOAPBinding) getExtensionOfType(binding, SOAP12Binding.class); } if (soapBinding == null) return; PortType portType = binding.resolvePortType(wsdlDocument); QName bindingName = WSDLModelerBase.getQNameOf(binding); // we dont want to process the port bound to the binding processed earlier if (bindingNameToPortMap.containsKey(bindingName)) return; bindingNameToPortMap.put(bindingName, port); for (Iterator itr = binding.operations(); itr.hasNext(); ) { BindingOperation bindingOperation = (BindingOperation) itr.next(); // get only the bounded operations Set boundedOps = portType.getOperationsNamed(bindingOperation.getName()); if (boundedOps.size() != 1) continue; Operation operation = (Operation) boundedOps.iterator().next(); // No pseudo schema required for doc/lit if (wsdlModeler.isAsync(portType, operation)) { buildAsync(portType, operation, bindingOperation); } } }
public int open(String filename, int flags) { Port port = new Port(); port.m_OpenFlags = flags; try { if (!filename.startsWith("\\\\")) filename = "\\\\.\\" + filename; port.m_Comm = CreateFileW( new WString(filename), GENERIC_READ | GENERIC_WRITE, 0, null, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, null); if (INVALID_HANDLE_VALUE == port.m_Comm) { if (GetLastError() == ERROR_FILE_NOT_FOUND) m_ErrNo = ENOENT; else m_ErrNo = EBUSY; port.fail(); } if (!SetupComm(port.m_Comm, (int) port.m_RdBuffer.size(), (int) port.m_WrBuffer.size())) port.fail(); // FIXME what would be appropriate error code here cfmakeraw(port.m_Termios); cfsetispeed(port.m_Termios, B9600); cfsetospeed(port.m_Termios, B9600); port.m_Termios.c_cc[VTIME] = 0; port.m_Termios.c_cc[VMIN] = 0; updateFromTermios(port); port.m_RdOVL.writeField("hEvent", CreateEventA(null, true, false, null)); if (port.m_RdOVL.hEvent == INVALID_HANDLE_VALUE) port.fail(); port.m_WrOVL.writeField("hEvent", CreateEventA(null, true, false, null)); if (port.m_WrOVL.hEvent == INVALID_HANDLE_VALUE) port.fail(); port.m_SelOVL.writeField("hEvent", CreateEventA(null, true, false, null)); if (port.m_SelOVL.hEvent == INVALID_HANDLE_VALUE) port.fail(); return port.m_FD; } catch (Exception f) { if (port != null) port.close(); return -1; } }
public int tcflush(int fd, int queue) { Port port = getPort(fd); if (port == null) return -1; try { if (queue == TCIFLUSH) { if (!PurgeComm(port.m_Comm, PURGE_RXABORT)) port.fail(); } else if (queue == TCOFLUSH) { if (!PurgeComm(port.m_Comm, PURGE_TXABORT)) port.fail(); } else if (queue == TCIOFLUSH) { if (!PurgeComm(port.m_Comm, PURGE_TXABORT)) port.fail(); if (!PurgeComm(port.m_Comm, PURGE_RXABORT)) port.fail(); } else { m_ErrNo = ENOTSUP; return -1; } return 0; } catch (Fail f) { return -1; } }
public int write(int fd, byte[] buffer, int length) { Port port = getPort(fd); if (port == null) return -1; synchronized (port.m_WrBuffer) { try { if (port.m_WritePending > 0) { while (true) { int res = WaitForSingleObject(port.m_WrOVL.hEvent, INFINITE); if (res == WAIT_TIMEOUT) { clearCommErrors(port); log = log && log( 1, "write pending, cbInQue %d cbOutQue %d\n", port.m_COMSTAT.cbInQue, port.m_COMSTAT.cbOutQue); continue; } if (!GetOverlappedResult(port.m_Comm, port.m_WrOVL, port.m_WrN, false)) port.fail(); if (port.m_WrN[0] != port.m_WritePending) // I exptect this is never going to happen, if it does new RuntimeException( "Windows OVERLAPPED WriteFile failed to write all, tried to write " + port.m_WritePending + " but got " + port.m_WrN[0]); break; } port.m_WritePending = 0; } if ((port.m_OpenFlags & O_NONBLOCK) != 0) { if (!ClearCommError(port.m_Comm, port.m_WrErr, port.m_WrStat)) port.fail(); int room = (int) port.m_WrBuffer.size() - port.m_WrStat.cbOutQue; if (length > room) length = room; } if (!ResetEvent(port.m_WrOVL.hEvent)) port.fail(); if (length > port.m_WrBuffer.size()) length = (int) port.m_WrBuffer.size(); port.m_WrBuffer.write(0, buffer, 0, length); // copy from buffer to Memory boolean ok = WriteFile(port.m_Comm, port.m_WrBuffer, length, port.m_WrN, port.m_WrOVL); if (!ok) { if (GetLastError() != ERROR_IO_PENDING) port.fail(); port.m_WritePending = length; } // return length; // port.m_WrN[0]; } catch (Fail f) { return -1; } } }
private Element generatePortNode(Document doc, Port port) { Element portEl = doc.createElement(EL_PORT); portEl.setAttribute(ATR_NAME, port.getName()); portEl.setAttribute(ATR_TYPE, port.getType()); portEl.setAttribute(ATR_X, Integer.toString(port.getX())); portEl.setAttribute(ATR_Y, Integer.toString(port.getY())); portEl.setAttribute(ATR_PORT_CONNECTION, port.isArea() ? "area" : ""); portEl.setAttribute(ATR_STRICT, Boolean.toString(port.isStrict())); portEl.setAttribute(ATR_MULTI, Boolean.toString(port.isMulti())); return portEl; }
public int ioctl(int fd, int cmd, int[] arg) { Port port = getPort(fd); if (port == null) return -1; try { if (cmd == FIONREAD) { clearCommErrors(port); arg[0] = port.m_COMSTAT.cbInQue; return 0; } else if (cmd == TIOCMSET) { int a = arg[0]; if ((a & TIOCM_DTR) != 0) port.MSR |= TIOCM_DTR; else port.MSR &= ~TIOCM_DTR; if (!EscapeCommFunction(port.m_Comm, ((a & TIOCM_DTR) != 0) ? SETDTR : CLRDTR)) port.fail(); if ((a & TIOCM_RTS) != 0) port.MSR |= TIOCM_RTS; else port.MSR &= ~TIOCM_RTS; if (!EscapeCommFunction(port.m_Comm, ((a & TIOCM_RTS) != 0) ? SETRTS : CLRRTS)) port.fail(); return 0; } else if (cmd == TIOCMGET) { int[] stat = {0}; if (!GetCommModemStatus(port.m_Comm, stat)) port.fail(); int s = stat[0]; int a = arg[0]; if ((s & MS_RLSD_ON) != 0) a |= TIOCM_CAR; else a &= ~TIOCM_CAR; if ((s & MS_RING_ON) != 0) a |= TIOCM_RNG; else a &= ~TIOCM_RNG; if ((s & MS_DSR_ON) != 0) a |= TIOCM_DSR; else a &= ~TIOCM_DSR; if ((s & MS_CTS_ON) != 0) a |= TIOCM_CTS; else a &= ~TIOCM_CTS; if ((port.MSR & TIOCM_DTR) != 0) a |= TIOCM_DTR; else a &= ~TIOCM_DTR; if ((port.MSR & TIOCM_RTS) != 0) a |= TIOCM_RTS; else a &= ~TIOCM_RTS; arg[0] = a; return 0; } else { m_ErrNo = ENOTSUP; return -1; } } catch (Fail f) { return -1; } }
public int select(int n, FDSet readfds, FDSet writefds, FDSet exceptfds, TimeVal timeout) { // long T0 = System.currentTimeMillis(); int ready = 0; LinkedList<Port> locked = new LinkedList<Port>(); try { try { LinkedList<Port> waiting = new LinkedList<Port>(); for (int fd = 0; fd < n; fd++) { boolean rd = FD_ISSET(fd, readfds); boolean wr = FD_ISSET(fd, writefds); FD_CLR(fd, readfds); FD_CLR(fd, writefds); if (rd || wr) { Port port = getPort(fd); if (port == null) return -1; try { port.lock(); locked.add(port); clearCommErrors(port); // check if there is data to be read, as WaitCommEvent // does check for only *new* data that and thus // might wait indefinitely if select() is called twice // without first reading away all data if (rd && port.m_COMSTAT.cbInQue > 0) { FD_SET(fd, readfds); ready++; } if (wr && port.m_COMSTAT.cbOutQue == 0) { FD_SET(fd, writefds); ready++; } if (!ResetEvent(port.m_SelOVL.hEvent)) port.fail(); int flags = 0; if (rd) flags |= EV_RXCHAR; if (wr) flags |= EV_TXEMPTY; if (!SetCommMask(port.m_Comm, flags)) port.fail(); if (WaitCommEvent(port.m_Comm, port.m_EventFlags, port.m_SelOVL)) { if (!GetOverlappedResult(port.m_Comm, port.m_SelOVL, port.m_SelN, false)) port.fail(); // actually it seems that overlapped // WaitCommEvent never returns true so we never get here ready = maskToFDSets(port, readfds, writefds, exceptfds, ready); } else { // FIXME if the port dies on us what happens if (GetLastError() != ERROR_IO_PENDING) port.fail(); waiting.add(port); } } catch (InterruptedException ie) { m_ErrNo = EINTR; return -1; } } } if (ready == 0) { int waitn = waiting.size(); if (waitn > 0) { HANDLE[] wobj = new HANDLE[waiting.size() * 2]; int i = 0; for (Port port : waiting) { wobj[i++] = port.m_SelOVL.hEvent; wobj[i++] = port.m_CancelWaitSema4; } int tout = timeout != null ? (int) (timeout.tv_sec * 1000 + timeout.tv_usec / 1000) : INFINITE; // int res = WaitForSingleObject(wobj[0], tout); int res = WaitForMultipleObjects(waitn * 2, wobj, false, tout); if (res == WAIT_TIMEOUT) { // work around the fact that sometimes we miss // events for (Port port : waiting) { clearCommErrors(port); int[] mask = {0}; if (!GetCommMask(port.m_Comm, mask)) port.fail(); if (port.m_COMSTAT.cbInQue > 0 && ((mask[0] & EV_RXCHAR) != 0)) { FD_SET(port.m_FD, readfds); log = log && log(1, "missed EV_RXCHAR event\n"); return 1; } if (port.m_COMSTAT.cbOutQue == 0 && ((mask[0] & EV_TXEMPTY) != 0)) { FD_SET(port.m_FD, writefds); log = log && log(1, "missed EV_TXEMPTY event\n"); return 1; } } } if (res != WAIT_TIMEOUT) { i = (res - WAIT_OBJECT_0) / 2; if (i < 0 || i >= waitn) throw new Fail(); Port port = waiting.get(i); if (!GetOverlappedResult(port.m_Comm, port.m_SelOVL, port.m_SelN, false)) port.fail(); ready = maskToFDSets(port, readfds, writefds, exceptfds, ready); } } else { if (timeout != null) nanoSleep(timeout.tv_sec * 1000000000L + timeout.tv_usec * 1000); else { m_ErrNo = EINVAL; return -1; } return 0; } } } catch (Fail f) { return -1; } } finally { for (Port port : locked) port.unlock(); } // long T1 = System.currentTimeMillis(); // System.err.println("select() " + (T1 - T0)); return ready; }
private void clearCommErrors(Port port) throws Fail { synchronized (port.m_COMSTAT) { if (!ClearCommError(port.m_Comm, port.m_ClearErr, port.m_COMSTAT)) port.fail(); } }
// FIXME this needs serious code review from people who know this stuff... public int updateFromTermios(Port port) throws Fail { Termios tios = port.m_Termios; int c_speed = tios.c_ospeed; int c_cflag = tios.c_cflag; int c_iflag = tios.c_iflag; int c_oflag = tios.c_oflag; if (c_speed != port.m_c_speed || c_cflag != port.m_c_cflag || c_iflag != port.m_c_iflag || c_oflag != port.m_c_oflag) { DCB dcb = port.m_DCB; if (!GetCommState(port.m_Comm, dcb)) port.fail(); dcb.DCBlength = dcb.size(); dcb.BaudRate = c_speed; if (tios.c_ospeed != tios.c_ispeed) log(0, "c_ospeed (%d) != c_ispeed (%d)\n", tios.c_ospeed, tios.c_ispeed); int flags = 0; // rxtx does: if ( s_termios->c_iflag & ISTRIP ) dcb.fBinary = FALSE; // but Winapi doc says fBinary always true flags |= fBinary; if ((c_cflag & PARENB) != 0) flags |= fParity; if ((c_iflag & IXON) != 0) flags |= fOutX; if ((c_iflag & IXOFF) != 0) flags |= fInX; if ((c_iflag & IXANY) != 0) flags |= fTXContinueOnXoff; if ((c_iflag & CRTSCTS) != 0) { flags |= fRtsControl; flags |= fOutxCtsFlow; } // Following have no corresponding functionality in unix termios // fOutxDsrFlow = 0x00000008; // fDtrControl = 0x00000030; // fDsrSensitivity = 0x00000040; // fErrorChar = 0x00000400; // fNull = 0x00000800; // fAbortOnError = 0x00004000; // fDummy2 = 0xFFFF8000; dcb.fFlags = flags; // Don't touch these, windows seems to use: XonLim 2048 XoffLim 512 and who am I to argue with // those // dcb.XonLim = 0; // dcb.XoffLim = 128; byte cs = 8; int csize = c_cflag & CSIZE; if (csize == CS5) cs = 5; if (csize == CS6) cs = 6; if (csize == CS7) cs = 7; if (csize == CS8) cs = 8; dcb.ByteSize = cs; if ((c_cflag & PARENB) != 0) { if ((c_cflag & PARODD) != 0 && (c_cflag & CMSPAR) != 0) dcb.Parity = MARKPARITY; else if ((c_cflag & PARODD) != 0) dcb.Parity = ODDPARITY; else if ((c_cflag & CMSPAR) != 0) dcb.Parity = SPACEPARITY; else dcb.Parity = EVENPARITY; } else dcb.Parity = NOPARITY; dcb.StopBits = (c_cflag & CSTOPB) != 0 ? TWOSTOPBITS : ONESTOPBIT; dcb.XonChar = tios.c_cc[ VSTART]; // In theory these could change but they only get updated if the // baudrate/char size changes so this could be a time bomb dcb.XoffChar = tios.c_cc[ VSTOP]; // In practice in PJC these are never changed so updating on the first pass is // enough dcb.ErrorChar = 0; // rxtx has some thing like // if ( EV_BREAK|EV_CTS|EV_DSR|EV_ERR|EV_RING | ( EV_RLSD & EV_RXFLAG ) // ) // dcb.EvtChar = '\n'; // else // dcb.EvtChar = '\0'; // But those are all defines so there is something fishy there? dcb.EvtChar = '\n'; dcb.EofChar = tios.c_cc[VEOF]; if (!SetCommState(port.m_Comm, dcb)) port.fail(); port.m_c_speed = c_speed; port.m_c_cflag = c_cflag; port.m_c_iflag = c_iflag; port.m_c_oflag = c_oflag; } int vmin = port.m_Termios.c_cc[VMIN] & 0xFF; int vtime = (port.m_Termios.c_cc[VTIME] & 0xFF) * 100; if (vmin != port.m_VMIN || vtime != port.m_VTIME) { COMMTIMEOUTS touts = port.m_Timeouts; // There are really no write timeouts in classic unix termios // FIXME test that we can still interrupt the tread touts.WriteTotalTimeoutConstant = 0; touts.WriteTotalTimeoutMultiplier = 0; if (vmin == 0 && vtime == 0) { // VMIN = 0 and VTIME = 0 => totally non blocking,if data is // available, return it, ie this is poll operation touts.ReadIntervalTimeout = MAXDWORD; touts.ReadTotalTimeoutConstant = 0; touts.ReadTotalTimeoutMultiplier = 0; } if (vmin == 0 && vtime > 0) { // VMIN = 0 and VTIME > 0 => timed read, return as soon as data is // available, VTIME = total time touts.ReadIntervalTimeout = 0; touts.ReadTotalTimeoutConstant = vtime; touts.ReadTotalTimeoutMultiplier = 0; } if (vmin > 0 && vtime > 0) { // VMIN > 0 and VTIME > 0 => blocks until VMIN chars has arrived or between chars expired, // note that this will block if nothing arrives touts.ReadIntervalTimeout = vtime; touts.ReadTotalTimeoutConstant = 0; touts.ReadTotalTimeoutMultiplier = 0; } if (vmin > 0 && vtime == 0) { // VMIN > 0 and VTIME = 0 => blocks until VMIN characters have been // received touts.ReadIntervalTimeout = 0; touts.ReadTotalTimeoutConstant = 0; touts.ReadTotalTimeoutMultiplier = 0; } if (!SetCommTimeouts(port.m_Comm, port.m_Timeouts)) port.fail(); port.m_VMIN = vmin; port.m_VTIME = vtime; log = log && log( 2, "vmin %d vtime %d ReadIntervalTimeout %d ReadTotalTimeoutConstant %d ReadTotalTimeoutMultiplier %d\n", vmin, vtime, touts.ReadIntervalTimeout, touts.ReadTotalTimeoutConstant, touts.ReadTotalTimeoutMultiplier); } return 0; }
public int close(int fd) { Port port = getPort(fd); if (port == null) return -1; port.close(); return 0; }
private void parsePort(PackageClass newClass, Element portNode) { String name = portNode.getAttribute(ATR_NAME); String type = portNode.getAttribute(ATR_TYPE); String x = portNode.getAttribute(ATR_X); String y = portNode.getAttribute(ATR_Y); String portConnection = portNode.getAttribute(ATR_PORT_CONNECTION); String strict = portNode.getAttribute(ATR_STRICT); String multi = portNode.getAttribute(ATR_MULTI); ClassField cf = newClass.getSpecField(name); if (newClass.getComponentType().hasSpec()) { if (name.indexOf(".") > -1) { // TODO - temporarily do not dig into hierarchy int idx = name.indexOf("."); String root = name.substring(0, idx); if (newClass.getSpecField(root) == null) { collector.collectDiagnostic( "Field " + root + " in class " + newClass.getName() + " is not declared in the specification, variable " + type + " " + name + " ignored "); return; } newClass.addSpecField(new ClassField(name, type)); } else if (!TypeUtil.TYPE_THIS.equalsIgnoreCase(name)) { if (cf == null) { collector.collectDiagnostic( "Port " + type + " " + name + " in class " + newClass.getName() + " does not have the corresponding field in the specification"); } else if (!cf.getType().equals(type) // type may be declared as "alias", however cf.getType() returns e.g. "double[]", ignore // it && !(cf.isAlias() && TypeUtil.TYPE_ALIAS.equals(type))) { collector.collectDiagnostic( "Port " + type + " " + name + " in class " + newClass.getName() + " does not match the field declared in the specification: " + cf.getType() + " " + cf.getName()); } } } Port newPort = new Port( name, type, Integer.parseInt(x), Integer.parseInt(y), portConnection, Boolean.parseBoolean(strict), Boolean.parseBoolean(multi)); if (portNode.hasAttribute(ATR_ID)) newPort.setId(portNode.getAttribute(ATR_ID)); Element gr; // open if ((gr = getElementByName(portNode, EL_OPEN)) != null && (gr = getElementByName(gr, EL_GRAPHICS)) != null) { newPort.setOpenGraphics(getGraphicsParser().parse(gr)); } // closed if ((gr = getElementByName(portNode, EL_CLOSED)) != null && (gr = getElementByName(gr, EL_GRAPHICS)) != null) { newPort.setClosedGraphics(getGraphicsParser().parse(gr)); } newClass.addPort(newPort); }
public int read(int fd, byte[] buffer, int length) { Port port = getPort(fd); if (port == null) return -1; synchronized (port.m_RdBuffer) { try { // limit reads to internal buffer size if (length > port.m_RdBuffer.size()) length = (int) port.m_RdBuffer.size(); if (length == 0) return 0; if ((port.m_OpenFlags & O_NONBLOCK) != 0) { clearCommErrors(port); int available = port.m_COMSTAT.cbInQue; if (available == 0) { m_ErrNo = EAGAIN; return -1; } length = min(length, available); } else { clearCommErrors(port); int available = port.m_COMSTAT.cbInQue; int vtime = 0xff & port.m_Termios.c_cc[VTIME]; int vmin = 0xff & port.m_Termios.c_cc[VMIN]; if (vmin == 0 && vtime == 0) { // VMIN = 0 and VTIME = 0 => totally non blocking,if data is // available, return it, ie this is poll operation // For reference below commented out is how timeouts are set for this vtime/vmin combo // touts.ReadIntervalTimeout = MAXDWORD; // touts.ReadTotalTimeoutConstant = 0; // touts.ReadTotalTimeoutMultiplier = 0; if (available == 0) return 0; length = min(length, available); } if (vmin == 0 && vtime > 0) { // VMIN = 0 and VTIME > 0 => timed read, return as soon as data is // available, VTIME = total time // For reference below commented out is how timeouts are set for this vtime/vmin combo // touts.ReadIntervalTimeout = 0; // touts.ReadTotalTimeoutConstant = vtime; // touts.ReadTotalTimeoutMultiplier = 0; // NOTE to behave like unix we should probably wait until there is something available // and then try to do a read as many bytes as are available bytes at that point in time. // As this is coded now, this will attempt to read as many bytes as requested and this // may end up // spending vtime in the read when a unix would return less bytes but as soon as they // become // available. } if (vmin > 0 && vtime > 0) { // VMIN > 0 and VTIME > 0 => blocks until VMIN chars has arrived or between chars // expired, // note that this will block if nothing arrives // For reference below commented out is how timeouts are set for this vtime/vmin combo // touts.ReadIntervalTimeout = vtime; // touts.ReadTotalTimeoutConstant = 0; // touts.ReadTotalTimeoutMultiplier = 0; length = min(max(vmin, available), length); } if (vmin > 0 && vtime == 0) { // VMIN > 0 and VTIME = 0 => blocks until VMIN characters have been // received // For reference below commented out is how timeouts are set for this vtime/vmin combo // touts.ReadIntervalTimeout = 0; // touts.ReadTotalTimeoutConstant = 0; // touts.ReadTotalTimeoutMultiplier = 0; length = min(max(vmin, available), length); } } if (!ResetEvent(port.m_RdOVL.hEvent)) port.fail(); if (!ReadFile(port.m_Comm, port.m_RdBuffer, length, port.m_RdN, port.m_RdOVL)) { if (GetLastError() != ERROR_IO_PENDING) port.fail(); if (WaitForSingleObject(port.m_RdOVL.hEvent, INFINITE) != WAIT_OBJECT_0) port.fail(); if (!GetOverlappedResult(port.m_Comm, port.m_RdOVL, port.m_RdN, true)) port.fail(); } port.m_RdBuffer.read(0, buffer, 0, port.m_RdN[0]); return port.m_RdN[0]; } catch (Fail ie) { return -1; } } }