1 /*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 /* clang-format off */
19
20 /** \file
21 * Implements 64-bit LIB3F fstat subprogram. */
22
23 /* must include ent3f.h AFTER io3f.h */
24 #include <sys/stat.h>
25 #include "io3f.h"
26 #include "ent3f.h"
27
ENT3F(FSTAT64,fstat64)28 int ENT3F(FSTAT64, fstat64)(int *lu, long long *statb)
29 {
30 #if defined(TARGET_WIN) || defined(WIN32) || defined(WIN64)
31 /*
32 * The __int64_t members in the _stat64 are 8-byte aligned, thus the
33 * st_size member is at offset 24. On WIN32, 64-bit ints are 4-byte
34 * aligned, so st_size shows up at offset 20!. The correct solution is
35 * to use or make default -Mllalign, but that's not in the picture.
36 * So, just declare a replacement struct which explicitly pad members
37 * the members line up with the _stat64 struct.
38 */
39 struct {
40 int st_dev; /* 0 */
41 short st_ino; /* 4 */
42 short st_mode; /* 6 */
43 short st_nlink; /* 8 */
44 short st_uid; /* 10 */
45 short st_gid; /* 12 */
46 short pad1; /* 14 */
47 int st_rdev; /* 16 */
48 int pad2; /* 20 */
49 __int64 st_size; /* 24 */
50 __int64 st_atime; /* 32 */
51 __int64 st_mtime; /* 40 */
52 __int64 st_ctime; /* 48 */
53 } b;
54 struct _stat64 *bp;
55 char *p;
56 int i;
57 void *f;
58 bp = (struct _stat64 *)&b;
59
60 f = __fio_find_unit(*lu);
61 if (f && !FIO_FCB_STDUNIT(f)) {
62 /** need a way to get f->fp's fildes **/
63 if (i = _stat64(FIO_FCB_NAME(f), bp))
64 i = __io_errno();
65 } else {
66 switch (*lu) {
67 case 0:
68 i = 2;
69 break;
70 case 5:
71 i = 0;
72 break;
73 case 6:
74 i = 1;
75 break;
76 default:
77 i = -1;
78 break;
79 }
80 if (i = _fstat64(i, bp))
81 i = __io_errno();
82 }
83 statb[0] = b.st_dev;
84 statb[1] = b.st_ino;
85 statb[2] = b.st_mode;
86 statb[3] = b.st_nlink;
87 statb[4] = b.st_uid;
88 statb[5] = b.st_gid;
89 statb[6] = b.st_rdev;
90 statb[7] = b.st_size;
91 statb[8] = b.st_atime;
92 statb[9] = b.st_mtime;
93 statb[10] = b.st_ctime;
94 statb[11] = 0;
95 statb[12] = 0;
96 return i;
97 #else
98 struct stat b;
99 char *p;
100 int i;
101 void *f;
102
103 f = __fio_find_unit(*lu);
104 if (f && !FIO_FCB_STDUNIT(f)) {
105 /** need a way to get f->fp's fildes **/
106 if ((i = stat(FIO_FCB_NAME(f), &b)))
107 i = __io_errno();
108 } else {
109 switch (*lu) {
110 case 0:
111 i = 2;
112 break;
113 case 5:
114 i = 0;
115 break;
116 case 6:
117 i = 1;
118 break;
119 default:
120 i = -1;
121 break;
122 }
123 if ((i = fstat(i, &b)))
124 i = __io_errno();
125 }
126 statb[0] = b.st_dev;
127 statb[1] = b.st_ino;
128 statb[2] = b.st_mode;
129 statb[3] = b.st_nlink;
130 statb[4] = b.st_uid;
131 statb[5] = b.st_gid;
132 statb[6] = b.st_rdev;
133 statb[7] = b.st_size;
134 statb[8] = b.st_atime;
135 statb[9] = b.st_mtime;
136 statb[10] = b.st_ctime;
137 statb[11] = b.st_blksize;
138 statb[12] = b.st_blocks;
139 return i;
140 #endif
141 }
142