001/*
002 * Copyright (C) 2009-2017 the original author(s).
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fusesource.jansi.internal;
017
018import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT;
019import static org.fusesource.hawtjni.runtime.MethodFlag.CONSTANT_INITIALIZER;
020
021import static org.fusesource.hawtjni.runtime.ArgFlag.*;
022
023import org.fusesource.hawtjni.runtime.ArgFlag;
024import org.fusesource.hawtjni.runtime.ClassFlag;
025import org.fusesource.hawtjni.runtime.JniArg;
026import org.fusesource.hawtjni.runtime.JniClass;
027import org.fusesource.hawtjni.runtime.JniField;
028import org.fusesource.hawtjni.runtime.JniMethod;
029import org.fusesource.hawtjni.runtime.Library;
030
031/**
032 * Interface to access some low level POSIX functions.
033 * 
034 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
035 */
036@JniClass()
037public class CLibrary {
038    
039    private static final Library LIBRARY = new Library("jansi", CLibrary.class);    
040    static {
041        LIBRARY.load();
042        init();
043    }
044
045    @JniMethod(flags={CONSTANT_INITIALIZER})
046    private static native void init();
047
048    @JniField(flags={CONSTANT}, conditional="defined(STDIN_FILENO)")
049    public static int STDIN_FILENO;
050    @JniField(flags={CONSTANT}, conditional="defined(STDOUT_FILENO)")
051    public static int STDOUT_FILENO;
052    @JniField(flags={CONSTANT}, conditional="defined(STDERR_FILENO)")
053    public static int STDERR_FILENO;
054
055    @JniField(flags={CONSTANT}, accessor="1", conditional="defined(HAVE_ISATTY)")
056    public static boolean HAVE_ISATTY;
057
058    @JniField(flags={CONSTANT}, accessor="1", conditional="defined(HAVE_TTYNAME)")
059    public static boolean HAVE_TTYNAME;
060
061    /**
062     * test whether a file descriptor refers to a terminal
063     * 
064     * @param fd file descriptor
065     * @return isatty() returns 1 if fd is an open file descriptor referring to a
066     * terminal; otherwise 0 is returned, and errno is set to indicate the
067     * error
068     * @see <a href="http://man7.org/linux/man-pages/man3/isatty.3.html">ISATTY(3) man-page</a>
069     * @see <a href="http://man7.org/linux/man-pages/man3/isatty.3p.html">ISATTY(3P) man-page</a>
070     */
071    @JniMethod(conditional="FALSE")
072    public static native int isatty(
073            @JniArg int fd);
074
075    @JniMethod(conditional="FALSE")
076    public static native String ttyname(
077            @JniArg int filedes);
078
079    /**
080     * The openpty() function finds an available pseudoterminal and returns
081     * file descriptors for the master and slave in amaster and aslave.
082     * @param amaster master return value
083     * @param aslave slave return value
084     * @param name filename return value
085     * @param termios
086     * @param winsize
087     * @return 0 on success
088     * @see <a href="http://man7.org/linux/man-pages/man3/openpty.3.html">OPENPTY(3) man-page</a>
089     */
090    @JniMethod(conditional="defined(HAVE_OPENPTY)")
091    public static native int openpty(
092            @JniArg(cast="int *", flags={NO_IN}) int[] amaster,
093            @JniArg(cast="int *", flags={NO_IN}) int[] aslave,
094            @JniArg(cast="char *", flags={NO_IN}) byte[] name,
095            @JniArg(cast="struct termios *", flags={NO_OUT}) Termios termios,
096            @JniArg(cast="struct winsize *", flags={NO_OUT}) WinSize winsize);
097
098    @JniMethod(conditional="defined(HAVE_TCGETATTR)")
099    public static native int tcgetattr(
100            @JniArg int filedes,
101            @JniArg(cast="struct termios *", flags={NO_IN}) Termios termios);
102
103    @JniMethod(conditional="defined(HAVE_TCSETATTR)")
104    public static native int tcsetattr(
105            @JniArg int filedes,
106            @JniArg int optional_actions,
107            @JniArg(cast="struct termios *", flags={NO_OUT}) Termios termios);
108
109    /*
110     * Commands passed to tcsetattr() for setting the termios structure.
111     */
112    @JniField(flags={CONSTANT}, conditional="defined(TCSANOW)")
113    public static int TCSANOW;              /* make change immediate */
114    @JniField(flags={CONSTANT}, conditional="defined(TCSADRAIN)")
115    public static int TCSADRAIN;                /* drain output, then change */
116    @JniField(flags={CONSTANT}, conditional="defined(TCSAFLUSH)")
117    public static int TCSAFLUSH;                /* drain output, flush input */
118
119    @JniField(flags={CONSTANT}, conditional="defined(TIOCGETA)")
120    public static long TIOCGETA;
121    @JniField(flags={CONSTANT}, conditional="defined(TIOCSETA)")
122    public static long TIOCSETA;
123    @JniField(flags={CONSTANT}, conditional="defined(TIOCGETD)")
124    public static long TIOCGETD;
125    @JniField(flags={CONSTANT}, conditional="defined(TIOCSETD)")
126    public static long TIOCSETD;
127    /**
128     * ioctl command: Get window size.
129     */
130    @JniField(flags={CONSTANT}, conditional="defined(TIOCGWINSZ)")
131    public static long TIOCGWINSZ;
132    /**
133     * ioctl command: Set window size.
134     */
135    @JniField(flags={CONSTANT}, conditional="defined(TIOCSWINSZ)")
136    public static long TIOCSWINSZ;
137
138    /**
139     * Control a STREAMS device.
140     *
141     * @param filedes
142     * @param request
143     * @param params
144     * @return
145     * @see <a href="http://man7.org/linux/man-pages/man3/ioctl.3p.html">IOCTL(3P) man-page</a>
146     */
147    @JniMethod(conditional="defined(HAVE_IOCTL)")
148    public static native int ioctl(
149            @JniArg int filedes,
150            @JniArg long request,
151            @JniArg int[] params);
152
153    @JniMethod(conditional="defined(HAVE_IOCTL)")
154    public static native int ioctl(
155            @JniArg int filedes,
156            @JniArg long request,
157            @JniArg(flags = ArgFlag.POINTER_ARG) WinSize params);
158
159    /**
160     * Window sizes.
161     * @see <a href="http://man7.org/linux/man-pages/man4/tty_ioctl.4.html">IOCTL_TTY(2) man-page</a>
162     */
163    @JniClass(flags={ClassFlag.STRUCT}, name="winsize", conditional="defined(HAVE_IOCTL)")
164    public static class WinSize {
165
166        static {
167            LIBRARY.load();
168            init();
169        }
170
171        @JniMethod(flags={CONSTANT_INITIALIZER})
172        private static native void init();
173        @JniField(flags={CONSTANT}, accessor="sizeof(struct winsize)")
174        public static int SIZEOF;
175
176        @JniField(accessor="ws_row")
177        public short ws_row;
178        @JniField(accessor="ws_col")
179        public short ws_col;
180        @JniField(accessor="ws_xpixel")
181        public short ws_xpixel;
182        @JniField(accessor="ws_ypixel")
183        public short ws_ypixel;
184
185        public WinSize() {
186        }
187
188        public WinSize(short ws_row, short ws_col) {
189            this.ws_row = ws_row;
190            this.ws_col = ws_col;
191        }
192    }
193
194    /**
195     * termios structure for termios functions, describing a general terminal interface that is
196     * provided to control asynchronous communications ports
197     *
198     * @see <a href="http://man7.org/linux/man-pages/man3/termios.3.html">TERMIOS(3) man-page</a>
199     */
200    @JniClass(flags={ClassFlag.STRUCT}, name="termios", conditional = "defined(HAVE_IOCTL)")
201    public static class Termios {
202
203        static {
204            LIBRARY.load();
205            init();
206        }
207
208        @JniMethod(flags={CONSTANT_INITIALIZER})
209        private static native void init();
210        @JniField(flags={CONSTANT}, accessor="sizeof(struct termios)")
211        public static int SIZEOF;
212
213        @JniField(accessor="c_iflag")
214        public long c_iflag;
215        @JniField(accessor="c_oflag")
216        public long c_oflag;
217        @JniField(accessor="c_cflag")
218        public long c_cflag;
219        @JniField(accessor="c_lflag")
220        public long c_lflag;
221        @JniField(accessor="c_cc")
222        public byte[] c_cc = new byte[32];
223        @JniField(accessor="c_ispeed")
224        public long c_ispeed;
225        @JniField(accessor="c_ospeed")
226        public long c_ospeed;
227    }
228
229}