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