ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Urlader/urlib.c
Revision: 1.1
Committed: Fri Dec 30 23:34:08 2011 UTC (12 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "urlib.h"
2    
3     #include <fcntl.h>
4    
5     #ifdef _WIN32
6    
7     #include <windows.h>
8     //#include <winbase.h>
9     #include <shlobj.h>
10     #include <shlwapi.h>
11     #include <wininet.h>
12    
13     static DWORD dword;
14    
15     #define u_handle HANDLE
16     #define u_invalid_handle 0
17     #define u_valid(handle) (!!handle)
18    
19     #define u_setenv(name,value) SetEnvironmentVariable (name, value)
20     #define u_mkdir(path) !CreateDirectory (path, NULL)
21     #define u_chdir(path) !SetCurrentDirectory (path)
22     #define u_rename(fr,to) !MoveFile (fr, to)
23     #define u_open(path) CreateFile (path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL)
24     #define u_creat(path,exec) CreateFile (path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL)
25     #define u_creat(path,exec) CreateFile (path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL)
26     #define u_close(handle) CloseHandle (handle)
27     #define u_append(path,add) PathAppend (path, add)
28     #define u_write(handle,data,len) (WriteFile (handle, data, len, &dword, 0) ? dword : -1)
29    
30     #define u_fsync(handle) FlushFileBuffers (handle)
31     #define u_sync()
32    
33     #define u_lockfile(path) CreateFile (path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)
34     #define u_cloexec(handle)
35    
36     #else
37    
38     #define _GNU_SOURCE 1
39     #define _BSD_SOURCE 1
40     // the above increases our chances of getting MAP_ANONYMOUS
41    
42     #include <sys/mman.h>
43     #include <sys/types.h>
44     #include <sys/stat.h>
45     #include <unistd.h>
46     #include <pwd.h>
47    
48     #if defined (MAP_ANON) && !defined (MAP_ANONYMOUS)
49     #define MAP_ANONYMOUS MAP_ANON
50     #endif
51    
52     #ifdef PATH_MAX
53     #define MAX_PATH (PATH_MAX < 4096 ? 4096 : PATH_MAX)
54     #else
55     #define MAX_PATH 4096
56     #endif
57    
58     #define u_handle int
59     #define u_invalid_handle -1
60     #define u_valid(fd) ((fd) >= 0)
61    
62     #define u_setenv(name,value) setenv (name, value, 1)
63     #define u_mkdir(path) mkdir (path, 0777)
64     #define u_chdir(path) chdir (path)
65     #define u_rename(fr,to) rename (fr, to)
66     #define u_open(path) open (path, O_RDONLY)
67     #define u_creat(path,exec) open (path, O_WRONLY | O_CREAT | O_TRUNC, (exec) ? 0777 : 0666)
68     #define u_close(handle) close (handle)
69     #define u_append(path,add) strcat (strcat (path, "/"), add)
70     #define u_write(handle,data,len) write (handle, data, len)
71    
72     // on a mostly idle system, a sync at the end is certainly faster, hope for the best
73     #define u_fsync(handle)
74     #define u_sync() sync ()
75    
76     #define u_lockfile(path) open (path, O_RDWR | O_CREAT, 0666)
77     #define u_cloexec(handle) fcntl (handle, F_SETFD, FD_CLOEXEC)
78    
79     #endif
80    
81     #define u_16(ptr) (((ptr)[0] << 8) | (ptr)[1])
82     #define u_32(ptr) (((ptr)[0] << 24) | ((ptr)[1] << 16) | ((ptr)[2] << 8) | (ptr)[3])
83    
84     static void *
85     u_malloc (unsigned int size)
86     {
87     void *addr;
88    
89     #ifdef _WIN32
90     HANDLE handle = CreateFileMapping (0, 0, PAGE_READWRITE, 0, size, NULL);
91    
92     if (!handle)
93     return 0;
94    
95     addr = MapViewOfFile (handle, FILE_MAP_WRITE, 0, 0, size);
96    
97     CloseHandle (handle);
98     #elif defined (MAP_ANONYMOUS)
99     addr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
100    
101     if (addr == (void *)-1)
102     addr = 0;
103     #else
104     addr = malloc (size);
105     #endif
106    
107     return addr;
108     }
109    
110     static void
111     u_free (void *addr, unsigned int size)
112     {
113     #ifdef _WIN32
114     UnmapViewOfFile (addr);
115     #elif defined (MAP_ANONYMOUS)
116     munmap (addr, size);
117     #else
118     free (addr);
119     #endif
120     }
121    
122     static void *
123     u_mmap (u_handle h, unsigned int size)
124     {
125     void *addr;
126    
127     #ifdef _WIN32
128     HANDLE handle = CreateFileMapping (h, 0, PAGE_READONLY, 0, size, NULL);
129    
130     if (!handle)
131     return 0;
132    
133     addr = MapViewOfFile (handle, FILE_MAP_READ, 0, 0, size);
134    
135     CloseHandle (handle);
136     #else
137     addr = mmap (0, size, PROT_READ, MAP_SHARED, h, 0);
138    
139     if (addr == (void *)-1)
140     addr = 0;
141     #endif
142    
143     return addr;
144     }
145    
146     static void
147     u_munmap (void *addr, unsigned int len)
148     {
149     #ifdef _WIN32
150     UnmapViewOfFile (addr);
151     #else
152     munmap (addr, len);
153     #endif
154     }
155     static u_handle
156     u_lock (const char *path, int excl, int dowait)
157     {
158     u_handle h;
159    
160     h = u_lockfile (path);
161     if (!u_valid (h))
162     return h;
163    
164     u_cloexec (h);
165    
166     for (;;)
167     {
168     int success;
169    
170     // acquire the lock
171     #ifdef _WIN32
172     OVERLAPPED ov = { 0 };
173    
174     success = LockFileEx (h,
175     (excl ? LOCKFILE_EXCLUSIVE_LOCK : 0)
176     | (dowait ? 0 : LOCKFILE_FAIL_IMMEDIATELY),
177     0,
178     1, 0,
179     &ov);
180     #else
181     struct flock lck = { 0 };
182    
183     lck.l_type = excl ? F_WRLCK : F_RDLCK;
184     lck.l_whence = SEEK_SET;
185     lck.l_len = 1;
186    
187     success = !fcntl (h, dowait ? F_SETLKW : F_SETLK, &lck);
188     #endif
189    
190     if (!success)
191     break;
192    
193     // we have the lock, now verify that the lockfile still exists
194    
195     #ifdef _WIN32
196     // apparently, we have to open the file to get its info :(
197     BY_HANDLE_FILE_INFORMATION s1, s2;
198     u_handle h2 = u_lockfile (path);
199     if (!u_valid (h))
200     break;
201    
202     success = GetFileInformationByHandle (h, &s1)
203     && GetFileInformationByHandle (h2, &s2);
204    
205     u_close (h2);
206    
207     if (!success)
208     break;
209    
210     success = s1.dwVolumeSerialNumber == s2.dwVolumeSerialNumber
211     && s1.nFileIndexHigh == s2.nFileIndexHigh
212     && s1.nFileIndexLow == s2.nFileIndexLow;
213     #else
214     struct stat s1, s2;
215    
216     if (fstat (h, &s1) || stat (path, &s2))
217     break;
218    
219     success = s1.st_dev == s2.st_dev
220     && s1.st_ino == s2.st_ino;
221     #endif
222    
223     if (success)
224     return h; // lock successfully acquired
225    
226     // files differ, close and retry - should be very rare
227     u_close (h);
228     }
229    
230     // failure
231     u_close (h);
232     return u_invalid_handle;
233     }
234