1370b324cSopenharmony_ci// FileStreams.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci// #include <stdio.h>
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#ifndef _WIN32
8370b324cSopenharmony_ci#include <fcntl.h>
9370b324cSopenharmony_ci#include <unistd.h>
10370b324cSopenharmony_ci#include <errno.h>
11370b324cSopenharmony_ci#include <grp.h>
12370b324cSopenharmony_ci#include <pwd.h>
13370b324cSopenharmony_ci
14370b324cSopenharmony_ci// for major()/minor():
15370b324cSopenharmony_ci#include <sys/types.h>
16370b324cSopenharmony_ci#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__)
17370b324cSopenharmony_ci#else
18370b324cSopenharmony_ci#ifndef major
19370b324cSopenharmony_ci#include <sys/sysmacros.h>
20370b324cSopenharmony_ci#endif
21370b324cSopenharmony_ci#endif
22370b324cSopenharmony_ci
23370b324cSopenharmony_ci#endif // _WIN32
24370b324cSopenharmony_ci
25370b324cSopenharmony_ci#include "../../Windows/FileFind.h"
26370b324cSopenharmony_ci
27370b324cSopenharmony_ci#ifdef Z7_DEVICE_FILE
28370b324cSopenharmony_ci#include "../../../C/Alloc.h"
29370b324cSopenharmony_ci#include "../../Common/Defs.h"
30370b324cSopenharmony_ci#endif
31370b324cSopenharmony_ci
32370b324cSopenharmony_ci#include "../PropID.h"
33370b324cSopenharmony_ci
34370b324cSopenharmony_ci#include "FileStreams.h"
35370b324cSopenharmony_ci
36370b324cSopenharmony_cistatic inline HRESULT GetLastError_HRESULT()
37370b324cSopenharmony_ci{
38370b324cSopenharmony_ci  DWORD lastError = ::GetLastError();
39370b324cSopenharmony_ci  if (lastError == 0)
40370b324cSopenharmony_ci    return E_FAIL;
41370b324cSopenharmony_ci  return HRESULT_FROM_WIN32(lastError);
42370b324cSopenharmony_ci}
43370b324cSopenharmony_ci
44370b324cSopenharmony_cistatic inline HRESULT ConvertBoolToHRESULT(bool result)
45370b324cSopenharmony_ci{
46370b324cSopenharmony_ci  if (result)
47370b324cSopenharmony_ci    return S_OK;
48370b324cSopenharmony_ci  return GetLastError_HRESULT();
49370b324cSopenharmony_ci}
50370b324cSopenharmony_ci
51370b324cSopenharmony_ci
52370b324cSopenharmony_ci#ifdef Z7_DEVICE_FILE
53370b324cSopenharmony_cistatic const UInt32 kClusterSize = 1 << 18;
54370b324cSopenharmony_ci#endif
55370b324cSopenharmony_ci
56370b324cSopenharmony_ciCInFileStream::CInFileStream():
57370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE
58370b324cSopenharmony_ci  VirtPos(0),
59370b324cSopenharmony_ci  PhyPos(0),
60370b324cSopenharmony_ci  Buf(NULL),
61370b324cSopenharmony_ci  BufSize(0),
62370b324cSopenharmony_ci #endif
63370b324cSopenharmony_ci #ifndef _WIN32
64370b324cSopenharmony_ci  _uid(0),
65370b324cSopenharmony_ci  _gid(0),
66370b324cSopenharmony_ci  StoreOwnerId(false),
67370b324cSopenharmony_ci  StoreOwnerName(false),
68370b324cSopenharmony_ci #endif
69370b324cSopenharmony_ci  _info_WasLoaded(false),
70370b324cSopenharmony_ci  SupportHardLinks(false),
71370b324cSopenharmony_ci  Callback(NULL),
72370b324cSopenharmony_ci  CallbackRef(0)
73370b324cSopenharmony_ci{
74370b324cSopenharmony_ci}
75370b324cSopenharmony_ci
76370b324cSopenharmony_ciCInFileStream::~CInFileStream()
77370b324cSopenharmony_ci{
78370b324cSopenharmony_ci  #ifdef Z7_DEVICE_FILE
79370b324cSopenharmony_ci  MidFree(Buf);
80370b324cSopenharmony_ci  #endif
81370b324cSopenharmony_ci
82370b324cSopenharmony_ci  if (Callback)
83370b324cSopenharmony_ci    Callback->InFileStream_On_Destroy(this, CallbackRef);
84370b324cSopenharmony_ci}
85370b324cSopenharmony_ci
86370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize))
87370b324cSopenharmony_ci{
88370b324cSopenharmony_ci  #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
89370b324cSopenharmony_ci
90370b324cSopenharmony_ci  #ifdef Z7_DEVICE_FILE
91370b324cSopenharmony_ci  if (processedSize)
92370b324cSopenharmony_ci    *processedSize = 0;
93370b324cSopenharmony_ci  if (size == 0)
94370b324cSopenharmony_ci    return S_OK;
95370b324cSopenharmony_ci  if (File.IsDeviceFile)
96370b324cSopenharmony_ci  {
97370b324cSopenharmony_ci    if (File.SizeDefined)
98370b324cSopenharmony_ci    {
99370b324cSopenharmony_ci      if (VirtPos >= File.Size)
100370b324cSopenharmony_ci        return VirtPos == File.Size ? S_OK : E_FAIL;
101370b324cSopenharmony_ci      const UInt64 rem = File.Size - VirtPos;
102370b324cSopenharmony_ci      if (size > rem)
103370b324cSopenharmony_ci        size = (UInt32)rem;
104370b324cSopenharmony_ci    }
105370b324cSopenharmony_ci    for (;;)
106370b324cSopenharmony_ci    {
107370b324cSopenharmony_ci      const UInt32 mask = kClusterSize - 1;
108370b324cSopenharmony_ci      const UInt64 mask2 = ~(UInt64)mask;
109370b324cSopenharmony_ci      const UInt64 alignedPos = VirtPos & mask2;
110370b324cSopenharmony_ci      if (BufSize > 0 && BufStartPos == alignedPos)
111370b324cSopenharmony_ci      {
112370b324cSopenharmony_ci        const UInt32 pos = (UInt32)VirtPos & mask;
113370b324cSopenharmony_ci        if (pos >= BufSize)
114370b324cSopenharmony_ci          return S_OK;
115370b324cSopenharmony_ci        const UInt32 rem = MyMin(BufSize - pos, size);
116370b324cSopenharmony_ci        memcpy(data, Buf + pos, rem);
117370b324cSopenharmony_ci        VirtPos += rem;
118370b324cSopenharmony_ci        if (processedSize)
119370b324cSopenharmony_ci          *processedSize += rem;
120370b324cSopenharmony_ci        return S_OK;
121370b324cSopenharmony_ci      }
122370b324cSopenharmony_ci
123370b324cSopenharmony_ci      bool useBuf = false;
124370b324cSopenharmony_ci      if ((VirtPos & mask) != 0 || ((size_t)(ptrdiff_t)data & mask) != 0 )
125370b324cSopenharmony_ci        useBuf = true;
126370b324cSopenharmony_ci      else
127370b324cSopenharmony_ci      {
128370b324cSopenharmony_ci        UInt64 end = VirtPos + size;
129370b324cSopenharmony_ci        if ((end & mask) != 0)
130370b324cSopenharmony_ci        {
131370b324cSopenharmony_ci          end &= mask2;
132370b324cSopenharmony_ci          if (end <= VirtPos)
133370b324cSopenharmony_ci            useBuf = true;
134370b324cSopenharmony_ci          else
135370b324cSopenharmony_ci            size = (UInt32)(end - VirtPos);
136370b324cSopenharmony_ci        }
137370b324cSopenharmony_ci      }
138370b324cSopenharmony_ci      if (!useBuf)
139370b324cSopenharmony_ci        break;
140370b324cSopenharmony_ci      if (alignedPos != PhyPos)
141370b324cSopenharmony_ci      {
142370b324cSopenharmony_ci        UInt64 realNewPosition;
143370b324cSopenharmony_ci        const bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition);
144370b324cSopenharmony_ci        if (!result)
145370b324cSopenharmony_ci          return ConvertBoolToHRESULT(result);
146370b324cSopenharmony_ci        PhyPos = realNewPosition;
147370b324cSopenharmony_ci      }
148370b324cSopenharmony_ci
149370b324cSopenharmony_ci      BufStartPos = alignedPos;
150370b324cSopenharmony_ci      UInt32 readSize = kClusterSize;
151370b324cSopenharmony_ci      if (File.SizeDefined)
152370b324cSopenharmony_ci        readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize);
153370b324cSopenharmony_ci
154370b324cSopenharmony_ci      if (!Buf)
155370b324cSopenharmony_ci      {
156370b324cSopenharmony_ci        Buf = (Byte *)MidAlloc(kClusterSize);
157370b324cSopenharmony_ci        if (!Buf)
158370b324cSopenharmony_ci          return E_OUTOFMEMORY;
159370b324cSopenharmony_ci      }
160370b324cSopenharmony_ci      const bool result = File.Read1(Buf, readSize, BufSize);
161370b324cSopenharmony_ci      if (!result)
162370b324cSopenharmony_ci        return ConvertBoolToHRESULT(result);
163370b324cSopenharmony_ci
164370b324cSopenharmony_ci      if (BufSize == 0)
165370b324cSopenharmony_ci        return S_OK;
166370b324cSopenharmony_ci      PhyPos += BufSize;
167370b324cSopenharmony_ci    }
168370b324cSopenharmony_ci
169370b324cSopenharmony_ci    if (VirtPos != PhyPos)
170370b324cSopenharmony_ci    {
171370b324cSopenharmony_ci      UInt64 realNewPosition;
172370b324cSopenharmony_ci      bool result = File.Seek((Int64)VirtPos, FILE_BEGIN, realNewPosition);
173370b324cSopenharmony_ci      if (!result)
174370b324cSopenharmony_ci        return ConvertBoolToHRESULT(result);
175370b324cSopenharmony_ci      PhyPos = VirtPos = realNewPosition;
176370b324cSopenharmony_ci    }
177370b324cSopenharmony_ci  }
178370b324cSopenharmony_ci  #endif
179370b324cSopenharmony_ci
180370b324cSopenharmony_ci  UInt32 realProcessedSize;
181370b324cSopenharmony_ci  const bool result = File.ReadPart(data, size, realProcessedSize);
182370b324cSopenharmony_ci  if (processedSize)
183370b324cSopenharmony_ci    *processedSize = realProcessedSize;
184370b324cSopenharmony_ci
185370b324cSopenharmony_ci  #ifdef Z7_DEVICE_FILE
186370b324cSopenharmony_ci  VirtPos += realProcessedSize;
187370b324cSopenharmony_ci  PhyPos += realProcessedSize;
188370b324cSopenharmony_ci  #endif
189370b324cSopenharmony_ci
190370b324cSopenharmony_ci  if (result)
191370b324cSopenharmony_ci    return S_OK;
192370b324cSopenharmony_ci
193370b324cSopenharmony_ci  #else // Z7_FILE_STREAMS_USE_WIN_FILE
194370b324cSopenharmony_ci
195370b324cSopenharmony_ci  if (processedSize)
196370b324cSopenharmony_ci    *processedSize = 0;
197370b324cSopenharmony_ci  const ssize_t res = File.read_part(data, (size_t)size);
198370b324cSopenharmony_ci  if (res != -1)
199370b324cSopenharmony_ci  {
200370b324cSopenharmony_ci    if (processedSize)
201370b324cSopenharmony_ci      *processedSize = (UInt32)res;
202370b324cSopenharmony_ci    return S_OK;
203370b324cSopenharmony_ci  }
204370b324cSopenharmony_ci  #endif // Z7_FILE_STREAMS_USE_WIN_FILE
205370b324cSopenharmony_ci
206370b324cSopenharmony_ci  {
207370b324cSopenharmony_ci    const DWORD error = ::GetLastError();
208370b324cSopenharmony_ci    if (Callback)
209370b324cSopenharmony_ci      return Callback->InFileStream_On_Error(CallbackRef, error);
210370b324cSopenharmony_ci    if (error == 0)
211370b324cSopenharmony_ci      return E_FAIL;
212370b324cSopenharmony_ci    return HRESULT_FROM_WIN32(error);
213370b324cSopenharmony_ci  }
214370b324cSopenharmony_ci}
215370b324cSopenharmony_ci
216370b324cSopenharmony_ci#ifdef UNDER_CE
217370b324cSopenharmony_ciZ7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize))
218370b324cSopenharmony_ci{
219370b324cSopenharmony_ci  size_t s2 = fread(data, 1, size, stdin);
220370b324cSopenharmony_ci  int error = ferror(stdin);
221370b324cSopenharmony_ci  if (processedSize)
222370b324cSopenharmony_ci    *processedSize = s2;
223370b324cSopenharmony_ci  if (s2 <= size && error == 0)
224370b324cSopenharmony_ci    return S_OK;
225370b324cSopenharmony_ci  return E_FAIL;
226370b324cSopenharmony_ci}
227370b324cSopenharmony_ci#else
228370b324cSopenharmony_ciZ7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize))
229370b324cSopenharmony_ci{
230370b324cSopenharmony_ci  #ifdef _WIN32
231370b324cSopenharmony_ci
232370b324cSopenharmony_ci  DWORD realProcessedSize;
233370b324cSopenharmony_ci  UInt32 sizeTemp = (1 << 20);
234370b324cSopenharmony_ci  if (sizeTemp > size)
235370b324cSopenharmony_ci    sizeTemp = size;
236370b324cSopenharmony_ci  BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL);
237370b324cSopenharmony_ci  if (processedSize)
238370b324cSopenharmony_ci    *processedSize = realProcessedSize;
239370b324cSopenharmony_ci  if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
240370b324cSopenharmony_ci    return S_OK;
241370b324cSopenharmony_ci  return ConvertBoolToHRESULT(res != FALSE);
242370b324cSopenharmony_ci
243370b324cSopenharmony_ci  #else
244370b324cSopenharmony_ci
245370b324cSopenharmony_ci  if (processedSize)
246370b324cSopenharmony_ci    *processedSize = 0;
247370b324cSopenharmony_ci  ssize_t res;
248370b324cSopenharmony_ci  do
249370b324cSopenharmony_ci  {
250370b324cSopenharmony_ci    res = read(0, data, (size_t)size);
251370b324cSopenharmony_ci  }
252370b324cSopenharmony_ci  while (res < 0 && (errno == EINTR));
253370b324cSopenharmony_ci  if (res == -1)
254370b324cSopenharmony_ci    return GetLastError_HRESULT();
255370b324cSopenharmony_ci  if (processedSize)
256370b324cSopenharmony_ci    *processedSize = (UInt32)res;
257370b324cSopenharmony_ci  return S_OK;
258370b324cSopenharmony_ci
259370b324cSopenharmony_ci  #endif
260370b324cSopenharmony_ci}
261370b324cSopenharmony_ci
262370b324cSopenharmony_ci#endif
263370b324cSopenharmony_ci
264370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
265370b324cSopenharmony_ci{
266370b324cSopenharmony_ci  if (seekOrigin >= 3)
267370b324cSopenharmony_ci    return STG_E_INVALIDFUNCTION;
268370b324cSopenharmony_ci
269370b324cSopenharmony_ci  #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
270370b324cSopenharmony_ci
271370b324cSopenharmony_ci  #ifdef Z7_DEVICE_FILE
272370b324cSopenharmony_ci  if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END))
273370b324cSopenharmony_ci  {
274370b324cSopenharmony_ci    switch (seekOrigin)
275370b324cSopenharmony_ci    {
276370b324cSopenharmony_ci      case STREAM_SEEK_SET: break;
277370b324cSopenharmony_ci      case STREAM_SEEK_CUR: offset += VirtPos; break;
278370b324cSopenharmony_ci      case STREAM_SEEK_END: offset += File.Size; break;
279370b324cSopenharmony_ci      default: return STG_E_INVALIDFUNCTION;
280370b324cSopenharmony_ci    }
281370b324cSopenharmony_ci    if (offset < 0)
282370b324cSopenharmony_ci      return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
283370b324cSopenharmony_ci    VirtPos = (UInt64)offset;
284370b324cSopenharmony_ci    if (newPosition)
285370b324cSopenharmony_ci      *newPosition = (UInt64)offset;
286370b324cSopenharmony_ci    return S_OK;
287370b324cSopenharmony_ci  }
288370b324cSopenharmony_ci  #endif
289370b324cSopenharmony_ci
290370b324cSopenharmony_ci  UInt64 realNewPosition = 0;
291370b324cSopenharmony_ci  const bool result = File.Seek(offset, seekOrigin, realNewPosition);
292370b324cSopenharmony_ci  const HRESULT hres = ConvertBoolToHRESULT(result);
293370b324cSopenharmony_ci
294370b324cSopenharmony_ci  /* 21.07: new File.Seek() in 21.07 already returns correct (realNewPosition)
295370b324cSopenharmony_ci     in case of error. So we don't need additional code below */
296370b324cSopenharmony_ci  // if (!result) { realNewPosition = 0; File.GetPosition(realNewPosition); }
297370b324cSopenharmony_ci
298370b324cSopenharmony_ci  #ifdef Z7_DEVICE_FILE
299370b324cSopenharmony_ci  PhyPos = VirtPos = realNewPosition;
300370b324cSopenharmony_ci  #endif
301370b324cSopenharmony_ci
302370b324cSopenharmony_ci  if (newPosition)
303370b324cSopenharmony_ci    *newPosition = realNewPosition;
304370b324cSopenharmony_ci
305370b324cSopenharmony_ci  return hres;
306370b324cSopenharmony_ci
307370b324cSopenharmony_ci  #else
308370b324cSopenharmony_ci
309370b324cSopenharmony_ci  const off_t res = File.seek((off_t)offset, (int)seekOrigin);
310370b324cSopenharmony_ci  if (res == -1)
311370b324cSopenharmony_ci  {
312370b324cSopenharmony_ci    const HRESULT hres = GetLastError_HRESULT();
313370b324cSopenharmony_ci    if (newPosition)
314370b324cSopenharmony_ci      *newPosition = (UInt64)File.seekToCur();
315370b324cSopenharmony_ci    return hres;
316370b324cSopenharmony_ci  }
317370b324cSopenharmony_ci  if (newPosition)
318370b324cSopenharmony_ci    *newPosition = (UInt64)res;
319370b324cSopenharmony_ci  return S_OK;
320370b324cSopenharmony_ci
321370b324cSopenharmony_ci  #endif
322370b324cSopenharmony_ci}
323370b324cSopenharmony_ci
324370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetSize(UInt64 *size))
325370b324cSopenharmony_ci{
326370b324cSopenharmony_ci  return ConvertBoolToHRESULT(File.GetLength(*size));
327370b324cSopenharmony_ci}
328370b324cSopenharmony_ci
329370b324cSopenharmony_ci#ifdef Z7_FILE_STREAMS_USE_WIN_FILE
330370b324cSopenharmony_ci
331370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib))
332370b324cSopenharmony_ci{
333370b324cSopenharmony_ci  if (!_info_WasLoaded)
334370b324cSopenharmony_ci  {
335370b324cSopenharmony_ci    RINOK(ReloadProps())
336370b324cSopenharmony_ci  }
337370b324cSopenharmony_ci  const BY_HANDLE_FILE_INFORMATION &info = _info;
338370b324cSopenharmony_ci  /*
339370b324cSopenharmony_ci  BY_HANDLE_FILE_INFORMATION info;
340370b324cSopenharmony_ci  if (!File.GetFileInformation(&info))
341370b324cSopenharmony_ci    return GetLastError_HRESULT();
342370b324cSopenharmony_ci  */
343370b324cSopenharmony_ci  {
344370b324cSopenharmony_ci    if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
345370b324cSopenharmony_ci    if (cTime) *cTime = info.ftCreationTime;
346370b324cSopenharmony_ci    if (aTime) *aTime = info.ftLastAccessTime;
347370b324cSopenharmony_ci    if (mTime) *mTime = info.ftLastWriteTime;
348370b324cSopenharmony_ci    if (attrib) *attrib = info.dwFileAttributes;
349370b324cSopenharmony_ci    return S_OK;
350370b324cSopenharmony_ci  }
351370b324cSopenharmony_ci}
352370b324cSopenharmony_ci
353370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props))
354370b324cSopenharmony_ci{
355370b324cSopenharmony_ci  if (!_info_WasLoaded)
356370b324cSopenharmony_ci  {
357370b324cSopenharmony_ci    RINOK(ReloadProps())
358370b324cSopenharmony_ci  }
359370b324cSopenharmony_ci  const BY_HANDLE_FILE_INFORMATION &info = _info;
360370b324cSopenharmony_ci  /*
361370b324cSopenharmony_ci  BY_HANDLE_FILE_INFORMATION info;
362370b324cSopenharmony_ci  if (!File.GetFileInformation(&info))
363370b324cSopenharmony_ci    return GetLastError_HRESULT();
364370b324cSopenharmony_ci  */
365370b324cSopenharmony_ci  {
366370b324cSopenharmony_ci    props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow;
367370b324cSopenharmony_ci    props->VolID = info.dwVolumeSerialNumber;
368370b324cSopenharmony_ci    props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
369370b324cSopenharmony_ci    props->FileID_High = 0;
370370b324cSopenharmony_ci    props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1;
371370b324cSopenharmony_ci    props->Attrib = info.dwFileAttributes;
372370b324cSopenharmony_ci    props->CTime = info.ftCreationTime;
373370b324cSopenharmony_ci    props->ATime = info.ftLastAccessTime;
374370b324cSopenharmony_ci    props->MTime = info.ftLastWriteTime;
375370b324cSopenharmony_ci    return S_OK;
376370b324cSopenharmony_ci  }
377370b324cSopenharmony_ci}
378370b324cSopenharmony_ci
379370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value))
380370b324cSopenharmony_ci{
381370b324cSopenharmony_ci  if (!_info_WasLoaded)
382370b324cSopenharmony_ci  {
383370b324cSopenharmony_ci    RINOK(ReloadProps())
384370b324cSopenharmony_ci  }
385370b324cSopenharmony_ci
386370b324cSopenharmony_ci  if (!_info_WasLoaded)
387370b324cSopenharmony_ci    return S_OK;
388370b324cSopenharmony_ci
389370b324cSopenharmony_ci  NWindows::NCOM::CPropVariant prop;
390370b324cSopenharmony_ci
391370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE
392370b324cSopenharmony_ci  if (File.IsDeviceFile)
393370b324cSopenharmony_ci  {
394370b324cSopenharmony_ci    switch (propID)
395370b324cSopenharmony_ci    {
396370b324cSopenharmony_ci      case kpidSize:
397370b324cSopenharmony_ci        if (File.SizeDefined)
398370b324cSopenharmony_ci          prop = File.Size;
399370b324cSopenharmony_ci        break;
400370b324cSopenharmony_ci      // case kpidAttrib: prop = (UInt32)0; break;
401370b324cSopenharmony_ci      case kpidPosixAttrib:
402370b324cSopenharmony_ci      {
403370b324cSopenharmony_ci        prop = (UInt32)NWindows::NFile::NFind::NAttributes::
404370b324cSopenharmony_ci            Get_PosixMode_From_WinAttrib(0);
405370b324cSopenharmony_ci        /* GNU TAR by default can't extract file with MY_LIN_S_IFBLK attribute
406370b324cSopenharmony_ci           so we don't use MY_LIN_S_IFBLK here */
407370b324cSopenharmony_ci        // prop = (UInt32)(MY_LIN_S_IFBLK | 0600); // for debug
408370b324cSopenharmony_ci        break;
409370b324cSopenharmony_ci      }
410370b324cSopenharmony_ci      /*
411370b324cSopenharmony_ci      case kpidDeviceMajor:
412370b324cSopenharmony_ci        prop = (UInt32)8; // id for SCSI type device (sda)
413370b324cSopenharmony_ci        break;
414370b324cSopenharmony_ci      case kpidDeviceMinor:
415370b324cSopenharmony_ci        prop = (UInt32)0;
416370b324cSopenharmony_ci        break;
417370b324cSopenharmony_ci      */
418370b324cSopenharmony_ci    }
419370b324cSopenharmony_ci  }
420370b324cSopenharmony_ci  else
421370b324cSopenharmony_ci #endif
422370b324cSopenharmony_ci  {
423370b324cSopenharmony_ci    switch (propID)
424370b324cSopenharmony_ci    {
425370b324cSopenharmony_ci      case kpidSize:
426370b324cSopenharmony_ci      {
427370b324cSopenharmony_ci        const UInt64 size = (((UInt64)_info.nFileSizeHigh) << 32) + _info.nFileSizeLow;
428370b324cSopenharmony_ci        prop = size;
429370b324cSopenharmony_ci        break;
430370b324cSopenharmony_ci      }
431370b324cSopenharmony_ci      case kpidAttrib:  prop = (UInt32)_info.dwFileAttributes; break;
432370b324cSopenharmony_ci      case kpidCTime:  PropVariant_SetFrom_FiTime(prop, _info.ftCreationTime); break;
433370b324cSopenharmony_ci      case kpidATime:  PropVariant_SetFrom_FiTime(prop, _info.ftLastAccessTime); break;
434370b324cSopenharmony_ci      case kpidMTime:  PropVariant_SetFrom_FiTime(prop, _info.ftLastWriteTime); break;
435370b324cSopenharmony_ci      case kpidPosixAttrib:
436370b324cSopenharmony_ci        prop = (UInt32)NWindows::NFile::NFind::NAttributes::
437370b324cSopenharmony_ci            Get_PosixMode_From_WinAttrib(_info.dwFileAttributes);
438370b324cSopenharmony_ci            // | (UInt32)(1 << 21); // for debug
439370b324cSopenharmony_ci        break;
440370b324cSopenharmony_ci    }
441370b324cSopenharmony_ci  }
442370b324cSopenharmony_ci  prop.Detach(value);
443370b324cSopenharmony_ci  return S_OK;
444370b324cSopenharmony_ci}
445370b324cSopenharmony_ci
446370b324cSopenharmony_ci
447370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::ReloadProps())
448370b324cSopenharmony_ci{
449370b324cSopenharmony_ci #ifdef Z7_DEVICE_FILE
450370b324cSopenharmony_ci  if (File.IsDeviceFile)
451370b324cSopenharmony_ci  {
452370b324cSopenharmony_ci    memset(&_info, 0, sizeof(_info));
453370b324cSopenharmony_ci    if (File.SizeDefined)
454370b324cSopenharmony_ci    {
455370b324cSopenharmony_ci      _info.nFileSizeHigh = (DWORD)(File.Size >> 32);
456370b324cSopenharmony_ci      _info.nFileSizeLow = (DWORD)(File.Size);
457370b324cSopenharmony_ci    }
458370b324cSopenharmony_ci    _info.nNumberOfLinks = 1;
459370b324cSopenharmony_ci    _info_WasLoaded = true;
460370b324cSopenharmony_ci    return S_OK;
461370b324cSopenharmony_ci  }
462370b324cSopenharmony_ci #endif
463370b324cSopenharmony_ci  _info_WasLoaded = File.GetFileInformation(&_info);
464370b324cSopenharmony_ci  if (!_info_WasLoaded)
465370b324cSopenharmony_ci    return GetLastError_HRESULT();
466370b324cSopenharmony_ci  return S_OK;
467370b324cSopenharmony_ci}
468370b324cSopenharmony_ci
469370b324cSopenharmony_ci
470370b324cSopenharmony_ci#elif !defined(_WIN32)
471370b324cSopenharmony_ci
472370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib))
473370b324cSopenharmony_ci{
474370b324cSopenharmony_ci  if (!_info_WasLoaded)
475370b324cSopenharmony_ci  {
476370b324cSopenharmony_ci    RINOK(ReloadProps())
477370b324cSopenharmony_ci  }
478370b324cSopenharmony_ci  const struct stat &st = _info;
479370b324cSopenharmony_ci  /*
480370b324cSopenharmony_ci  struct stat st;
481370b324cSopenharmony_ci  if (File.my_fstat(&st) != 0)
482370b324cSopenharmony_ci    return GetLastError_HRESULT();
483370b324cSopenharmony_ci  */
484370b324cSopenharmony_ci
485370b324cSopenharmony_ci  if (size) *size = (UInt64)st.st_size;
486370b324cSopenharmony_ci  if (cTime) FiTime_To_FILETIME (ST_CTIME(st), *cTime);
487370b324cSopenharmony_ci  if (aTime) FiTime_To_FILETIME (ST_ATIME(st), *aTime);
488370b324cSopenharmony_ci  if (mTime) FiTime_To_FILETIME (ST_MTIME(st), *mTime);
489370b324cSopenharmony_ci  if (attrib) *attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
490370b324cSopenharmony_ci
491370b324cSopenharmony_ci  return S_OK;
492370b324cSopenharmony_ci}
493370b324cSopenharmony_ci
494370b324cSopenharmony_ci// #include <stdio.h>
495370b324cSopenharmony_ci
496370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props))
497370b324cSopenharmony_ci{
498370b324cSopenharmony_ci  if (!_info_WasLoaded)
499370b324cSopenharmony_ci  {
500370b324cSopenharmony_ci    RINOK(ReloadProps())
501370b324cSopenharmony_ci  }
502370b324cSopenharmony_ci  const struct stat &st = _info;
503370b324cSopenharmony_ci  /*
504370b324cSopenharmony_ci  struct stat st;
505370b324cSopenharmony_ci  if (File.my_fstat(&st) != 0)
506370b324cSopenharmony_ci    return GetLastError_HRESULT();
507370b324cSopenharmony_ci  */
508370b324cSopenharmony_ci
509370b324cSopenharmony_ci  props->Size = (UInt64)st.st_size;
510370b324cSopenharmony_ci  /*
511370b324cSopenharmony_ci    dev_t stat::st_dev:
512370b324cSopenharmony_ci       GCC:Linux  long unsigned int :  __dev_t
513370b324cSopenharmony_ci       Mac:       int
514370b324cSopenharmony_ci  */
515370b324cSopenharmony_ci  props->VolID = (UInt64)(Int64)st.st_dev;
516370b324cSopenharmony_ci  props->FileID_Low = st.st_ino;
517370b324cSopenharmony_ci  props->FileID_High = 0;
518370b324cSopenharmony_ci  props->NumLinks = (UInt32)st.st_nlink; // we reduce to UInt32 from (nlink_t) that is (unsigned long)
519370b324cSopenharmony_ci  props->Attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
520370b324cSopenharmony_ci
521370b324cSopenharmony_ci  FiTime_To_FILETIME (ST_CTIME(st), props->CTime);
522370b324cSopenharmony_ci  FiTime_To_FILETIME (ST_ATIME(st), props->ATime);
523370b324cSopenharmony_ci  FiTime_To_FILETIME (ST_MTIME(st), props->MTime);
524370b324cSopenharmony_ci
525370b324cSopenharmony_ci  /*
526370b324cSopenharmony_ci  printf("\nGetProps2() NumLinks=%d = st_dev=%d st_ino = %d\n"
527370b324cSopenharmony_ci      , (unsigned)(props->NumLinks)
528370b324cSopenharmony_ci      , (unsigned)(st.st_dev)
529370b324cSopenharmony_ci      , (unsigned)(st.st_ino)
530370b324cSopenharmony_ci      );
531370b324cSopenharmony_ci  */
532370b324cSopenharmony_ci
533370b324cSopenharmony_ci  return S_OK;
534370b324cSopenharmony_ci}
535370b324cSopenharmony_ci
536370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value))
537370b324cSopenharmony_ci{
538370b324cSopenharmony_ci  if (!_info_WasLoaded)
539370b324cSopenharmony_ci  {
540370b324cSopenharmony_ci    RINOK(ReloadProps())
541370b324cSopenharmony_ci  }
542370b324cSopenharmony_ci
543370b324cSopenharmony_ci  if (!_info_WasLoaded)
544370b324cSopenharmony_ci    return S_OK;
545370b324cSopenharmony_ci
546370b324cSopenharmony_ci  const struct stat &st = _info;
547370b324cSopenharmony_ci
548370b324cSopenharmony_ci  NWindows::NCOM::CPropVariant prop;
549370b324cSopenharmony_ci  {
550370b324cSopenharmony_ci    switch (propID)
551370b324cSopenharmony_ci    {
552370b324cSopenharmony_ci      case kpidSize: prop = (UInt64)st.st_size; break;
553370b324cSopenharmony_ci      case kpidAttrib:
554370b324cSopenharmony_ci        prop = (UInt32)NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode);
555370b324cSopenharmony_ci        break;
556370b324cSopenharmony_ci      case kpidCTime:  PropVariant_SetFrom_FiTime(prop, ST_CTIME(st)); break;
557370b324cSopenharmony_ci      case kpidATime:  PropVariant_SetFrom_FiTime(prop, ST_ATIME(st)); break;
558370b324cSopenharmony_ci      case kpidMTime:  PropVariant_SetFrom_FiTime(prop, ST_MTIME(st)); break;
559370b324cSopenharmony_ci      case kpidPosixAttrib: prop = (UInt32)st.st_mode; break;
560370b324cSopenharmony_ci
561370b324cSopenharmony_ci        #if defined(__APPLE__)
562370b324cSopenharmony_ci        #pragma GCC diagnostic push
563370b324cSopenharmony_ci        #pragma GCC diagnostic ignored "-Wsign-conversion"
564370b324cSopenharmony_ci        #endif
565370b324cSopenharmony_ci
566370b324cSopenharmony_ci      case kpidDeviceMajor:
567370b324cSopenharmony_ci      {
568370b324cSopenharmony_ci        // printf("\nst.st_rdev = %d\n", st.st_rdev);
569370b324cSopenharmony_ci        if (S_ISCHR(st.st_mode) ||
570370b324cSopenharmony_ci            S_ISBLK(st.st_mode))
571370b324cSopenharmony_ci          prop = (UInt32)(major(st.st_rdev)); //  + 1000);
572370b324cSopenharmony_ci        // prop = (UInt32)12345678; // for debug
573370b324cSopenharmony_ci        break;
574370b324cSopenharmony_ci      }
575370b324cSopenharmony_ci
576370b324cSopenharmony_ci      case kpidDeviceMinor:
577370b324cSopenharmony_ci        if (S_ISCHR(st.st_mode) ||
578370b324cSopenharmony_ci            S_ISBLK(st.st_mode))
579370b324cSopenharmony_ci          prop = (UInt32)(minor(st.st_rdev)); // + 100);
580370b324cSopenharmony_ci        // prop = (UInt32)(st.st_rdev); // for debug
581370b324cSopenharmony_ci        // printf("\nst.st_rdev = %d\n", st.st_rdev);
582370b324cSopenharmony_ci        // prop = (UInt32)123456789; // for debug
583370b324cSopenharmony_ci        break;
584370b324cSopenharmony_ci
585370b324cSopenharmony_ci        #if defined(__APPLE__)
586370b324cSopenharmony_ci        #pragma GCC diagnostic pop
587370b324cSopenharmony_ci        #endif
588370b324cSopenharmony_ci
589370b324cSopenharmony_ci      /*
590370b324cSopenharmony_ci      case kpidDevice:
591370b324cSopenharmony_ci        if (S_ISCHR(st.st_mode) ||
592370b324cSopenharmony_ci            S_ISBLK(st.st_mode))
593370b324cSopenharmony_ci          prop = (UInt64)(st.st_rdev);
594370b324cSopenharmony_ci        break;
595370b324cSopenharmony_ci      */
596370b324cSopenharmony_ci
597370b324cSopenharmony_ci      case kpidUserId:
598370b324cSopenharmony_ci      {
599370b324cSopenharmony_ci        if (StoreOwnerId)
600370b324cSopenharmony_ci          prop = (UInt32)st.st_uid;
601370b324cSopenharmony_ci        break;
602370b324cSopenharmony_ci      }
603370b324cSopenharmony_ci      case kpidGroupId:
604370b324cSopenharmony_ci      {
605370b324cSopenharmony_ci        if (StoreOwnerId)
606370b324cSopenharmony_ci          prop = (UInt32)st.st_gid;
607370b324cSopenharmony_ci        break;
608370b324cSopenharmony_ci      }
609370b324cSopenharmony_ci      case kpidUser:
610370b324cSopenharmony_ci      {
611370b324cSopenharmony_ci        if (StoreOwnerName)
612370b324cSopenharmony_ci        {
613370b324cSopenharmony_ci          const uid_t uid = st.st_uid;
614370b324cSopenharmony_ci          {
615370b324cSopenharmony_ci            if (!OwnerName.IsEmpty() && _uid == uid)
616370b324cSopenharmony_ci              prop = OwnerName;
617370b324cSopenharmony_ci            else
618370b324cSopenharmony_ci            {
619370b324cSopenharmony_ci              const passwd *pw = getpwuid(uid);
620370b324cSopenharmony_ci              if (pw)
621370b324cSopenharmony_ci              {
622370b324cSopenharmony_ci                // we can use utf-8 here.
623370b324cSopenharmony_ci                // prop = pw->pw_name;
624370b324cSopenharmony_ci              }
625370b324cSopenharmony_ci            }
626370b324cSopenharmony_ci          }
627370b324cSopenharmony_ci        }
628370b324cSopenharmony_ci        break;
629370b324cSopenharmony_ci      }
630370b324cSopenharmony_ci      case kpidGroup:
631370b324cSopenharmony_ci      {
632370b324cSopenharmony_ci        if (StoreOwnerName)
633370b324cSopenharmony_ci        {
634370b324cSopenharmony_ci          const uid_t gid = st.st_gid;
635370b324cSopenharmony_ci          {
636370b324cSopenharmony_ci            if (!OwnerGroup.IsEmpty() && _gid == gid)
637370b324cSopenharmony_ci              prop = OwnerGroup;
638370b324cSopenharmony_ci            else
639370b324cSopenharmony_ci            {
640370b324cSopenharmony_ci              const group *gr = getgrgid(gid);
641370b324cSopenharmony_ci              if (gr)
642370b324cSopenharmony_ci              {
643370b324cSopenharmony_ci                // we can use utf-8 here.
644370b324cSopenharmony_ci                // prop = gr->gr_name;
645370b324cSopenharmony_ci              }
646370b324cSopenharmony_ci            }
647370b324cSopenharmony_ci          }
648370b324cSopenharmony_ci        }
649370b324cSopenharmony_ci        break;
650370b324cSopenharmony_ci      }
651370b324cSopenharmony_ci    }
652370b324cSopenharmony_ci  }
653370b324cSopenharmony_ci  prop.Detach(value);
654370b324cSopenharmony_ci  return S_OK;
655370b324cSopenharmony_ci}
656370b324cSopenharmony_ci
657370b324cSopenharmony_ci
658370b324cSopenharmony_ciZ7_COM7F_IMF(CInFileStream::ReloadProps())
659370b324cSopenharmony_ci{
660370b324cSopenharmony_ci  _info_WasLoaded = (File.my_fstat(&_info) == 0);
661370b324cSopenharmony_ci  if (!_info_WasLoaded)
662370b324cSopenharmony_ci    return GetLastError_HRESULT();
663370b324cSopenharmony_ci  return S_OK;
664370b324cSopenharmony_ci}
665370b324cSopenharmony_ci
666370b324cSopenharmony_ci#endif
667370b324cSopenharmony_ci
668370b324cSopenharmony_ci
669370b324cSopenharmony_ci
670370b324cSopenharmony_ci
671370b324cSopenharmony_ci//////////////////////////
672370b324cSopenharmony_ci// COutFileStream
673370b324cSopenharmony_ci
674370b324cSopenharmony_ciHRESULT COutFileStream::Close()
675370b324cSopenharmony_ci{
676370b324cSopenharmony_ci  return ConvertBoolToHRESULT(File.Close());
677370b324cSopenharmony_ci}
678370b324cSopenharmony_ci
679370b324cSopenharmony_ciZ7_COM7F_IMF(COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
680370b324cSopenharmony_ci{
681370b324cSopenharmony_ci  #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
682370b324cSopenharmony_ci
683370b324cSopenharmony_ci  UInt32 realProcessedSize;
684370b324cSopenharmony_ci  const bool result = File.Write(data, size, realProcessedSize);
685370b324cSopenharmony_ci  ProcessedSize += realProcessedSize;
686370b324cSopenharmony_ci  if (processedSize)
687370b324cSopenharmony_ci    *processedSize = realProcessedSize;
688370b324cSopenharmony_ci  return ConvertBoolToHRESULT(result);
689370b324cSopenharmony_ci
690370b324cSopenharmony_ci  #else
691370b324cSopenharmony_ci
692370b324cSopenharmony_ci  if (processedSize)
693370b324cSopenharmony_ci    *processedSize = 0;
694370b324cSopenharmony_ci  size_t realProcessedSize;
695370b324cSopenharmony_ci  const ssize_t res = File.write_full(data, (size_t)size, realProcessedSize);
696370b324cSopenharmony_ci  ProcessedSize += realProcessedSize;
697370b324cSopenharmony_ci  if (processedSize)
698370b324cSopenharmony_ci    *processedSize = (UInt32)realProcessedSize;
699370b324cSopenharmony_ci  if (res == -1)
700370b324cSopenharmony_ci    return GetLastError_HRESULT();
701370b324cSopenharmony_ci  return S_OK;
702370b324cSopenharmony_ci
703370b324cSopenharmony_ci  #endif
704370b324cSopenharmony_ci}
705370b324cSopenharmony_ci
706370b324cSopenharmony_ciZ7_COM7F_IMF(COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
707370b324cSopenharmony_ci{
708370b324cSopenharmony_ci  if (seekOrigin >= 3)
709370b324cSopenharmony_ci    return STG_E_INVALIDFUNCTION;
710370b324cSopenharmony_ci
711370b324cSopenharmony_ci  #ifdef Z7_FILE_STREAMS_USE_WIN_FILE
712370b324cSopenharmony_ci
713370b324cSopenharmony_ci  UInt64 realNewPosition = 0;
714370b324cSopenharmony_ci  const bool result = File.Seek(offset, seekOrigin, realNewPosition);
715370b324cSopenharmony_ci  if (newPosition)
716370b324cSopenharmony_ci    *newPosition = realNewPosition;
717370b324cSopenharmony_ci  return ConvertBoolToHRESULT(result);
718370b324cSopenharmony_ci
719370b324cSopenharmony_ci  #else
720370b324cSopenharmony_ci
721370b324cSopenharmony_ci  const off_t res = File.seek((off_t)offset, (int)seekOrigin);
722370b324cSopenharmony_ci  if (res == -1)
723370b324cSopenharmony_ci    return GetLastError_HRESULT();
724370b324cSopenharmony_ci  if (newPosition)
725370b324cSopenharmony_ci    *newPosition = (UInt64)res;
726370b324cSopenharmony_ci  return S_OK;
727370b324cSopenharmony_ci
728370b324cSopenharmony_ci  #endif
729370b324cSopenharmony_ci}
730370b324cSopenharmony_ci
731370b324cSopenharmony_ciZ7_COM7F_IMF(COutFileStream::SetSize(UInt64 newSize))
732370b324cSopenharmony_ci{
733370b324cSopenharmony_ci  return ConvertBoolToHRESULT(File.SetLength_KeepPosition(newSize));
734370b324cSopenharmony_ci}
735370b324cSopenharmony_ci
736370b324cSopenharmony_ciHRESULT COutFileStream::GetSize(UInt64 *size)
737370b324cSopenharmony_ci{
738370b324cSopenharmony_ci  return ConvertBoolToHRESULT(File.GetLength(*size));
739370b324cSopenharmony_ci}
740370b324cSopenharmony_ci
741370b324cSopenharmony_ci#ifdef UNDER_CE
742370b324cSopenharmony_ci
743370b324cSopenharmony_ciZ7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
744370b324cSopenharmony_ci{
745370b324cSopenharmony_ci  size_t s2 = fwrite(data, 1, size, stdout);
746370b324cSopenharmony_ci  if (processedSize)
747370b324cSopenharmony_ci    *processedSize = s2;
748370b324cSopenharmony_ci  return (s2 == size) ? S_OK : E_FAIL;
749370b324cSopenharmony_ci}
750370b324cSopenharmony_ci
751370b324cSopenharmony_ci#else
752370b324cSopenharmony_ci
753370b324cSopenharmony_ciZ7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
754370b324cSopenharmony_ci{
755370b324cSopenharmony_ci  if (processedSize)
756370b324cSopenharmony_ci    *processedSize = 0;
757370b324cSopenharmony_ci
758370b324cSopenharmony_ci  #ifdef _WIN32
759370b324cSopenharmony_ci
760370b324cSopenharmony_ci  UInt32 realProcessedSize;
761370b324cSopenharmony_ci  BOOL res = TRUE;
762370b324cSopenharmony_ci  if (size > 0)
763370b324cSopenharmony_ci  {
764370b324cSopenharmony_ci    // Seems that Windows doesn't like big amounts writing to stdout.
765370b324cSopenharmony_ci    // So we limit portions by 32KB.
766370b324cSopenharmony_ci    UInt32 sizeTemp = (1 << 15);
767370b324cSopenharmony_ci    if (sizeTemp > size)
768370b324cSopenharmony_ci      sizeTemp = size;
769370b324cSopenharmony_ci    res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
770370b324cSopenharmony_ci        data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
771370b324cSopenharmony_ci    _size += realProcessedSize;
772370b324cSopenharmony_ci    size -= realProcessedSize;
773370b324cSopenharmony_ci    data = (const void *)((const Byte *)data + realProcessedSize);
774370b324cSopenharmony_ci    if (processedSize)
775370b324cSopenharmony_ci      *processedSize += realProcessedSize;
776370b324cSopenharmony_ci  }
777370b324cSopenharmony_ci  return ConvertBoolToHRESULT(res != FALSE);
778370b324cSopenharmony_ci
779370b324cSopenharmony_ci  #else
780370b324cSopenharmony_ci
781370b324cSopenharmony_ci  ssize_t res;
782370b324cSopenharmony_ci
783370b324cSopenharmony_ci  do
784370b324cSopenharmony_ci  {
785370b324cSopenharmony_ci    res = write(1, data, (size_t)size);
786370b324cSopenharmony_ci  }
787370b324cSopenharmony_ci  while (res < 0 && (errno == EINTR));
788370b324cSopenharmony_ci
789370b324cSopenharmony_ci  if (res == -1)
790370b324cSopenharmony_ci    return GetLastError_HRESULT();
791370b324cSopenharmony_ci
792370b324cSopenharmony_ci  _size += (size_t)res;
793370b324cSopenharmony_ci  if (processedSize)
794370b324cSopenharmony_ci    *processedSize = (UInt32)res;
795370b324cSopenharmony_ci  return S_OK;
796370b324cSopenharmony_ci
797370b324cSopenharmony_ci  #endif
798370b324cSopenharmony_ci}
799370b324cSopenharmony_ci
800370b324cSopenharmony_ci#endif
801