9 typedef struct Fdtab Fdtab
;
43 trace("putfile(): closing %p %s", file
, file
->path
);
44 if(devtab
[file
->dev
]->close
)
45 devtab
[file
->dev
]->close(file
);
47 while(d
= file
->rdaux
){
48 file
->rdaux
= d
->next
;
59 tab
= kmallocz(sizeof(*tab
), 1);
72 /* assumes tab->lock aquired */
78 if((tab
->nfd
% CHUNK
) == 0)
79 tab
->fd
= krealloc(tab
->fd
, sizeof(tab
->fd
[0]) * (tab
->nfd
+ CHUNK
));
80 memset(&tab
->fd
[tab
->nfd
], 0, sizeof(tab
->fd
[0]));
84 Ufile
*procfdgetfile(Uproc
*proc
, int fd
)
90 if(tab
= proc
->fdtab
){
92 if(fd
>= 0 && fd
< tab
->nfd
)
93 file
= getfile(tab
->fd
[fd
].file
);
102 return procfdgetfile(current
, fd
);
106 newfd(Ufile
*file
, int flags
)
111 tab
= current
->fdtab
;
114 if((fd
>= 0) && (fd
< tab
->nfd
) && (tab
->fd
[fd
].file
== nil
))
116 for(fd
=0; fd
<tab
->nfd
; fd
++)
117 if(tab
->fd
[fd
].file
== nil
)
122 tab
->fd
[fd
].file
= file
;
123 tab
->fd
[fd
].flags
= flags
;
133 getfdtab(Fdtab
*tab
, int copy
)
144 new->lastfd
= tab
->lastfd
;
146 new->fd
= kmallocz(sizeof(new->fd
[0]) * (((tab
->nfd
+CHUNK
-1)/CHUNK
)*CHUNK
), 1);
147 for(i
=0; i
<new->nfd
; i
++){
150 if((file
= tab
->fd
[i
].file
) == nil
)
153 new->fd
[i
].file
= file
;
154 new->fd
[i
].flags
= tab
->fd
[i
].flags
;
167 for(i
=0; i
<tab
->nfd
; i
++){
169 if((file
= tab
->fd
[i
].file
) == nil
)
171 tab
->fd
[i
].file
= nil
;
178 int sys_dup2(int old
, int new)
184 trace("sys_dup2(%d, %d)", old
, new);
186 tab
= current
->fdtab
;
188 if((file
= fdgetfile(old
)) == nil
)
191 return newfd(file
, 0);
195 while(new >= tab
->nfd
){
203 if(tab
->fd
[new].file
!= nil
)
204 putfile(tab
->fd
[new].file
);
205 tab
->fd
[new].file
= file
;
206 tab
->fd
[new].flags
&= ~FD_CLOEXEC
;
214 return sys_dup2(fd
, -1);
241 int sys_fcntl(int fd
, int cmd
, int arg
)
247 trace("sys_fcntl(%d, %lux, %lux)", fd
, (ulong
)cmd
, (ulong
)arg
);
249 tab
= current
->fdtab
;
252 if((file
= fdgetfile(fd
)) == nil
)
257 trace("sys_fcntl() cmd %lux not implemented", (ulong
)cmd
);
261 if(arg
< 0 || arg
>= MAXFD
)
264 for(ret
=arg
; ret
<tab
->nfd
; ret
++)
265 if(tab
->fd
[ret
].file
== nil
)
268 if((ret
= grow1(tab
)) < 0)
273 tab
->fd
[ret
].file
= file
;
274 tab
->fd
[ret
].flags
= tab
->fd
[fd
].flags
& ~FD_CLOEXEC
;
284 ret
= tab
->fd
[fd
].flags
& FD_CLOEXEC
;
286 tab
->fd
[fd
].flags
= (arg
& FD_CLOEXEC
);
296 trace("sys_fcntl() changing mode from %o to %o", file
->mode
, arg
);
302 ((struct linux_flock
*)arg
)->l_type
= F_UNLCK
;
309 ((struct linux_flock64
*)arg
)->l_type
= F_UNLCK
;
319 int sys_close(int fd
)
324 trace("sys_close(%d)", fd
);
326 tab
= current
->fdtab
;
328 if(fd
>= 0 && fd
< tab
->nfd
){
329 if(file
= tab
->fd
[fd
].file
){
330 tab
->fd
[fd
].file
= nil
;
342 int sys_ioctl(int fd
, int cmd
, void *arg
)
347 trace("sys_ioctl(%d, %lux, %p)", fd
, (ulong
)cmd
, arg
);
349 if((file
= fdgetfile(fd
)) == nil
)
352 if(devtab
[file
->dev
]->ioctl
)
353 ret
= devtab
[file
->dev
]->ioctl(file
, cmd
, arg
);
358 int preadfile(Ufile
*file
, void *buf
, int len
, vlong off
)
360 if(file
->mode
& O_NONBLOCK
){
361 if(devtab
[file
->dev
]->poll
!= nil
){
362 if((devtab
[file
->dev
]->poll(file
, nil
) & POLLIN
) == 0){
363 trace("readfile(): nonblocking read blocked");
369 if(devtab
[file
->dev
]->read
== nil
)
371 return devtab
[file
->dev
]->read(file
, buf
, len
, off
);
374 int readfile(Ufile
*file
, void *buf
, int len
)
378 if((err
= preadfile(file
, buf
, len
, file
->off
)) > 0)
383 int pwritefile(Ufile
*file
, void *buf
, int len
, vlong off
)
385 if(devtab
[file
->dev
]->write
== nil
)
387 if(file
->mode
& O_APPEND
){
388 if(devtab
[file
->dev
]->size
){
389 off
= devtab
[file
->dev
]->size(file
);
394 return devtab
[file
->dev
]->write(file
, buf
, len
, off
);
397 int writefile(Ufile
*file
, void *buf
, int len
)
402 if(devtab
[file
->dev
]->write
== nil
)
404 if(file
->mode
& O_APPEND
){
405 if(devtab
[file
->dev
]->size
){
406 end
= devtab
[file
->dev
]->size(file
);
414 if((err
= devtab
[file
->dev
]->write(file
, buf
, len
, file
->off
)) > 0)
419 int sys_read(int fd
, void *buf
, int len
)
424 trace("sys_read(%d, %p, %x)", fd
, buf
, len
);
425 if((file
= fdgetfile(fd
)) == nil
)
427 ret
= readfile(file
, buf
, len
);
432 int sys_write(int fd
, void *buf
, int len
)
437 trace("sys_write(%d, %p, %x)", fd
, buf
, len
);
438 if((file
= fdgetfile(fd
)) == nil
)
440 ret
= writefile(file
, buf
, len
);
446 int sys_pread64(int fd
, void *buf
, int len
, ulong off
)
451 trace("sys_pread(%d, %p, %x, %lux)", fd
, buf
, len
, off
);
452 if((file
= fdgetfile(fd
)) == nil
)
454 ret
= preadfile(file
, buf
, len
, off
);
459 int sys_pwrite64(int fd
, void *buf
, int len
, ulong off
)
464 trace("sys_pwrite(%d, %p, %x, %lux)", fd
, buf
, len
, off
);
465 if((file
= fdgetfile(fd
)) == nil
)
467 ret
= pwritefile(file
, buf
, len
, off
);
478 int sys_writev(int fd
, void *vec
, int n
)
480 struct linux_iovec
*v
= vec
;
484 trace("sys_writev(%d, %p, %d)", fd
, vec
, n
);
486 if((file
= fdgetfile(fd
)) == nil
)
490 w
= writefile(file
, v
[i
].base
, v
[i
].len
);
505 int sys_readv(int fd
, void *vec
, int n
)
507 struct linux_iovec
*v
= vec
;
511 trace("sys_readv(%d, %p, %d)", fd
, vec
, n
);
513 if((file
= fdgetfile(fd
)) == nil
)
517 r
= readfile(file
, v
[i
].base
, v
[i
].len
);
532 int seekfile(Ufile
*file
, vlong off
, int whence
)
536 if(devtab
[file
->dev
]->size
== nil
)
547 end
= devtab
[file
->dev
]->size(file
);
550 file
->off
= end
+ off
;
557 ulong
sys_lseek(int fd
, ulong off
, int whence
)
562 trace("sys_lseek(%d, %lux, %d)", fd
, off
, whence
);
564 if((file
= fdgetfile(fd
)) == nil
)
565 return (ulong
)-EBADF
;
566 ret
= seekfile(file
, off
, whence
);
574 int sys_llseek(int fd
, ulong hioff
, ulong looff
, vlong
*res
, int whence
)
579 trace("sys_llseek(%d, %lux, %lux, %p, %d)", fd
, hioff
, looff
, res
, whence
);
581 if((file
= fdgetfile(fd
)) == nil
)
583 ret
= seekfile(file
, ((vlong
)hioff
<<32) | ((vlong
)looff
), whence
);
584 if((ret
== 0) && res
)
591 int sys_umask(int umask
)
595 trace("sys_umask(%#o)", umask
);
597 old
= current
->umask
;
598 current
->umask
= (umask
& 0777);
608 trace("chdirfile(%s)", f
->path
);
613 if(devtab
[f
->dev
]->fstat
== nil
)
615 if((err
= devtab
[f
->dev
]->fstat(f
, &s
)) < 0)
618 if((s
.mode
& ~0777) != S_IFDIR
)
621 current
->cwd
= kstrdup(fsrootpath(f
->path
));
622 if(f
->dev
== ROOTDEV
&& chdir(f
->path
) == 0){
624 current
->kcwd
= kstrdup(f
->path
);
635 trace("sys_fchdir(%d)", fd
);
637 if((f
= fdgetfile(fd
)) == nil
)
645 sys_fchown(int fd
, int uid
, int gid
)
650 trace("sys_fchown(%d, %d, %d)", fd
, uid
, gid
);
652 if((f
= fdgetfile(fd
)) == nil
)
655 if(devtab
[f
->dev
]->fchown
)
656 err
= devtab
[f
->dev
]->fchown(f
, uid
, gid
);
663 sys_fchmod(int fd
, int mode
)
668 trace("sys_fchmod(%d, %#o)", fd
, mode
);
670 if((f
= fdgetfile(fd
)) == nil
)
673 if(devtab
[f
->dev
]->fchmod
)
674 err
= devtab
[f
->dev
]->fchmod(f
, mode
);
681 sys_ftruncate(int fd
, ulong size
)
686 trace("sys_ftruncate(%d, %lux)", fd
, size
);
688 if((f
= fdgetfile(fd
)) == nil
)
691 if(devtab
[f
->dev
]->ftruncate
)
692 err
= devtab
[f
->dev
]->ftruncate(f
, (uvlong
)size
);
700 current
->fdtab
= newfdtab();
701 current
->umask
= 022;
704 void exitfile(Uproc
*proc
)
708 if(tab
= proc
->fdtab
){
714 void clonefile(Uproc
*new, int copy
)
718 if((tab
= current
->fdtab
) == nil
){
722 new->fdtab
= getfdtab(tab
, copy
);
730 if((tab
= current
->fdtab
) == nil
)
733 for(i
=0; i
<tab
->nfd
; i
++){
736 if((f
= tab
->fd
[i
].file
) == nil
)
738 if((tab
->fd
[i
].flags
& FD_CLOEXEC
) == 0)
741 tab
->fd
[i
].file
= nil
;
742 tab
->fd
[i
].flags
= 0;
749 int sys_flock(int fd
, int cmd
)
751 trace("sys_flock(%d, %d)", fd
, cmd
);
755 int sys_fsync(int fd
)
757 trace("sys_fsync(%d)", fd
);