void local_notify_all_1(int s) { int rc; struct neighbour *neigh; const char *header = "BABEL 0.0\n"; struct xroute_stream *xroutes; struct route_stream *routes; rc = write_timeout(s, header, strlen(header)); if(rc < 0) goto fail; local_notify_self_1(s); FOR_ALL_NEIGHBOURS(neigh) { local_notify_neighbour_1(s, neigh, LOCAL_ADD); } xroutes = xroute_stream(); if(xroutes) { while(1) { struct xroute *xroute = xroute_stream_next(xroutes); if(xroute == NULL) break; local_notify_xroute_1(s, xroute, LOCAL_ADD); } xroute_stream_done(xroutes); } routes = route_stream(0); if(routes) { while(1) { struct babel_route *route = route_stream_next(routes); if(route == NULL) break; local_notify_route_1(s, route, LOCAL_ADD); } route_stream_done(routes); } rc = write_timeout(s, "done\n", 5); if(rc < 0) goto fail; return; fail: shutdown(s, 1); return; }
void local_notify_route(struct route *route, int kind) { char buf[512]; int rc; if(local_socket < 0) return; rc = snprintf(buf, 512, "%s route %s-%lx prefix %s installed %s " "id %s metric %d refmetric %d via %s if %s\n", local_kind(kind), format_prefix(route->src->prefix, route->src->plen), (unsigned long)route->neigh, format_prefix(route->src->prefix, route->src->plen), route->installed ? "yes" : "no", format_eui64(route->src->id), route_metric(route), route->refmetric, format_address(route->neigh->address), route->neigh->network->ifname); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(local_socket, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(local_socket, 1); return; }
static void local_notify_self_1(int s) { char buf[512]; char host[64]; int rc; rc = gethostname(host, 64); if(rc < 0) strncpy(host, "alamakota", 64); rc = snprintf(buf, 512, "add self %.64s id %s\n", host, format_eui64(myid)); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(s, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(s, 1); return; }
static void local_notify_xroute_1(int s, struct xroute *xroute, int kind) { char buf[512]; int rc; const char *dst_prefix = format_prefix(xroute->prefix, xroute->plen); const char *src_prefix = format_prefix(xroute->src_prefix, xroute->src_plen); rc = snprintf(buf, 512, "%s xroute %s-%s prefix %s from %s metric %d\n", local_kind(kind), dst_prefix, src_prefix, dst_prefix, src_prefix, xroute->metric); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(s, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(s, 1); return; }
static void local_notify_route_1(int s, struct babel_route *route, int kind) { char buf[512]; int rc; const char *dst_prefix = format_prefix(route->src->prefix, route->src->plen); const char *src_prefix = format_prefix(route->src->src_prefix, route->src->src_plen); rc = snprintf(buf, 512, "%s route %s-%lx-%s prefix %s from %s installed %s " "id %s metric %d refmetric %d via %s if %s\n", local_kind(kind), dst_prefix, (unsigned long)route->neigh, src_prefix, dst_prefix, src_prefix, route->installed ? "yes" : "no", format_eui64(route->src->id), route_metric(route), route->refmetric, format_address(route->neigh->address), route->neigh->ifp->name); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(s, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(s, 1); return; }
ssize_t writen(int fp,const void *buf,size_t count) { int ret = 0; //这里按照write的调用方式来封转 size_t nleft = count;//剩余需要发送的字节数 ssize_t nwrite;//已经成功发送的字节数 char *bufp = (char *)buf; while(nleft > 0) { //进行超时判断 if((ret = write_timeout(fp,5)) < 0) { return ret; } if((nwrite = write(fp,bufp,nleft)) < 0) { if(EINTR == errno) {//这个是被信号中断不认为错 continue; } //其它错误都直接返回失败 return nwrite; } else if(0 == nwrite) {//说明写入了0个字节等于什么也没发送 continue; } //发送了数据 bufp += nwrite; nleft -= nwrite; } return count;//必须是完全发送完否则都算错 }
void local_dump() { int i, rc; struct neighbour *neigh; const char *header = "BABEL 0.0\n"; if(local_socket < 0) return; rc = write_timeout(local_socket, header, strlen(header)); if(rc < 0) goto fail; local_notify_self(); FOR_ALL_NEIGHBOURS(neigh) { local_notify_neighbour(neigh, LOCAL_ADD); } for(i = 0; i < numxroutes; i++) local_notify_xroute(&xroutes[i], LOCAL_ADD); for(i = 0; i < numroutes; i++) local_notify_route(&routes[i], LOCAL_ADD); return; fail: shutdown(local_socket, 1); return; }
void local_notify_xroute(struct xroute *xroute, int kind) { char buf[512]; int rc; if(local_socket < 0) return; rc = snprintf(buf, 512, "%s xroute %s prefix %s metric %d\n", local_kind(kind), format_prefix(xroute->prefix, xroute->plen), format_prefix(xroute->prefix, xroute->plen), xroute->metric); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(local_socket, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(local_socket, 1); return; }
void local_notify_neighbour(struct neighbour *neigh, int kind) { char buf[512]; int rc; if(local_socket < 0) return; rc = snprintf(buf, 512, "%s neighbour %lx address %s " "if %s reach %04x rxcost %d txcost %d cost %d\n", local_kind(kind), /* Neighbours never move around in memory , so we can use the address as a unique identifier. */ (unsigned long int)neigh, format_address(neigh->address), neigh->network->ifname, neigh->reach, neighbour_rxcost(neigh), neighbour_txcost(neigh), neighbour_cost(neigh)); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(local_socket, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(local_socket, 1); return; }
int sckClient_send(void *handle, unsigned char *data, int datalen) { int ret = 0; SckHandle *tmp = handle; ret = write_timeout(tmp->sockfd, tmp->sendtime); printf("sckClient_send() write_timeout ret=%d\n", ret); if(ret == 0){ int netDataLen = htonl(datalen); char *buf = malloc(4+datalen); if(buf == NULL){ ret = SCK_ERRMALLOC; printf("sckClient_send() err: %d\n", ret); return ret; } memcpy(buf, &netDataLen, 4); memcpy(buf+4, data, datalen); int writenLen = writen(tmp->sockfd, buf, datalen + 4); if(writenLen < datalen + 4){ if(buf != NULL){ free(buf); buf = NULL; return writenLen; } } if(buf != NULL){ free(buf); buf = NULL; } return writenLen; } if(ret < 0) { if(ret == -1 && errno == ETIMEDOUT) { ret = SCK_ERRTIMEOUT; printf("func send() err: %d\n", ret); return ret; } return ret; } return ret; }
static void local_notify_neighbour_1(struct local_socket *s, struct neighbour *neigh, int kind) { char buf[512], rttbuf[64]; int rc; rttbuf[0] = '\0'; if(valid_rtt(neigh)) { rc = snprintf(rttbuf, 64, " rtt %s rttcost %d", format_thousands(neigh->rtt), neighbour_rttcost(neigh)); if(rc < 0 || rc >= 64) rttbuf[0] = '\0'; } rc = snprintf(buf, 512, "%s neighbour %lx address %s " "if %s reach %04x rxcost %d txcost %d%s cost %d\n", local_kind(kind), /* Neighbours never move around in memory , so we can use the address as a unique identifier. */ (unsigned long int)neigh, format_address(neigh->address), neigh->ifp->name, neigh->reach, neighbour_rxcost(neigh), neighbour_txcost(neigh), rttbuf, neighbour_cost(neigh)); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(s->fd, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(s->fd, 1); return; }
int sckServer_send(int connfd, unsigned char *data, int datalen, int timeout){ int ret = 0; ret = write_timeout(connfd, timeout); if(ret == 0){ int netDataLen = htonl(datalen); char *buf = malloc(4+datalen); if(buf == NULL){ ret = SCK_ERRMALLOC; printf("sckServer_send() err: %d\n", ret); return ret; } memcpy(buf, &netDataLen, 4); memcpy(buf+4, data, datalen); int writenLen = writen(connfd, buf, datalen + 4); if(writenLen < datalen + 4){ if(buf != NULL){ free(buf); buf = NULL; return writenLen; } } if(buf != NULL){ free(buf); buf = NULL; } return writenLen; } if(ret < 0) { if(ret == -1 && errno == ETIMEDOUT) { ret = SCK_ERRTIMEOUT; printf("func send() err: %d\n", ret); return ret; } return ret; } return ret; }
int local_header(struct local_socket *s) { char buf[512], host[64]; int rc; rc = gethostname(host, 64); if(rc < 0) strncpy(host, "alamakota", 64); rc = snprintf(buf, 512, "BABEL 1.0\nversion %s\nhost %s\nmy-id %s\nok\n", BABELD_VERSION, host, format_eui64(myid)); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(s->fd, buf, rc); if(rc < 0) goto fail; return 1; fail: shutdown(s->fd, 1); return -1; }
void local_notify_self() { char buf[512]; int rc; if(local_socket < 0) return; rc = snprintf(buf, 512, "add self alamakota id %s\n", format_eui64(myid)); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(local_socket, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(local_socket, 1); return; }
static void local_notify_interface_1(struct local_socket *s, struct interface *ifp, int kind) { char buf[512], v4[INET_ADDRSTRLEN]; int rc; int up; up = if_up(ifp); if(up && ifp->ipv4) inet_ntop(AF_INET, ifp->ipv4, v4, INET_ADDRSTRLEN); else v4[0] = '\0'; if(up) rc = snprintf(buf, 512, "%s interface %s up true%s%s%s%s\n", local_kind(kind), ifp->name, ifp->ll ? " ipv6 " : "", ifp->ll ? format_address(*ifp->ll) : "", v4[0] ? " ipv4 " : "", v4); else rc = snprintf(buf, 512, "%s interface %s up false\n", local_kind(kind), ifp->name); if(rc < 0 || rc >= 512) goto fail; rc = write_timeout(s->fd, buf, rc); if(rc < 0) goto fail; return; fail: shutdown(s->fd, 1); return; }
static int write_mount_timeout(FILE *f, const char *where, const char *opts) { return write_timeout(f, where, opts, "x-systemd.mount-timeout\0", "TimeoutSec"); }
static int write_idle_timeout(FILE *f, const char *where, const char *opts) { return write_timeout(f, where, opts, "x-systemd.idle-timeout\0", "TimeoutIdleSec"); }
int main(int ac, char **av) { const char * const fifoname = "./fio.fifo"; const char * const filename = "./fio.file"; const mode_t mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; FILE *file; char line[BUFSIZ]; const int lock = 1; int errors = 0; int fd, wfd; if (ac == 2 && !strcmp(av[1], "help")) { printf("usage: %s\n", *av); return EXIT_SUCCESS; } printf("Testing: %s\n", "fio"); umask(0); if ((fd = fifo_open(fifoname, mode, lock, &wfd)) == -1) { ++errors, printf("Test1: fifo_open(\"%s\", %d, %d) failed (%s)\n", fifoname, (int)mode, lock, strerror(errno)); #ifndef HAVE_FCNTL_THAT_CAN_LOCK_FIFOS printf("\n Can your system lock fifos?\n\n"); #endif } else { if ((fcntl_lock(fd, F_SETLK, F_WRLCK, SEEK_SET, 0, 0)) != -1) ++errors, printf("Test2: fcntl_lock(wrlock) failed\n"); /* Should really test that the following non-blocking changes do occur */ if (nonblock_on(fd) == -1) ++errors, printf("Test3: nonblock_on() failed (%s)\n", strerror(errno)); if (nonblock_off(fd) == -1) ++errors, printf("Test4: nonblock_off() failed (%s)\n", strerror(errno)); if (fcntl_set_flag(fd, O_NONBLOCK) == -1) ++errors, printf("Test5: fcntl_set_flag() failed (%s)\n", strerror(errno)); if (fcntl_clear_flag(fd, O_NONBLOCK) == -1) ++errors, printf("Test6: fcntl_clear_flag() failed (%s)\n", strerror(errno)); close(fd); close(wfd); unlink(fifoname); } #define CHECK_FGETLINE(i, size, expected) \ if ((expected) && !fgetline(line, (size), file)) \ ++errors, printf("Test%d: fgetline() failed\n", (i)); \ else if ((expected) && strcmp(line, ((expected) ? (expected) : ""))) \ ++errors, printf("Test%d: fgetline() read \"%s\", not \"%s\"\n", (i), line, (expected ? expected : "(null)")); #define TEST_FGETLINE(i, buf, size, contents, line1, line2, line3) \ if (!(file = fopen(filename, "wb"))) \ ++errors, printf("Test%d: failed to run test: failed to create test file\n", (i)); \ else \ { \ if (fwrite((contents), 1, strlen(contents), file) != strlen(contents)) \ ++errors, printf("Test%d: failed to run test: failed to write to test file\n", (i)); \ else \ { \ fclose(file); \ if (!(file = fopen(filename, "r"))) \ ++errors, printf("Test%d: failed to run test: failed to open test file for reading\n", (i)); \ else \ { \ CHECK_FGETLINE((i), (size), (line1)) \ CHECK_FGETLINE((i), (size), (line2)) \ CHECK_FGETLINE((i), (size), (line3)) \ if (fgetline(buf, BUFSIZ, file)) \ ++errors, printf("Test%d: fgetline() failed to return NULL at end of file\n", (i)); \ } \ } \ fclose(file); \ unlink(filename); \ } TEST_FGETLINE(7, line, BUFSIZ, "abc\ndef\r\nghi\r", "abc\n", "def\n", "ghi\n") TEST_FGETLINE(8, line, BUFSIZ, "abc\rdef\nghi\r\n", "abc\n", "def\n", "ghi\n") TEST_FGETLINE(9, line, BUFSIZ, "abc\r\ndef\rghi\n", "abc\n", "def\n", "ghi\n") TEST_FGETLINE(10, line, BUFSIZ, "abc\ndef\rghi", "abc\n", "def\n", "ghi") TEST_FGETLINE(11, line, BUFSIZ, "", (char *)NULL, (char *)NULL, (char *)NULL) TEST_FGETLINE(12, line, 5, "abc", "abc", (char *)NULL, (char *)NULL) TEST_FGETLINE(13, line, 5, "abc\n", "abc\n", (char *)NULL, (char *)NULL) TEST_FGETLINE(14, line, 5, "abc\r\n", "abc\n", (char *)NULL, (char *)NULL) TEST_FGETLINE(15, line, 5, "abc\r", "abc\n", (char *)NULL, (char *)NULL) TEST_FGETLINE(16, line, 3, "abc\r", "ab", "c\n", (char *)NULL) TEST_FGETLINE(17, NULL, 0, "abc\r", (char *)NULL, (char *)NULL, (char *)NULL) /* Test read_timeout() and write_timeout() */ if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK, S_IRUSR | S_IWUSR)) == -1) ++errors, printf("Test19: failed to create %s (%s)\n", filename, strerror(errno)); else { char buf[12] = "0123456789\n"; if (write_timeout(fd, 1, 0) == -1) ++errors, printf("Test18: write_timeout(fd, 1, 0) failed (%s)\n", strerror(errno)); else if (write(fd, buf, 11) != 11) ++errors, printf("Test18: write(fd, \"0123456789\\n\", 11) failed (%s)\n", strerror(errno)); else { close(fd); if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) == -1) ++errors, printf("Test19: failed to open %s for reading (%s)\n", filename, strerror(errno)); else if (read_timeout(fd, 1, 0) == -1) ++errors, printf("Test19: read_timeout(fd, 1, 0) failed (%s)\n", strerror(errno)); else if (read(fd, buf, 11) != 11) ++errors, printf("Test19: read(fd) failed (%s)\n", strerror(errno)); } close(fd); } unlink(filename); /* Test error handling */ #define TEST_ERR(i, func) \ if ((func) != -1) \ ++errors, printf("Test%d: %s failed to return -1\n", (i), (#func)); \ else if (errno != EINVAL) \ ++errors, printf("Test%d: %s failed (errno = %s, not %s)\n", (i), (#func), strerror(errno), strerror(EINVAL)); TEST_ERR(20, read_timeout(-1, 0, 0)) TEST_ERR(21, read_timeout(0, -1, 0)) TEST_ERR(22, read_timeout(0, 0, -1)) TEST_ERR(23, write_timeout(-1, 0, 0)) TEST_ERR(24, write_timeout(0, -1, 0)) TEST_ERR(25, write_timeout(0, 0, -1)) TEST_ERR(26, rw_timeout(-1, 0, 0)) TEST_ERR(27, rw_timeout(0, -1, 0)) TEST_ERR(28, rw_timeout(0, 0, -1)) TEST_ERR(29, nap(-1, 0)) TEST_ERR(30, nap(0, -1)) if (errors) printf("%d/30 tests failed\n", errors); else printf("All tests passed\n"); #ifndef HAVE_FCNTL_THAT_CAN_LOCK_FIFOS printf("\n"); printf(" Note: Some systems (e.g. FreeBSD) can't lock fifos so fifo_open()\n"); printf(" can't guarantee a unique reader.\n"); #endif return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE; }
int local_read(struct local_socket *s) { int rc; char *eol; char reply[100] = "ok\n"; const char *message = NULL; if(s->buf == NULL) s->buf = malloc(LOCAL_BUFSIZE); if(s->buf == NULL) return -1; if(s->n >= LOCAL_BUFSIZE) { errno = ENOSPC; goto fail; } rc = read(s->fd, s->buf + s->n, LOCAL_BUFSIZE - s->n); if(rc <= 0) return rc; s->n += rc; eol = memchr(s->buf, '\n', s->n); if(eol == NULL) return 1; rc = parse_config_from_string(s->buf, eol + 1 - s->buf, &message); switch(rc) { case CONFIG_ACTION_DONE: break; case CONFIG_ACTION_QUIT: shutdown(s->fd, 1); reply[0] = '\0'; break; case CONFIG_ACTION_DUMP: local_notify_all_1(s); break; case CONFIG_ACTION_MONITOR: local_notify_all_1(s); s->monitor = 1; break; case CONFIG_ACTION_UNMONITOR: s->monitor = 0; break; case CONFIG_ACTION_NO: snprintf(reply, sizeof(reply), "no%s%s\n", message ? " " : "", message ? message : ""); break; default: snprintf(reply, sizeof(reply), "bad\n"); } if(reply[0] != '\0') { rc = write_timeout(s->fd, reply, strlen(reply)); if(rc < 0) goto fail; } if(s->n > eol + 1 - s->buf) { memmove(s->buf, eol + 1, s->n - (eol + 1 - s->buf)); s->n -= (eol + 1 - s->buf); } else { s->n = 0; free(s->buf); s->buf = NULL; } return 1; fail: shutdown(s->fd, 1); return -1; }