private static void release(String lockName, FileLock fileLock, File file, Closeable stream) { synchronized (LOCK_MAP) { if (fileLock != null) { try { LOCK_MAP.remove(lockName, fileLock.hashCode()); ConcurrentHashMap<Integer, ProcessLock> locks = LOCK_MAP.get(lockName); if (locks == null || locks.isEmpty()) { IOUtil.deleteFileOrDir(file); } if (fileLock.channel().isOpen()) { fileLock.release(); } } catch (Throwable ex) { LogUtil.e(ex.getMessage(), ex); } finally { IOUtil.closeQuietly(fileLock.channel()); } } IOUtil.closeQuietly(stream); } }
public synchronized int incrementNextTaskId() { int toRet = -1; try { FileLock l = channel.lock(); buffer.position(0); int current = buffer.getInt(); buffer.position(0); current++; toRet = current; buffer.putInt(current); l.release(); } catch (IOException e) { System.err.println("SharedSystemData, IOException : " + e.getMessage()); e.printStackTrace(); } return toRet; }
/** * Compactar uma arquivo. * @param inputFile informar o arquivo a ser compactado. * @param zipFilePath informar o nome e caminho zip. * @param iZipFile se necessário, informar uma {@link IZipFile}. * @throws IOException */ public static void zipFile(File inputFile, String zipFilePath, IZipFile iZipFile) throws IOException { FileOutputStream fileOutputStream = new FileOutputStream(zipFilePath); ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream); ZipEntry zipEntry = new ZipEntry(inputFile.getName()); zipOutputStream.putNextEntry(zipEntry); FileInputStream fileInputStream = new FileInputStream(inputFile); FileChannel fileChannel = fileInputStream.getChannel(); FileLock fileLock = fileChannel.tryLock(0L, Long.MAX_VALUE, /*shared*/true); long sizeToZip = fileInputStream.available(); long sizeCompacted = 0; try { byte[] buf = new byte[1024]; int bytesRead; while ((bytesRead = fileInputStream.read(buf)) > 0) { sizeCompacted += bytesRead; zipOutputStream.write(buf, 0, bytesRead); if (iZipFile != null) iZipFile.progress(sizeToZip, sizeCompacted); } } finally { fileLock.release(); zipOutputStream.closeEntry(); zipOutputStream.close(); fileOutputStream.close(); } }
public void testOperationActions() throws Exception { // #72397 final NbModuleProject project = generateStandaloneModule("module"); cgpi.setProject(project); DialogDisplayerImpl dd = (DialogDisplayerImpl) Lookup.getDefault().lookup(DialogDisplayer.class); FileObject lock = FileUtil.createData(project.getProjectDirectory(), "build/testuserdir/lock"); RandomAccessFile raf = new RandomAccessFile(FileUtil.toFile(lock), "rw"); FileLock lck = raf.getChannel().lock(); EventQueue.invokeAndWait(new Runnable() { @Override public void run() { ((ContextAwareAction) CommonProjectActions.deleteProjectAction()).createContextAwareInstance(Lookups.singleton(project)).actionPerformed(null); } }); assertNotNull("warning message emitted", dd.getLastNotifyDescriptor()); assertEquals("warning message emitted", dd.getLastNotifyDescriptor().getMessage(), Bundle.ERR_ModuleIsBeingRun()); dd.reset(); lck.release(); raf.close(); lock.delete(); EventQueue.invokeAndWait(new Runnable() { @Override public void run() { CommonProjectActions.deleteProjectAction().actionPerformed(null); } }); assertNull("no warning message", dd.getLastNotifyDescriptor()); }
/** * Will modify length of section if differnt amoutn actually written * @param writeSection * @param sourceChannel * @throws IOException */ private void writeFromSocketChannel(Section writeSection, SocketChannel sourceChannel) throws IOException{ synchronized (sourceChannel) { try ( FileLock sectionLock = pieceChannel.lock(Integer.toUnsignedLong(writeSection.begin), Integer.toUnsignedLong(writeSection.length), false) ) { // System.out.println("dksahfksjadh"); int plz = writeSection.length; //writeSection.length = Math.toIntExact(pieceChannel.transferFrom(sourceChannel, Integer.toUnsignedLong(writeSection.begin), Integer.toUnsignedLong(writeSection.length))); ByteBuffer cant = ByteBuffer.allocate(plz); cant.clear(); sourceChannel.read(cant); cant.rewind(); pieceChannel.write(cant, writeSection.begin); // System.out.println("LENGTH ACTUALLY: " + plz); }; } }
/** * Unlock file already locked with {@link #lockFile(String) lockFile()} method * * @param fileName file name */ @Override public void unlockFile( String fileName ) { synchronized (lockedFiles) { FileLock fileLock = lockedFiles.get(fileName); if (fileLock != null) { try { fileLock.release(); } catch (Exception e) { throw new FileSystemOperationException("Could not unlock file '" + fileName + "'", e); } finally { IoUtils.closeStream(fileLock.channel()); lockedFiles.remove(fileName); } } else { log.warn("File '" + fileName + "' is not locked, so we will not try to unlock it"); } } }
/** * Attempts to acquire an exclusive lock on the directory. * * @return A lock object representing the newly-acquired lock or * <code>null</code> if directory is already locked. * @throws IOException if locking fails. */ @SuppressWarnings("resource") private FileLock tryLock(File dir) throws IOException { File lockF = new File(dir, FILE_LOCK); lockF.deleteOnExit(); RandomAccessFile file = new RandomAccessFile(lockF, "rws"); FileLock res = null; try { res = file.getChannel().tryLock(); } catch (OverlappingFileLockException oe) { file.close(); return null; } catch (IOException e) { LOGGER.error("Cannot create lock on " + lockF, e); file.close(); throw e; } return res; }
private File unzipFile(File cachedFile) throws IOException { String filename = cachedFile.getName(); File destDir = new File(cachedFile.getParentFile(), filename + "_unzip"); if (!destDir.exists()) { File lockFile = new File(cachedFile.getParentFile(), filename + "_unzip.lock"); FileOutputStream out = new FileOutputStream(lockFile); try { FileLock lock = out.getChannel().lock(); try { // Recheck in case of concurrent processes if (!destDir.exists()) { Path tempDir = fileCache.createTempDir(); ZipUtils.unzip(cachedFile, tempDir.toFile(), newLibFilter()); FileUtils.moveDirectory(tempDir.toFile(), destDir); } } finally { lock.release(); } } finally { out.close(); FileUtils.deleteQuietly(lockFile); } } return destDir; }
/** * Tries to obtain a write lock on the file. This can be used to verify that no other processes concurrently * writes to the file, for example to check that writing to a file, i.e. on a MODIFY_ENTRY event, is completed * @param path * the path to the file * @return * true, if the lock could be obtained. False, if not. Please not that the lock is released once the method * returns! */ public static boolean tryWriteLock(final Path path) { try(FileChannel ch = FileChannel.open(path, StandardOpenOption.WRITE); FileLock lock = ch.lock()){ if(lock == null) { LOG.log(Level.INFO, "Could not obtain lock on file, maybe still writing"); return false; } else { return true; } } catch (IOException e) { LOG.log(Level.INFO, "File not open for write access", e); return false; } }
/** write lock file to prevent duplicate execution */ @SuppressWarnings("resource") public static void fileLock() throws FileNotFoundException { lockFile = new File(Main.LOCK_FILE_LOCATION); FileChannel channel; channel = new RandomAccessFile(lockFile, "rw").getChannel(); // try lock FileLock lock; try { lock = channel.tryLock(); // already obtain lock in other JVM if (lock == null) { channel.close(); System.exit(0); } } catch (IOException e) { // error handle } }
void releaseLock(final FileLock fileLock, final File lockFile) throws IOException { if (lockFile == null) { return; } try { if (fileLock != null) { fileLock.release(); fileLock.channel().close(); } } finally { if (!lockFile.delete()) { lockFile.deleteOnExit(); } } }
private ShareFileLockHelper(File lockFile) throws IOException { this.outputStream = new FileOutputStream(lockFile); int numAttempts = 0; FileLock localFileLock = null; Exception saveException = null; while (numAttempts < 3) { numAttempts++; try { localFileLock = this.outputStream.getChannel().lock(); if (localFileLock != null) { break; } Thread.sleep(10); } catch (Exception e) { saveException = e; Log.e(TAG, "getInfoLock Thread failed time:10"); } } if (localFileLock == null) { throw new IOException("Tinker Exception:FileLockHelper lock file failed: " + lockFile .getAbsolutePath(), saveException); } this.fileLock = localFileLock; }
@Override public boolean isPreUpgradableLayout(StorageDirectory sd) throws IOException { File oldF = new File(sd.getRoot(), "storage"); if (!oldF.exists()) return false; // check the layout version inside the storage file // Lock and Read old storage file RandomAccessFile oldFile = new RandomAccessFile(oldF, "rws"); FileLock oldLock = oldFile.getChannel().tryLock(); try { oldFile.seek(0); int oldVersion = oldFile.readInt(); if (oldVersion < LAST_PRE_UPGRADE_LAYOUT_VERSION) return false; } finally { oldLock.release(); oldFile.close(); } return true; }
/** * Lock storage to provide exclusive access. * * <p> Locking is not supported by all file systems. * E.g., NFS does not consistently support exclusive locks. * * <p> If locking is supported we guarantee exclusive access to the * storage directory. Otherwise, no guarantee is given. * * @throws IOException if locking fails */ public void lock() throws IOException { if (isShared()) { LOG.info("Locking is disabled for " + this.root); return; } FileLock newLock = tryLock(); if (newLock == null) { String msg = "Cannot lock storage " + this.root + ". The directory is already locked"; LOG.info(msg); throw new IOException(msg); } // Don't overwrite lock until success - this way if we accidentally // call lock twice, the internal state won't be cleared by the second // (failed) lock attempt lock = newLock; }
/** * Check whether underlying file system supports file locking. * * @return <code>true</code> if exclusive locks are supported or * <code>false</code> otherwise. * @throws IOException * @see StorageDirectory#lock() */ public boolean isLockSupported() throws IOException { FileLock firstLock = null; FileLock secondLock = null; try { firstLock = lock; if(firstLock == null) { firstLock = tryLock(); if(firstLock == null) return true; } secondLock = tryLock(); if(secondLock == null) return true; } finally { if(firstLock != null && firstLock != lock) { firstLock.release(); firstLock.channel().close(); } if(secondLock != null) { secondLock.release(); secondLock.channel().close(); } } return false; }
/** * Get file lock for writing too file * <p/> * TODO:this appears to have little effect on Windows Vista * * @param fileChannel * @param filePath * @return lock or null if locking is not supported * @throws IOException if unable to get lock because already locked by another program * @throws java.nio.channels.OverlappingFileLockException if already locked by another thread in the same VM, we dont catch this * because indicates a programming error */ protected FileLock getFileLockForWriting(FileChannel fileChannel, String filePath) throws IOException { logger.finest("locking fileChannel for " + filePath); FileLock fileLock; try { fileLock = fileChannel.tryLock(); } //Assumes locking is not supported on this platform so just returns null catch (IOException exception) { return null; } //Couldnt getFields lock because file is already locked by another application if (fileLock == null) { throw new IOException(ErrorMessage.GENERAL_WRITE_FAILED_FILE_LOCKED.getMsg(filePath)); } return fileLock; }
@Nullable public FileLock tryLock(RandomAccessFile lockFileAccess, boolean shared) throws IOException { try { return lockFileAccess.getChannel().tryLock(infoRegionPos, INFORMATION_REGION_SIZE - infoRegionPos, shared); } catch (OverlappingFileLockException e) { // Locked by the same process, treat as if locked by another process return null; } }
public FileLock tryLock(RandomAccessFile lockFileAccess, boolean shared) throws IOException { try { return lockFileAccess.getChannel().tryLock(REGION_START, stateRegionSize, shared); } catch (OverlappingFileLockException e) { return null; } }
/** * Acquire file lock and set next task id. */ public synchronized void setNextTaskId(int pNextTaskId) { try { FileLock l = channel.lock(); buffer.position(0); buffer.putInt(pNextTaskId); l.release(); } catch (IOException e) { System.err.println("SharedSystemData, IOException : " + e.getMessage()); e.printStackTrace(); } }
/** * Acquire file lock and get next task id. * @return */ public synchronized int getNextTaskId() { int toRet = -1; try { FileLock l = channel.lock(); buffer.position(0); toRet = buffer.getInt(); l.release(); } catch (IOException e) { System.err.println("SharedSystemData, IOException : " + e.getMessage()); e.printStackTrace(); } return toRet; }
public synchronized void setShutdownSignal(boolean pShutdownSignal) { try { FileLock l = channel.lock(); buffer.position(Integer.BYTES); buffer.putInt(pShutdownSignal ? 1 : 0); l.release(); } catch (IOException e) { System.err.println("SharedSystemData, IOException : " + e.getMessage()); e.printStackTrace(); } }
public boolean getShutdownSignal() { boolean toRet = false; try { FileLock l = channel.lock(Integer.BYTES, Integer.BYTES, false); buffer.position(Integer.BYTES); toRet = buffer.getInt() == 1 ? true : false; l.release(); } catch (IOException e) { System.err.println("SharedSystemData, IOException : " + e.getMessage()); e.printStackTrace(); } return toRet; }
private ShareFileLockHelper(File lockFile) throws IOException { outputStream = new FileOutputStream(lockFile); int numAttempts = 0; boolean isGetLockSuccess; FileLock localFileLock = null; //just wait twice, Exception saveException = null; while (numAttempts < MAX_LOCK_ATTEMPTS) { numAttempts++; try { localFileLock = outputStream.getChannel().lock(); isGetLockSuccess = (localFileLock != null); if (isGetLockSuccess) { break; } //it can just sleep 0, afraid of cpu scheduling Thread.sleep(LOCK_WAIT_EACH_TIME); } catch (Exception e) { // e.printStackTrace(); saveException = e; Log.e(TAG, "getInfoLock Thread failed time:" + LOCK_WAIT_EACH_TIME); } } if (localFileLock == null) { throw new IOException("Tinker Exception:FileLockHelper lock file failed: " + lockFile.getAbsolutePath(), saveException); } fileLock = localFileLock; }
private ProcessLock(String lockName, File file, FileLock fileLock, Closeable stream, boolean writeMode) { mLockName = lockName; mFileLock = fileLock; mFile = file; mStream = stream; mWriteMode = writeMode; }
private static ProcessLock tryLockInternal(final String lockName, final String hash, final boolean writeMode) { synchronized (LOCK_MAP) { ConcurrentHashMap<Integer, ProcessLock> locks = LOCK_MAP.get(lockName); if (locks != null && !locks.isEmpty()) { Iterator<Map.Entry<Integer, ProcessLock>> itr = locks.entrySet().iterator(); while (itr.hasNext()) { Map.Entry<Integer, ProcessLock> entry = itr.next(); ProcessLock value = entry.getValue(); if (value != null) { if (!value.isValid()) { itr.remove(); } else if (writeMode) { return null; } else if (value.mWriteMode) { return null; } } else { itr.remove(); } } } FileChannel channel = null; Closeable stream = null; try { File file = new File( x.app().getDir(LOCK_FILE_DIR, Context.MODE_PRIVATE), hash); if (file.exists() || file.createNewFile()) { if (writeMode) { FileOutputStream out = new FileOutputStream(file, false); channel = out.getChannel(); stream = out; } else { FileInputStream in = new FileInputStream(file); channel = in.getChannel(); stream = in; } if (channel != null) { FileLock fileLock = channel.tryLock(0L, Long.MAX_VALUE, !writeMode); if (isValid(fileLock)) { ProcessLock result = new ProcessLock(lockName, file, fileLock, stream, writeMode); LOCK_MAP.put(lockName, fileLock.hashCode(), result); return result; } else { release(lockName, fileLock, file, stream); } } else { throw new IOException("can not get file channel:" + file.getAbsolutePath()); } } } catch (Throwable ignored) { LogUtil.d("tryLock: " + lockName + ", " + ignored.getMessage()); IOUtil.closeQuietly(stream); IOUtil.closeQuietly(channel); } } return null; }
private static FileLock tryLock(RandomAccessFile raf) throws IOException { try { return raf.getChannel().tryLock(333L, 1L, false); } catch (OverlappingFileLockException ex) { OUTPUT.log(Level.INFO, "tryLock fails in the same VM", ex); // happens in CLIHandlerTest as it simulates running multiple // instances of the application in the same VM return null; } }
public void testCannotLock() throws Exception { FileOutputStream os = new FileOutputStream(file); FileLock lock = os.getChannel().lock(); try { assertTrue("Is locked", condition.eval()); } finally { lock.release(); } }
public void run(){ try{ FileLock fl=fc.lock(start,end,false); System.out.println("Locked: "+start+" to"+end); while (buff.position()<buff.limit()-1){ buff.put((byte)(buff.get()+1)); } fl.release(); System.out.println("Released: "+start+" to "+end); }catch (IOException e){ throw new RuntimeException(e); } }
public static void main(String[] args) throws Exception{ FileOutputStream fos=new FileOutputStream(""); FileLock fl=fos.getChannel().tryLock(); if(fl!=null){ System.out.println("Locked File"); TimeUnit.MILLISECONDS.sleep(100); fl.release(); System.out.println("Released Lock"); } fos.close(); }
@Override public Lock obtainLock(@NonNull Directory dir, String lockName) throws IOException { if (!(dir instanceof RedisDirectory)) { throw new IllegalArgumentException("Expect argument of type [" + RedisDirectory.class.getName() + "]!"); } Path lockFile = lockFileDirectory.resolve(lockName); try { Files.createFile(lockFile); log.debug("Lock file path = {}", lockFile.toFile().getAbsolutePath()); } catch (IOException ignore) { //ignore log.debug("Lock file already exists!"); } final Path realPath = lockFile.toRealPath(); final FileTime creationTime = Files.readAttributes(realPath, BasicFileAttributes.class).creationTime(); if (LOCK_HELD.add(realPath.toString())) { FileChannel fileChannel = null; FileLock lock = null; try { fileChannel = FileChannel.open(realPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE); lock = fileChannel.tryLock(); if (lock != null) { return new RedisLock(lock, fileChannel, realPath, creationTime); } else { throw new LockObtainFailedException("Lock held by another program: " + realPath); } } finally { if (lock == null) { IOUtils.closeQuietly(fileChannel); clearLockHeld(realPath); } } } else { throw new LockObtainFailedException("Lock held by this virtual machine: " + realPath); } }
@Override public void close() throws IOException { if (closed) { return; } try (FileChannel channel = this.fileChannel; FileLock lock = this.lock) { Objects.requireNonNull(channel); Objects.requireNonNull(lock); } finally { closed = true; clearLockHeld(path); } }
public byte[] computeHash() throws IOException, NoSuchAlgorithmException { final int CHUNK_SIZE = 8192; try (FileLock lock = pieceChannel.lock()) { ByteBuffer buf = ByteBuffer.allocateDirect(CHUNK_SIZE); buf.clear(); MessageDigest md = MessageDigest.getInstance("SHA-1"); while (pieceChannel.read(buf) != -1) { buf.flip(); md.update(buf); buf.clear(); } return md.digest(); } }
public static boolean obtain() { FileLock lock = LockingHelper.getLock(new File(PlatformData.installationDirectory, "lockfile")); if (lock != null) { _lock_ = lock; return true; } else { return false; } }
@SuppressWarnings("resource") public static synchronized FileLock getLock(File file) { System.out.println("Attempting to acquire file lock for " + file.getAbsolutePath()); FileChannel channel = null; try { channel = new RandomAccessFile(file, "rw").getChannel(); return channel.tryLock(); } catch (IOException | OverlappingFileLockException e) { System.err.println("Failed to lock channel"); e.printStackTrace(); if (channel != null) { try { channel.close(); } catch (IOException e1) { System.err.println("Failed to close lock channel"); e1.printStackTrace(); } } return null; } }
/** * Returns wether the underlying file is locked, non-blocking. * @return true if the underlying file is locked. * @throws ClosedChannelException the underlying FileChannel has been closed. * @throws NonWritableChannelException the underlying FileChannel * hasn't been opened with the WRITE OpenOption. */ public boolean isLocked() throws IOException { try (FileLock fl = fileToLock.tryLock()) { return fl != null; } catch (OverlappingFileLockException e) { return true; } }
/** * <pre> * Acquires an exclusive lock on a file * * <b>Platform dependencies</b> * * - In Windows it works as expected * - In Linux it depends on the locking mechanism of the system. The file locking types are two - advisory and mandatory: * * a) <b>Advisory locking</b> - advisory locking will work, only if the participating process are cooperative. * Advisory locking sometimes also called as "unenforced" locking. * * b) <b>Mandatory locking</b> - mandatory locking doesn’t require cooperation from the participating processes. * It causes the kernel to check every open, read and write to verify that the calling process isn’t * violating a lock on the given file. To enable mandatory locking in Linux, you need to enable it on * a file system level and also on the individual files. The steps to be followed are: * 1. Mount the file system with "<i>-o mand</i>" option * 2. For the lock_file, turn on the set-group-ID bit and turn off the group-execute bit, to enable * mandatory locking on that particular file. (This way has been chosen because when you turn off * the group-execute bit, set-group-ID has no real meaning to it ) * * How to do mandatory locking: * Note: You need to be root to execute the below command * <i># mount -oremount,mand /</i> * <i># touch mandatory.txt</i> * <i># chmod g+s,g-x mandatory.txt</i> * </pre> * * @param fileName file name */ @Override public void lockFile( String fileName ) { synchronized (lockedFiles) { if (lockedFiles.containsKey(fileName)) { log.warn("File '" + fileName + "' is already locked"); } else { try { File fileToLock = new File(fileName); @SuppressWarnings( "resource") //keep lock to the file FileChannel channel = new RandomAccessFile(fileToLock, "rw").getChannel(); FileLock fileLock = channel.lock(); lockedFiles.put(fileName, fileLock); } catch (FileNotFoundException fnfe) { throw new FileSystemOperationException("File '" + fileName + "' is not found", fnfe); } catch (OverlappingFileLockException ofle) { throw new FileSystemOperationException("File '" + fileName + "' is already locked in the current JVM" + ", but not from this class, so we can't unlock it later.", ofle); } catch (Exception e) { throw new FileSystemOperationException("Could not lock file '" + fileName + "'", e); } } } }
private int RefCntInc(String name, FileLock fileLock, RandomAccessFile fOs, FileChannel fChannel){ Integer val = 0; if (mRefCountMap.containsKey(name)){ val = mRefCountMap.get(name).mRefCount++; } else { val = 1; FileLockCount newFileLockCount = new FileLockCount(fileLock, val, fOs, fChannel); mRefCountMap.put(name, newFileLockCount); } return val; }
/** * Lock storage to provide exclusive access. * * <p> Locking is not supported by all file systems. * E.g., NFS does not consistently support exclusive locks. * * <p> If locking is supported we guarantee exclusive access to the * storage directory. Otherwise, no guarantee is given. * * @throws IOException if locking fails */ public void lock() throws IOException { FileLock newLock = tryLock(); if (newLock == null) { String msg = "Cannot lock storage " + this.root + ". The directory is already locked"; LOG.info(msg); throw new IOException(msg); } // Don't overwrite lock until success - this way if we accidentally // call lock twice, the internal state won't be cleared by the second // (failed) lock attempt lock = newLock; }
/** * Attempts to acquire an exclusive lock on the storage. * * @return A lock object representing the newly-acquired lock or * <code>null</code> if storage is already locked. * @throws IOException if locking fails. */ private FileLock tryLock() throws IOException { boolean deletionHookAdded = false; File lockF = new File(root, STORAGE_FILE_LOCK); if (!lockF.exists()) { lockF.deleteOnExit(); deletionHookAdded = true; } RandomAccessFile file = new RandomAccessFile(lockF, "rws"); String jvmName = ManagementFactory.getRuntimeMXBean().getName(); FileLock res; try { res = file.getChannel().tryLock(); if (null == res) { LOG.error("Unable to acquire file lock on path " + lockF.toString()); throw new OverlappingFileLockException(); } file.write(jvmName.getBytes(StandardCharsets.UTF_8)); LOG.info("Lock on " + lockF + " acquired by nodename " + jvmName); } catch (OverlappingFileLockException oe) { // Cannot read from the locked file on Windows. LOG.error("It appears that another process " + "has already locked the storage directory: " + root, oe); file.close(); return null; } catch(IOException e) { LOG.error("Failed to acquire lock on " + lockF + ". If this storage directory is mounted via NFS, " + "ensure that the appropriate nfs lock services are running.", e); file.close(); throw e; } if (!deletionHookAdded) { // If the file existed prior to our startup, we didn't // call deleteOnExit above. But since we successfully locked // the dir, we can take care of cleaning it up. lockF.deleteOnExit(); } return res; }