dca29630e7e2f5b5e7a60175e681cd77df76e6df
[tpg/acess2.git] / Usermode / Libraries / libposix.so_src / unistd.c
1 /*
2  * Acess2 POSIX Emulation Layer
3  * - By John Hodge
4  * 
5  * unistd.c
6  * - POSIX->Acess VFS call translation
7  */
8 #include <unistd.h>
9 #include <acess/sys.h>
10 #include <stdarg.h>
11 #include <sys/select.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <acess/devices/pty.h>
15 #include <errno.h>
16
17 // === CODE ===
18 int unlink(const char *pathname)
19 {
20         return _SysUnlink(pathname);
21 }
22
23 int open(const char *path, int openmode, ...)
24 {
25         mode_t  create_mode = 0;
26         int openflags = 0;
27         
28         switch( openmode & O_RDWR )
29         {
30         case 0: // Special
31                 break;
32         case O_RDONLY:  openflags |= OPENFLAG_READ;     break;
33         case O_WRONLY:  openflags |= OPENFLAG_WRITE;    break;
34         case O_RDWR:    openflags |= OPENFLAG_READ|OPENFLAG_WRITE;      break;
35         }
36         
37         if( openmode & O_CREAT ) {
38                 openflags |= OPENFLAG_CREATE;
39                 va_list args;
40                 va_start(args, openmode);
41                 create_mode = va_arg(args, mode_t);
42                 va_end(args);
43         }
44         
45         if( openmode & O_NONBLOCK )
46                 openflags |= OPENFLAG_NONBLOCK;
47         
48         int ret = _SysOpen(path, openflags, create_mode);
49         _SysDebug("open('%s', 0%o, 0%o) = %i", path, openmode, create_mode, ret);
50         return ret;
51 }
52
53 int access(const char *path, int openmode)
54 {
55         errno = EINVAL;
56         return -1;
57 }
58
59 int creat(const char *path, mode_t mode)
60 {
61         // TODO: Make native call to do this cheaper
62         int fd = _SysOpen(path, OPENFLAG_CREATE, mode);
63         if( fd == -1 )  return -1;
64         _SysClose(fd);
65         return 0;
66 }
67
68 int close(int fd)
69 {
70         _SysClose(fd);
71         return 0;
72 }
73
74 ssize_t write(int fd, const void *buf, size_t count)
75 {
76         return _SysWrite(fd, buf, count);
77 }
78
79 ssize_t read(int fd, void *buf, size_t count)
80 {
81         return _SysRead(fd, buf, count);
82 }
83
84 int seek(int fd, int whence, off_t dest)
85 {
86         return _SysSeek(fd, whence, dest);
87 }
88
89 off_t lseek(int fd, off_t offset, int whence)
90 {
91         return _SysSeek(fd, whence, offset);
92 }
93
94 off_t tell(int fd)
95 {
96         return _SysTell(fd);
97 }
98
99 int fork(void)
100 {
101         return _SysClone(CLONE_VM, 0);
102 }
103
104 int execv(const char *b, char *v[])
105 {
106         return _SysExecVE(b, v, NULL);
107 }
108
109 int dup(int oldfd)
110 {
111         _SysDebug("libposix: dup() does not share offsets/flags");
112         // NOTE: Acess's CopyFD doesn't cause offset sharing
113         int ret = _SysCopyFD(oldfd, -1);
114         _SysDebug("dup(%i) = %i", oldfd, ret);
115         return ret;
116 }
117
118 int dup2(int oldfd, int newfd)
119 {
120         _SysDebug("libposix: dup2() does not share offsets/flags");
121         // NOTE: Acess's CopyFD doesn't cause offset sharing
122         _SysDebug("dup2(%i,%i)", oldfd, newfd);
123         return _SysCopyFD(oldfd, newfd);
124 }
125
126 int chown(const char *path, uid_t owner, gid_t group)
127 {
128         _SysDebug("TODO: chown(%s, %i, %i)", path, owner, group);
129         errno = ENOTIMPL;
130         return -1;
131 }
132 int chmod(const char *path, mode_t mode)
133 {
134         _SysDebug("TODO: chmod(%s, 0%o)", path, mode);
135         errno = ENOTIMPL;
136         return -1;
137 }
138
139 /*
140  * Set session ID to PID
141  */
142 pid_t setsid(void)
143 {
144         // TODO: actual syscall for this
145         return _SysGetPID();
146 }
147
148 pid_t getpid(void)
149 {
150         return _SysGetPID();
151 }
152
153 uid_t getuid(void)
154 {
155         return _SysGetUID();
156 }
157 gid_t getgid(void)
158 {
159         return _SysGetGID();
160 }
161
162 uid_t geteuid(void)
163 {
164         // TODO: Impliment EUIDs in-kernel?
165         return _SysGetUID();
166 }
167
168 int seteuid(uid_t euid)
169 {
170         _SysDebug("TODO: %s", __func__);
171         return 0;
172 }
173 int setegid(gid_t egid)
174 {
175         _SysDebug("TODO: %s", __func__);
176         return 0;
177 }
178
179 unsigned int sleep(unsigned int seconds)
180 {
181         int64_t start = _SysTimestamp();
182         _SysTimedSleep( seconds*1000 );
183         return (_SysTimestamp() - start) / 1000;
184 }
185
186 int usleep(useconds_t usec)
187 {
188         _SysTimedSleep( (usec+999)/1000 );
189         return 0;
190 }
191
192 unsigned int alarm(unsigned int seconds)
193 {
194         static int64_t  alarm_time;
195         if( seconds > 0 )
196         {
197                 alarm_time = _SysTimestamp() + seconds * 1000;
198                 // TODO: Schedule SIGALRM
199         }
200         return (alarm_time - _SysTimestamp()) / 1000;
201 }
202
203 int kill(pid_t pid, int signal)
204 {
205         // TODO: Need special handling?
206         return _SysKill(pid, signal);
207 }
208
209 int select(int nfd, fd_set *rfd, fd_set *wfd, fd_set *efd, struct timeval *timeout)
210 {
211         int64_t ltimeout = 0, *ltimeoutp = NULL;
212         if( timeout )
213         {
214                 ltimeout = timeout->tv_sec*1000 + timeout->tv_usec / 1000;
215                 ltimeoutp = &ltimeout;
216         }
217         _SysDebug("select(%i,{0x%x},{0x%x},{0x%x},%lli)",
218                 nfd, (rfd?rfd->flags[0]:0), (wfd?wfd->flags[0]:0), (efd?efd->flags[0]:0),
219                 (ltimeoutp ? *ltimeoutp : -1)
220                 );
221         return _SysSelect(nfd, rfd, wfd, efd, ltimeoutp, 0);
222 }
223
224 int pipe(int pipefd[2])
225 {
226         pipefd[0] = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE);
227         pipefd[1] = _SysCopyFD(pipefd[0], -1);
228         _SysFDFlags(pipefd[1], OPENFLAG_READ|OPENFLAG_WRITE, OPENFLAG_WRITE);
229         _SysDebug("pipe({%i,%i})", pipefd[0], pipefd[1]);
230         return 0;
231 }
232
233 int chdir(const char *dir)
234 {
235         return _SysChdir(dir);
236 }
237
238 int rmdir(const char *pathname)
239 {
240 //      return _SysUnlink(pathname);
241         _SysDebug("TODO: POSIX rmdir('%s')", pathname);
242         errno = ENOTIMPL;
243         return -1;
244 }
245
246 int mkdir(const char *pathname, mode_t mode)
247 {
248         _SysDebug("TODO: POSIX mkdir('%s', 0%o)", pathname, mode);
249         _SysMkDir(pathname);
250         return 0;
251 }
252
253 char *getpass(const char *prompt)
254 {
255         static char passbuf[PASS_MAX+1];
256         struct ptymode  oldmode, mode;
257         _SysIOCtl(STDIN_FILENO, PTY_IOCTL_GETMODE, &oldmode);
258         mode.InputMode = PTYIMODE_CANON;
259         mode.OutputMode = 0;
260         _SysIOCtl(STDIN_FILENO, PTY_IOCTL_SETMODE, &mode);
261         fprintf(stderr, "%s", prompt);
262         fflush(stdin);  // clear stdin buffer
263         fgets(passbuf, PASS_MAX+1, stdin);
264         fprintf(stderr, "\n");
265         for( int i = strlen(passbuf); i > 0 && (passbuf[i-1] == '\r' || passbuf[i-1] == '\n'); i -- )
266                 passbuf[i-1] = 0;
267
268         _SysIOCtl(STDIN_FILENO, PTY_IOCTL_SETMODE, &oldmode);
269
270         return passbuf;
271 }
272
273 char *ttyname(int fd)
274 {
275         static char ttyname_buf[32];
276         errno = ttyname_r(fd, ttyname_buf, sizeof(ttyname_buf));
277         if(errno)       return NULL;
278         
279         return ttyname_buf;
280 }
281 int ttyname_r(int fd, char *buf, size_t buflen)
282 {
283          int    type = _SysIOCtl(fd, DRV_IOCTL_TYPE, NULL);
284         if( type == -1 )
285                 return errno;
286         if( type != DRV_TYPE_TERMINAL )
287                 return ENOTTY;
288
289         _SysIOCtl(fd, PTY_IOCTL_GETID, NULL);   
290
291         _SysDebug("TODO: ttyname_r");
292
293         return ENOTIMPL;
294 }
295
296 int isatty(int fd)
297 {
298         if( fd < 0 ) {
299                 errno = EBADF;
300                 return 0;
301         }
302         
303          int    type = _SysIOCtl(fd, DRV_IOCTL_TYPE, NULL);
304         if( type == -1 )
305                 return 0;
306         if( type != DRV_TYPE_TERMINAL ) {
307                 errno = ENOTTY;
308                 // NOTE: Pre POSIX 2001, EINVAL was returned
309                 return 0;
310         }
311         return 1;
312 }

UCC git Repository :: git.ucc.asn.au