int VTCP_connect(const struct suckaddr *name, int msec) { int s, i; struct pollfd fds[1]; const struct sockaddr *sa; socklen_t sl; int val; if (name == NULL) return (-1); /* Attempt the connect */ AN(VSA_Sane(name)); sa = VSA_Get_Sockaddr(name, &sl); AN(sa); AN(sl); s = socket(sa->sa_family, SOCK_STREAM, 0); if (s < 0) return (s); /* Set the socket non-blocking */ if (msec != 0) (void)VTCP_nonblocking(s); val = 1; AZ(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &val, sizeof val)); i = connect(s, sa, sl); if (i == 0) return (s); if (errno != EINPROGRESS) { closefd(&s); return (-1); } if (msec < 0) { /* * Caller is responsible for waiting and * calling VTCP_connected */ return (s); } assert(msec > 0); /* Exercise our patience, polling for write */ fds[0].fd = s; fds[0].events = POLLWRNORM; fds[0].revents = 0; i = poll(fds, 1, msec); if (i == 0) { /* Timeout, close and give up */ closefd(&s); errno = ETIMEDOUT; return (-1); } return (VTCP_connected(s)); }
int catgrepmore(char *fname, int fds1[2], int fds2[2]) { int ifd, grep_status, more_status; /* This is essentially how the pipes are set up: -------------- ------------- parent PIPE1 grep PIPE2 more -------------- ------------- ^ ^ ^ ^ Write Read Write Read */ //CHILD: grep pid_t grep_pid = fork(); if(grep_pid == -1) { perror("fork"); exit(1); } if(grep_pid == 0) { closefd(fds1[WRITE_END]); /* close write end of pipe1 */ closefd(fds2[READ_END]); /* close read end of pipe2 */ redirect(fds1[READ_END], STDIN); /* redirect stdin to read end of pipe1, then close read end */ redirect(fds2[WRITE_END], STDOUT); /* redirect stdout to write end of pipe2, then close write end */ execlp("grep", "grep", pattern, (char *) NULL); perror("execlp: grep"); exit(1); } pid_t more_pid = fork(); if(more_pid == -1) { perror("fork"); exit(1); } //CHILD: more if(more_pid == 0) { closefd(fds1[WRITE_END]); /* close write end of pipe1 */ closefd(fds1[READ_END]); /* close read end of pipe1 */ closefd(fds2[WRITE_END]); /* close write end of pipe2 */ redirect(fds2[READ_END], STDIN); /* redirect stdin to read end of pipe2, then close read end */ execlp("more", "more", (char *) NULL); perror("execlp: more"); exit(1); } //PARENT if(grep_pid != 0 && more_pid != 0) { if((ifd = open(fname, O_RDONLY, 0666)) == -1) { fprintf(stderr, "open: Can't open %s for reading: %s\n", fname, strerror(errno)); exit(1); } closefd(fds1[READ_END]); /* close read end of pipe1 */ closefd(fds2[WRITE_END]); /* close write end of pipe2 */ closefd(fds2[READ_END]); /* close read end of pipe2 */ readwrite(ifd, fds1[WRITE_END]); /* fill read end of pipe1 with data from infile */ closefd(fds1[WRITE_END]); /* close write end of pipe1 cuz we're done with it */ closefd(ifd); /* close input fd cuz we're done with it */ grep_pid = waitpid(grep_pid, &grep_status, 0); more_pid = waitpid(more_pid, &more_status, 0); pchildstatus(grep_pid, grep_status, "grep"); /* report exit status of grep */ pchildstatus(more_pid, more_status, "more"); /* report exit status of more */ } return 0; }
int VTCP_bind(const struct suckaddr *sa, const char **errp) { int sd, val, e; socklen_t sl; const struct sockaddr *so; int proto; if (errp != NULL) *errp = NULL; proto = VSA_Get_Proto(sa); sd = socket(proto, SOCK_STREAM, 0); if (sd < 0) { if (errp != NULL) *errp = "socket(2)"; return (-1); } val = 1; if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) != 0) { if (errp != NULL) *errp = "setsockopt(SO_REUSEADDR, 1)"; e = errno; closefd(&sd); errno = e; return (-1); } #ifdef IPV6_V6ONLY /* forcibly use separate sockets for IPv4 and IPv6 */ val = 1; if (proto == AF_INET6 && setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof val) != 0) { if (errp != NULL) *errp = "setsockopt(IPV6_V6ONLY, 1)"; e = errno; closefd(&sd); errno = e; return (-1); } #endif so = VSA_Get_Sockaddr(sa, &sl); if (bind(sd, so, sl) != 0) { if (errp != NULL) *errp = "bind(2)"; e = errno; closefd(&sd); errno = e; return (-1); } return (sd); }
int VPF_Read(const char *path, pid_t *pidptr) { char buf[16], *endptr; int error, fd, i; fd = open(path, O_RDONLY | O_CLOEXEC); if (fd == -1) return (errno); i = read(fd, buf, sizeof(buf) - 1); error = errno; closefd(&fd); if (i == -1) return (error); else if (i == 0) return (EAGAIN); if (i > 0 && buf[i - 1] == '\n') i--; buf[i] = '\0'; *pidptr = strtol(buf, &endptr, 10); if (endptr != &buf[i]) return (EINVAL); return (0); }
/* * Wrapper for dup2 - same semantics as dup2 system call except * that any threads blocked in an I/O system call on fd2 will be * preempted and return -1/EBADF; */ int NET_Dup2(int fd, int fd2) { if (fd < 0) { errno = EBADF; return -1; } return closefd(fd, fd2); }
void mgt_cli_secret(const char *S_arg) { int i, fd; char buf[BUFSIZ]; /* Save in shmem */ mgt_SHM_static_alloc(S_arg, strlen(S_arg) + 1L, "Arg", "-S"); VJ_master(JAIL_MASTER_FILE); fd = open(S_arg, O_RDONLY); if (fd < 0) { fprintf(stderr, "Can not open secret-file \"%s\"\n", S_arg); exit(2); } VJ_master(JAIL_MASTER_LOW); MCH_TrackHighFd(fd); i = read(fd, buf, sizeof buf); if (i == 0) { fprintf(stderr, "Empty secret-file \"%s\"\n", S_arg); exit(2); } if (i < 0) { fprintf(stderr, "Can not read secret-file \"%s\"\n", S_arg); exit(2); } closefd(&fd); secret_file = S_arg; }
int VJ_make_workdir(const char *dname) { int fd; AN(dname); CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC); if (vjt->make_workdir != NULL) return (vjt->make_workdir(dname)); VJ_master(JAIL_MASTER_FILE); if (mkdir(dname, 0755) < 0 && errno != EEXIST) ARGV_ERR("Cannot create working directory '%s': %s\n", dname, strerror(errno)); if (chdir(dname) < 0) ARGV_ERR("Cannot change to working directory '%s': %s\n", dname, strerror(errno)); fd = open("_.testfile", O_RDWR|O_CREAT|O_EXCL, 0600); if (fd < 0) ARGV_ERR("Cannot create test-file in %s (%s)\n" "Check permissions (or delete old directory)\n", dname, strerror(errno)); closefd(&fd); AZ(unlink("_.testfile")); VJ_master(JAIL_MASTER_LOW); return (0); }
void PukeController::Traffic(int fd) /*FOLD00*/ { PukeMessage pm; int bytes = -1; memset(&pm, 0, sizeof(pm)); while((bytes = read(fd, &pm, 5*sizeof(int))) > 0){ if(bytes != 5*sizeof(int)){ cerr << "Short message, Got: " << bytes << " Wanted: " << sizeof(PukeMessage) << " NULL Padded" << endl; } #ifdef DEBUG printf("Traffic on: %d => %d %d %d %d", fd, pm.iCommand, pm.iWinId, pm.iArg, pm.iTextSize); if(pm.iCommand == 0x0){ abort(); } #endif /* DEBUG */ if(pm.iHeader != iPukeHeader){ warning("Invalid packet received, discarding!"); return; } if(pm.iTextSize > 0){ pm.cArg = new char[pm.iTextSize + 1]; read(fd, pm.cArg, pm.iTextSize * sizeof(char)); pm.cArg[pm.iTextSize] = 0x0; // Null terminate the string. // printf(" %s\n", pm.cArg); } else { pm.cArg = 0; // printf("\n"); } MessageDispatch(fd, &pm); delete[] pm.cArg; // Free up cArg is used memset(&pm, 0, 5*sizeof(int)); } if(bytes <= 0){ // Shutdown the socket! switch(errno){ case EAGAIN: // Don't do anything for try again break; // case 0: // break; // We just read nothing, don't panic case EIO: case EISDIR: case EBADF: case EINVAL: case EFAULT: default: perror("PukeController: read failed"); closefd(fd); close(fd); } } else{ qidConnectFd[fd]->sr->setEnabled(TRUE); } }
fd_t simple_socket_stoppable::create_pipe_for_stopping () { if (autoclose_fd && fd_to_monitor != INVALID_SOCKET) closefd(fd_to_monitor); fd_t pipes[2] = {INVALID_SOCKET, INVALID_SOCKET}; if (pipe(pipes) == -1) throw socketxx::other_error("Pipe creation error in simple_socket_stoppable::create_pipe_for_stopping"); fd_to_monitor = pipes[0]; autoclose_fd = true; return pipes[1]; }
void filesrv::remove (fh_entry *fhe) { timeoutlist.remove (fhe); entries.remove (fhe); fhe_n--; closefd (fhe); delete fhe; }
vws_fini(struct waiter *w) { struct vws *vws; void *vp; CAST_OBJ_NOTNULL(vws, w->priv, VWS_MAGIC); vws->die = 1; closefd(&vws->dport); AZ(pthread_join(vws->thread, &vp)); }
void VPF_Remove(struct vpf_fh *pfh) { if (vpf_verify(pfh) == 0) { (void)unlink(pfh->pf_path); closefd(&pfh->pf_fd); } free(pfh->pf_path); free(pfh); }
/* * Copied from libvarnish/vfil.c to avoid pulling libvarnish or vfil.c * directly when daemon() is not working/available (i.e. OSX). * */ static void vfil_null_fd(int target) { int fd; assert(target >= 0); fd = open("/dev/null", O_RDWR); assert(fd >= 0); assert(dup2(fd, target) == target); closefd(&fd); }
void filesrv::purgefd (int force) { time_t curtime = time (NULL); for (fh_entry *fhe = timeoutlist.first; fhe != 0; fhe = timeoutlist.next(fhe)) { if (force || (curtime > fhe->lastused + fd_expire)) { (void ) closefd(fhe); } } }
StatFile::~StatFile() { for (size_t i = 0; i != sizeof(pages)/sizeof(pages[0]); ++i) { if (pages[i].ptr != 0) { mm_->unmap(pages[i].ptr, fileHeader_->page_size); } } if (fileHeader_) { mm_->unmap(fileHeader_, sizeof(Header)); } closefd(); }
run_vcc(void *priv) { struct vsb *csrc; struct vsb *sb = NULL; struct vcc_priv *vp; int fd, i, l; struct vcc *vcc; struct stevedore *stv; VJ_subproc(JAIL_SUBPROC_VCC); CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC); AZ(chdir(vp->dir)); vcc = VCC_New(); AN(vcc); VCC_Builtin_VCL(vcc, builtin_vcl); VCC_VCL_path(vcc, mgt_vcl_path); VCC_VMOD_path(vcc, mgt_vmod_path); VCC_Err_Unref(vcc, mgt_vcc_err_unref); VCC_Allow_InlineC(vcc, mgt_vcc_allow_inline_c); VCC_Unsafe_Path(vcc, mgt_vcc_unsafe_path); STV_Foreach(stv) VCC_Predef(vcc, "VCL_STEVEDORE", stv->ident); mgt_vcl_export_labels(vcc); csrc = VCC_Compile(vcc, &sb, vp->vclsrc, vp->vclsrcfile); AZ(VSB_finish(sb)); if (VSB_len(sb)) printf("%s", VSB_data(sb)); VSB_destroy(&sb); if (csrc == NULL) exit(2); fd = open(VGC_SRC, O_WRONLY|O_TRUNC|O_CREAT, 0600); if (fd < 0) { fprintf(stderr, "VCC cannot open %s", vp->csrcfile); exit(2); } l = VSB_len(csrc); i = write(fd, VSB_data(csrc), l); if (i != l) { fprintf(stderr, "VCC cannot write %s", vp->csrcfile); exit(2); } closefd(&fd); VSB_destroy(&csrc); exit(0); }
static int mgt_vcc_touchfile(const char *fn, struct vsb *sb) { int i; i = open(fn, O_WRONLY|O_CREAT|O_TRUNC, 0640); if (i < 0) { VSB_printf(sb, "Failed to create %s: %s", fn, strerror(errno)); return (2); } if (fchown(i, mgt_param.uid, mgt_param.gid) != 0) if (geteuid() == 0) VSB_printf(sb, "Failed to change owner on %s: %s\n", fn, strerror(errno)); closefd(&i); return (0); }
int VTCP_connected(int s) { int k; socklen_t l; /* Find out if we got a connection */ l = sizeof k; AZ(getsockopt(s, SOL_SOCKET, SO_ERROR, &k, &l)); /* An error means no connection established */ errno = k; if (k) { closefd(&s); return (-1); } (void)VTCP_blocking(s); return (s); }
int VTCP_listen(const struct suckaddr *sa, int depth, const char **errp) { int sd; int e; if (errp != NULL) *errp = NULL; sd = VTCP_bind(sa, errp); if (sd >= 0) { if (listen(sd, depth) != 0) { e = errno; closefd(&sd); errno = e; if (errp != NULL) *errp = "listen(2)"; return (-1); } } return (sd); }
sender& sender::operator<<(std::istream& str){ char c; // std::cout<<"xxx: "<<str<<std::endl; //membaca seluruh str dan menyimpan ke string startSending(); std::string msg=""; while(str.get(c)){ msg+=c; if (msg.length()>=charperframe){ *this<<msg; msg=""; } } msg+=Endfile; *this<<msg; stopSending(); //harusnya dipanggil waktu baca EOF closefd(); return *this; }
static void mcf_auth(struct cli *cli, const char *const *av, void *priv) { int fd; char buf[CLI_AUTH_RESPONSE_LEN + 1]; AN(av[2]); (void)priv; if (secret_file == NULL) { VCLI_Out(cli, "Secret file not configured\n"); VCLI_SetResult(cli, CLIS_CANT); return; } VJ_master(JAIL_MASTER_FILE); fd = open(secret_file, O_RDONLY); if (fd < 0) { VCLI_Out(cli, "Cannot open secret file (%s)\n", strerror(errno)); VCLI_SetResult(cli, CLIS_CANT); VJ_master(JAIL_MASTER_LOW); return; } VJ_master(JAIL_MASTER_LOW); MCH_TrackHighFd(fd); VCLI_AuthResponse(fd, cli->challenge, buf); closefd(&fd); if (strcasecmp(buf, av[2])) { MGT_Complain(C_SECURITY, "CLI Authentication failure from %s", cli->ident); VCLI_SetResult(cli, CLIS_CLOSE); return; } cli->auth = MCF_AUTH; memset(cli->challenge, 0, sizeof cli->challenge); VCLI_SetResult(cli, CLIS_OK); mcf_banner(cli, av, priv); }
/* * Wrapper for close - same semantics as close system call * except that any threads blocked in an I/O on fd will be * preempted and the I/O system call will return -1/EBADF. */ int NET_SocketClose(int fd) { return closefd(-1, fd); }
int mcpOpen(char *name) { char host[MAXHOSTNAMELEN], service[MAXHOSTNAMELEN]; char buf[1024]; char *cptr; int count, status; int sock_fd; struct hostent *hp; struct servent *sp; struct in_addr tmpaddr; int optval; struct sockaddr_in inet_a; // inet_addr is a function name #ifndef _WIN32 char path[MAXPATHLEN]; struct sockaddr_un unix_addr; size_t unix_addr_len; #endif //WIN32 #ifdef _WIN32 // make sure we are initialized extern struct { int initialized; } initializer; if (initializer.initialized == 0) return -1; #endif //WIN32 /* * Parse the name string. * * A. If there is a ':' then it is an internet socket connection. * 1. Parse the name into <host>:<service> format. * a. If host is empty, use "localhost". * b. Lookup service with getservbyname(). If found, use * that port value. If not found, attempt to convert * it to an integer and use that port value. * 2. Connect to <host>:<port>. If the connection fails, * attempt to connect to <host>:tcpmux then request <service> * from tcpmux. * B. Else the name is a unix domain socket name. * 1. If the first character is not '/', prepend '/tmp/' to the * name string. * 2. Connect to the socket name. */ cptr = strchr(name, ':'); if (cptr) { /* Copy the host name */ if (cptr == name) { strcpy(host, "localhost"); } else { strncpy(host, name, (cptr - name)); host[cptr-name] = '\0'; } /* Copy the service name */ strcpy(service, cptr + 1); /* Initialize the inet_a struct */ bzero((char *) &inet_a, sizeof(inet_a)); inet_a.sin_family = AF_INET; /* Attempt to convert the host address as a dotted decimal number */ #ifdef _WIN32 tmpaddr.s_addr = inet_addr(host); status = (tmpaddr.s_addr != INADDR_NONE) ? 1 : 0; #else status = inet_aton(host, &tmpaddr); #endif //WIN32 if (status == 1) { bcopy((char *) &tmpaddr, (char *) &inet_a.sin_addr, sizeof(tmpaddr)); } else { /* Now find the host */ hp = gethostbyname(host); if (!hp) { /* We could not find the host */ errno = ENOENT; return -1; } bcopy(hp->h_addr, (char *) &inet_a.sin_addr, hp->h_length); } /* Attempt to decode the service parameter */ sp = getservbyname(service, "tcp"); if (sp) { inet_a.sin_port = sp->s_port; } else { /* Attempt to convert the service name as an integer */ inet_a.sin_port = htons((unsigned short)atoi(service)); } /* Create the socket */ sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd < 0) { return -1; } status = connect(sock_fd, (struct sockaddr *) &inet_a, sizeof(inet_a)); if (status < 0) { int status2; /* * The connection failed, try connecting to the tcpmux service. * tcpmux is at the well known port 1 so I just hardcoded it. */ inet_a.sin_port = htons(1); status = errno; status2 = connect(sock_fd, (struct sockaddr *) &inet_a, sizeof(inet_a)); if (status2 < 0) { closefd(sock_fd); errno = status; return -1; } /* * We connected to tcpmux, now send the service name and see if * tcpmux can give it to us. The tcpmux protocol works as follows: * * 1 Connect to the tcpmux port * 2 write the name of the service that you want followed by <CRLF>. * 3 read back the response terminated by <CRLF> * a If the first character is a '+' then we are connected. * b if the first character is a '-' then we are not connected. */ sprintf(buf, "%s\r\n", service); status = mcpWrite(sock_fd, buf, (unsigned int) strlen(buf)); if (status != (int)strlen(buf)) { status = errno; closefd(sock_fd); errno = status; return -1; } /* Read up through the <CRLF> pair */ /* There will be at least 3 characters coming back */ cptr = buf; count = 3; while (1) { status = mcpRead(sock_fd, cptr, count); if (status <= 0) { status = errno; closefd(sock_fd); errno = status; return -1; } cptr += status; if (cptr[-1] == '\n') { break; } else if (cptr[-1] == '\r') { count = 1; } else { count = 2; } } if (buf[0] != '+') { closefd(sock_fd); #ifdef _WIN32 errno = WSAECONNREFUSED; WSASetLastError (WSAECONNREFUSED); #else errno = ECONNREFUSED; #endif //WIN32 return -1; } } /* * We did it! We actually succeeded in connecting to the name * via internet sockets. Now make sure that we can send small * packets without delay. */ optval = 1; status = setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&optval, sizeof(optval)); } else /* This must be a unix domain socket name */ { #ifndef _WIN32 // { /* Initialize the unix_addr struct */ bzero((char *) &unix_addr, sizeof(unix_addr)); unix_addr.sun_family = AF_UNIX; /* * If there is a leading '/' in the name name, it is an * absolute path name, otherwise, it is relative to /tmp. */ if (name[0] == '/') { strcpy(path, name); } else { sprintf(path, "/tmp/%s", name); } strcpy(unix_addr.sun_path, path); unix_addr_len = sizeof(unix_addr.sun_len) + sizeof(unix_addr.sun_family) + strlen(path); /* Create the socket */ sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (sock_fd < 0) { return -1; } /* Connect to the name */ status = connect(sock_fd, (struct sockaddr *) &unix_addr, unix_addr_len); if (status < 0) { closefd(sock_fd); return -1; } /* * We did it! We actually succeeded in connecting to the name * via unix sockets. */ #else // } { HANDLE h; void* pmem; DWORD *mask, bit; struct sockmap* map; int i; h = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, MAYA_UNIX_SOCKET_SHARE_SIZE, MAYA_UNIX_SOCKET_SHARE_NAME); if (!h) return -1; if (GetLastError() != ERROR_ALREADY_EXISTS) { /* no "unix" handles exist */ CloseHandle(h); return -1; } pmem = MapViewOfFile(h, FILE_MAP_WRITE, 0, 0, 0); if (!pmem) { CloseHandle(h); return -1; } mask = (DWORD*)pmem; map = (struct sockmap*)((char*)pmem+sizeof(DWORD)); /* check if name is already here */ sock_fd = -1; for (bit = 1, i = 0; i < 32; ++i) { if (*mask & bit) { if (strcmp(map[i].unix_path, name) == 0) break; /* found */ } bit = bit << 1; } /* found */ if (i < 32) { /* Initialize the inet_a struct */ bzero((char *) &inet_a, sizeof(inet_a)); inet_a.sin_family = AF_INET; /* Now find the host */ hp = gethostbyname("localhost"); if (!hp) errno = ENOENT; else { bcopy(hp->h_addr, (char *) &inet_a.sin_addr, hp->h_length); inet_a.sin_port = map[i].port; /* Create the socket */ sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd >= 0) { status = connect(sock_fd, (struct sockaddr*)&inet_a, sizeof(inet_a)); if (status < 0) { closefd(sock_fd); sock_fd = -1; errno = status; } else { optval = 1; status = setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&optval, sizeof(optval)); } } } } UnmapViewOfFile(pmem); CloseHandle(h); #endif //WIN32 } } /* Ok, we are connected. Return the socket descriptor */ return sock_fd; }
void mcpClose(int fd) { closefd(fd); }
int main(int argc, char **argv) { int fd; /* File descriptor to monitor */ int kq; /* KQueue */ int ret; /* Return value */ struct kevent ev; struct timespec ts; /* Don't care about our children */ signal(SIGCHLD, SIG_IGN); /* Open syslog */ #ifdef DEBUG openlog(argv[0], LOG_CONS|LOG_PID|LOG_PERROR, LOG_DAEMON); #else openlog(argv[0], LOG_CONS|LOG_PID, LOG_DAEMON); #endif /* #ifdef DEBUG */ /* Make sure we have at least a file and one parameter */ if (argc < 2) { usage(argv[0]); exit(EX_USAGE); } /* Make a kqueue */ if (-1 == (kq = kqueue())) { syslog(LOG_ERR, "Unable to create kqueue: %s", strerror(errno)); exit(EX_OSERR); } fd = -1; /* Main loop */ for (;;) { /* Close the open file if we have one */ if (-1 != fd) { closefd(&fd); } /* Get a descriptor for the file to monitor */ #ifdef DEBUG printf("Opening %s\n", argv[1]); #endif /* #ifdef DEBUG */ fd = open_or_sleep(argv[1]); #ifdef DEBUG printf("Opened %s: %i\n", argv[1], fd); #endif /* #ifdef DEBUG */ /* Set up the event */ EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD, NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_TRUNCATE|NOTE_RENAME|NOTE_REVOKE, 0, NULL); /* Add the event to the kqueue */ #ifdef DEBUG printf("Adding event to kqueue\n"); #endif /* #ifdef DEBUG */ if (-1 == (ret = kevent(kq, &ev, 1, NULL, 0, NULL))) { /* If it fails, log it and try again */ syslog(LOG_WARNING, "Sleeping %is because " "setting watch on %s failed: " "%s", SLEEPTIME, argv[1], strerror(errno)); closefd(&fd); sleep(SLEEPTIME); } #ifdef DEBUG printf("Event added\n"); #endif /* #ifdef DEBUG */ /* Time to sleep between logging that nothing happened */ ts.tv_sec = KQTIME; ts.tv_nsec = 0; /* Clear kevent */ memset((void*)&ev, 0, sizeof(ev)); #ifdef DEBUG printf("Waiting for a kevent\n"); #endif /* #ifdef DEBUG */ /* Get an event from the kqueue (or timeout) */ ret = kevent(kq, NULL, 0, &ev, 1, &ts); #ifdef DEBUG printf("Got a kevent. Ret: %i\n", ret); #endif /* #ifdef DEBUG */ /* Nothing has happened */ if (0 == ret) { syslog(LOG_INFO, "Still waiting for changes to %s", argv[1]); continue; } /* An error occurred */ if ((EV_ERROR & ev.flags) || ret == -1) { syslog(LOG_WARNING, "Sleeping %is due to an error " "waiting for a change in %s: %s", SLEEPTIME, argv[1], strerror(errno)); sleep(SLEEPTIME); closefd(&fd); continue; } /* Log what happened */ if (ev.fflags & NOTE_DELETE) { syslog(LOG_INFO, "%s was deleted", argv[1]); } CC(NOTE_DELETE, "was deleted"); CC(NOTE_WRITE, "was written"); CC(NOTE_EXTEND, "was extended"); CC(NOTE_TRUNCATE, "was truncated"); CC(NOTE_RENAME, "was renamed"); CC(NOTE_REVOKE, "was disappeared"); /* Execute command if something happened and we have a * command to execute */ if (((NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_TRUNCATE|NOTE_RENAME|NOTE_REVOKE) & ev.fflags) && argc >= 3) { #ifdef DEBUG int i; printf("Executing commands:\n"); for (i = 2; i < argc; i++) printf("\targv[%i]: %s\n", i-2, argv[i]); #endif /* #ifdef DEBUG */ ret = fork(); /* If we're the child code, execute argv[3]... */ if (0 == ret) { execvp(argv[2], argv+2); /* If execlp returned, an error occurred */ syslog(LOG_ERR, "Unable to execute command " "(arguments to) follow: %s", strerror(errno)); /* Send the arguments to syslog */ for (fd = 2; fd < argc; fd++) { syslog(LOG_WARNING, "%i: %s", fd, argv[fd]); } return -2; } else if (-1 == ret) { syslog(LOG_ERR, "Command not executed " "because forking failed: %s", strerror(errno)); } } } return 0; }
/* returns an exit code */ unsigned VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, const char *name, int maxlines) { int rv, p[2], status; pid_t pid; struct vsub_priv sp; sp.sb = sb; sp.name = name; sp.lines = 0; sp.maxlines = maxlines; if (pipe(p) < 0) { VSB_printf(sb, "Starting %s: pipe() failed: %s", name, strerror(errno)); return (1); } assert(p[0] > STDERR_FILENO); assert(p[1] > STDERR_FILENO); if ((pid = fork()) < 0) { VSB_printf(sb, "Starting %s: fork() failed: %s", name, strerror(errno)); closefd(&p[0]); closefd(&p[1]); return (1); } if (pid == 0) { VFIL_null_fd(STDIN_FILENO); assert(dup2(p[1], STDOUT_FILENO) == STDOUT_FILENO); assert(dup2(p[1], STDERR_FILENO) == STDERR_FILENO); /* Close all other fds */ VSUB_closefrom(STDERR_FILENO + 1); func(priv); /* * func should either exec or exit, so getting here should be * treated like an assertion failure - except that we don't know * if it's safe to trigger an actual assertion */ _exit(4); } closefd(&p[1]); (void)VLU_File(p[0], vsub_vlu, &sp, 0); if (sp.maxlines >= 0 && sp.lines > sp.maxlines) VSB_printf(sb, "[%d lines truncated]\n", sp.lines - sp.maxlines); do { rv = waitpid(pid, &status, 0); if (rv < 0 && errno != EINTR) { VSB_printf(sb, "Running %s: waitpid() failed: %s\n", name, strerror(errno)); return (1); } } while (rv < 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { rv = -1; VSB_printf(sb, "Running %s failed", name); if (WIFEXITED(status)) { rv = WEXITSTATUS(status); VSB_printf(sb, ", exited with %d", rv); } if (WIFSIGNALED(status)) { rv = 2; VSB_printf(sb, ", signal %d", WTERMSIG(status)); } if (WCOREDUMP(status)) VSB_printf(sb, ", core dumped"); VSB_printf(sb, "\n"); assert(rv != -1); return (rv); } return (0); }
//return 0: continue, //return -1(<0): error //return 1(>0): exit success static inline int init_command(App & app, const char * pidfile){ int ret = 0; if (app.cmdopt().hasopt("stop")){ if (!pidfile){ fprintf(stderr, "lacking command line option pid-file ...\n"); return -1; } int killpid = lockpidfile(pidfile, SIGTERM, true); fprintf(stderr, "stoped process with normal stop mode [%d]\n", killpid); return 1; } if (app.cmdopt().hasopt("restart")){ if (!pidfile){ fprintf(stderr, "lacking command line option pid-file ...\n"); return -1; } int killpid = lockpidfile(pidfile, SIGUSR1, true); fprintf(stderr, "stoped process with restart mode [%d]\n", killpid); return 1; } if (app.cmdopt().hasopt("reload")){ if (!pidfile){ fprintf(stderr, "lacking command line option pid-file ...\n"); return -1; } int killpid = lockpidfile(pidfile, SIGUSR2, true, nullptr, true); fprintf(stderr, "reloaded process [%d]\n", killpid); return 1; } if (app.cmdopt().hasopt("console-shell")){ const char * console = app.cmdopt().getoptstr("console-listen"); if (!console){ fprintf(stderr, "has no console-listen option open console shell error !\n"); return -1; } string console_server = "tcp://"; console_server += console; printf("connecting to %s ...\n", console_server.c_str()); int confd = openfd(console_server.c_str(), "w", 3000); if (!confd){ fprintf(stderr, "connect error %s!\n", strerror(errno)); return -1; } enum { CONSOLE_BUFFER_SIZE = 1024*1024}; char * console_buffer = new char[CONSOLE_BUFFER_SIZE]; printf("console server connected ! command <quit> will exit shell\n"); while (true){ int n = readfd(confd, console_buffer, CONSOLE_BUFFER_SIZE, "token:\r\n\r\n", 1000 * 3600); if (n < 0){ fprintf(stderr, "console server closed [ret=%d]!\n", n); break; } printf("%s\n%s$", console_buffer, console); const char * command = fgets(console_buffer, CONSOLE_BUFFER_SIZE, stdin); if (strcasecmp(command, "quit") == 0){ break; } dcs::writefd(confd, command, 0, "token:\r\n\r\n"); } closefd(confd); delete console_buffer; return 1; } /////////////////////////////////////////////////////////////////// ret = _shm_command(app); if (ret < 0){ GLOG_ERR("shm command check error:%d !", ret); return -1; } if (ret > 0){ return 1; } return app.on_cmd_opt(); }
void simple_socket_stoppable::set_monitored_fd (fd_t to_monitor, bool autoclose) { if (autoclose_fd && fd_to_monitor != INVALID_SOCKET) closefd(fd_to_monitor); fd_to_monitor = to_monitor; autoclose_fd = autoclose; if (to_monitor == INVALID_SOCKET) throw bad_socket_error(); }
void simple_socket_stoppable::unset_monitoring () { if (autoclose_fd && fd_to_monitor != INVALID_SOCKET) closefd(fd_to_monitor); fd_to_monitor = INVALID_SOCKET; }
Joystick::~Joystick() { closefd(); }