Initial release of Maemo 5 port of gnuplot
[gnuplot] / src / os9.c
1 /* $Id: os9.c,v 1.4 2004/07/25 12:25:01 broeker Exp $ */
2
3 /* GNUPLOT - os9.c */
4
5 /*[
6  * Copyright 1986 - 1993, 1998, 2004   Thomas Williams, Colin Kelley
7  *
8  * Permission to use, copy, and distribute this software and its
9  * documentation for any purpose with or without fee is hereby granted,
10  * provided that the above copyright notice appear in all copies and
11  * that both that copyright notice and this permission notice appear
12  * in supporting documentation.
13  *
14  * Permission to modify the software is granted, but not the right to
15  * distribute the complete modified source code.  Modifications are to
16  * be distributed as patches to the released version.  Permission to
17  * distribute binaries produced by compiling modified sources is granted,
18  * provided you
19  *   1. distribute the corresponding source modifications from the
20  *    released version in the form of a patch file along with the binaries,
21  *   2. add special version identification to distinguish your version
22  *    in addition to the base release version number,
23  *   3. provide your name and address as the primary contact for the
24  *    support of your modified version, and
25  *   4. retain our contact information in regard to use of the base
26  *    software.
27  * Permission to distribute the released version of the source code along
28  * with corresponding source modifications in the form of a patch file is
29  * granted with same provisions 2 through 4 for binary distributions.
30  *
31  * This software is provided "as is" without express or implied warranty
32  * to the extent permitted by applicable law.
33 ]*/
34
35
36 /*
37  * Some Unix like functions that gnuplot uses.
38  * Original sources from the blars lib.
39  */
40
41 #include <stdio.h>
42 #include <modes.h>
43 #include <direct.h>
44 #include <sgstat.h>
45
46 #ifdef PIPES
47
48 /* Original version by Robert A. Larson */
49 /* Adapted by M.N. Schipper */
50
51 #include <string.h>
52 #include <module.h>
53
54 extern char *_environ;
55 extern int os9fork();
56 extern mh_com *modlink();
57 extern mh_com *modloadp();
58
59 static int proc[_NFILE];
60 static mh_com *loadmods[_NFILE];
61
62 FILE *
63 popen(char *command, char *mode)
64 {
65     int temp, fd;
66     FILE *pipe;
67     char *argv[4];
68     char *cp;
69     mh_com *mod;
70     int linked = 0;
71
72     if(mode[1]!='\0' || (*mode!='r' && *mode!='w'))
73         return (FILE *)NULL;
74     fd = (*mode=='r');
75     if((temp = dup(fd)) <= 0)
76         return (FILE *)NULL;
77     if((pipe = fopen("/pipe", "r+")) == NULL) {
78         close(temp);
79         return (FILE *)NULL;
80     }
81     close(fd);
82     dup(fileno(pipe));
83
84     if (strrchr (command, '/') == NULL)
85         mod = modlink (command, 0);
86     else
87         mod = (mh_com *) -1;
88     if (mod == (mh_com *) -1)
89         loadmods[fileno(pipe)] = mod = modloadp (command, 0, NULL);
90     else {
91         linked = 1;
92         loadmods[fileno(pipe)] = (mh_com *) -1;
93     }
94
95     argv[0] = "shell";
96     if (mod != (mh_com *) -1) {
97         argv[1] = "ex";
98         argv[2] = command;
99         argv[3] = (char *)NULL;
100     } else {
101         argv[1] = command;
102         argv[2] = (char *)NULL;
103     }
104     if((proc[fileno(pipe)] = os9exec(os9fork, argv[0], argv, _environ, 0, 0))
105        < 0) {
106         fclose(pipe);
107         pipe = NULL;
108     }
109     close(fd);
110     dup(temp);
111     close(temp);
112     if (linked && mod != (mh_com *) -1)
113         munlink (mod);
114     return pipe;
115 }
116
117 int
118 pclose(FILE *pipe)
119 {
120     int p, stat, w;
121
122     if((p = proc[fileno(pipe)]) <= 0)
123         return -1;
124     proc[fileno(pipe)] = 0;
125     fflush(pipe);
126     if (loadmods[fileno(pipe)] != (mh_com *) -1)
127         munlink (loadmods[fileno(pipe)]);
128     fclose(pipe);
129     while((w=wait(&stat)) != -1 && w!=p)
130         ;                       /* do nothing */
131
132     return w==-1 ? -1 : stat;
133 }
134
135 #endif  /* PIPES */
136
137
138 int
139 isatty(int f)
140 {
141     struct sgbuf sgbuf;
142
143     if(_gs_opt(f, &sgbuf) < 0) return -1;
144     return sgbuf.sg_class == 0;
145 }
146
147
148 char *
149 getwd(char *p)
150 {
151     char *cp;
152     struct dirent *dp;
153     int l, olddot = 0, i, d, dot, dotdot;
154     struct dirent db[8];
155     char buf[1024];
156
157     cp = &buf[1024-1];
158     *cp = '\0';
159     for(;;) {
160         if((d = open(".", S_IREAD | S_IFDIR)) < 0) {
161             if(*cp) chdir(cp+1);
162             return NULL;
163         }
164         if((i = read(d, (char *)db, sizeof(db))) == 0) {
165             if(*cp) chdir(cp+1);
166             close(d);
167             return NULL;
168         }
169         dotdot = db[0].dir_addr;
170         dot = db[1].dir_addr;
171         if(olddot) {
172             i -= 2 * sizeof(struct dirent);
173             dp = &db[2];
174             for(;;) {
175                 if(i <= 0) {
176                     if((i = read(d, (char *) db, sizeof(db))) == 0) {
177                         if(*cp)
178                             chdir(cp+1);
179                         close(d);
180                         return NULL;
181                     }
182                     dp = &db[0];
183                 }
184                 if(olddot == dp->dir_addr) {
185                     l = strlen(dp->dir_name);
186                     /* last character has parity bit set... */
187                     *--cp = dp->dir_name[--l] & 0x7f;
188                     while(l)
189                         *--cp = dp->dir_name[--l];
190                     *--cp = '/';
191                     break;
192                 }
193                 i -= sizeof(struct dirent);
194                 dp++;
195             }
196         }
197         if(dot==dotdot) {
198             if(*cp) chdir(cp+1);
199             *p = '/';
200             if(_gs_devn(d, p+1) < 0) {
201                 close(d);
202                 return NULL;
203             }
204             close(d);
205             strcat(p, cp);
206             return p;
207         }
208         close(d);
209         if(chdir("..") != 0) {
210             if(*cp) chdir(cp+1);
211             return NULL;
212         }
213         olddot = dot;
214     }
215 }