static int do_pid(int fd, pid_t pid) { char nfmt[NFMT_SIZE]; size_t n; int e = 0; do{ e = ftruncate(fd, 0); }while((e == -1) && (errno == EINTR)); if(e == -1){ return -1; } nfmt_uint32(nfmt, (uint32_t) pid); /* append newline: */ n = cstr_len(nfmt); nfmt[n] = '\n'; ++n; nfmt[n] = '\0'; do{ e = write(fd, nfmt, n); }while((e == -1) && (errno == EINTR)); if((e < 0) || ((size_t)e != n)){ return -1; } /* success: */ return 0; }
static void cb_conn_read_cli(struct bufferevent *bev, void *user_data) { void* buffer = NULL; uint32_t buf_len = 0; struct evbuffer *buf_in = bufferevent_get_input(bev); cli_cmd_t cmd; cstr *json = cstr_new(); cli_cmd_init(&cmd); /* bufferevent_lock(bev); */ /* read data frome buffer in */ buf_len = evbuffer_get_length(buf_in); buffer = calloc(1, buf_len); bufferevent_read(bev, buffer, buf_len); /* bufferevent_unlock(bev); */ log_dbg("recv command: %s", (char*)buffer); cli_parse(&cmd, (char*)buffer); cli_cmd_to_json(&cmd, json); log_dbg("cli response: %s", cstr_body(json)); bufferevent_send(bev, cstr_body(json), cstr_len(json) + 1); /* put data to addr recv buffer, and translate to command format */ cli_cmd_release(&cmd); cstr_free(json); free(buffer); /* bufferevent_free(bev); */ }
int main(int argc, char const *argv[]) { cstr s = cstr_create(1024); cstr *array; size_t len, i; cstr_ncat(s, "asasasas", 8); printf("%u %u \n", cstr_len(s), cstr_used(s)); cstr_ncat(s, "asasasas", 8); printf("%s\n", s); printf("%u %u \n", cstr_len(s), cstr_used(s)); array = cstr_split("1 2 3 4 5 ", 11, " ", 1, &len); printf("array len %lu\n", len); for(i = 0; i < len; i++) { printf("array[%lu]:%s\n", i, array[i]); cstr_destroy(array[i]); } jfree(array); cstr_destroy(s); return 0; }
/* do_choom() ** if opt_e: abort on fail ** no chdir(), no effect to cwd */ static void do_choom(void) { int fd; /* comment: ** normally we would first create/write a tmpfile ** then atomically rename() tmpfile into procfile ** but open(...,O_CREAT,...) of a new tmpfile on /proc fails (EEXIST) ** leaving no choice but to write into the procfile directly */ if((fd = open(pathbuf, O_WRONLY | O_TRUNC, 0)) == -1){ if(opt_e){ fatal_syserr("failure on open() for path: ", pathbuf); } /* else: */ if(opt_v){ syserr_warn("ignoring failure on open() for path: ", pathbuf); } return; } fd_cloexec(fd); if(write_all(fd, setbuf, cstr_len(setbuf)) == -1){ if(opt_e){ fatal_syserr("failure on write() to path: ", pathbuf); } /* else: */ if(opt_v){ syserr_warn("ignoring failure on write() to path: ", pathbuf); } return; } /* comment: ** fsync() on /proc fails (EINVAL) ** so we simply ignore any following errors */ fsync(fd); close(fd); /* success: */ if(opt_v){ eputs(progname, ": successfully configured ", pathbuf); } return; }
int domsock_create(const char *path, mode_t mode) { struct sockaddr_un sockaddr; mode_t umask_orig; int s; int e, terrno; if(sizeof(sockaddr.sun_path) < (cstr_len(path) + 1)){ errno = ENAMETOOLONG; return -1; } if((s = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1){ return -1; } unlink(path); buf_zero(&sockaddr, sizeof (sockaddr)); sockaddr.sun_family = AF_LOCAL; cstr_copy(sockaddr.sun_path, path); if(bind(s, (const struct sockaddr *)&sockaddr, sizeof(sockaddr)) == -1){ goto FAIL; } if(mode != 0){ umask_orig = umask(0); e = chmod(path, mode); umask(umask_orig); if(e == -1){ goto FAIL; } } /* success: */ return s; FAIL: terrno = errno; unlink(path); close(s); errno = terrno; return -1; }
/** Copies a c string src into the stick from dst to dst, taking capacity into consideration. If the dst has a too small capacity, the string will be truncated, and NULL will be returned. Otherwise, dst is returned. */ Stick * stick_strcpy(Stick* dst, char *src) { int stop, index, len; len = cstr_len(src); return stick_strncpy(dst, src, len); }
int dynbuf_puts(dynbuf *d, const char *str) { return dynbuf_putbuf(d, str, cstr_len(str)); }
/* perpd_svdef_activate() ** activate service definition ** called by perpd_scan() ** ** return: ** 0: success ** -1: failure ** ** notes: ** failures include: ** - service definition directory name too long ** (must me less than, say, 240 characters) ** - open() on service definition directory ** - pipe() for logpipe ** service is activated only on success */ int perpd_svdef_activate(struct svdef *svdef, const char *svdir, const struct stat *st_dir) { struct stat st; char path_buf[256]; int fd; perpd_svdef_clear(svdef); if(cstr_len(svdir) > 240){ errno = ENAMETOOLONG; warn_syserr("service definition directory name error: ", svdir); return -1; } svdef->dev = st_dir->st_dev; svdef->ino = st_dir->st_ino; cstr_lcpy(svdef->name, svdir, sizeof svdef->name); tain_now(&svdef->when); svdef->bitflags |= SVDEF_FLAG_ACTIVE; /* open an fd to use for fchdir() in perpd_svrun(): */ cstr_vcopy(path_buf, "./", svdir); if((fd = open(path_buf, O_RDONLY)) == -1){ warn_syserr("failure open() on service definition directory ", svdir); return -1; } fd_cloexec(fd); svdef->fd_dir = fd; /* inspect service definition directory: */ cstr_vcopy(path_buf, "./", svdir, "/flag.down"); if(stat(path_buf, &st) != -1){ svdef->bitflags |= SVDEF_FLAG_DOWN; } cstr_vcopy(path_buf, "./", svdir, "/flag.once"); if(stat(path_buf, &st) != -1){ svdef->bitflags |= SVDEF_FLAG_ONCE; } /* logging? */ cstr_vcopy(path_buf, "./", svdir, "/rc.log"); if(stat(path_buf, &st) != -1){ if(st.st_mode & S_IXUSR){ svdef->bitflags |= SVDEF_FLAG_HASLOG; log_debug("rc.log exists and is executable for ", svdir); }else{ log_warning("rc.log exists but is not set executable for ", svdir); } } /* setup logpipe: */ if(svdef->bitflags & SVDEF_FLAG_HASLOG){ if(pipe(svdef->logpipe) == -1){ warn_syserr("failure pipe() on logpipe for ", svdir); close(fd); return -1; } fd_cloexec(svdef->logpipe[0]); fd_cloexec(svdef->logpipe[1]); } /* ** from here on, the service is considered activated */ /* first time startup: */ /* log: if FLAG_HASLOG, start irrespective of any other svdef->bitflags: */ if(svdef->bitflags & SVDEF_FLAG_HASLOG){ svdef->svpair[SUBSV_LOG].bitflags |= SUBSV_FLAG_ISLOG; perpd_svdef_run(svdef, SUBSV_LOG, SVRUN_START); } /* XXX, bail here if log startup fails on fork() ? */ /* main: */ if(!(svdef->bitflags & SVDEF_FLAG_DOWN)){ /* setup for running once? */ if(svdef->bitflags & SVDEF_FLAG_ONCE){ svdef->svpair[SUBSV_MAIN].bitflags |= SUBSV_FLAG_ISONCE; } perpd_svdef_run(svdef, SUBSV_MAIN, SVRUN_START); } else { svdef->svpair[SUBSV_MAIN].bitflags |= SUBSV_FLAG_WANTDOWN; } return 0; }
int dynbuf_copys(struct dynbuf *d, const char *str) { return dynbuf_copybuf(d, str, cstr_len(str)); }