summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
0f4f1fb)
* Calculate the open(2) flags ahead of time.
* Move the open(2) until after we set up the alarm. This means that
we might not actually set `fd' at all, if we get delayed and the
alarm goes off.
* Use a separate static (because setjmp(3)) variable to record the
fcntl(2) return code.
* Use `goto' and labels for the control flow, rather than having
everything in an `else' branch.
* Use `switch' to pick the results of fcntl(2) apart.
/*----- Static variables --------------------------------------------------*/
static jmp_buf jmp;
/*----- Static variables --------------------------------------------------*/
static jmp_buf jmp;
/*----- Main code ---------------------------------------------------------*/
/*----- Main code ---------------------------------------------------------*/
const char *prog = 0;
char *const *av;
void (*oalrm)(int) = 0;
const char *prog = 0;
char *const *av;
void (*oalrm)(int) = 0;
struct flock l;
char *p;
int t = -1;
struct flock l;
char *p;
int t = -1;
unsigned int ot = 0;
time_t nt;
pid_t kid;
unsigned int ot = 0;
time_t nt;
pid_t kid;
av = &argv[optind];
if (!prog) prog = av[0];
av = &argv[optind];
if (!prog) prog = av[0];
- if ((fd = open(file,
- ((f & f_create ? O_CREAT : 0) |
- (f & f_excl ? O_RDWR : O_RDONLY)), 0666)) < 0)
- die(111, "error opening `%s': %s", file, strerror(errno));
+ oflag = f & f_excl ? O_RDWR : O_RDONLY;
+ if (f & f_create) oflag |= O_CREAT;
l.l_type = f & f_excl ? F_WRLCK : F_RDLCK;
l.l_whence = SEEK_SET;
l.l_start = 0;
l.l_len = 0;
nt = time(0);
if (setjmp(jmp)) {
l.l_type = f & f_excl ? F_WRLCK : F_RDLCK;
l.l_whence = SEEK_SET;
l.l_start = 0;
l.l_len = 0;
nt = time(0);
if (setjmp(jmp)) {
- } else {
- ot = alarm(0);
- oalrm = signal(SIGALRM, alrm);
- if (t >= 0) alarm(t);
- if (fcntl(fd, f & f_wait ? F_SETLKW : F_SETLK, &l) >= 0) errno = 0;
+ ot = alarm(0);
+ oalrm = signal(SIGALRM, alrm);
+ if (t >= 0) alarm(t);
+ if ((fd = open(file, oflag, 0666)) < 0)
+ die(111, "error opening `%s': %s", file, strerror(errno));
+ err = fcntl(fd, f & f_wait ? F_SETLKW : F_SETLK, &l) >= 0 ? 0 : errno;
+done:
signal(SIGALRM, oalrm);
if (!ot)
alarm(0);
signal(SIGALRM, oalrm);
if (!ot)
alarm(0);
if (nt > ot) raise(SIGALRM);
else alarm(ot - nt);
}
if (nt > ot) raise(SIGALRM);
else alarm(ot - nt);
}
- if (errno &&
- ((errno != EAGAIN && errno != EWOULDBLOCK && errno != EACCES) ||
- (f & f_fail)))
- die(111, "error locking `%s': %s", file, strerror(errno));
- if (errno) exit(0);
-
+ switch (err) {
+ case 0: break;
+ case EAGAIN:
+#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
+ case EACCES:
+ if (!(f & f_fail)) exit(0);
+ default:
+ die(111, "error locking `%s': %s", file, strerror(errno));
+ }
if ((kid = fork()) < 0) die(111, "error from fork: %s", strerror(errno));
if (!kid) {
close(fd);
if ((kid = fork()) < 0) die(111, "error from fork: %s", strerror(errno));
if (!kid) {
close(fd);
l.l_start = 0;
l.l_len = 0;
fcntl(fd, F_SETLK, &l);
l.l_start = 0;
l.l_len = 0;
fcntl(fd, F_SETLK, &l);
+ if (fd >= 0) close(fd);
if (WIFEXITED(rc)) exit(WEXITSTATUS(rc));
else exit(128 + WTERMSIG(rc));
}
if (WIFEXITED(rc)) exit(WEXITSTATUS(rc));
else exit(128 + WTERMSIG(rc));
}