001: /*
002: * OpenCmd.java --
003: *
004: * Copyright (c) 1997 Sun Microsystems, Inc.
005: *
006: * See the file "license.terms" for information on usage and
007: * redistribution of this file, and for a DISCLAIMER OF ALL
008: * WARRANTIES.
009: *
010: * RCS: @(#) $Id: OpenCmd.java,v 1.6 2006/07/11 09:10:44 mdejong Exp $
011: *
012: */
013:
014: package tcl.lang;
015:
016: import java.util.*;
017: import java.io.*;
018:
019: /**
020: * This class implements the built-in "open" command in Tcl.
021: */
022:
023: class OpenCmd implements Command {
024: /**
025: * This procedure is invoked to process the "open" Tcl command.
026: * See the user documentation for details on what it does.
027: *
028: * @param interp the current interpreter.
029: * @param argv command arguments.
030: */
031:
032: public void cmdProc(Interp interp, TclObject argv[])
033: throws TclException {
034:
035: boolean pipeline = false; /* True if opening pipeline chan */
036: int prot = 0666; /* Final rdwr permissions of file */
037: int modeFlags = TclIO.RDONLY; /* Rdwr mode for the file. See the
038: * TclIO class for more info on the
039: * valid modes */
040:
041: if ((argv.length < 2) || (argv.length > 4)) {
042: throw new TclNumArgsException(interp, 1, argv,
043: "fileName ?access? ?permissions?");
044: }
045:
046: if (argv.length > 2) {
047: TclObject mode = argv[2];
048: String modeStr = mode.toString();
049: int len = modeStr.length();
050:
051: // This "r+1" hack is just to get a test case to pass
052: if ((len == 0) || (modeStr.startsWith("r+") && len >= 3)) {
053: throw new TclException(interp, "illegal access mode \""
054: + modeStr + "\"");
055: }
056:
057: if (len < 3) {
058: switch (modeStr.charAt(0)) {
059: case 'r': {
060: if (len == 1) {
061: modeFlags = TclIO.RDONLY;
062: break;
063: } else if (modeStr.charAt(1) == '+') {
064: modeFlags = TclIO.RDWR;
065: break;
066: }
067: }
068: case 'w': {
069: if (len == 1) {
070: modeFlags = (TclIO.WRONLY | TclIO.CREAT | TclIO.TRUNC);
071: break;
072: } else if (modeStr.charAt(1) == '+') {
073: modeFlags = (TclIO.RDWR | TclIO.CREAT | TclIO.TRUNC);
074: break;
075: }
076: }
077: case 'a': {
078: if (len == 1) {
079: modeFlags = (TclIO.WRONLY | TclIO.APPEND);
080: break;
081: } else if (modeStr.charAt(1) == '+') {
082: modeFlags = (TclIO.RDWR | TclIO.CREAT | TclIO.APPEND);
083: break;
084: }
085: }
086: default: {
087: throw new TclException(interp,
088: "illegal access mode \"" + modeStr + "\"");
089: }
090: }
091: } else {
092: modeFlags = 0;
093: boolean gotRorWflag = false;
094: final int mlen = TclList.getLength(interp, mode);
095: for (int i = 0; i < mlen; i++) {
096: TclObject marg = TclList.index(interp, mode, i);
097: if (marg.toString().equals("RDONLY")) {
098: modeFlags |= TclIO.RDONLY;
099: gotRorWflag = true;
100: } else if (marg.toString().equals("WRONLY")) {
101: modeFlags |= TclIO.WRONLY;
102: gotRorWflag = true;
103: } else if (marg.toString().equals("RDWR")) {
104: modeFlags |= TclIO.RDWR;
105: gotRorWflag = true;
106: } else if (marg.toString().equals("APPEND")) {
107: modeFlags |= TclIO.APPEND;
108: } else if (marg.toString().equals("CREAT")) {
109: modeFlags |= TclIO.CREAT;
110: } else if (marg.toString().equals("EXCL")) {
111: modeFlags |= TclIO.EXCL;
112: } else if (marg.toString().equals("TRUNC")) {
113: modeFlags |= TclIO.TRUNC;
114: } else {
115: throw new TclException(
116: interp,
117: "invalid access mode \""
118: + marg.toString()
119: + "\": must be RDONLY, WRONLY, RDWR, APPEND, "
120: + "CREAT EXCL, NOCTTY, NONBLOCK, or TRUNC");
121: }
122: }
123: if (!gotRorWflag) {
124: throw new TclException(interp,
125: "access mode must include either RDONLY, WRONLY, or RDWR");
126: }
127: }
128: }
129:
130: if (argv.length == 4) {
131: prot = TclInteger.get(interp, argv[3]);
132: throw new TclException(interp,
133: "setting permissions not implemented yet");
134: }
135: if ((argv[1].toString().length() > 0)
136: && (argv[1].toString().charAt(0) == '|')) {
137: pipeline = true;
138: throw new TclException(interp,
139: "pipelines not implemented yet");
140: }
141:
142: /*
143: * Open the file or create a process pipeline.
144: */
145:
146: if (!pipeline) {
147: try {
148: FileChannel file = new FileChannel();
149: file.open(interp, argv[1].toString(), modeFlags);
150: TclIO.registerChannel(interp, file);
151: interp.setResult(file.getChanName());
152: } catch (IOException e) {
153: throw new TclException(interp, "cannot open file: "
154: + argv[1].toString());
155: }
156: } else {
157: /*
158: * Pipeline code here...
159: */
160:
161: }
162: }
163: }
|