/* * This file is a part of Alchemy OS project. * Copyright (C) 2011-2013, Sergey Basalaev <sbasalaev@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package alchemy.fs.devfs; import alchemy.fs.FSDriver; import alchemy.fs.Filesystem; import alchemy.io.NullInputStream; import alchemy.io.NullOutputStream; import alchemy.io.RandomInputStream; import alchemy.system.ProcessThread; import alchemy.util.HashMap; import alchemy.util.Strings; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.microedition.io.Connector; /** * Device file system for Alchemy OS. * Typically mounted under {@code /dev}. * <p> * Implemented nodes: * <ul> * <li>{@code /null}</li> * <li>{@code /zero}</li> * <li>{@code /random}</li> * <li>{@code /stdin}</li> * <li>{@code /stdout}</li> * <li>{@code /stderr}</li> * <li>COMM ports on mobile platforms</li> * </ul> * </p> * * @author Sergey Basalaev */ public final class Driver extends FSDriver { private final HashMap sharedinputs = new HashMap(); private final HashMap sharedoutputs = new HashMap(); private final String[] stddevs = {"stdin", "stdout", "stderr", "null", "zero", "random"}; private final String[] commdevs; public Driver() { NullOutputStream sink = new NullOutputStream(); sharedoutputs.set("zero", sink); sharedoutputs.set("null", sink); sharedinputs.set("zero", new NullInputStream(0)); sharedinputs.set("null", new NullInputStream(-1)); sharedinputs.set("random", new RandomInputStream()); String comm = System.getProperty("microedition.commports"); commdevs = (comm == null) ? new String[0] : Strings.split(comm, ',', false); } public InputStream read(String file) throws IOException { String name = Filesystem.fileName(file); if ("stdin".equals(name)) { Thread th = Thread.currentThread(); if (th instanceof ProcessThread) { return ((ProcessThread)th).getProcess().stdin; } } InputStream input = (InputStream) sharedinputs.get(name); if (input != null) { return input; } for (int i=0; i<commdevs.length; i++) { if (commdevs[i].equals(name)) { return Connector.openInputStream("comm:" + name); } } throw new IOException("No such device"); } public OutputStream write(String file) throws IOException { String name = Filesystem.fileName(file); if ("stdout".equals(name)) { Thread th = Thread.currentThread(); if (th instanceof ProcessThread) { return ((ProcessThread)th).getProcess().stdout; } } if ("stderr".equals(name)) { Thread th = Thread.currentThread(); if (th instanceof ProcessThread) { return ((ProcessThread)th).getProcess().stderr; } } OutputStream output = (OutputStream) sharedoutputs.get(name); if (output != null) { return output; } for (int i=0; i<commdevs.length; i++) { if (commdevs[i].equals(name)) { return Connector.openOutputStream("comm:" + name); } } throw new IOException("No such device"); } public OutputStream append(String file) throws IOException { return write(file); } public String[] list(String file) throws IOException { String[] alldevs = new String[stddevs.length + commdevs.length]; System.arraycopy(stddevs, 0, alldevs, 0, stddevs.length); System.arraycopy(commdevs, 0, alldevs, stddevs.length, commdevs.length); return alldevs; } public boolean exists(String file) { String name = Filesystem.fileName(file); if (name.length() == 0) return true; for (int i=0; i<stddevs.length; i++) { if (name.equals(stddevs[i])) return true; } for (int i=0; i<commdevs.length; i++) { if (name.equals(commdevs[i])) return true; } return false; } public boolean isDirectory(String file) { return file.length() == 0; } public void create(String file) throws IOException { throw new IOException("Cannot create new device"); } public void mkdir(String file) throws IOException { throw new IOException("Cannot create new device"); } public void remove(String file) throws IOException { throw new IOException("Cannot remove device"); } public long lastModified(String file) throws IOException { return System.currentTimeMillis(); } public boolean canRead(String file) { String name = Filesystem.fileName(file); if (name.length() == 0 || name.equals("stdin")) return true; if (sharedinputs.get(name) != null) return true; for (int i=0; i<commdevs.length; i++) { if (name.equals(commdevs[i])) return true; } return false; } public boolean canWrite(String file) { String name = Filesystem.fileName(file); if (name.equals("stdout") || name.equals("stderr")) return true; if (sharedoutputs.get(name) != null) return true; for (int i=0; i<commdevs.length; i++) { if (name.equals(commdevs[i])) return true; } return false; } public boolean canExec(String file) { return false; } public void setRead(String file, boolean on) throws IOException { throw new IOException("Cannot change device permissions"); } public void setWrite(String file, boolean on) throws IOException { throw new IOException("Cannot change device permissions"); } public void setExec(String file, boolean on) throws IOException { throw new IOException("Cannot change device permissions"); } public long size(String file) { return 0L; } public long spaceTotal() { return 0L; } public long spaceFree() { return 0L; } public long spaceUsed() { return 0L; } }