ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libeio/eio.c
(Generate patch)

Comparing libeio/eio.c (file contents):
Revision 1.85 by root, Wed Jul 13 00:53:03 2011 UTC vs.
Revision 1.89 by root, Thu Jul 14 22:36:17 2011 UTC

54#include <stdlib.h> 54#include <stdlib.h>
55#include <string.h> 55#include <string.h>
56#include <errno.h> 56#include <errno.h>
57#include <sys/types.h> 57#include <sys/types.h>
58#include <sys/stat.h> 58#include <sys/stat.h>
59#include <sys/statvfs.h>
60#include <limits.h> 59#include <limits.h>
61#include <fcntl.h> 60#include <fcntl.h>
62#include <assert.h> 61#include <assert.h>
63 62
64/* intptr_t comes from unistd.h, says POSIX/UNIX/tradition */ 63/* intptr_t comes from unistd.h, says POSIX/UNIX/tradition */
83 82
84#ifndef EIO_FEED 83#ifndef EIO_FEED
85# define EIO_FEED(req) do { if ((req)->feed ) (req)->feed (req); } while (0) 84# define EIO_FEED(req) do { if ((req)->feed ) (req)->feed (req); } while (0)
86#endif 85#endif
87 86
87#ifndef EIO_FD_TO_WIN32_HANDLE
88# define EIO_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd)
89#endif
90#ifndef EIO_WIN32_HANDLE_TO_FD
91# define EIO_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0)
92#endif
93
94#define EIO_ERRNO(errval,retval) ((errno = errval), retval)
95
96#define EIO_ENOSYS() EIO_ERRNO (ENOSYS, -1)
97
88#ifdef _WIN32 98#ifdef _WIN32
89 99
90 /*doh*/ 100 #define PAGESIZE 4096 /* GetSystemInfo? */
101
102 #ifdef EIO_STRUCT_STATI64
103 #define stat(path,buf) _stati64 (path,buf)
104 #define fstat(fd,buf) _fstati64 (path,buf)
105 #endif
106 #define lstat(path,buf) stat (path,buf)
107 #define fsync(fd) (FlushFileBuffers (EIO_FD_TO_WIN32_HANDLE (fd)) ? 0 : EIO_ERRNO (EBADF, -1))
108 #define mkdir(path,mode) _mkdir (path)
109 #define link(old,neu) (CreateHardLink (neu, old, 0) ? 0 : EIO_ERRNO (ENOENT, -1))
110
111 #define chown(path,uid,gid) EIO_ENOSYS ()
112 #define fchown(fd,uid,gid) EIO_ENOSYS ()
113 #define truncate(path,offs) EIO_ENOSYS () /* far-miss: SetEndOfFile */
114 #define ftruncate(fd,offs) EIO_ENOSYS () /* near-miss: SetEndOfFile */
115 #define mknod(path,mode,dev) EIO_ENOSYS ()
116 #define sync() EIO_ENOSYS ()
117
118 /* we could even stat and see if it exists */
119 static int
120 symlink (const char *old, const char *neu)
121 {
122 if (CreateSymbolicLink (neu, old, 1))
123 return 0;
124
125 if (CreateSymbolicLink (neu, old, 0))
126 return 0;
127
128 return EIO_ERRNO (ENOENT, -1);
129 }
130
91#else 131#else
92 132
93# include <sys/time.h> 133 #include <sys/time.h>
94# include <sys/select.h> 134 #include <sys/select.h>
135 #include <sys/statvfs.h>
95# include <unistd.h> 136 #include <unistd.h>
96# include <utime.h> 137 #include <utime.h>
97# include <signal.h> 138 #include <signal.h>
98# include <dirent.h> 139 #include <dirent.h>
99 140
100#if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES 141 #if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES
101# include <sys/mman.h> 142 #include <sys/mman.h>
102#endif 143 #endif
103 144
104/* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */ 145 /* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */
105# if __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ 146 #if __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
106# define _DIRENT_HAVE_D_TYPE /* sigh */ 147 #define _DIRENT_HAVE_D_TYPE /* sigh */
107# define D_INO(de) (de)->d_fileno 148 #define D_INO(de) (de)->d_fileno
108# define D_NAMLEN(de) (de)->d_namlen 149 #define D_NAMLEN(de) (de)->d_namlen
109# elif __linux || defined d_ino || _XOPEN_SOURCE >= 600 150 #elif __linux || defined d_ino || _XOPEN_SOURCE >= 600
110# define D_INO(de) (de)->d_ino 151 #define D_INO(de) (de)->d_ino
111# endif 152 #endif
112 153
113#ifdef _D_EXACT_NAMLEN 154 #ifdef _D_EXACT_NAMLEN
114# undef D_NAMLEN 155 #undef D_NAMLEN
115# define D_NAMLEN(de) _D_EXACT_NAMLEN (de) 156 #define D_NAMLEN(de) _D_EXACT_NAMLEN (de)
116#endif 157 #endif
117 158
118# ifdef _DIRENT_HAVE_D_TYPE 159 #ifdef _DIRENT_HAVE_D_TYPE
119# define D_TYPE(de) (de)->d_type 160 #define D_TYPE(de) (de)->d_type
120# endif 161 #endif
121 162
122# ifndef EIO_STRUCT_DIRENT 163 #ifndef EIO_STRUCT_DIRENT
123# define EIO_STRUCT_DIRENT struct dirent 164 #define EIO_STRUCT_DIRENT struct dirent
124# endif 165 #endif
125 166
126#endif 167#endif
127 168
128#if HAVE_SENDFILE 169#if HAVE_SENDFILE
129# if __linux 170# if __linux
836# undef pread 877# undef pread
837# undef pwrite 878# undef pwrite
838# define pread eio__pread 879# define pread eio__pread
839# define pwrite eio__pwrite 880# define pwrite eio__pwrite
840 881
841static ssize_t 882static eio_ssize_t
842eio__pread (int fd, void *buf, size_t count, off_t offset) 883eio__pread (int fd, void *buf, size_t count, off_t offset)
843{ 884{
844 ssize_t res; 885 eio_ssize_t res;
845 off_t ooffset; 886 off_t ooffset;
846 887
847 X_LOCK (preadwritelock); 888 X_LOCK (preadwritelock);
848 ooffset = lseek (fd, 0, SEEK_CUR); 889 ooffset = lseek (fd, 0, SEEK_CUR);
849 lseek (fd, offset, SEEK_SET); 890 lseek (fd, offset, SEEK_SET);
852 X_UNLOCK (preadwritelock); 893 X_UNLOCK (preadwritelock);
853 894
854 return res; 895 return res;
855} 896}
856 897
857static ssize_t 898static eio_ssize_t
858eio__pwrite (int fd, void *buf, size_t count, off_t offset) 899eio__pwrite (int fd, void *buf, size_t count, off_t offset)
859{ 900{
860 ssize_t res; 901 eio_ssize_t res;
861 off_t ooffset; 902 off_t ooffset;
862 903
863 X_LOCK (preadwritelock); 904 X_LOCK (preadwritelock);
864 ooffset = lseek (fd, 0, SEEK_CUR); 905 ooffset = lseek (fd, 0, SEEK_CUR);
865 lseek (fd, offset, SEEK_SET); 906 lseek (fd, offset, SEEK_SET);
954 995
955#if !HAVE_READAHEAD 996#if !HAVE_READAHEAD
956# undef readahead 997# undef readahead
957# define readahead(fd,offset,count) eio__readahead (fd, offset, count, self) 998# define readahead(fd,offset,count) eio__readahead (fd, offset, count, self)
958 999
959static ssize_t 1000static eio_ssize_t
960eio__readahead (int fd, off_t offset, size_t count, etp_worker *self) 1001eio__readahead (int fd, off_t offset, size_t count, etp_worker *self)
961{ 1002{
962 size_t todo = count; 1003 size_t todo = count;
963 dBUF; 1004 dBUF;
964 1005
976} 1017}
977 1018
978#endif 1019#endif
979 1020
980/* sendfile always needs emulation */ 1021/* sendfile always needs emulation */
981static ssize_t 1022static eio_ssize_t
982eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self) 1023eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self)
983{ 1024{
984 ssize_t written = 0; 1025 eio_ssize_t written = 0;
985 ssize_t res; 1026 eio_ssize_t res;
986 1027
987 if (!count) 1028 if (!count)
988 return 0; 1029 return 0;
989 1030
990 for (;;) 1031 for (;;)
1042 if (res < 0 && sbytes) 1083 if (res < 0 && sbytes)
1043 res = sbytes; 1084 res = sbytes;
1044 1085
1045# endif 1086# endif
1046 1087
1047#elif defined (_WIN32) 1088#elif defined (_WIN32) && 0
1048 /* does not work, just for documentation of what would need to be done */ 1089 /* does not work, just for documentation of what would need to be done */
1049 /* actually, cannot be done like this, as TransmitFile changes the file offset, */ 1090 /* actually, cannot be done like this, as TransmitFile changes the file offset, */
1050 /* libeio guarantees that the file offset does not change, and windows */ 1091 /* libeio guarantees that the file offset does not change, and windows */
1051 /* has no way to get an independent handle to the same file description */ 1092 /* has no way to get an independent handle to the same file description */
1052 HANDLE h = TO_SOCKET (ifd); 1093 HANDLE h = TO_SOCKET (ifd);
1099 1140
1100 res = 0; 1141 res = 0;
1101 1142
1102 while (count) 1143 while (count)
1103 { 1144 {
1104 ssize_t cnt; 1145 eio_ssize_t cnt;
1105 1146
1106 cnt = pread (ifd, eio_buf, count > EIO_BUFSIZE ? EIO_BUFSIZE : count, offset); 1147 cnt = pread (ifd, eio_buf, count > EIO_BUFSIZE ? EIO_BUFSIZE : count, offset);
1107 1148
1108 if (cnt <= 0) 1149 if (cnt <= 0)
1109 { 1150 {
1157 /* round up length */ 1198 /* round up length */
1158 *length = (*length + mask) & ~mask; 1199 *length = (*length + mask) & ~mask;
1159} 1200}
1160 1201
1161#if !_POSIX_MEMLOCK 1202#if !_POSIX_MEMLOCK
1162# define eio__mlockall(a) ((errno = ENOSYS), -1) 1203# define eio__mlockall(a) EIO_ENOSYS ()
1163#else 1204#else
1164 1205
1165static int 1206static int
1166eio__mlockall (int flags) 1207eio__mlockall (int flags)
1167{ 1208{
1181 return mlockall (flags); 1222 return mlockall (flags);
1182} 1223}
1183#endif 1224#endif
1184 1225
1185#if !_POSIX_MEMLOCK_RANGE 1226#if !_POSIX_MEMLOCK_RANGE
1186# define eio__mlock(a,b) ((errno = ENOSYS), -1) 1227# define eio__mlock(a,b) EIO_ENOSYS ()
1187#else 1228#else
1188 1229
1189static int 1230static int
1190eio__mlock (void *addr, size_t length) 1231eio__mlock (void *addr, size_t length)
1191{ 1232{
1195} 1236}
1196 1237
1197#endif 1238#endif
1198 1239
1199#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO) 1240#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO)
1200# define eio__msync(a,b,c) ((errno = ENOSYS), -1) 1241# define eio__msync(a,b,c) EIO_ENOSYS ()
1201#else 1242#else
1202 1243
1203static int 1244static int
1204eio__msync (void *mem, size_t len, int flags) 1245eio__msync (void *mem, size_t len, int flags)
1205{ 1246{
1317 res += strlen (res); 1358 res += strlen (res);
1318 } 1359 }
1319 1360
1320 while (*rel) 1361 while (*rel)
1321 { 1362 {
1322 ssize_t len, linklen; 1363 eio_ssize_t len, linklen;
1323 char *beg = rel; 1364 char *beg = rel;
1324 1365
1325 while (*rel && *rel != '/') 1366 while (*rel && *rel != '/')
1326 ++rel; 1367 ++rel;
1327 1368
2138eio_req *eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data) 2179eio_req *eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data)
2139{ 2180{
2140 REQ (EIO_FCHMOD); req->int1 = fd; req->int2 = (long)mode; SEND; 2181 REQ (EIO_FCHMOD); req->int1 = fd; req->int2 = (long)mode; SEND;
2141} 2182}
2142 2183
2143eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data) 2184eio_req *eio_fchown (int fd, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data)
2144{ 2185{
2145 REQ (EIO_FCHOWN); req->int1 = fd; req->int2 = (long)uid; req->int3 = (long)gid; SEND; 2186 REQ (EIO_FCHOWN); req->int1 = fd; req->int2 = (long)uid; req->int3 = (long)gid; SEND;
2146} 2187}
2147 2188
2148eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data) 2189eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data)
2168eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data) 2209eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data)
2169{ 2210{
2170 REQ (EIO_TRUNCATE); PATH; req->offs = offset; SEND; 2211 REQ (EIO_TRUNCATE); PATH; req->offs = offset; SEND;
2171} 2212}
2172 2213
2173eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data) 2214eio_req *eio_chown (const char *path, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data)
2174{ 2215{
2175 REQ (EIO_CHOWN); PATH; req->int2 = (long)uid; req->int3 = (long)gid; SEND; 2216 REQ (EIO_CHOWN); PATH; req->int2 = (long)uid; req->int3 = (long)gid; SEND;
2176} 2217}
2177 2218
2178eio_req *eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data) 2219eio_req *eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data)
2325} 2366}
2326 2367
2327/*****************************************************************************/ 2368/*****************************************************************************/
2328/* misc garbage */ 2369/* misc garbage */
2329 2370
2330ssize_t 2371eio_ssize_t
2331eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count) 2372eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count)
2332{ 2373{
2333 etp_worker wrk; 2374 etp_worker wrk;
2334 ssize_t ret; 2375 eio_ssize_t ret;
2335 2376
2336 wrk.dbuf = 0; 2377 wrk.dbuf = 0;
2337 2378
2338 ret = eio__sendfile (ofd, ifd, offset, count, &wrk); 2379 ret = eio__sendfile (ofd, ifd, offset, count, &wrk);
2339 2380

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines