DCL 3.7.4
Loading...
Searching...
No Matches
_stdio.cpp
Go to the documentation of this file.
1
2#include <dcl/Config.h>
3
4#ifndef __WINNT__
5
6#include <errno.h>
7#if defined(_AIX) || defined(__sun__)
8 #include <alloca.h>
9#endif
10#include <stdlib.h> // alloca
11#include <sys/stat.h> // stat
12#include <fcntl.h> // open
13#include <unistd.h> // close
14#include <utime.h> // utime
15#include <dcl/_stdio.h>
16
17#if __linux__
18#include <sys/sendfile.h>
19#endif
20#include <dcl/Object.h> // __T(str)
21#include <dcl/String.h>
22
23#include "__strumbs.h"
24
25#if __DCL_HAVE_THIS_FILE__
26#undef __THIS_FILE__
27static const char_t __UNUSED__ __THIS_FILE__[] = __T("dcl/_stdio.cpp");
28#endif
29
30__DCL_BEGIN_NAMESPACE
31
32int __remove(const String& _path)
33{
34 STRTOMBS_ER(_path, path);
35 return remove(path);
36}
37
38int __rename(const char* _oldpath, const char* _newpath)
39{
40 if (!rename(_oldpath, _newpath))
41 return 0;
42
43 if (errno != EXDEV)
44 return -1;
45
46 // device가 달라서 실패한 경우 파일을 복사하고 이전파일을 지운다
47
48 int oldfd = -1, newfd = -1;
49 struct stat oldstat, newstat;
50
51 if (lstat(_oldpath, &oldstat) || lstat(_newpath, &newstat))
52 return -1;
53#if 0
54 if (S_ISLNK(oldstat.st_mode)) {
55 char oldpath[1024 + 1];
56 int n = readlink(_oldpath, oldpath, sizeof(oldpath) - 1);
57 if (n > 0) {
58 // FIXME
59 // oldpath is relative path ?
60 oldpath[n] = '\0';
61 if (symlink(oldpath, _newpath))
62 return -1;
63 unlink(_oldpath);
64 }
65 return -1;
66 }
67#endif
68 if (!S_ISREG(oldstat.st_mode)) {
69 errno = EINVAL;
70 return -1;
71 }
72
73 do {
74 oldfd = open(_oldpath, O_RDONLY);
75 newfd = open(_newpath, O_CREAT | O_WRONLY, oldstat.st_mode);
76 if (oldfd == -1 || newfd == -1)
77 break;
78#if __linux__
79 off_t offset = 0;
80 ssize_t n = sendfile(newfd, oldfd, &offset, oldstat.st_size);
81 if (n == -1)
82 break;
83#else
84 char* buf = (char*)malloc(newstat.st_blksize);
85 if (!buf) {
86 errno = ENOMEM;
87 break;
88 }
89 ssize_t n = 0;
90 while ((n != -1) && (n = read(oldfd, buf, newstat.st_blksize)) > 0)
91 n = write(newfd, buf, n);
92 free(buf);
93 if (n == -1)
94 break;
95#endif
96 close(oldfd);
97 close(newfd);
98
99 struct utimbuf ub;
100 ub.actime = oldstat.st_atime;
101 ub.modtime = oldstat.st_mtime;
102 utime(_newpath, &ub);
103 unlink(_oldpath);
104 return 0;
105 } while (true);
106
107 int save = errno;
108 if (oldfd != -1)
109 close(oldfd);
110 if (newfd != -1) {
111 close(newfd);
112 unlink(_newpath);
113 }
114
115 errno = save;
116 return -1;
117}
118
119int __rename(const String& _oldpath, const String& _newpath)
120{
121 STRTOMBS_ER(_oldpath, oldpath);
122 STRTOMBS_ER(_newpath, newpath);
123 if (noldpath == (size_t)-1 || nnewpath == (size_t)-1) {
124 errno = EILSEQ;
125 return -1;
126 }
127 return __rename(oldpath, newpath);
128}
129
130FILE* __fopen(const String& _path, const String& _mode)
131{
132 STRTOMBS(_path, path);
133 STRTOMBS(_mode, mode);
134 if (npath == (size_t) -1 || nmode == (size_t) -1) {
135 errno = EILSEQ;
136 return NULL;
137 }
138 return fopen(path, mode);
139}
140
141FILE* __fdopen(int _fd, const String& _mode)
142{
143 STRTOMBS(_mode, mode);
144 if (nmode == (size_t) -1) {
145 errno = EILSEQ;
146 return NULL;
147 }
148 return fdopen(_fd, mode);
149}
150
151__DCL_END_NAMESPACE
152
153#endif // __WINNT__
#define STRTOMBS_ER(str, mbs)
Definition __strumbs.h:33
#define STRTOMBS(str, mbs)
Definition __strumbs.h:25
int __rename(const char *_oldpath, const char *_newpath)
Definition _stdio.cpp:38
__DCL_BEGIN_NAMESPACE int __remove(const String &_path)
Definition _stdio.cpp:32
FILE * __fopen(const String &_path, const String &_mode)
Definition _stdio.cpp:130
FILE * __fdopen(int _fd, const String &_mode)
Definition _stdio.cpp:141
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
#define __UNUSED__
Definition Config.h:341
wchar_t char_t
Definition Config.h:247
#define __T(str)
Definition Object.h:60