opendir change: refinement
[minix.git] / lib / libc / sys-minix / stat.c
blob983eb2eb5426f2d4076124bce615f9a30bc9a1f1
1 #include <sys/cdefs.h>
2 #include "namespace.h"
3 #include <lib.h>
5 #include <sys/stat.h>
6 #include <string.h>
8 /* XXX until that st_Xtime macroses used, we have to undefine them,
9 * because of minix_prev_stat
11 #undef st_atime
12 #undef st_ctime
13 #undef st_mtime
15 static void prev_stat2new_stat(struct stat *new, struct minix_prev_stat *prev)
17 /* Copy field by field because of st_gid type mismath and
18 * difference in order after atime.
20 new->st_dev = prev->st_dev;
21 new->st_ino = prev->st_ino;
22 new->st_mode = prev->st_mode;
23 new->st_nlink = prev->st_nlink;
24 new->st_uid = prev->st_uid;
25 new->st_gid = prev->st_gid;
26 new->st_rdev = prev->st_rdev;
27 new->st_size = prev->st_size;
28 new->st_atimespec.tv_sec = prev->st_atime;
29 new->st_mtimespec.tv_sec = prev->st_mtime;
30 new->st_ctimespec.tv_sec = prev->st_ctime;
33 int _stat(const char *name, struct stat *buffer);
34 int _lstat(const char *name, struct stat *buffer);
35 int _fstat(int fd, struct stat *buffer);
37 #ifdef __weak_alias
38 __weak_alias(_stat, __stat50);
39 __weak_alias(_lstat, __lstat50);
40 __weak_alias(_fstat, __fstat50);
42 __weak_alias(stat, __stat50);
43 __weak_alias(lstat, __lstat50);
44 __weak_alias(fstat, __fstat50);
45 #endif
47 int stat(const char *name, struct stat *buffer)
49 message m;
50 int r;
51 struct minix_prev_stat old_sb;
53 m.m1_i1 = strlen(name) + 1;
54 m.m1_p1 = (char *) __UNCONST(name);
55 m.m1_p2 = (char *) buffer;
57 if((r = _syscall(VFS_PROC_NR, STAT, &m)) >= 0 || errno != ENOSYS)
58 return r;
60 errno = 0;
62 /* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
63 * User has struct stat (buffer), VFS still fills minix_prev_stat.
65 m.m1_i1 = strlen(name) + 1;
66 m.m1_p1 = (char *) __UNCONST(name);
67 m.m1_p2 = (char *) &old_sb;
69 if((r = _syscall(VFS_PROC_NR, PREV_STAT, &m)) < 0)
70 return r;
72 memset(buffer, 0, sizeof(struct stat));
73 prev_stat2new_stat(buffer, &old_sb);
75 return r;
78 int _fstat(int fd, struct stat *buffer) { return fstat(fd, buffer); }
80 int fstat(int fd, struct stat *buffer)
82 message m;
83 int r;
84 struct minix_prev_stat old_sb;
86 m.m1_i1 = fd;
87 m.m1_p1 = (char *) buffer;
89 if((r = _syscall(VFS_PROC_NR, FSTAT, &m)) >= 0 || errno != ENOSYS)
90 return r;
92 errno = 0;
94 /* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
95 * User has struct stat (buffer), VFS still fills minix_prev_stat.
97 m.m1_i1 = fd;
98 m.m1_p1 = (char *) &old_sb;
100 if((r = _syscall(VFS_PROC_NR, PREV_FSTAT, &m)) < 0)
101 return r;
103 memset(buffer, 0, sizeof(struct stat));
104 prev_stat2new_stat(buffer, &old_sb);
106 return r;
109 int _lstat(const char *name, struct stat *buffer) { return lstat(name, buffer); }
111 int lstat(const char *name, struct stat *buffer)
113 message m;
114 int r;
115 struct minix_prev_stat old_sb;
117 m.m1_i1 = strlen(name) + 1;
118 m.m1_p1 = (char *) __UNCONST(name);
119 m.m1_p2 = (char *) buffer;
121 if((r = _syscall(VFS_PROC_NR, LSTAT, &m)) >= 0 || errno != ENOSYS)
122 return r;
124 errno = 0;
126 /* ENOSYS: new binary and old VFS, fallback to PREV_STAT.
127 * User has struct stat (buffer), VFS still fills minix_prev_stat.
129 m.m1_i1 = strlen(name) + 1;
130 m.m1_p1 = (char *) __UNCONST(name);
131 m.m1_p2 = (char *) &old_sb;
133 if((r = _syscall(VFS_PROC_NR, PREV_LSTAT, &m)) < 0)
134 return r;
136 memset(buffer, 0, sizeof(struct stat));
137 prev_stat2new_stat(buffer, &old_sb);
139 return r;