diff --git a/binlog.c b/binlog.c index 34738b9d..682adff2 100644 --- a/binlog.c +++ b/binlog.c @@ -126,7 +126,10 @@ static void binlog_dref(binlog b) { if (!b) return; - if (b->refs < 1) return twarnx("refs is zero for binlog: %s", b->path); + if (b->refs < 1) { + twarnx("refs is zero for binlog: %s", b->path); + return; + } --b->refs; if (b->refs < 1) { @@ -162,35 +165,49 @@ binlog_read_log_file(binlog b, job binlog_jobs) int version; r = read(b->fd, &version, sizeof(version)); - if (r == -1) return twarn("read()"); + if (r == -1) { + twarn("read()"); + return; + } if (r < sizeof(version)) { - return binlog_warn(b, "EOF while reading version record"); + binlog_warn(b, "EOF while reading version record"); + return; } if (version != binlog_version) { - return warnx("%s: binlog version mismatch %d %d", b->path, version, + warnx("%s: binlog version mismatch %d %d", b->path, version, binlog_version); + return; } while (read(b->fd, &namelen, sizeof(size_t)) == sizeof(size_t)) { if (namelen >= MAX_TUBE_NAME_LEN) { - return binlog_warn(b, "namelen %d exceeds maximum of %d", namelen, MAX_TUBE_NAME_LEN - 1); + binlog_warn(b, "namelen %d exceeds maximum of %d", namelen, MAX_TUBE_NAME_LEN - 1); + return; } if (namelen > 0) { r = read(b->fd, tubename, namelen); - if (r == -1) return twarn("read()"); + if (r == -1) { + twarn("read()"); + return; + } if (r < namelen) { lseek(b->fd, SEEK_CUR, 0); - return binlog_warn(b, "EOF while reading tube name"); + binlog_warn(b, "EOF while reading tube name"); + return; } } tubename[namelen] = '\0'; r = read(b->fd, &js, job_record_size); - if (r == -1) return twarn("read()"); + if (r == -1) { + twarn("read()"); + return; + } if (r < job_record_size) { - return binlog_warn(b, "EOF while reading job record"); + binlog_warn(b, "EOF while reading job record"); + return; } if (!js.id) break; @@ -222,16 +239,21 @@ binlog_read_log_file(binlog b, job binlog_jobs) job_remove(j); binlog_dref(j->binlog); job_free(j); - return binlog_warn(b, "EOF while reading job body"); + binlog_warn(b, "EOF while reading job body"); + return; } r = read(b->fd, j->body, js.body_size); - if (r == -1) return twarn("read()"); + if (r == -1) { + twarn("read()"); + return; + } if (r < js.body_size) { warnx("dropping incomplete job %llu", j->id); job_remove(j); binlog_dref(j->binlog); job_free(j); - return binlog_warn(b, "EOF while reading job body"); + binlog_warn(b, "EOF while reading job body"); + return; } } break; @@ -353,7 +375,10 @@ binlog_open(binlog log, size_t *written) fd = open(log->path, O_WRONLY | O_CREAT, 0400); - if (fd < 0) return twarn("Cannot open binlog %s", log->path); + if (fd < 0) { + twarn("Cannot open binlog %s", log->path); + return; + } #ifdef HAVE_POSIX_FALLOCATE { @@ -378,7 +403,8 @@ binlog_open(binlog log, size_t *written) close(fd); binlog_dref(log); errno = r; - return twarn("Cannot allocate space for binlog %s", log->path); + twarn("Cannot allocate space for binlog %s", log->path); + return; } } #endif @@ -716,7 +742,10 @@ binlog_init(job binlog_jobs) /* Recover any jobs in old binlogs */ if (stat(binlog_dir, &sbuf) < 0) { - if (mkdir(binlog_dir, 0700) < 0) return twarn("%s", binlog_dir); + if (mkdir(binlog_dir, 0700) < 0) { + twarn("%s", binlog_dir); + return; + } } else if (!(sbuf.st_mode & S_IFDIR)) { twarnx("%s", binlog_dir); return; @@ -727,7 +756,10 @@ binlog_init(job binlog_jobs) if (binlog_index_min) { for (idx = binlog_index_min; idx <= binlog_index; idx++) { r = snprintf(path, PATH_MAX, "%s/binlog.%d", binlog_dir, idx); - if (r > PATH_MAX) return twarnx("path too long: %s", binlog_dir); + if (r > PATH_MAX) { + twarnx("path too long: %s", binlog_dir); + return; + } fd = open(path, O_RDONLY); @@ -748,7 +780,10 @@ binlog_init(job binlog_jobs) /* Set up for writing out new jobs */ n = ensure_free_space(1); - if (!n) return twarnx("error making first writable binlog"); + if (!n) { + twarnx("error making first writable binlog"); + return; + } current_binlog = newest_binlog; } diff --git a/conn.c b/conn.c index 32f5f169..1fc9cbbf 100644 --- a/conn.c +++ b/conn.c @@ -37,7 +37,8 @@ static unsigned int tot_conn_ct = 0; static conn conn_alloc() { - return conn_remove(pool.next) ? : malloc(sizeof(struct conn)); + conn x = conn_remove(pool.next); + return x ? x : malloc(sizeof(struct conn)); } static void @@ -226,7 +227,7 @@ soonest_job(conn c) if (soonest == NULL) { for (j = c->reserved_jobs.next; j != &c->reserved_jobs; j = j->next) { - if (j->deadline_at <= (soonest ? : j)->deadline_at) soonest = j; + if (j->deadline_at <= (soonest ? soonest : j)->deadline_at) soonest = j; } } c->soonest_job = soonest; diff --git a/ms.c b/ms.c index af93709b..9ac17224 100644 --- a/ms.c +++ b/ms.c @@ -35,7 +35,8 @@ static void grow(ms a) { void **nitems; - size_t ncap = (a->cap << 1) ? : 1; + size_t cap = (a->cap << 1); + size_t ncap = cap ? cap : 1; nitems = malloc(ncap * sizeof(void *)); if (!nitems) return; diff --git a/net.c b/net.c index 70c23471..da7dd504 100644 --- a/net.c +++ b/net.c @@ -88,7 +88,7 @@ unbrake(evh h) if (after_startup) twarnx("releasing the brakes"); after_startup = 1; - accept_handler = h ? : accept_handler; + accept_handler = h ? h : accept_handler; event_set(&listen_evq, listen_socket, EV_READ | EV_PERSIST, accept_handler, &listen_evq); diff --git a/pq.c b/pq.c index 290f41fb..0b840c15 100644 --- a/pq.c +++ b/pq.c @@ -47,7 +47,7 @@ static void pq_grow(pq q) { job *nheap; - unsigned int ncap = q->cap << 1 ? : 1; + unsigned int ncap = q->cap << 1 ? q->cap << 1 : 1; nheap = malloc(ncap * sizeof(job)); if (!nheap) return; diff --git a/prot.c b/prot.c index 4291d817..a1011e5a 100644 --- a/prot.c +++ b/prot.c @@ -283,7 +283,11 @@ reply(conn c, const char *line, int len, int state) if (!c) return; r = conn_update_evq(c, EV_WRITE | EV_PERSIST); - if (r == -1) return twarnx("conn_update_evq() failed"), conn_close(c); + if (r == -1) { + twarnx("conn_update_evq() failed"); + conn_close(c); + return; + } c->reply = line; c->reply_len = len; @@ -308,9 +312,12 @@ reply_line(conn c, int state, const char *fmt, ...) va_end(ap); /* Make sure the buffer was big enough. If not, we have a bug. */ - if (r >= LINE_BUF_SIZE) return reply_serr(c, MSG_INTERNAL_ERROR); + if (r >= LINE_BUF_SIZE) { + reply_serr(c, MSG_INTERNAL_ERROR); + return; + } - return reply(c, c->reply_buf, r, state); + reply(c, c->reply_buf, r, state); } static void @@ -320,7 +327,7 @@ reply_job(conn c, job j, const char *word) c->out_job = j; c->out_job_sent = 0; - return reply_line(c, STATE_SENDJOB, "%s %llu %u\r\n", + reply_line(c, STATE_SENDJOB, "%s %llu %u\r\n", word, j->id, j->body_size - 2); } @@ -356,7 +363,7 @@ reserve_job(conn c, job j) if (c->soonest_job && j->deadline_at < c->soonest_job->deadline_at) { c->soonest_job = j; } - return reply_job(c, j, MSG_RESERVED); + reply_job(c, j, MSG_RESERVED); } static job @@ -792,27 +799,41 @@ enqueue_incoming_job(conn c) /* check if the trailer is present and correct */ if (memcmp(j->body + j->body_size - 2, "\r\n", 2)) { job_free(j); - return reply_msg(c, MSG_EXPECTED_CRLF); + reply_msg(c, MSG_EXPECTED_CRLF); + return; } if (drain_mode) { job_free(j); - return reply_serr(c, MSG_DRAINING); + reply_serr(c, MSG_DRAINING); + return; } - if (j->reserved_binlog_space) return reply_serr(c, MSG_INTERNAL_ERROR); + if (j->reserved_binlog_space) { + reply_serr(c, MSG_INTERNAL_ERROR); + return; + } j->reserved_binlog_space = binlog_reserve_space_put(j); - if (!j->reserved_binlog_space) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (!j->reserved_binlog_space) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } /* we have a complete job, so let's stick it in the pqueue */ r = enqueue_job(j, j->delay, 1); - if (r < 0) return reply_serr(c, MSG_INTERNAL_ERROR); + if (r < 0) { + reply_serr(c, MSG_INTERNAL_ERROR); + return; + } op_ct[OP_PUT]++; /* stats */ global_stat.total_jobs_ct++; j->tube->stat.total_jobs_ct++; - if (r == 1) return reply_line(c, STATE_SENDWORD, MSG_INSERTED_FMT, j->id); + if (r == 1) { + reply_line(c, STATE_SENDWORD, MSG_INSERTED_FMT, j->id); + return; + } /* out of memory trying to grow the queue, so it gets buried */ bury_job(j, 0); @@ -955,7 +976,11 @@ wait_for_job(conn c, int timeout) /* this conn is waiting, but we want to know if they hang up */ r = conn_update_evq(c, EV_READ | EV_PERSIST); - if (r == -1) return twarnx("update events failed"), conn_close(c); + if (r == -1) { + twarnx("update events failed"); + conn_close(c); + return; + } } typedef int(*fmt_fn)(char *, size_t, void *); @@ -969,7 +994,10 @@ do_stats(conn c, fmt_fn fmt, void *data) stats_len = fmt(NULL, 0, data) + 16; c->out_job = allocate_job(stats_len); /* fake job to hold stats data */ - if (!c->out_job) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (!c->out_job) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } /* Mark this job as a copy so it can be appropriately freed later on */ c->out_job->state = JOB_STATE_COPY; @@ -978,7 +1006,10 @@ do_stats(conn c, fmt_fn fmt, void *data) r = fmt(c->out_job->body, stats_len, data); /* and set the actual body size */ c->out_job->body_size = r; - if (r > stats_len) return reply_serr(c, MSG_INTERNAL_ERROR); + if (r > stats_len) { + reply_serr(c, MSG_INTERNAL_ERROR); + return; + } c->out_job_sent = 0; return reply_line(c, STATE_SENDJOB, "OK %d\r\n", r - 2); @@ -999,7 +1030,10 @@ do_list_tubes(conn c, ms l) } c->out_job = allocate_job(resp_z); /* fake job to hold response data */ - if (!c->out_job) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (!c->out_job) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } /* now actually format the response */ buf = c->out_job->body; @@ -1012,7 +1046,7 @@ do_list_tubes(conn c, ms l) buf[1] = '\n'; c->out_job_sent = 0; - return reply_line(c, STATE_SENDJOB, "OK %d\r\n", resp_z - 2); + reply_line(c, STATE_SENDJOB, "OK %d\r\n", resp_z - 2); } static int @@ -1090,7 +1124,10 @@ maybe_enqueue_incoming_job(conn c) job j = c->in_job; /* do we have a complete job? */ - if (c->in_job_read == j->body_size) return enqueue_incoming_job(c); + if (c->in_job_read == j->body_size) { + enqueue_incoming_job(c); + return; + } /* otherwise we have incomplete data, so just keep waiting */ c->state = STATE_WANTDATA; @@ -1150,7 +1187,8 @@ dispatch_cmd(conn c) /* check for possible maliciousness */ if (strlen(c->cmd) != c->cmd_len - 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } type = which_cmd(c); @@ -1159,28 +1197,44 @@ dispatch_cmd(conn c) switch (type) { case OP_PUT: r = read_pri(&pri, c->cmd + 4, &delay_buf); - if (r) return reply_msg(c, MSG_BAD_FORMAT); + if (r) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } r = read_delay(&delay, delay_buf, &ttr_buf); - if (r) return reply_msg(c, MSG_BAD_FORMAT); + if (r) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } r = read_ttr(&ttr, ttr_buf, &size_buf); - if (r) return reply_msg(c, MSG_BAD_FORMAT); + if (r) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } errno = 0; body_size = strtoul(size_buf, &end_buf, 10); - if (errno) return reply_msg(c, MSG_BAD_FORMAT); + if (errno) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } if (body_size > job_data_size_limit) { - return reply_msg(c, MSG_JOB_TOO_BIG); + reply_msg(c, MSG_JOB_TOO_BIG); + return; } /* don't allow trailing garbage */ - if (end_buf[0] != '\0') return reply_msg(c, MSG_BAD_FORMAT); + if (end_buf[0] != '\0') { + reply_msg(c, MSG_BAD_FORMAT); + return; + } conn_set_producer(c); - c->in_job = make_job(pri, delay, ttr ? : 1, body_size + 2, c->use); + c->in_job = make_job(pri, delay, ttr ? ttr : 1, body_size + 2, c->use); /* OOM? */ if (!c->in_job) { @@ -1191,7 +1245,10 @@ dispatch_cmd(conn c) c->in_job_read = body_size + 2; fill_extra_data(c); - if (c->in_job_read == 0) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (c->in_job_read == 0) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } c->state = STATE_BITBUCKET; return; @@ -1206,46 +1263,61 @@ dispatch_cmd(conn c) case OP_PEEK_READY: /* don't allow trailing garbage */ if (c->cmd_len != CMD_PEEK_READY_LEN + 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } op_ct[type]++; j = job_copy(pq_peek(&c->use->ready)); - if (!j) return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + if (!j) { + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; + } reply_job(c, j, MSG_FOUND); break; case OP_PEEK_DELAYED: /* don't allow trailing garbage */ if (c->cmd_len != CMD_PEEK_DELAYED_LEN + 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } op_ct[type]++; j = job_copy(pq_peek(&c->use->delay)); - if (!j) return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + if (!j) { + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; + } reply_job(c, j, MSG_FOUND); break; case OP_PEEK_BURIED: /* don't allow trailing garbage */ if (c->cmd_len != CMD_PEEK_BURIED_LEN + 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } op_ct[type]++; j = job_copy(buried_job_p(c->use)? j = c->use->buried.next : NULL); - if (!j) return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + if (!j) { + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; + } reply_job(c, j, MSG_FOUND); break; case OP_PEEKJOB: errno = 0; id = strtoull(c->cmd + CMD_PEEKJOB_LEN, &end_buf, 10); - if (errno) return reply_msg(c, MSG_BAD_FORMAT); + if (errno) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; /* So, peek is annoying, because some other connection might free the @@ -1253,25 +1325,33 @@ dispatch_cmd(conn c) * then free the copy when it's done sending. */ j = job_copy(peek_job(id)); - if (!j) return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + if (!j) { + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; + } reply_job(c, j, MSG_FOUND); break; case OP_RESERVE_TIMEOUT: errno = 0; timeout = strtol(c->cmd + CMD_RESERVE_TIMEOUT_LEN, &end_buf, 10); - if (errno) return reply_msg(c, MSG_BAD_FORMAT); + if (errno) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } case OP_RESERVE: /* FALLTHROUGH */ /* don't allow trailing garbage */ if (type == OP_RESERVE && c->cmd_len != CMD_RESERVE_LEN + 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } op_ct[type]++; conn_set_worker(c); if (conn_has_close_deadline(c) && !conn_ready(c)) { - return reply_msg(c, MSG_DEADLINE_SOON); + reply_msg(c, MSG_DEADLINE_SOON); + return; } /* try to get a new job for this guy */ @@ -1281,45 +1361,75 @@ dispatch_cmd(conn c) case OP_DELETE: errno = 0; id = strtoull(c->cmd + CMD_DELETE_LEN, &end_buf, 10); - if (errno) return reply_msg(c, MSG_BAD_FORMAT); + if (errno) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; j = job_find(id); - j = remove_reserved_job(c, j) ? : - remove_ready_job(j) ? : - remove_buried_job(j); + { + job res_j = remove_reserved_job(c, j); + if (res_j) { + j = res_j; + } else { + job red_j = remove_ready_job(j); + j = red_j ? red_j : remove_buried_job(j); + } + } - if (!j) return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + if (!j) { + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; + } j->state = JOB_STATE_INVALID; r = binlog_write_job(j); job_free(j); - if (!r) return reply_serr(c, MSG_INTERNAL_ERROR); + if (!r) { + reply_serr(c, MSG_INTERNAL_ERROR); + return; + } reply(c, MSG_DELETED, MSG_DELETED_LEN, STATE_SENDWORD); break; case OP_RELEASE: errno = 0; id = strtoull(c->cmd + CMD_RELEASE_LEN, &pri_buf, 10); - if (errno) return reply_msg(c, MSG_BAD_FORMAT); + if (errno) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } r = read_pri(&pri, pri_buf, &delay_buf); - if (r) return reply_msg(c, MSG_BAD_FORMAT); + if (r) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } r = read_delay(&delay, delay_buf, NULL); - if (r) return reply_msg(c, MSG_BAD_FORMAT); + if (r) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; j = remove_reserved_job(c, job_find(id)); - if (!j) return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + if (!j) { + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; + } /* We want to update the delay deadline on disk, so reserve space for * that. */ if (delay) { z = binlog_reserve_space_update(j); - if (!z) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (!z) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } j->reserved_binlog_space += z; } @@ -1328,9 +1438,13 @@ dispatch_cmd(conn c) j->release_ct++; r = enqueue_job(j, delay, !!delay); - if (r < 0) return reply_serr(c, MSG_INTERNAL_ERROR); + if (r < 0) { + reply_serr(c, MSG_INTERNAL_ERROR); + return; + } if (r == 1) { - return reply(c, MSG_RELEASED, MSG_RELEASED_LEN, STATE_SENDWORD); + reply(c, MSG_RELEASED, MSG_RELEASED_LEN, STATE_SENDWORD); + return; } /* out of memory trying to grow the queue, so it gets buried */ @@ -1340,38 +1454,59 @@ dispatch_cmd(conn c) case OP_BURY: errno = 0; id = strtoull(c->cmd + CMD_BURY_LEN, &pri_buf, 10); - if (errno) return reply_msg(c, MSG_BAD_FORMAT); + if (errno) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } r = read_pri(&pri, pri_buf, NULL); - if (r) return reply_msg(c, MSG_BAD_FORMAT); + if (r) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; j = remove_reserved_job(c, job_find(id)); - if (!j) return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + if (!j) { + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; + } j->pri = pri; r = bury_job(j, 1); - if (!r) return reply_serr(c, MSG_INTERNAL_ERROR); + if (!r) { + reply_serr(c, MSG_INTERNAL_ERROR); + return; + } reply(c, MSG_BURIED, MSG_BURIED_LEN, STATE_SENDWORD); break; case OP_KICK: errno = 0; count = strtoul(c->cmd + CMD_KICK_LEN, &end_buf, 10); if (end_buf == c->cmd + CMD_KICK_LEN) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; + } + if (errno) { + reply_msg(c, MSG_BAD_FORMAT); + return; } - if (errno) return reply_msg(c, MSG_BAD_FORMAT); op_ct[type]++; i = kick_jobs(c->use, count); - return reply_line(c, STATE_SENDWORD, "KICKED %u\r\n", i); + reply_line(c, STATE_SENDWORD, "KICKED %u\r\n", i); + return; case OP_TOUCH: errno = 0; id = strtoull(c->cmd + CMD_TOUCH_LEN, &end_buf, 10); - if (errno) return twarn("strtoull"), reply_msg(c, MSG_BAD_FORMAT); + if (errno) { + twarn("strtoull"); + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; @@ -1380,13 +1515,15 @@ dispatch_cmd(conn c) if (j) { reply(c, MSG_TOUCHED, MSG_TOUCHED_LEN, STATE_SENDWORD); } else { - return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; } break; case OP_STATS: /* don't allow trailing garbage */ if (c->cmd_len != CMD_STATS_LEN + 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } op_ct[type]++; @@ -1396,24 +1533,39 @@ dispatch_cmd(conn c) case OP_JOBSTATS: errno = 0; id = strtoull(c->cmd + CMD_JOBSTATS_LEN, &end_buf, 10); - if (errno) return reply_msg(c, MSG_BAD_FORMAT); + if (errno) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; j = peek_job(id); - if (!j) return reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + if (!j) { + reply(c, MSG_NOTFOUND, MSG_NOTFOUND_LEN, STATE_SENDWORD); + return; + } - if (!j->tube) return reply_serr(c, MSG_INTERNAL_ERROR); + if (!j->tube) { + reply_serr(c, MSG_INTERNAL_ERROR); + return; + } do_stats(c, (fmt_fn) fmt_job_stats, j); break; case OP_STATS_TUBE: name = c->cmd + CMD_STATS_TUBE_LEN; - if (!name_is_ok(name, 200)) return reply_msg(c, MSG_BAD_FORMAT); + if (!name_is_ok(name, 200)) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; t = tube_find(name); - if (!t) return reply_msg(c, MSG_NOTFOUND); + if (!t) { + reply_msg(c, MSG_NOTFOUND); + return; + } do_stats(c, (fmt_fn) fmt_stats_tube, t); t = NULL; @@ -1421,7 +1573,8 @@ dispatch_cmd(conn c) case OP_LIST_TUBES: /* don't allow trailing garbage */ if (c->cmd_len != CMD_LIST_TUBES_LEN + 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } op_ct[type]++; @@ -1430,7 +1583,8 @@ dispatch_cmd(conn c) case OP_LIST_TUBE_USED: /* don't allow trailing garbage */ if (c->cmd_len != CMD_LIST_TUBE_USED_LEN + 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } op_ct[type]++; @@ -1439,7 +1593,8 @@ dispatch_cmd(conn c) case OP_LIST_TUBES_WATCHED: /* don't allow trailing garbage */ if (c->cmd_len != CMD_LIST_TUBES_WATCHED_LEN + 2) { - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } op_ct[type]++; @@ -1447,11 +1602,17 @@ dispatch_cmd(conn c) break; case OP_USE: name = c->cmd + CMD_USE_LEN; - if (!name_is_ok(name, 200)) return reply_msg(c, MSG_BAD_FORMAT); + if (!name_is_ok(name, 200)) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; TUBE_ASSIGN(t, tube_find_or_make(name)); - if (!t) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (!t) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } c->use->using_ct--; TUBE_ASSIGN(c->use, t); @@ -1462,22 +1623,34 @@ dispatch_cmd(conn c) break; case OP_WATCH: name = c->cmd + CMD_WATCH_LEN; - if (!name_is_ok(name, 200)) return reply_msg(c, MSG_BAD_FORMAT); + if (!name_is_ok(name, 200)) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; TUBE_ASSIGN(t, tube_find_or_make(name)); - if (!t) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (!t) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } r = 1; if (!ms_contains(&c->watch, t)) r = ms_append(&c->watch, t); TUBE_ASSIGN(t, NULL); - if (!r) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (!r) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } reply_line(c, STATE_SENDWORD, "WATCHING %d\r\n", c->watch.used); break; case OP_IGNORE: name = c->cmd + CMD_IGNORE_LEN; - if (!name_is_ok(name, 200)) return reply_msg(c, MSG_BAD_FORMAT); + if (!name_is_ok(name, 200)) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } op_ct[type]++; t = NULL; @@ -1487,7 +1660,10 @@ dispatch_cmd(conn c) t = NULL; } - if (t && c->watch.used < 2) return reply_msg(c, MSG_NOT_IGNORED); + if (t && c->watch.used < 2) { + reply_msg(c, MSG_NOT_IGNORED); + return; + } if (t) ms_remove(&c->watch, t); /* may free t if refcount => 0 */ t = NULL; @@ -1501,14 +1677,23 @@ dispatch_cmd(conn c) op_ct[type]++; r = read_tube_name(&name, c->cmd + CMD_PAUSE_TUBE_LEN, &delay_buf); - if (r) return reply_msg(c, MSG_BAD_FORMAT); + if (r) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } r = read_delay(&delay, delay_buf, NULL); - if (r) return reply_msg(c, MSG_BAD_FORMAT); + if (r) { + reply_msg(c, MSG_BAD_FORMAT); + return; + } *delay_buf = '\0'; t = tube_find(name); - if (!t) return reply_msg(c, MSG_NOTFOUND); + if (!t) { + reply_msg(c, MSG_NOTFOUND); + return; + } t->deadline_at = now_usec() + delay; t->pause = delay; @@ -1518,7 +1703,8 @@ dispatch_cmd(conn c) reply_line(c, STATE_SENDWORD, "PAUSED\r\n"); break; default: - return reply_msg(c, MSG_UNKNOWN_COMMAND); + reply_msg(c, MSG_UNKNOWN_COMMAND); + return; } } @@ -1557,16 +1743,22 @@ h_conn_timeout(conn c) r = enqueue_job(remove_this_reserved_job(c, j), 0, 0); if (r < 1) bury_job(j, 0); /* out of memory, so bury it */ r = conn_update_evq(c, c->evq.ev_events); - if (r == -1) return twarnx("conn_update_evq() failed"), conn_close(c); + if (r == -1) { + twarnx("conn_update_evq() failed"); + conn_close(c); + return; + } } if (should_timeout) { dprintf("conn_waiting(%p) = %d\n", c, conn_waiting(c)); - return reply_msg(remove_waiting_conn(c), MSG_DEADLINE_SOON); + reply_msg(remove_waiting_conn(c), MSG_DEADLINE_SOON); + return; } else if (conn_waiting(c) && c->pending_timeout >= 0) { dprintf("conn_waiting(%p) = %d\n", c, conn_waiting(c)); c->pending_timeout = -1; - return reply_msg(remove_waiting_conn(c), MSG_TIMED_OUT); + reply_msg(remove_waiting_conn(c), MSG_TIMED_OUT); + return; } } @@ -1589,7 +1781,11 @@ reset_conn(conn c) int r; r = conn_update_evq(c, EV_READ | EV_PERSIST); - if (r == -1) return twarnx("update events failed"), conn_close(c); + if (r == -1) { + twarnx("update events failed"); + conn_close(c); + return; + } /* was this a peek or stats command? */ if (c->out_job && c->out_job->state == JOB_STATE_COPY) job_free(c->out_job); @@ -1609,22 +1805,32 @@ h_conn_data(conn c) switch (c->state) { case STATE_WANTCOMMAND: r = read(c->fd, c->cmd + c->cmd_read, LINE_BUF_SIZE - c->cmd_read); - if (r == -1) return check_err(c, "read()"); - if (r == 0) return conn_close(c); /* the client hung up */ + if (r == -1) { + check_err(c, "read()"); + return; + } + if (r == 0) { + conn_close(c); /* the client hung up */ + return; + } c->cmd_read += r; /* we got some bytes */ c->cmd_len = cmd_len(c); /* find the EOL */ /* yay, complete command line */ - if (c->cmd_len) return do_cmd(c); + if (c->cmd_len) { + do_cmd(c); + return; + } /* c->cmd_read > LINE_BUF_SIZE can't happen */ /* command line too long? */ if (c->cmd_read == LINE_BUF_SIZE) { c->cmd_read = 0; /* discard the input so far */ - return reply_msg(c, MSG_BAD_FORMAT); + reply_msg(c, MSG_BAD_FORMAT); + return; } /* otherwise we have an incomplete line, so just keep waiting */ @@ -1634,21 +1840,36 @@ h_conn_data(conn c) * counts the bytes that remain to be thrown away. */ to_read = min(c->in_job_read, BUCKET_BUF_SIZE); r = read(c->fd, bucket, to_read); - if (r == -1) return check_err(c, "read()"); - if (r == 0) return conn_close(c); /* the client hung up */ + if (r == -1) { + check_err(c, "read()"); + return; + } + if (r == 0) { + conn_close(c); /* the client hung up */ + return; + } c->in_job_read -= r; /* we got some bytes */ /* (c->in_job_read < 0) can't happen */ - if (c->in_job_read == 0) return reply_serr(c, MSG_OUT_OF_MEMORY); + if (c->in_job_read == 0) { + reply_serr(c, MSG_OUT_OF_MEMORY); + return; + } break; case STATE_WANTDATA: j = c->in_job; r = read(c->fd, j->body + c->in_job_read, j->body_size -c->in_job_read); - if (r == -1) return check_err(c, "read()"); - if (r == 0) return conn_close(c); /* the client hung up */ + if (r == -1) { + check_err(c, "read()"); + return; + } + if (r == 0) { + conn_close(c); /* the client hung up */ + return; + } c->in_job_read += r; /* we got some bytes */ @@ -1658,14 +1879,23 @@ h_conn_data(conn c) break; case STATE_SENDWORD: r= write(c->fd, c->reply + c->reply_sent, c->reply_len - c->reply_sent); - if (r == -1) return check_err(c, "write()"); - if (r == 0) return conn_close(c); /* the client hung up */ + if (r == -1) { + check_err(c, "write()"); + return; + } + if (r == 0) { + conn_close(c); /* the client hung up */ + return; + } c->reply_sent += r; /* we got some bytes */ /* (c->reply_sent > c->reply_len) can't happen */ - if (c->reply_sent == c->reply_len) return reset_conn(c); + if (c->reply_sent == c->reply_len) { + reset_conn(c); + return; + } /* otherwise we sent an incomplete reply, so just keep waiting */ break; @@ -1678,8 +1908,14 @@ h_conn_data(conn c) iov[1].iov_len = j->body_size - c->out_job_sent; r = writev(c->fd, iov, 2); - if (r == -1) return check_err(c, "writev()"); - if (r == 0) return conn_close(c); /* the client hung up */ + if (r == -1) { + check_err(c, "writev()"); + return; + } + if (r == 0) { + conn_close(c); /* the client hung up */ + return; + } /* update the sent values */ c->reply_sent += r; @@ -1691,7 +1927,10 @@ h_conn_data(conn c) /* (c->out_job_sent > j->body_size) can't happen */ /* are we done? */ - if (c->out_job_sent == j->body_size) return reset_conn(c); + if (c->out_job_sent == j->body_size) { + reset_conn(c); + return; + } /* otherwise we sent incomplete data, so just keep waiting */ break; @@ -1700,8 +1939,14 @@ h_conn_data(conn c) if (LINE_BUF_SIZE - c->cmd_read < 1) break; r = read(c->fd, c->cmd + c->cmd_read, LINE_BUF_SIZE - c->cmd_read); - if (r == -1) return check_err(c, "read()"); - if (r == 0) return conn_close(c); /* the client hung up */ + if (r == -1) { + check_err(c, "read()"); + return; + } + if (r == 0) { + conn_close(c); /* the client hung up */ + return; + } c->cmd_read += r; /* we got some bytes */ } } @@ -1715,7 +1960,8 @@ h_conn(const int fd, const short which, conn c) if (fd != c->fd) { twarnx("Argh! event fd doesn't match conn fd."); close(fd); - return conn_close(c); + conn_close(c); + return; } switch (which) { @@ -1773,7 +2019,10 @@ h_accept(const int fd, const short which, struct event *ev) socklen_t addrlen; struct sockaddr addr; - if (which == EV_TIMEOUT) return h_delay(); + if (which == EV_TIMEOUT) { + h_delay(); + return; + } addrlen = sizeof addr; cfd = accept(fd, &addr, &addrlen); @@ -1784,17 +2033,37 @@ h_accept(const int fd, const short which, struct event *ev) } flags = fcntl(cfd, F_GETFL, 0); - if (flags < 0) return twarn("getting flags"), close(cfd), v(); + if (flags < 0) { + twarn("getting flags"); + close(cfd); + v(); + return; + } r = fcntl(cfd, F_SETFL, flags | O_NONBLOCK); - if (r < 0) return twarn("setting O_NONBLOCK"), close(cfd), v(); + if (r < 0) { + twarn("setting O_NONBLOCK"); + close(cfd); + v(); + return; + } c = make_conn(cfd, STATE_WANTCOMMAND, default_tube, default_tube); - if (!c) return twarnx("make_conn() failed"), close(cfd), brake(); + if (!c) { + twarnx("make_conn() failed"); + close(cfd); + brake(); + return; + } dprintf("accepted conn, fd=%d\n", cfd); r = conn_set_evq(c, EV_READ | EV_PERSIST, (evh) h_conn); - if (r == -1) return twarnx("conn_set_evq() failed"), close(cfd), brake(); + if (r == -1) { + twarnx("conn_set_evq() failed"); + close(cfd); + brake(); + return; + } } void diff --git a/tube.c b/tube.c index 6d0fe4f8..d284e939 100644 --- a/tube.c +++ b/tube.c @@ -68,7 +68,10 @@ void tube_dref(tube t) { if (!t) return; - if (t->refs < 1) return twarnx("refs is zero for tube: %s", t->name); + if (t->refs < 1) { + twarnx("refs is zero for tube: %s", t->name); + return; + } --t->refs; if (t->refs < 1) tube_free(t); @@ -114,6 +117,7 @@ tube_find(const char *name) tube tube_find_or_make(const char *name) { - return tube_find(name) ? : make_and_insert_tube(name); + tube t = tube_find(name); + return t ? t : make_and_insert_tube(name); } diff --git a/util.h b/util.h index c6865fb0..0c94ee29 100644 --- a/util.h +++ b/util.h @@ -28,7 +28,9 @@ #include #include -#define min(a,b) ((a)<(b)?(a):(b)) +#ifndef min + #define min(a,b) ((a)<(b)?(a):(b)) +#endif void v(); diff --git a/win32/inttypes.h b/win32/inttypes.h new file mode 100644 index 00000000..4b3828a2 --- /dev/null +++ b/win32/inttypes.h @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/win32/stdint.h b/win32/stdint.h new file mode 100644 index 00000000..d02608a5 --- /dev/null +++ b/win32/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ]