blkno_t i_addr[20];
} dinode; /* Exactly 64 bytes long! */
-struct stat /* Really only used by libc */
-{
- int16_t st_dev;
- uint16_t st_ino;
- uint16_t st_mode;
- uint16_t st_nlink;
- uint16_t st_uid;
- uint16_t st_gid;
- uint16_t st_rdev;
- off_t st_size;
- uint32_t st_atime; /* Break in 2038 */
- uint32_t st_mtime;
- uint32_t st_ctime;
-};
-
/* We use the Linux one for compatibility. There's no real Unix 'standard'
for such things */
--- /dev/null
+#ifndef _USERSTRUCTURES_H
+#define _USERSTRUCTURES_H
+
+/* Structures shared between kernel and user space.
+ *
+ * Only use explicitly sized types here --- otherwise differing compiler
+ * flags between kernel code and user code can pack them differently.
+ */
+
+struct _uzistat
+{
+ /* Do not change this without also changing stcpy() in syscall_fs.c. */
+
+ int16_t st_dev;
+ uint16_t st_ino;
+ uint16_t st_mode;
+ uint16_t st_nlink;
+ uint16_t st_uid;
+ uint16_t st_gid;
+ uint16_t st_rdev;
+ uint32_t st_size;
+ uint32_t st_atime; /* Breaks in 2038 */
+ uint32_t st_mtime;
+ uint32_t st_ctime;
+ uint32_t st_timeh; /* Time high bytes */
+};
+
+#endif
+
#include <version.h>
#include <kdata.h>
#include <printf.h>
+#include <userstructs.h>
void updoff(void)
{
/* Utility for stat and fstat */
int stcpy(inoptr ino, char *buf)
{
- int err = uput((char *) &(ino->c_dev), buf, 12);
- err |= uput((char *) &(ino->c_node.i_addr[0]), buf + 12, 2);
- err |= uput((char *) &(ino->c_node.i_size), buf + 14, 16);
+ /* Copying the structure a member at a time is too expensive. Instead we
+ * copy sequential runs of identical types (the only members which the
+ * compiler guarantees are next to each other). */
+
+ uint32_t zero = 0;
+ struct _uzistat* st = (struct _uzistat*) buf;
+ int err = uput(&ino->c_dev, &st->st_dev, 2 * sizeof(uint16_t));
+ err |= uput(&ino->c_node.i_mode, &st->st_mode, 4 * sizeof(uint16_t));
+ err |= uput(&ino->c_node.i_addr[0], &st->st_rdev, 1 * sizeof(uint16_t));
+ err |= uput(&ino->c_node.i_size, &st->st_size, 4 * sizeof(uint32_t));
+ err |= uput(&zero, &st->st_timeh, 1 * sizeof(uint32_t));
return err;
}
#endif
#include <sys/stat.h>
+/* TODO: make this less nasty. */
+#include "../../Kernel/include/userstructs.h"
+
extern int errno;
extern int syscall(int callno, ...);
-struct _uzistat
-{
- int16_t st_dev;
- uint16_t st_ino;
- uint16_t st_mode;
- uint16_t st_nlink;
- uint16_t st_uid;
- uint16_t st_gid;
- uint16_t st_rdev;
- uint32_t st_size;
- uint32_t st_atime;
- uint32_t st_mtime;
- uint32_t st_ctime;
- uint32_t st_timeh; /* Time high bytes */
-};
-
struct _uzisysinfoblk {
uint8_t infosize; /* For expandability */
uint8_t banks; /* Banks in our 64K (and thus pagesize) */