UbixOS  2.0
vfs_calls.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <ubixos/sched.h>
30 #include <sys/thread.h>
31 #include <sys/sysproto_posix.h>
32 #include <sys/descrip.h>
33 #include <sys/video.h>
34 #include <sys/pipe.h>
35 #include <sys/errno.h>
36 #include <string.h>
37 #include <ufs/ufs.h>
38 
39 int sys_open(struct thread *td, struct sys_open_args *args) {
40  kprintf("sys_open?");
41  return (kern_openat(td, AT_FDCWD, args->path, args->flags, args->mode));
42 
43 }
44 
45 int sys_openat(struct thread *td, struct sys_openat_args *args) {
46 
47  int error = 0x0;
48  int fd = 0x0;
49  struct file *nfp = 0x0;
50 
51  error = falloc(td, &nfp, &fd);
52 
53  if (error)
54  return (error);
55 
56  if ((args->flag & O_WRONLY) == O_WRONLY)
57  nfp->fd = fopen(args->path, "w");
58  else if ((args->flag & O_RDWR) == O_RDWR)
59  nfp->fd = fopen(args->path, "a");
60  else
61  nfp->fd = fopen(args->path, "r");
62 
63  if (nfp->fd == 0x0) {
64  if (fdestroy(td, nfp, fd) != 0x0)
65  kprintf("[%s:%i] fdestroy() failed.", __FILE__, __LINE__);
66 
67  td->td_retval[0] = -1;
68  error = -1;
69  /*
70 
71  kprintf("[sOA: 0x%X:%s:%s:]", args->flag, args->mode, args->path, td->td_retval[0]);
72 
73  if ((args->flag & O_RDONLY) == O_RDONLY)
74  kprintf("O_RDONLY");
75 
76  if ((args->flag & O_WRONLY) == O_WRONLY)
77  kprintf("O_WRONLY");
78 
79  if ((args->flag & O_RDWR) == O_RDWR)
80  kprintf("O_RDWR");
81 
82  if ((args->flag & O_ACCMODE) == O_ACCMODE)
83  kprintf("O_ACCMODE");
84  */
85 
86  }
87  else {
88  td->td_retval[0] = fd;
89  }
90 
91  return (error);
92 }
93 
94 int sys_close(struct thread *td, struct sys_close_args *args) {
95  struct file *fd = 0x0;
96  struct pipeInfo *pFD = 0x0;
97 
98  getfd(td, &fd, args->fd);
99 
100  //kprintf("[sC:%i:0x%X:0x%X]", args->fd, fd, fd->fd);
101 
102 #ifdef DEBUG_VFS_CALLS
103  kprintf("[sC::0x%X:0x%X]", args->fd, fd, fd->fd);
104 #endif
105 
106  if (fd == 0x0) {
107  kprintf("COULDN'T FIND FD: ", args->fd);
108  td->td_retval[0] = -1;
109  }
110  else {
111  switch (fd->fd_type) {
112  case 3:
113  pFD = fd->data;
114  if (args->fd == pFD->rFD) {
115  if (pFD->rfdCNT < 2)
116  if (fdestroy(td, fd, args->fd) != 0x0)
117  kprintf("[%s:%i] fdestroy() failed.", __FILE__, __LINE__);
118  pFD->rfdCNT--;
119  }
120 
121  if (args->fd == pFD->wFD) {
122  if (pFD->wfdCNT < 2)
123  if (fdestroy(td, fd, args->fd) != 0x0)
124  kprintf("[%s:%i] fdestroy() failed.", __FILE__, __LINE__);
125  pFD->wfdCNT--;
126  }
127 
128  break;
129  default:
130  if (args->fd < 3)
131  td->td_retval[0] = 0;
132  else {
133  if (!fclose(fd->fd))
134  td->td_retval[0] = -1;
135 
136  //kprintf("DESTROY: %i!", args->fd);
137  if (fdestroy(td, fd, args->fd) != 0x0)
138  kprintf("[%s:%i] fdestroy(0x%X, 0x%X) failed\n", __FILE__, __LINE__, fd, td->o_files[args->fd]);
139 
140  td->td_retval[0] = 0;
141 
142  }
143  }
144  }
145  return (0);
146 }
147 
148 int sys_read(struct thread *td, struct sys_read_args *args) {
149  int x = 0;
150  char c = 0x0;
151  char bf[2];
152  volatile char *buf = args->buf;
153 
154  struct file *fd = 0x0;
155 
156  struct pipeInfo *pFD = 0x0;
157  struct pipeInfo *rpFD = 0x0;
158 
159  size_t nbytes;
160 
161  int rpCNT = 0;
162 
163  getfd(td, &fd, args->fd);
164 
165  if (args->fd > 3) {
166  switch (fd->fd_type) {
167  case 3: /* XXX - Pipe2 Handling */
168  pFD = fd->data;
169  while (pFD->bCNT == 0 && rpCNT < 100) {
170  sched_yield();
171  rpCNT++;
172  }
173 
174  if (rpCNT >= 100 && pFD->bCNT == 0) {
175  td->td_retval[0] = 0;
176  }
177  else {
178  nbytes = (args->nbyte - (pFD->headPB->nbytes - pFD->headPB->offset) <= 0) ? args->nbyte : (pFD->headPB->nbytes - pFD->headPB->offset);
179  //kprintf("[unb: , nbs: %i, bf: 0x%X]", args->nbyte, nbytes, fd->fd->buffer);
180  //kprintf("PR: []", nbytes);
181  memcpy(args->buf, pFD->headPB->buffer + pFD->headPB->offset, nbytes);
182  pFD->headPB->offset += nbytes;
183 
184  if (pFD->headPB->offset >= pFD->headPB->nbytes) {
185  rpFD = pFD->headPB;
186  pFD->headPB = pFD->headPB->next;
187  kfree(rpFD);
188  pFD->bCNT--;
189  }
190 
191  td->td_retval[0] = nbytes;
192  }
193  break;
194  default:
195  //kprintf("[r:0x%X::%i:%s]",fd->fd, args->fd, fd->fd_type, fd->fd->fileName);
196  //kprintf("[%s:%i]", __FILE__, __LINE__);
197  td->td_retval[0] = fread(args->buf, args->nbyte, 1, fd->fd);
198  }
199  }
200  else {
201  bf[1] = '\0';
202  if (_current->term == tty_foreground)
203  c = getchar();
204 
205  for (x = 0; x < args->nbyte && c != '\n';) {
206  if (_current->term == tty_foreground) {
207 
208  if (c != 0x0) {
209  buf[x++] = c;
210  bf[0] = c;
211  kprintf(bf);
212  }
213 
214  if (c == '\n') {
215  buf[x++] = c;
216  break;
217  }
218 
219  sched_yield();
220  c = getchar();
221  }
222  else {
223  sched_yield();
224  }
225  }
226  if (c == '\n')
227  buf[x++] = '\n';
228 
229  bf[0] = '\n';
230  kprintf(bf);
231 
232  td->td_retval[0] = x;
233  }
234  return (0);
235 }
236 
237 int sys_pread(struct thread *td, struct sys_pread_args *args) {
238  int offset = 0;
239  int x = 0;
240  char c = 0x0;
241  char bf[2];
242  volatile char *buf = args->buf;
243 
244  struct file *fd = 0x0;
245 
246  getfd(td, &fd, args->fd);
247 
248  if (args->fd > 3) {
249  offset = fd->fd->offset;
250  fd->fd->offset = args->offset;
251  td->td_retval[0] = fread(args->buf, args->nbyte, 1, fd->fd);
252  fd->fd->offset = offset;
253  }
254  else {
255  bf[1] = '\0';
256  if (_current->term == tty_foreground)
257  c = getchar();
258 
259  for (x = 0; x < args->nbyte && c != '\n';) {
260  if (_current->term == tty_foreground) {
261 
262  if (c != 0x0) {
263  buf[x++] = c;
264  bf[0] = c;
265  kprintf(bf);
266  }
267 
268  if (c == '\n') {
269  buf[x++] = c;
270  break;
271  }
272 
273  sched_yield();
274  c = getchar();
275  }
276  else {
277  sched_yield();
278  }
279  }
280  if (c == '\n')
281  buf[x++] = '\n';
282 
283  bf[0] = '\n';
284  kprintf(bf);
285 
286  td->td_retval[0] = x;
287  }
288  return (0);
289 }
290 
291 int sys_write(struct thread *td, struct sys_write_args *uap) {
292  char *buffer = 0x0;
293  struct file *fd = 0x0;
294 
295  struct pipeInfo *pFD = 0x0;
296  struct pipeBuf *pBuf = 0x0;
297 
298  size_t nbytes;
299 
300  if (uap->fd == 2) {
301  buffer = kmalloc(1024);
302  memcpy(buffer, uap->buf, uap->nbyte);
303  printColor += 1;
304  kprintf(buffer);
306  kfree(buffer);
307  td->td_retval[0] = uap->nbyte;
308  }
309  else if (uap->fd == 1 && ((struct file*) td->o_files[1])->fd == 0x0) {
310  buffer = kmalloc(1024);
311  memcpy(buffer, uap->buf, uap->nbyte);
312  kprintf(buffer);
313  kfree(buffer);
314  td->td_retval[0] = uap->nbyte;
315  }
316  else {
317  getfd(td, &fd, uap->fd);
318 
319  //kprintf("[fd: %i:0x%X, fd_type: %i]", uap->fd, fd, fd->fd_type);
320 
321  switch (fd->fd_type) {
322  case 3: /* XXX - Temp Pipe Stuff */
323 
324  pFD = fd->data;
325  pBuf = (struct pipeBuf*) kmalloc(sizeof(struct pipeBuf));
326  pBuf->buffer = kmalloc(uap->nbyte);
327 
328  memcpy(pBuf->buffer, uap->buf, uap->nbyte);
329 
330  pBuf->nbytes = uap->nbyte;
331 
332  if (pFD->tailPB)
333  pFD->tailPB->next = pBuf;
334 
335  pFD->tailPB = pBuf;
336 
337  if (!pFD->headPB)
338  pFD->headPB = pBuf;
339 
340  pFD->bCNT++;
341 
342  td->td_retval[0] = nbytes;
343 
344  break;
345  default:
346  if (fd->fd) {
347  kprintf("[0x%X]", fd->fd->res);
348  td->td_retval[0] = fwrite(uap->buf, uap->nbyte, 1, fd->fd);
349  }
350  else {
351  kprintf("[%i]", uap->nbyte);
352  buffer = kmalloc(uap->nbyte);
353  memcpy(buffer, uap->buf, uap->nbyte);
354  kprintf("(%i) %s", uap->fd, uap->buf);
355  kfree(buffer);
356  td->td_retval[0] = uap->nbyte;
357  }
358  }
359 
360  }
361  return (0x0);
362 }
363 
364 int sys_access(struct thread *td, struct sys_access_args *args) {
365  /* XXX - This is a temporary as it always returns true */
366 
367  td->td_retval[0] = 0;
368  return (0);
369 }
370 
371 int sys_getdirentries(struct thread *td, struct sys_getdirentries_args *args) {
372 
373  struct file *fd = 0x0;
374 
375  getfd(td, &fd, args->fd);
376 
377  char buf[DEV_BSIZE];
378  struct dirent *d;
379  char *s;
380  ssize_t n;
381 
382  td->td_retval[0] = fread(args->buf, args->count, 1, fd->fd);
383 
384  return (0);
385 }
386 
387 int sys_readlink(struct thread *thr, struct sys_readlink_args *args) {
388  /* XXX - Need to implement readlink */
389 
390  kprintf("RL: %s:\n", args->path, args->count);
391 
392  //Return Error
393  thr->td_retval[0] = 2;
394  return (-1);
395 }
396 
397 int kern_openat(struct thread *thr, int afd, char *path, int flags, int mode) {
398  int error = 0x0;
399  int fd = 0x0;
400  struct file *nfp = 0x0;
401 
402  /*
403  * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags
404  * may be specified.
405  */
406  if (flags & O_EXEC) {
407  if (flags & O_ACCMODE)
408  return (EINVAL);
409  }
410  else if ((flags & O_ACCMODE) == O_ACCMODE) {
411  return (EINVAL);
412  }
413  else {
414  flags = FFLAGS(flags);
415  }
416 
417  error = falloc(thr, &nfp, &fd);
418 
419  if (error) {
420  thr->td_retval[0] = -1;
421  return (error);
422  }
423 
424  if (flags | O_CREAT)
425  kprintf("O_CREAT\n");
426 
427  nfp->f_flag = flags & FMASK;
428 
429  nfp->fd = fopen(path, "rwb");
430 
431  if (nfp->fd == 0x0) {
432  if (fdestroy(thr, nfp, fd) != 0x0)
433  kprintf("[%s:%i] fdestroy() failed.", __FILE__, __LINE__);
434 
435  thr->td_retval[0] = -1;
436 
437  error = -1;
438  }
439  else {
440  thr->td_retval[0] = fd;
441  }
442 
443  //kprintf("sO: 0x%X:%s:", args->mode, args->path, td->td_retval[0]);
444 
445  return (error);
446 
447 }
448 
449 int sys_unlink(struct thread *td, struct sys_unlink_args *uap) {
450  int error = 0x0;
451  td->td_retval[0] = fl_remove(uap->path);
452  if (td->td_retval[0] != 0x0)
453  kprintf("[%s:%i]Path: %s", __FILE__, __LINE__, uap->path);
454  return (error);
455 }
sys_getdirentries
int sys_getdirentries(struct thread *td, struct sys_getdirentries_args *args)
Definition: vfs_calls.c:371
sys_write_args::buf
const void * buf
Definition: sysproto_posix.h:80
sys_pread_args::fd
int fd
Definition: sysproto_posix.h:730
FMASK
#define FMASK
Definition: fcntl.h:93
sys_pread_args::offset
off_t offset
Definition: sysproto_posix.h:739
sys_open_args::mode
int mode
Definition: sysproto_posix.h:98
buffer
char * buffer
Definition: shell.c:47
sys_pread_args::nbyte
size_t nbyte
Definition: sysproto_posix.h:736
O_EXEC
#define O_EXEC
Definition: fcntl.h:78
defaultColor
#define defaultColor
Definition: video.h:34
sys_openat
int sys_openat(struct thread *td, struct sys_openat_args *args)
Definition: vfs_calls.c:45
fopen
fileDescriptor_t * fopen(const char *file, const char *flags)
Definition: file.c:395
fileDescriptor::res
void * res
Definition: file.h:82
thread::o_files
void * o_files[512]
Definition: thread.h:42
pipeBuf::next
struct pipeBuf * next
Definition: pipe.h:38
file::data
void * data
Definition: descrip.h:74
string.h
fl_remove
int fl_remove(const char *filename)
Definition: fat_filelib.c:1314
fileDescriptor::offset
off_t offset
Definition: file.h:69
file::f_flag
uint32_t f_flag
Definition: descrip.h:68
video.h
sysproto_posix.h
fread
size_t fread(void *ptr, size_t size, size_t nmemb, fileDescriptor_t *fd)
Definition: file.c:297
file
Definition: descrip.h:67
kfree
void kfree(void *baseAddr)
Definition: kmalloc.c:342
printColor
int printColor
Definition: video.c:35
thread
Definition: thread.h:40
sys_open_args::flags
int flags
Definition: sysproto_posix.h:94
sys_close_args::fd
int fd
Definition: sysproto_posix.h:104
fwrite
size_t fwrite(void *ptr, int size, int nmemb, fileDescriptor_t *fd)
Definition: file.c:317
fdestroy
int fdestroy(struct thread *td, struct file *fp, int fd)
This destroys a thread local file descriptor.
Definition: descrip.c:147
sys_open_args
Definition: sysproto_posix.h:88
sys_getdirentries_args::count
u_int count
Definition: sysproto_posix.h:634
pipeInfo::rfdCNT
int rfdCNT
Definition: pipe.h:47
O_ACCMODE
#define O_ACCMODE
Definition: fcntl.h:64
sched.h
falloc
int falloc(struct thread *, struct file **, int *)
Definition: descrip.c:97
sys_getdirentries_args::fd
int fd
Definition: sysproto_posix.h:628
file::fd_type
int fd_type
Definition: descrip.h:72
sys_open
int sys_open(struct thread *td, struct sys_open_args *args)
Definition: vfs_calls.c:39
sys_getdirentries_args
Definition: sysproto_posix.h:626
O_RDWR
#define O_RDWR
Definition: fcntl.h:63
memcpy
void * memcpy(const void *dst, const void *src, size_t length)
sys_unlink
int sys_unlink(struct thread *td, struct sys_unlink_args *uap)
Definition: vfs_calls.c:449
sys_pread_args
Definition: sysproto_posix.h:728
pipeInfo::bCNT
int bCNT
Definition: pipe.h:50
pipe.h
errno.h
pipeInfo::rFD
int rFD
Definition: pipe.h:46
file::fd
fileDescriptor_t * fd
Definition: descrip.h:71
AT_FDCWD
#define AT_FDCWD
Definition: fcntl.h:32
thread::td_retval
int td_retval[2]
Definition: thread.h:41
sys_write
int sys_write(struct thread *td, struct sys_write_args *uap)
Definition: vfs_calls.c:291
fclose
int fclose(fileDescriptor_t *fd)
Definition: file.c:533
pipeBuf::nbytes
size_t nbytes
Definition: pipe.h:40
dirent
Definition: ufs.h:92
sys_read_args
Definition: sysproto_posix.h:62
taskStruct::term
tty_term * term
Definition: sched.h:77
buf
Definition: buf.h:35
sys_readlink
int sys_readlink(struct thread *thr, struct sys_readlink_args *args)
Definition: vfs_calls.c:387
pipeBuf::buffer
char * buffer
Definition: pipe.h:39
getfd
int getfd(struct thread *td, struct file **fp, int fd)
get pointer to file fd in specified thread
Definition: descrip.c:213
pipeInfo::wFD
int wFD
Definition: pipe.h:48
sys_openat_args::flag
int flag
Definition: sysproto_posix.h:507
sys_write_args
Definition: sysproto_posix.h:74
pipeInfo::tailPB
struct pipeBuf * tailPB
Definition: pipe.h:52
sys_read_args::fd
int fd
Definition: sysproto_posix.h:64
sys_write_args::fd
int fd
Definition: sysproto_posix.h:76
sys_read_args::buf
const void * buf
Definition: sysproto_posix.h:67
O_WRONLY
#define O_WRONLY
Definition: fcntl.h:62
sys_pread_args::buf
void * buf
Definition: sysproto_posix.h:733
sys_read
int sys_read(struct thread *td, struct sys_read_args *args)
Definition: vfs_calls.c:148
_current
kTask_t * _current
Definition: sched.c:50
pipeBuf::offset
off_t offset
Definition: pipe.h:41
sys_write_args::nbyte
size_t nbyte
Definition: sysproto_posix.h:84
sys_openat_args::path
char * path
Definition: sysproto_posix.h:504
ufs.h
sys_access
int sys_access(struct thread *td, struct sys_access_args *args)
Definition: vfs_calls.c:364
tty_foreground
tty_term * tty_foreground
Definition: tty.c:38
kmalloc
void * kmalloc(uInt32 len)
Definition: kmalloc.c:241
descrip.h
sys_openat_args
Definition: sysproto_posix.h:499
pipeBuf
Definition: pipe.h:37
kern_openat
int kern_openat(struct thread *thr, int afd, char *path, int flags, int mode)
Definition: vfs_calls.c:397
sys_getdirentries_args::buf
char * buf
Definition: sysproto_posix.h:631
O_CREAT
#define O_CREAT
Definition: fcntl.h:57
pipeInfo::headPB
struct pipeBuf * headPB
Definition: pipe.h:51
sys_open_args::path
char * path
Definition: sysproto_posix.h:90
pipeInfo
Definition: pipe.h:45
sys_access_args
Definition: sysproto_posix.h:587
ssize_t
__ssize_t ssize_t
Definition: types.h:117
sys_pread
int sys_pread(struct thread *td, struct sys_pread_args *args)
Definition: vfs_calls.c:237
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
getchar
int getchar()
Definition: atkbd.c:343
FFLAGS
#define FFLAGS(oflags)
Definition: fcntl.h:88
thread.h
DEV_BSIZE
#define DEV_BSIZE
Definition: gpt.h:42
sys_close
int sys_close(struct thread *td, struct sys_close_args *args)
Definition: vfs_calls.c:94
EINVAL
#define EINVAL
Definition: errno.h:55
sys_close_args
Definition: sysproto_posix.h:102
sys_read_args::nbyte
size_t nbyte
Definition: sysproto_posix.h:70
sched_yield
void sched_yield()
Definition: sched.c:244
pipeInfo::wfdCNT
int wfdCNT
Definition: pipe.h:49