about summary refs log tree commit diff homepage
path: root/runtime/POSIX/fd_32.c
blob: 1e96de3784d61f3bb2395a492d0e551207d1d83b (plain) (blame)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
//===-- fd_32.c -----------------------------------------------------------===//
//
//                     The KLEE Symbolic Virtual Machine
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Contains 32bit definitions of posix file functions
//===---

#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENV64
#else
#define ENV32
#endif
#endif

#include "klee/Config/Version.h"
#if defined(ENV32) || (LLVM_VERSION_CODE < LLVM_VERSION(3, 3))
#define _LARGEFILE64_SOURCE
#include "fd.h"

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/vfs.h>
#include <fcntl.h>
#include <stdarg.h>
#include <assert.h>
#include <unistd.h>
#include <dirent.h>

/***/

static void __stat64_to_stat(struct stat64 *a, struct stat *b) {
  b->st_dev = a->st_dev;
  b->st_ino = a->st_ino;
  b->st_mode = a->st_mode;
  b->st_nlink = a->st_nlink;
  b->st_uid = a->st_uid;
  b->st_gid = a->st_gid;
  b->st_rdev = a->st_rdev;
  b->st_size = a->st_size;
  b->st_atime = a->st_atime;
  b->st_mtime = a->st_mtime;
  b->st_ctime = a->st_ctime;
  b->st_blksize = a->st_blksize;
  b->st_blocks = a->st_blocks;
}

/***/

int open(const char *pathname, int flags, ...) {
  mode_t mode = 0;

  if (flags & O_CREAT) {
    /* get mode */
    va_list ap;
    va_start(ap, flags);
    mode = va_arg(ap, mode_t);
    va_end(ap);
  }

  return __fd_open(pathname, flags, mode);
}

off_t lseek(int fd, off_t off, int whence) {
  return (off_t) __fd_lseek(fd, off, whence);
}

int __xstat(int vers, const char *path, struct stat *buf) {
  struct stat64 tmp;
  int res = __fd_stat(path, &tmp);
  __stat64_to_stat(&tmp, buf);
  return res;
}

int stat(const char *path, struct stat *buf) {
  struct stat64 tmp;
  int res = __fd_stat(path, &tmp);
  __stat64_to_stat(&tmp, buf);
  return res;
}

int __lxstat(int vers, const char *path, struct stat *buf) {
  struct stat64 tmp;
  int res = __fd_lstat(path, &tmp);
  __stat64_to_stat(&tmp, buf);
  return res;
}

int lstat(const char *path, struct stat *buf) {
  struct stat64 tmp;
  int res = __fd_lstat(path, &tmp);
  __stat64_to_stat(&tmp, buf);
  return res;
}

int __fxstat(int vers, int fd, struct stat *buf) {
  struct stat64 tmp;
  int res = __fd_fstat(fd, &tmp);
  __stat64_to_stat(&tmp, buf);
  return res;
}

int fstat(int fd, struct stat *buf) {
  struct stat64 tmp;
  int res = __fd_fstat(fd, &tmp);
  __stat64_to_stat(&tmp, buf);
  return res;
}

int ftruncate(int fd, off_t length) {
  return __fd_ftruncate(fd, length);
}

int statfs(const char *path, struct statfs *buf32) {
#if 0
    struct statfs64 buf;

    if (__fd_statfs(path, &buf) < 0)
	return -1;

    buf32->f_type = buf.f_type;
    buf32->f_bsize = buf.f_bsize;
    buf32->f_blocks = buf.f_blocks;
    buf32->f_bfree = buf.f_bfree;
    buf32->f_bavail = buf.f_bavail;
    buf32->f_files = buf.f_files;
    buf32->f_ffree = buf.f_ffree;
    buf32->f_fsid = buf.f_fsid;
    buf32->f_namelen = buf.f_namelen;

    return 0;
#else
    return __fd_statfs(path, buf32);
#endif
}

/* Based on uclibc version. We use getdents64 and then rewrite the
   results over themselves, as dirent32s. */
ssize_t getdents(int fd, struct dirent *dirp, size_t nbytes) {
  struct dirent64 *dp64 = (struct dirent64*) dirp;
  ssize_t res = __fd_getdents(fd, dp64, nbytes);

  if (res>0) {
    struct dirent64 *end = (struct dirent64*) ((char*) dp64 + res);
    while (dp64 < end) {
      struct dirent *dp = (struct dirent *) dp64;
      size_t name_len = (dp64->d_reclen - 
                           (size_t) &((struct dirent64*) 0)->d_name);
      dp->d_ino = dp64->d_ino;
      dp->d_off = dp64->d_off;
      dp->d_reclen = dp64->d_reclen;
      dp->d_type = dp64->d_type;
      memmove(dp->d_name, dp64->d_name, name_len);
      dp64 = (struct dirent64*) ((char*) dp64 + dp->d_reclen);
    }
  }

  return res;
}
int __getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
     __attribute__((alias("getdents")));

/* Forward to 64 versions (uclibc expects versions w/o asm specifier) */

__attribute__((weak)) int open64(const char *pathname, int flags, ...) {
  mode_t mode = 0;

  if (flags & O_CREAT) {
    /* get mode */
    va_list ap;
    va_start(ap, flags);
    mode = va_arg(ap, mode_t);
    va_end(ap);
  }

  return __fd_open(pathname, flags, mode);
}

__attribute__((weak)) off64_t lseek64(int fd, off64_t off, int whence) {
  return __fd_lseek(fd, off, whence);
}

__attribute__((weak)) int stat64(const char *path, struct stat64 *buf) {
  return __fd_stat(path, buf);
}

__attribute__((weak)) int lstat64(const char *path, struct stat64 *buf) {
  return __fd_lstat(path, buf);
}

__attribute__((weak)) int fstat64(int fd, struct stat64 *buf) {
  return __fd_fstat(fd, buf);
}

#endif