8 typedef struct Mount Mount
;
21 fsmount(Udev
*dev
, char *path
)
30 m
= kmalloc(sizeof(*m
) + n
+ 1);
34 strcpy(m
->path
, path
);
36 for(p
=&mtab
;;p
=&((*p
)->next
)){
40 if(m
->npath
< x
->npath
)
42 if(m
->npath
== x
->npath
){
43 if(strcmp(m
->path
, x
->path
) < 0)
58 h
= (h
* 13) + (*s
- 'a');
63 basepath(char *p
, char **ps
)
68 if(s
= strrchr(p
, '/')){
86 allocpath(char *base
, char *prefix
, char *name
)
93 k
= prefix
? strlen(prefix
) : 0;
94 p
= s
= kmalloc(n
+m
+k
+2);
100 memmove(p
, prefix
, k
);
103 memmove(p
, name
, m
+1);
108 fullpath(char *base
, char *name
)
112 if(*name
== '/' || *name
== '#'){
115 s
= allocpath(base
, nil
, name
);
125 shortpath(char *base
, char *path
)
130 if((n
<= strlen(path
)) && (strncmp(path
, base
, n
)==0)){
141 fsfullpath(char *path
)
145 path
= fullpath(current
->cwd
, path
);
146 if(path
&& (root
= current
->root
)){
147 root
= allocpath(root
, nil
, path
+1);
155 fsrootpath(char *path
)
159 if(root
= current
->root
){
160 root
= shortpath(root
, path
);
163 } else if(root
> path
){
171 path2mount(char *path
)
175 for(m
=mtab
; m
; m
=m
->next
){
176 if(strncmp(path
, m
->path
, m
->npath
) == 0){
177 switch(path
[m
->npath
]){
192 if(m
= path2mount(path
))
204 if(current
->linkloop
> 8)
205 return *perr
= -ELOOP
;
216 int sys_getcwd(char *buf
, int len
)
221 trace("sys_getcwd(%p, %x)", buf
, len
);
227 memmove(buf
, cwd
, n
);
232 fsopen(char *path
, int mode
, int perm
, Ufile
**pf
)
237 trace("fsopen(%s, %#o, %#o)", path
, mode
, perm
);
240 if(fsenter(&err
) < 0)
243 if((dev
= path2dev(path
)) && dev
->open
)
244 err
= dev
->open(path
, mode
, perm
, pf
);
250 fsaccess(char *path
, int mode
)
255 trace("fsaccess(%s, %#o)", path
, mode
);
257 if(fsenter(&err
) < 0)
260 if(dev
= path2dev(path
)){
263 err
= dev
->access(path
, mode
);
270 int sys_access(char *name
, int mode
)
274 trace("sys_access(%s, %#o)", name
, mode
);
276 if((name
= fsfullpath(name
)) == nil
)
278 err
= fsaccess(name
, mode
);
284 int sys_open(char *name
, int mode
, int perm
)
289 trace("sys_open(%s, %#o, %#o)", name
, mode
, perm
);
291 if((name
= fsfullpath(name
)) == nil
)
293 err
= fsopen(name
, mode
, perm
, &file
);
297 err
= newfd(file
, FD_CLOEXEC
);
302 int sys_creat(char *name
, int perm
)
304 trace("sys_create(%s, %#o)", name
, perm
);
306 return sys_open(name
, O_CREAT
|O_TRUNC
, perm
);
310 fsstat(char *path
, int link
, Ustat
*ps
)
315 trace("fsstat(%s, %d)", path
, link
);
317 if(fsenter(&err
) < 0)
320 if((dev
= path2dev(path
)) && dev
->stat
){
321 memset(ps
, 0, sizeof(Ustat
));
322 err
= dev
->stat(path
, link
, ps
);
329 sys_chdir(char *name
)
334 trace("sys_chdir(%s)", name
);
336 if((name
= fsfullpath(name
)) == nil
)
338 err
= fsopen(name
, O_RDONLY
, 0, &f
);
347 int sys_chroot(char *name
)
353 trace("sys_chroot(%s)", name
);
356 if((err
= fsopen(name
, O_RDONLY
, 0, &f
)) < 0)
361 if(devtab
[f
->dev
]->fstat
== nil
)
363 if((err
= devtab
[f
->dev
]->fstat(f
, &s
)) < 0)
366 if((s
.mode
& ~0777) != S_IFDIR
)
370 if(strcmp(f
->path
, "/") == 0){
373 current
->root
= kstrdup(f
->path
);
381 fschown(char *path
, int uid
, int gid
, int link
)
386 trace("fschown(%s, %d, %d, %d)", path
, uid
, gid
, link
);
388 if(fsenter(&err
) < 0)
391 if((dev
= path2dev(path
)) && dev
->chown
)
392 err
= dev
->chown(path
, uid
, gid
, link
);
397 int sys_chown(char *name
, int uid
, int gid
)
401 trace("sys_chown(%s, %d, %d)", name
, uid
, gid
);
403 if((name
= fsfullpath(name
)) == nil
)
405 err
= fschown(name
, uid
, gid
, 0);
411 int sys_lchown(char *name
, int uid
, int gid
)
415 trace("sys_lchown(%s, %d, %d)", name
, uid
, gid
);
417 if((name
= fsfullpath(name
)) == nil
)
419 err
= fschown(name
, uid
, gid
, 1);
426 fsreadlink(char *path
, char *buf
, int len
)
431 trace("fsreadlink(%s)", path
);
433 if(fsenter(&err
) < 0)
436 if((dev
= path2dev(path
)) && dev
->readlink
)
437 err
= dev
->readlink(path
, buf
, len
);
443 int sys_readlink(char *name
, char *buf
, int len
)
447 trace("sys_readlink(%s, %p, %x)", name
, buf
, len
);
449 if((name
= fsfullpath(name
)) == nil
)
451 err
= fsreadlink(name
, buf
, len
);
458 fsrename(char *old
, char *new)
463 trace("fsrename(%s, %s)", old
, new);
465 if(fsenter(&err
) < 0)
468 if((dev
= path2dev(old
)) && dev
->rename
){
470 if(dev
== path2dev(new))
471 err
= dev
->rename(old
, new);
479 int sys_rename(char *from
, char *to
)
483 trace("sys_rename(%s, %s)", from
, to
);
485 if((from
= fsfullpath(from
)) == nil
)
487 if((to
= fsfullpath(to
)) == nil
){
491 err
= fsrename(from
, to
);
499 fsmkdir(char *path
, int mode
)
504 trace("fsmkdir(%s, %#o)", path
, mode
);
506 if(fsenter(&err
) < 0)
510 if((dev
= path2dev(path
)) && dev
->mkdir
)
511 err
= dev
->mkdir(path
, mode
);
517 int sys_mkdir(char *name
, int mode
)
521 trace("sys_mkdir(%s, %#o)", name
, mode
);
523 if((name
= fsfullpath(name
)) == nil
)
525 err
= fsmkdir(name
, mode
);
532 fsutime(char *path
, int atime
, int mtime
)
537 trace("fsutime(%s, %d, %d)", path
, atime
, mtime
);
539 if(fsenter(&err
) < 0)
542 if((dev
= path2dev(path
)) && dev
->utime
)
543 err
= dev
->utime(path
, atime
, mtime
);
555 int sys_utime(char *name
, void *times
)
558 struct linux_utimbuf
*t
= times
;
560 trace("sys_utime(%s, %p)", name
, times
);
562 if((name
= fsfullpath(name
)) == nil
)
565 err
= fsutime(name
, t
->atime
, t
->mtime
);
568 err
= fsutime(name
, x
, x
);
575 int sys_utimes(char *name
, void *tvp
)
578 struct linux_timeval
*t
= tvp
;
580 trace("sys_utimes(%s, %p)", name
, tvp
);
582 if((name
= fsfullpath(name
)) == nil
)
585 err
= fsutime(name
, t
[0].tv_sec
, t
[1].tv_sec
);
588 err
= fsutime(name
, x
, x
);
596 fschmod(char *path
, int mode
)
601 trace("fschmod(%s, %#o)", path
, mode
);
603 if(fsenter(&err
) < 0)
606 if((dev
= path2dev(path
)) && dev
->chmod
)
607 err
= dev
->chmod(path
, mode
);
613 int sys_chmod(char *name
, int mode
)
617 trace("sys_chmod(%s, %#o)", name
, mode
);
619 if((name
= fsfullpath(name
)) == nil
)
621 err
= fschmod(name
, mode
);
628 fstruncate(char *path
, vlong size
)
633 trace("fstruncate(%s, %llx)", path
, size
);
635 if(fsenter(&err
) < 0)
638 if((dev
= path2dev(path
)) && dev
->truncate
)
639 err
= dev
->truncate(path
, size
);
645 int sys_truncate(char *name
, ulong size
)
649 trace("sys_truncate(%s, %lux)", name
, size
);
651 if((name
= fsfullpath(name
)) == nil
)
653 err
= fstruncate(name
, size
);
660 fsunlink(char *path
, int rmdir
)
665 trace("fsunlink(%s, %d)", path
, rmdir
);
667 if(fsenter(&err
) < 0)
670 if((dev
= path2dev(path
)) && dev
->unlink
)
671 err
= dev
->unlink(path
, rmdir
);
677 int sys_unlink(char *name
)
681 trace("sys_unlink(%s)", name
);
683 if((name
= fsfullpath(name
)) == nil
)
685 err
= fsunlink(name
, 0);
691 int sys_rmdir(char *name
)
695 trace("sys_rmdir(%s)", name
);
697 if((name
= fsfullpath(name
)) == nil
)
699 err
= fsunlink(name
, 1);
706 fslink(char *old
, char *new, int sym
)
711 trace("fslink(%s, %s, %d)", old
, new, sym
);
713 if(fsenter(&err
) < 0)
716 if((dev
= path2dev(new)) && dev
->link
){
718 if(sym
|| dev
== path2dev(old
))
719 err
= dev
->link(old
, new, sym
);
726 int sys_link(char *old
, char *new)
730 trace("sys_link(%s, %s)", old
, new);
732 if((old
= fsfullpath(old
)) == nil
)
734 if((new = fsfullpath(new)) == nil
){
738 err
= fslink(old
, new, 0);
745 int sys_symlink(char *old
, char *new)
749 trace("sys_symlink(%s, %s)", old
, new);
751 if((new = fsfullpath(new)) == nil
)
753 err
= fslink(old
, new, 1);