149
int SysCall::open_excl (const char *file, int flags, ErrorSink *err) {
150
int fd = open (file, flags, err);
153
flock lock = { F_WRLCK, SEEK_SET, 0, 0, 0 };
154
if (fcntl (fd, F_SETLKW, &lock) == -1)
155
printerror (err, "fcntl lock", file);
161
int SysCall::create (const char *file, int mode, ErrorSink *err) {
164
char *n = StrCol::dup (file);
167
fd = ::open (n, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, mode);
171
fd = ::open (file, O_CREAT|O_WRONLY|O_TRUNC, mode);
173
if (fd == -1) printerror (err, "create", file);
177
int SysCall::create_excl (const char *file, int mode, ErrorSink *err) {
178
int fd = create (file, mode, err);
181
flock lock = { F_WRLCK, SEEK_SET, 0, 0, 0 };
182
if (fcntl (fd, F_SETLKW, &lock) == -1)
183
printerror (err, "fcntl lock", file);
144
189
bool SysCall::close (int fd, ErrorSink *err) {
145
190
int ret = ::close (fd);
198
bool SysCall::close_excl (int fd, ErrorSink *err) {
200
flock lock = { F_UNLCK, SEEK_SET, 0, 0, 0 };
201
if (fcntl (fd, F_SETLKW, &lock) == -1) {
202
printerror (err, "fcntl unlock", fd);
206
return close (fd, err);
154
209
long SysCall::read (int fd, void *buffer, size_t n, ErrorSink *err) {
155
210
long bytes = ::read (fd, buffer, n);
388
444
if (strlen (name) == 2 && name[1] == ':' && isalpha (name[0])) {
389
445
result = toupper (name[0]);
393
448
// normalize the directory part recursively ...
394
449
Filename norm_path;
395
if (!normalize (filename.path (), norm_path, err))
450
if (! canonical (filename.path (), norm_path, err)) {
397
453
// .. and find the normlized filename with _findfirst
398
454
struct _finddata_t find_data;
399
long hdl = _findfirst (filename.name (), &find_data);
455
long hdl = _findfirst (name, &find_data);
402
459
result = norm_path.name ();
404
461
result += find_data.name;
412
470
typedef map<DString, Filename> FilenameMap;
413
471
typedef FilenameMap::value_type FilenameMapPair;
414
472
FilenameMap canonical_cache;
416
474
bool SysCall::canonical (Filename filename, Filename &result, ErrorSink *err) {
418
475
// first check if the searched canonical name is already cached
419
476
FilenameMap::iterator fn = canonical_cache.find (filename.name ());
420
477
if (fn != canonical_cache.end ()) {
425
482
// build a canonical path name
427
char file_buf[PATH_MAX];
483
const char *file_abs = filename.name ();
484
char file_buf[MAX_PATH];
429
486
#if defined (WIN32)
430
file_abs = _fullpath(file_buf, filename.name (), PATH_MAX);
487
if ((strlen (file_abs) == 2 && file_abs[1] == ':' && isalpha (file_abs[0])) ||
488
(file_abs = _fullpath(file_buf, file_abs, MAX_PATH))) {
432
489
Filename abs (file_abs);
433
if (!normalize (abs, result, err))
490
if (! normalize (abs, result, err)) {
437
file_abs = realpath(filename.name (), file_buf);
495
file_abs = realpath(file_abs, file_buf);
439
497
result.name (file_abs);
443
502
printerror (err, "canonical", filename.name ());