summaryrefslogtreecommitdiff
path: root/cpu/sysdeps/unix/sysv/linux/i386/cpu-stat-linux.h
blob: 7c5c46eb32e8db3ea7f196578d684c948ef1e35d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/***************************************************************
  CPU-STAT-LINUX.H

       This file contains Linux/i386/ILP32 conversion helpers
       for the HOST struct stat -> MCPU struct __cpu_stat ABI.

       PART OF : CPU - library .

       USAGE   : Internal only .

       Copyright (C) 2026  by Andrew V.Kosteltsev.
       All Rights Reserved.
 ***************************************************************/

#ifndef   __CPU_STAT_LINUX_H
#define   __CPU_STAT_LINUX_H

#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <libmcpu.h>
#include <cpu-sysdeps.h>


static int
__cpu_stat_mode( mode_t mode, __mpu_uint64_t *out )
{
  __mpu_uint64_t  m = 0;

  if( !out ) return( __MCPU_EFAULT );

  switch( mode & S_IFMT )
  {
  case S_IFIFO:  m |= __CPU_S_IFIFO;  break;
  case S_IFCHR:  m |= __CPU_S_IFCHR;  break;
  case S_IFDIR:  m |= __CPU_S_IFDIR;  break;
  case S_IFBLK:  m |= __CPU_S_IFBLK;  break;
  case S_IFREG:  m |= __CPU_S_IFREG;  break;
  case S_IFLNK:  m |= __CPU_S_IFLNK;  break;
#ifdef S_IFSOCK
  case S_IFSOCK: m |= __CPU_S_IFSOCK; break;
#endif
  default: return( __MCPU_EOVERFLOW );
  }

  if( mode & S_ISUID ) m |= __CPU_S_ISUID;
  if( mode & S_ISGID ) m |= __CPU_S_ISGID;
#ifdef S_ISVTX
  if( mode & S_ISVTX ) m |= __CPU_S_ISVTX;
#endif
  if( mode & S_IRUSR ) m |= __CPU_S_IRUSR;
  if( mode & S_IWUSR ) m |= __CPU_S_IWUSR;
  if( mode & S_IXUSR ) m |= __CPU_S_IXUSR;
  if( mode & S_IRGRP ) m |= __CPU_S_IRGRP;
  if( mode & S_IWGRP ) m |= __CPU_S_IWGRP;
  if( mode & S_IXGRP ) m |= __CPU_S_IXGRP;
  if( mode & S_IROTH ) m |= __CPU_S_IROTH;
  if( mode & S_IWOTH ) m |= __CPU_S_IWOTH;
  if( mode & S_IXOTH ) m |= __CPU_S_IXOTH;

  *out = m;
  return( 0 );

} /* End of __cpu_stat_mode() */


static int
__cpu_stat_from_host( struct __cpu_stat *dst, const struct stat *src )
{
  int  error;

  if( !dst || !src ) return( __MCPU_EFAULT );

  dst->st_dev = (__mpu_uint64_t)src->st_dev;
  if( (dev_t)dst->st_dev != src->st_dev ) return( __MCPU_EOVERFLOW );

  dst->st_ino = (__mpu_uint64_t)src->st_ino;
  if( (ino_t)dst->st_ino != src->st_ino ) return( __MCPU_EOVERFLOW );

  error = __cpu_stat_mode( src->st_mode, &dst->st_mode );
  if( error ) return( error );

  dst->st_nlink = (__mpu_uint64_t)src->st_nlink;
  if( (nlink_t)dst->st_nlink != src->st_nlink ) return( __MCPU_EOVERFLOW );

  dst->st_uid = (__mpu_uint64_t)src->st_uid;
  if( (uid_t)dst->st_uid != src->st_uid ) return( __MCPU_EOVERFLOW );

  dst->st_gid = (__mpu_uint64_t)src->st_gid;
  if( (gid_t)dst->st_gid != src->st_gid ) return( __MCPU_EOVERFLOW );

  dst->st_rdev = (__mpu_uint64_t)src->st_rdev;
  if( (dev_t)dst->st_rdev != src->st_rdev ) return( __MCPU_EOVERFLOW );

  dst->st_size = (__mpu_int64_t)src->st_size;
  if( (off_t)dst->st_size != src->st_size ) return( __MCPU_EOVERFLOW );

  dst->st_blksize = (__mpu_int64_t)src->st_blksize;
  if( (blksize_t)dst->st_blksize != src->st_blksize ) return( __MCPU_EOVERFLOW );

  dst->st_blocks = (__mpu_int64_t)src->st_blocks;
  if( (blkcnt_t)dst->st_blocks != src->st_blocks ) return( __MCPU_EOVERFLOW );

  dst->st_atime_sec = (__mpu_int64_t)src->st_atim.tv_sec;
  if( (time_t)dst->st_atime_sec != src->st_atim.tv_sec ) return( __MCPU_EOVERFLOW );
  if( src->st_atim.tv_nsec < 0 ) return( __MCPU_EOVERFLOW );
  dst->st_atime_nsec = (__mpu_uint64_t)src->st_atim.tv_nsec;

  dst->st_mtime_sec = (__mpu_int64_t)src->st_mtim.tv_sec;
  if( (time_t)dst->st_mtime_sec != src->st_mtim.tv_sec ) return( __MCPU_EOVERFLOW );
  if( src->st_mtim.tv_nsec < 0 ) return( __MCPU_EOVERFLOW );
  dst->st_mtime_nsec = (__mpu_uint64_t)src->st_mtim.tv_nsec;

  dst->st_ctime_sec = (__mpu_int64_t)src->st_ctim.tv_sec;
  if( (time_t)dst->st_ctime_sec != src->st_ctim.tv_sec ) return( __MCPU_EOVERFLOW );
  if( src->st_ctim.tv_nsec < 0 ) return( __MCPU_EOVERFLOW );
  dst->st_ctime_nsec = (__mpu_uint64_t)src->st_ctim.tv_nsec;

  return( 0 );

} /* End of __cpu_stat_from_host() */

#endif /* __CPU_STAT_LINUX_H */