Exemplo n.º 1
0
void execfg(char *cmdarr[MAXCMD][MAXOP],int i) {		//Brings the specified background process to the foreground
    if(cmdarr[i][1] == NULL) {
        printf("Takes one argument\n");
        return;
    }
    strcpy(fname,cmdarr[i][0]);
    int j,temppid = 0;

    int tempposn = atoi(cmdarr[i][1]);
    //int tempcnt = 0;
    for(j=0; j<(MAXNUM*MAXOP); j++) {
        if(jobsarray[j].count == tempposn && jobsarray[j].state == 1) {
            temppid = jobsarray[j].pid;
            break;
        }
    }

    if(temppid > 0) {
        for(j=0; j<(MAXNUM*MAXOP); j++) {
            if(jobsarray[j].pid == temppid && jobsarray[j].state == 1) {
                strcpy(fname,jobsarray[j].name);
                jobsarray[j].state = 0;
                fpid = temppid;



                int temppgid=getpgid(temppid);

                tcsetpgrp(shell_terminal,temppgid);

                killpg(temppgid,SIGCONT);

                int status;
                do {
                    int w = waitpid(temppid, &status, WUNTRACED | WCONTINUED);
                    if (w == -1) {

                        perror("waitpid");
                        exit(EXIT_FAILURE);
                    }

                    if (WIFEXITED(status)) {
                        printf("exited, status=%d\n", WEXITSTATUS(status));
                        break;
                    }
                    else if (WIFSIGNALED(status)) {
                        printf("killed by signal %d\n", WTERMSIG(status));
                        break;
                    }
                    else if (WIFSTOPPED(status)) {
                        printf("\nstopped by signal %d\n", WSTOPSIG(status));
                        if(WSTOPSIG(status) == 19 || WSTOPSIG(status) == 20) {
                            strcpy(jobsarray[jobsarraycnt].name,fname);
                            jobsarray[jobsarraycnt].pid = fpid;
                            jobsarray[jobsarraycnt].stopped = 1;
                            jobsarray[jobsarraycnt++].state = 1;
                        }
                        printf("\nstopped by signal %d\n", WSTOPSIG(status));
                        if(WSTOPSIG(status) == 22)
                            kill(fpid,SIGKILL);
                        break;
                    }
                    else if (WIFCONTINUED(status)) {
                        printf("continued\n");
                    }
                } while(!WIFEXITED(status) && !WIFSIGNALED(status));
                tcsetpgrp (shell_terminal, shell_pgid);

                return;
            }
        }
    }
    printf("No background job with given pid exists\n");
    return;
}
Exemplo n.º 2
0
char *
print_arg(struct syscall_args *sc, unsigned long *args, long retval,
    struct trussinfo *trussinfo)
{
	char *tmp;
	pid_t pid;

	tmp = NULL;
	pid = trussinfo->pid;
	switch (sc->type & ARG_MASK) {
	case Hex:
		asprintf(&tmp, "0x%x", (int)args[sc->offset]);
		break;
	case Octal:
		asprintf(&tmp, "0%o", (int)args[sc->offset]);
		break;
	case Int:
		asprintf(&tmp, "%d", (int)args[sc->offset]);
		break;
	case Name: {
		/* NULL-terminated string. */
		char *tmp2;
		tmp2 = get_string(pid, (void*)args[sc->offset], 0);
		asprintf(&tmp, "\"%s\"", tmp2);
		free(tmp2);
		break;
	}
	case BinString: {
		/* Binary block of data that might have printable characters.
		   XXX If type|OUT, assume that the length is the syscall's
		   return value.  Otherwise, assume that the length of the block
		   is in the next syscall argument. */
		int max_string = trussinfo->strsize;
		char tmp2[max_string+1], *tmp3;
		int len;
		int truncated = 0;

		if (sc->type & OUT)
			len = retval;
		else
			len = args[sc->offset + 1];

		/* Don't print more than max_string characters, to avoid word
		   wrap.  If we have to truncate put some ... after the string.
		*/
		if (len > max_string) {
			len = max_string;
			truncated = 1;
		}
		if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len)
		    != -1) {
			tmp3 = malloc(len * 4 + 1);
			while (len) {
				if (strvisx(tmp3, tmp2, len,
				    VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
					break;
				len--;
				truncated = 1;
			};
			asprintf(&tmp, "\"%s\"%s", tmp3, truncated ?
			    "..." : "");
			free(tmp3);
		} else {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		}
		break;
	}
	case StringArray: {
		int num, size, i;
		char *tmp2;
		char *string;
		char *strarray[100];	/* XXX This is ugly. */

		if (get_struct(pid, (void *)args[sc->offset],
		    (void *)&strarray, sizeof(strarray)) == -1)
			err(1, "get_struct %p", (void *)args[sc->offset]);
		num = 0;
		size = 0;

		/* Find out how large of a buffer we'll need. */
		while (strarray[num] != NULL) {
			string = get_string(pid, (void*)strarray[num], 0);
			size += strlen(string);
			free(string);
			num++;
		}
		size += 4 + (num * 4);
		tmp = (char *)malloc(size);
		tmp2 = tmp;

		tmp2 += sprintf(tmp2, " [");
		for (i = 0; i < num; i++) {
			string = get_string(pid, (void*)strarray[i], 0);
			tmp2 += sprintf(tmp2, " \"%s\"%c", string,
			    (i + 1 == num) ? ' ' : ',');
			free(string);
		}
		tmp2 += sprintf(tmp2, "]");
		break;
	}
#ifdef __LP64__
	case Quad:
		asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
#else
	case Quad: {
		unsigned long long ll;
		ll = *(unsigned long long *)(args + sc->offset);
		asprintf(&tmp, "0x%llx", ll);
		break;
	}
#endif
	case Ptr:
		asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	case Readlinkres: {
		char *tmp2;
		if (retval == -1) {
			tmp = strdup("");
			break;
		}
		tmp2 = get_string(pid, (void*)args[sc->offset], retval);
		asprintf(&tmp, "\"%s\"", tmp2);
		free(tmp2);
		break;
	}
	case Ioctl: {
		const char *temp = ioctlname(args[sc->offset]);
		if (temp)
			tmp = strdup(temp);
		else {
			unsigned long arg = args[sc->offset];
			asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }",
			    arg, arg & IOC_OUT ? "R" : "",
			    arg & IOC_IN ? "W" : "", IOCGROUP(arg),
			    isprint(IOCGROUP(arg)) ? (char)IOCGROUP(arg) : '?',
			    arg & 0xFF, IOCPARM_LEN(arg));
		}
		break;
	}
	case Umtx: {
		struct umtx umtx;
		if (get_struct(pid, (void *)args[sc->offset], &umtx,
		    sizeof(umtx)) != -1)
			asprintf(&tmp, "{ 0x%lx }", (long)umtx.u_owner);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Timespec: {
		struct timespec ts;
		if (get_struct(pid, (void *)args[sc->offset], &ts,
		    sizeof(ts)) != -1)
			asprintf(&tmp, "{%ld.%09ld }", (long)ts.tv_sec,
			    ts.tv_nsec);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Timeval: {
		struct timeval tv;
		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
		    != -1)
			asprintf(&tmp, "{%ld.%06ld }", (long)tv.tv_sec,
			    tv.tv_usec);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Timeval2: {
		struct timeval tv[2];
		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
		    != -1)
			asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }",
			    (long)tv[0].tv_sec, tv[0].tv_usec,
			    (long)tv[1].tv_sec, tv[1].tv_usec);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Itimerval: {
		struct itimerval itv;
		if (get_struct(pid, (void *)args[sc->offset], &itv,
		    sizeof(itv)) != -1)
			asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }",
			    (long)itv.it_interval.tv_sec,
			    itv.it_interval.tv_usec,
			    (long)itv.it_value.tv_sec,
			    itv.it_value.tv_usec);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case LinuxSockArgs:
	{
		struct linux_socketcall_args largs;
		if (get_struct(pid, (void *)args[sc->offset], (void *)&largs,
		    sizeof(largs)) == -1) {
			err(1, "get_struct %p", (void *)args[sc->offset]);
		}
		const char *what;
		char buf[30];

		switch (largs.what) {
		case LINUX_SOCKET:
			what = "LINUX_SOCKET";
			break;
		case LINUX_BIND:
			what = "LINUX_BIND";
			break;
		case LINUX_CONNECT:
			what = "LINUX_CONNECT";
			break;
		case LINUX_LISTEN:
			what = "LINUX_LISTEN";
			break;
		case LINUX_ACCEPT:
			what = "LINUX_ACCEPT";
			break;
		case LINUX_GETSOCKNAME:
			what = "LINUX_GETSOCKNAME";
			break;
		case LINUX_GETPEERNAME:
			what = "LINUX_GETPEERNAME";
			break;
		case LINUX_SOCKETPAIR:
			what = "LINUX_SOCKETPAIR";
			break;
		case LINUX_SEND:   
			what = "LINUX_SEND";
			break;
		case LINUX_RECV: 
			what = "LINUX_RECV";
			break;
		case LINUX_SENDTO:
			what = "LINUX_SENDTO";
			break;
		case LINUX_RECVFROM:
			what = "LINUX_RECVFROM";
			break;
		case LINUX_SHUTDOWN:
			what = "LINUX_SHUTDOWN";
			break;
		case LINUX_SETSOCKOPT:
			what = "LINUX_SETSOCKOPT";
			break;
		case LINUX_GETSOCKOPT:
			what = "LINUX_GETSOCKOPT";
			break;
		case LINUX_SENDMSG:
			what = "LINUX_SENDMSG";
			break;
		case LINUX_RECVMSG:
			what = "LINUX_RECVMSG";
			break;
		default:
			sprintf(buf, "%d", largs.what);
			what = buf;
			break;
		}
		asprintf(&tmp, "(0x%lx)%s, 0x%lx", args[sc->offset], what, (long unsigned int)largs.args);
		break;
	}
	case Pollfd: {
		/*
		 * XXX: A Pollfd argument expects the /next/ syscall argument
		 * to be the number of fds in the array. This matches the poll
		 * syscall.
		 */
		struct pollfd *pfd;
		int numfds = args[sc->offset+1];
		int bytes = sizeof(struct pollfd) * numfds;
		int i, tmpsize, u, used;
		const int per_fd = 100;

		if ((pfd = malloc(bytes)) == NULL)
			err(1, "Cannot malloc %d bytes for pollfd array",
			    bytes);
		if (get_struct(pid, (void *)args[sc->offset], pfd, bytes)
		    != -1) {
			used = 0;
			tmpsize = 1 + per_fd * numfds + 2;
			if ((tmp = malloc(tmpsize)) == NULL)
				err(1, "Cannot alloc %d bytes for poll output",
				    tmpsize);

			tmp[used++] = '{';
			for (i = 0; i < numfds; i++) {

				u = snprintf(tmp + used, per_fd, "%s%d/%s",
				    i > 0 ? " " : "", pfd[i].fd,
				    xlookup_bits(poll_flags, pfd[i].events));
				if (u > 0)
					used += u < per_fd ? u : per_fd;
			}
			tmp[used++] = '}';
			tmp[used++] = '\0';
		} else {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		}
		free(pfd);
		break;
	}
	case Fd_set: {
		/*
		 * XXX: A Fd_set argument expects the /first/ syscall argument
		 * to be the number of fds in the array.  This matches the
		 * select syscall.
		 */
		fd_set *fds;
		int numfds = args[0];
		int bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
		int i, tmpsize, u, used;
		const int per_fd = 20;

		if ((fds = malloc(bytes)) == NULL)
			err(1, "Cannot malloc %d bytes for fd_set array",
			    bytes);
		if (get_struct(pid, (void *)args[sc->offset], fds, bytes)
		    != -1) {
			used = 0;
			tmpsize = 1 + numfds * per_fd + 2;
			if ((tmp = malloc(tmpsize)) == NULL)
				err(1, "Cannot alloc %d bytes for fd_set "
				    "output", tmpsize);

			tmp[used++] = '{';
			for (i = 0; i < numfds; i++) {
				if (FD_ISSET(i, fds)) {
					u = snprintf(tmp + used, per_fd, "%d ",
					    i);
					if (u > 0)
						used += u < per_fd ? u : per_fd;
				}
			}
			if (tmp[used-1] == ' ')
				used--;
			tmp[used++] = '}';
			tmp[used++] = '\0';
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		free(fds);
		break;
	}
	case Signal:
		tmp = strsig2(args[sc->offset]);
		break;
	case Sigset: {
		long sig;
		sigset_t ss;
		int i, used;
		char *signame;

		sig = args[sc->offset];
		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
		    sizeof(ss)) == -1) {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
			break;
		}
		tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */
		used = 0;
		for (i = 1; i < sys_nsig; i++) {
			if (sigismember(&ss, i)) {
				signame = strsig(i);
				used += sprintf(tmp + used, "%s|", signame);
				free(signame);
			}
		}
		if (used)
			tmp[used-1] = 0;
		else
			strcpy(tmp, "0x0");
		break;
	}
	case Sigprocmask: {
		switch (args[sc->offset]) {
#define	S(a)	case a: tmp = strdup(#a); break;
			S(SIG_BLOCK);
			S(SIG_UNBLOCK);
			S(SIG_SETMASK);
#undef S
		}
		if (tmp == NULL)
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Fcntlflag: {
		/* XXX output depends on the value of the previous argument */
		switch (args[sc->offset-1]) {
		case F_SETFD:
			tmp = strdup(xlookup_bits(fcntlfd_arg,
			    args[sc->offset]));
			break;
		case F_SETFL:
			tmp = strdup(xlookup_bits(fcntlfl_arg,
			    args[sc->offset]));
			break;
		case F_GETFD:
		case F_GETFL:
		case F_GETOWN:
			tmp = strdup("");
			break;
		default:
			asprintf(&tmp, "0x%lx", args[sc->offset]);
			break;
		}
		break;
	}
	case Open:
		tmp = strdup(xlookup_bits(open_flags, args[sc->offset]));
		break;
	case Fcntl:
		tmp = strdup(xlookup(fcntl_arg, args[sc->offset]));
		break;
	case Mprot:
		tmp = strdup(xlookup_bits(mprot_flags, args[sc->offset]));
		break;
	case Mmapflags: {
		char *base, *alignstr;
		int align, flags;

		/*
		 * MAP_ALIGNED can't be handled by xlookup_bits(), so
		 * generate that string manually and prepend it to the
		 * string from xlookup_bits().  Have to be careful to
		 * avoid outputting MAP_ALIGNED|0 if MAP_ALIGNED is
		 * the only flag.
		 */
		flags = args[sc->offset] & ~MAP_ALIGNMENT_MASK;
		align = args[sc->offset] & MAP_ALIGNMENT_MASK;
		if (align != 0) {
			if (align == MAP_ALIGNED_SUPER)
				alignstr = strdup("MAP_ALIGNED_SUPER");
			else
				asprintf(&alignstr, "MAP_ALIGNED(%d)",
				    align >> MAP_ALIGNMENT_SHIFT);
			if (flags == 0) {
				tmp = alignstr;
				break;
			}
		} else
			alignstr = NULL;
		base = strdup(xlookup_bits(mmap_flags, flags));
		if (alignstr == NULL) {
			tmp = base;
			break;
		}
		asprintf(&tmp, "%s|%s", alignstr, base);
		free(alignstr);
		free(base);
		break;
	}
	case Whence:
		tmp = strdup(xlookup(whence_arg, args[sc->offset]));
		break;
	case Sockdomain:
		tmp = strdup(xlookup(sockdomain_arg, args[sc->offset]));
		break;
	case Socktype:
		tmp = strdup(xlookup(socktype_arg, args[sc->offset]));
		break;
	case Shutdown:
		tmp = strdup(xlookup(shutdown_arg, args[sc->offset]));
		break;
	case Resource:
		tmp = strdup(xlookup(resource_arg, args[sc->offset]));
		break;
	case Pathconf:
		tmp = strdup(xlookup(pathconf_arg, args[sc->offset]));
		break;
	case Rforkflags:
		tmp = strdup(xlookup_bits(rfork_flags, args[sc->offset]));
		break;
	case Sockaddr: {
		struct sockaddr_storage ss;
		char addr[64];
		struct sockaddr_in *lsin;
		struct sockaddr_in6 *lsin6;
		struct sockaddr_un *sun;
		struct sockaddr *sa;
		char *p;
		u_char *q;
		int i;

		if (args[sc->offset] == 0) {
			asprintf(&tmp, "NULL");
			break;
		}

		/* yuck: get ss_len */
		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
		    sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1)
			err(1, "get_struct %p", (void *)args[sc->offset]);
		/*
		 * If ss_len is 0, then try to guess from the sockaddr type.
		 * AF_UNIX may be initialized incorrectly, so always frob
		 * it by using the "right" size.
		 */
		if (ss.ss_len == 0 || ss.ss_family == AF_UNIX) {
			switch (ss.ss_family) {
			case AF_INET:
				ss.ss_len = sizeof(*lsin);
				break;
			case AF_UNIX:
				ss.ss_len = sizeof(*sun);
				break;
			default:
				/* hurrrr */
				break;
			}
		}
		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
		    ss.ss_len) == -1) {
			err(2, "get_struct %p", (void *)args[sc->offset]);
		}

		switch (ss.ss_family) {
		case AF_INET:
			lsin = (struct sockaddr_in *)&ss;
			inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof addr);
			asprintf(&tmp, "{ AF_INET %s:%d }", addr,
			    htons(lsin->sin_port));
			break;
		case AF_INET6:
			lsin6 = (struct sockaddr_in6 *)&ss;
			inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
			    sizeof addr);
			asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr,
			    htons(lsin6->sin6_port));
			break;
		case AF_UNIX:
			sun = (struct sockaddr_un *)&ss;
			asprintf(&tmp, "{ AF_UNIX \"%s\" }", sun->sun_path);
			break;
		default:
			sa = (struct sockaddr *)&ss;
			asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data "
			    "= {%n%*s } }", (int)sa->sa_len, (int)sa->sa_family,
			    &i, 6 * (int)(sa->sa_len - ((char *)&sa->sa_data -
			    (char *)sa)), "");
			if (tmp != NULL) {
				p = tmp + i;
				for (q = (u_char *)&sa->sa_data;
				    q < (u_char *)sa + sa->sa_len; q++)
					p += sprintf(p, " %#02x,", *q);
			}
		}
		break;
	}
	case Sigaction: {
		struct sigaction sa;
		char *hand;
		const char *h;

		if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa))
		    != -1) {
			asprintf(&hand, "%p", sa.sa_handler);
			if (sa.sa_handler == SIG_DFL)
				h = "SIG_DFL";
			else if (sa.sa_handler == SIG_IGN)
				h = "SIG_IGN";
			else
				h = hand;

			asprintf(&tmp, "{ %s %s ss_t }", h,
			    xlookup_bits(sigaction_flags, sa.sa_flags));
			free(hand);
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Kevent: {
		/*
		 * XXX XXX: the size of the array is determined by either the
		 * next syscall argument, or by the syscall returnvalue,
		 * depending on which argument number we are.  This matches the
		 * kevent syscall, but luckily that's the only syscall that uses
		 * them.
		 */
		struct kevent *ke;
		int numevents = -1;
		int bytes = 0;
		int i, tmpsize, u, used;
		const int per_ke = 100;

		if (sc->offset == 1)
			numevents = args[sc->offset+1];
		else if (sc->offset == 3 && retval != -1)
			numevents = retval;

		if (numevents >= 0)
			bytes = sizeof(struct kevent) * numevents;
		if ((ke = malloc(bytes)) == NULL)
			err(1, "Cannot malloc %d bytes for kevent array",
			    bytes);
		if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset],
		    ke, bytes) != -1) {
			used = 0;
			tmpsize = 1 + per_ke * numevents + 2;
			if ((tmp = malloc(tmpsize)) == NULL)
				err(1, "Cannot alloc %d bytes for kevent "
				    "output", tmpsize);

			tmp[used++] = '{';
			for (i = 0; i < numevents; i++) {
				u = snprintf(tmp + used, per_ke,
				    "%s%p,%s,%s,%d,%p,%p",
				    i > 0 ? " " : "",
				    (void *)ke[i].ident,
				    xlookup(kevent_filters, ke[i].filter),
				    xlookup_bits(kevent_flags, ke[i].flags),
				    ke[i].fflags,
				    (void *)ke[i].data,
				    (void *)ke[i].udata);
				if (u > 0)
					used += u < per_ke ? u : per_ke;
			}
			tmp[used++] = '}';
			tmp[used++] = '\0';
		} else {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		}
		free(ke);
		break;
	}
	case Stat: {
		struct stat st;
		if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st))
		    != -1) {
			char mode[12];
			strmode(st.st_mode, mode);
			asprintf(&tmp,
			    "{ mode=%s,inode=%jd,size=%jd,blksize=%ld }", mode,
			    (intmax_t)st.st_ino, (intmax_t)st.st_size,
			    (long)st.st_blksize);
		} else {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		}
		break;
	}
	case Rusage: {
		struct rusage ru;
		if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru))
		    != -1) {
			asprintf(&tmp,
			    "{ u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld }",
			    (long)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
			    (long)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec,
			    ru.ru_inblock, ru.ru_oublock);
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Rlimit: {
		struct rlimit rl;
		if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl))
		    != -1) {
			asprintf(&tmp, "{ cur=%ju,max=%ju }",
			    rl.rlim_cur, rl.rlim_max);
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case ExitStatus: {
		char *signame;
		int status;
		signame = NULL;
		if (get_struct(pid, (void *)args[sc->offset], &status,
		    sizeof(status)) != -1) {
			if (WIFCONTINUED(status))
				tmp = strdup("{ CONTINUED }");
			else if (WIFEXITED(status))
				asprintf(&tmp, "{ EXITED,val=%d }",
				    WEXITSTATUS(status));
			else if (WIFSIGNALED(status))
				asprintf(&tmp, "{ SIGNALED,sig=%s%s }",
				    signame = strsig2(WTERMSIG(status)),
				    WCOREDUMP(status) ? ",cored" : "");
			else
				asprintf(&tmp, "{ STOPPED,sig=%s }",
				    signame = strsig2(WTERMSIG(status)));
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		free(signame);
		break;
	}
	case Waitoptions:
		tmp = strdup(xlookup_bits(wait_options, args[sc->offset]));
		break;
	case Idtype:
		tmp = strdup(xlookup(idtype_arg, args[sc->offset]));
		break;
	case Procctl:
		tmp = strdup(xlookup(procctl_arg, args[sc->offset]));
		break;
	default:
		errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
	}
Exemplo n.º 3
0
//int CreateChild()
int CreateChild(flooder f)
{
  int status;
  int cstatus;
  int pstatus;

  pid = fork();
  switch(pid)
  {
    case -1:
      /* Failure */
      perror("fork failed");
      exit(1);
    case 0:
      /* Child */
      printf("Creating child process...pid: %d\n", pid);

      // Get the child pid
      printf("In [CreateChild] - getting child pid with getpid(): %d\n", getpid());
    
      printf("In [CreateChild] - starting udpinject script...\n");

      // Construct the packit injection string from the flooder
      printf("In [CreateChild] - constructing 'injector' string\n");
      //char injector[168];
      char injector[169];
      //char * injector;

      //sprintf(injector, "/usr/sbin/packit -m inject -t UDP -s %s -d %s -S %d -D %d -c %d -b 20 -p '0x 68 76 6D 72 20 74 65 73 74 20 75 70 64 20 70 61 63 6B 65 74 73'", f.sipaddr, f.dipaddr, f.sportno, f.dportno, f.tinterval);
      //sprintf(injector, "packit -m inject -t UDP -s %s -d %s -S %d -D %d -c %d -b 20 -p '0x 68 76 6D 72 20 74 65 73 74 20 75 70 64 20 70 61 63 6B 65 74 73'", f.sipaddr, f.dipaddr, f.sportno, f.dportno, f.tinterval);

      // Redirect stdout and stderr to log file
      int out = open(LOG_FILE, O_RDWR|O_CREAT|O_APPEND,0600);
      if (-1 == out) { perror("opening flooder.log"); return 255; }

      //int err = open("error.log", O_RDWR|O_CREAT|O_APPEND, 0600);
      int err = open(ERROR_LOG_FILE, O_RDWR|O_CREAT|O_APPEND, 0600);
      if (-1 == err) { perror("opening error.log"); return 255; }

      int save_out = dup(fileno(stdout));
      int save_err = dup(fileno(stderr));

      if (-1 == dup2(out, fileno(stdout))) { perror("cannot redirect stdout"); return 255; }
      if (-1 == dup2(err, fileno(stderr))) { perror("cannot redirect stderr"); return 255; }

      //execlp("/home/jim/udpinject.sh", "udpinject.sh", (char *) NULL);

      /*
      // Construct the packit injection string from the flooder
      printf("In [CreateChild] - constructing 'injector' string\n");
      //char injector[168];
      char injector[169];
      //char * injector;

      //sprintf(injector, "/usr/sbin/packit -m inject -t UDP -s %s -d %s -S %d -D %d -c %d -b 20 -p '0x 68 76 6D 72 20 74 65 73 74 20 75 70 64 20 70 61 63 6B 65 74 73'", f.sipaddr, f.dipaddr, f.sportno, f.dportno, f.tinterval);
      //sprintf(injector, "packit -m inject -t UDP -s %s -d %s -S %d -D %d -c %d -b 20 -p '0x 68 76 6D 72 20 74 65 73 74 20 75 70 64 20 70 61 63 6B 65 74 73'", f.sipaddr, f.dipaddr, f.sportno, f.dportno, f.tinterval);
       */

      // Start injecting packets
      printf("In [CreateChild] ...using 'injector' string:\n");
      printf("%s\n", injector);
      //system(injector);
      //execlp("/usr/sbin/packit", injector, (char *) NULL);

      //execlp("/usr/sbin/packit", "packit", "-m", "inject", "-t", "UDP", "-s", "10.10.10.208", "-d", "10.10.10.9", "-S", "403", "-D", "80", "-c", "300", "-b", "20", "-p", "'0x 68 76 6D 72 20 74 65 73 74 20 75 70 64 20 70 61 63 6B 65 74 73'", (char *) NULL);

      execlp("/usr/sbin/packit", "packit", "-m", "inject", "-t", "UDP", "-s", f.sipaddr, "-d", f.dipaddr, "-S", f.sportno , "-D", f.dportno, "-c", f.tinterval, "-b", "20", "-p", "'0x 68 76 6D 72 20 74 65 73 74 20 75 70 64 20 70 61 63 6B 65 74 73'", (char *) NULL);

      //system("packit -m inject -t UDP -s 10.10.10.208 -d 10.10.10.9 -S 403 -D 80 -c 300 -b 20 -p '0x 68 76 6D 72 20 74 65 73 74 20 75 70 64 20 70 61 63 6B 65 74 73'");

      fflush(stdout); close(out);
      fflush(stderr); close(err);

      dup2(save_out, fileno(stdout));
      dup2(save_err, fileno(stderr));

      close(save_out);
      close(save_err);

      waitpid(pid, &status, WNOHANG);
      printf("In [CreateChild] - child pid: %d\n", getpid());
      printf("In [CreateChild] - child waitpid status: %d\n",status);

      do
      {
        // Get pid exit status
        pid_t w = waitpid(getpid(), &cstatus, WUNTRACED | WCONTINUED);
        if(w == -1) { perror("waitpid"); exit(EXIT_FAILURE); }

        if (WIFEXITED(cstatus))
        {
          printf("exited, status=%d\n", WEXITSTATUS(cstatus));
        }
        else if (WIFSIGNALED(cstatus))
        {
          printf("killed by signal %d\n", WTERMSIG(cstatus));
        }
        else if (WIFSTOPPED(cstatus))
        {
          printf("stopped signal %d\n", WSTOPSIG(cstatus));
        }
        else if (WIFCONTINUED(cstatus))
        {
          printf("continued\n");
        }
      } 
      while (!WIFEXITED(cstatus) && !WIFSIGNALED(cstatus));

      exit(EXIT_SUCCESS);
  }
}
Exemplo n.º 4
0
static void process_wait(void *opaque) {
	Process *process = opaque;
	int status;
	int rc;
	ProcessStateChange change;

	for (;;) {
		do {
			rc = waitpid(process->pid, &status, WUNTRACED | WCONTINUED);
		} while (rc < 0 && errno_interrupted());

		if (rc < 0) {
			log_error("Could not wait for child process (executable: %s, pid: %u) state change: %s (%d)",
			          process->executable->buffer, process->pid, get_errno_name(errno), errno);

			break;
		}

		change.timestamp = time(NULL);

		if (WIFEXITED(status)) {
			change.state = PROCESS_STATE_EXITED;
			change.exit_code = WEXITSTATUS(status);

			// the child process has limited capabilities to report errors. the
			// coreutils env executable that executes other programs reserves
			// three exit codes to report errors (125, 126 and 127). our child
			// process uses the same mechanism. check for these three exit codes
			// and change state to error if found. the downside of this approach
			// is that these three exit codes can be used by the program to be
			// executed as normal exit codes with a different meaning, leading
			// to a misinterpretation here. but the coreutils env executable has
			// the same problem, so we will live with this
			if (change.exit_code == PROCESS_E_INTERNAL_ERROR ||
			    change.exit_code == PROCESS_E_CANNOT_EXECUTE ||
			    change.exit_code == PROCESS_E_DOES_NOT_EXIST) {
				change.state = PROCESS_STATE_ERROR;
			}
		} else if (WIFSIGNALED(status)) {
			change.state = PROCESS_STATE_KILLED;
			change.exit_code = WTERMSIG(status);
		} else if (WIFSTOPPED(status)) {
			change.state = PROCESS_STATE_STOPPED;
			change.exit_code = WSTOPSIG(status);
		} else if (WIFCONTINUED(status)) {
			change.state = PROCESS_STATE_RUNNING;
			change.exit_code = 0; // invalid
		} else {
			change.state = PROCESS_STATE_UNKNOWN;
			change.exit_code = 0; // invalid
		}

		log_debug("State of child process (executable: %s, pid: %u) changed (state: %s, exit_code: %u)",
		          process->executable->buffer, process->pid,
		          process_get_state_name(change.state), change.exit_code);

		if (pipe_write(&process->state_change_pipe, &change, sizeof(change)) < 0) {
			log_error("Could not write to state change pipe for child process (executable: %s, pid: %u): %s (%d)",
			          process->executable->buffer, process->pid, get_errno_name(errno), errno);

			break;
		}

		if (!process_state_is_alive(change.state)) {
			break;
		}
	}
}
Exemplo n.º 5
0
static void monitor_worker_process(int child_pid, const debugger_request_t& request) {
  struct timespec timeout = {.tv_sec = 10, .tv_nsec = 0 };
  if (should_attach_gdb(request)) {
    // If wait_for_gdb is enabled, set the timeout to something large.
    timeout.tv_sec = INT_MAX;
  }

  sigset_t signal_set;
  sigemptyset(&signal_set);
  sigaddset(&signal_set, SIGCHLD);

  bool kill_worker = false;
  bool kill_target = false;
  bool kill_self = false;

  int status;
  siginfo_t siginfo;
  int signal = TEMP_FAILURE_RETRY(sigtimedwait(&signal_set, &siginfo, &timeout));
  if (signal == SIGCHLD) {
    pid_t rc = waitpid(-1, &status, WNOHANG | WUNTRACED);
    if (rc != child_pid) {
      ALOGE("debuggerd: waitpid returned unexpected pid (%d), committing murder-suicide", rc);

      if (WIFEXITED(status)) {
        ALOGW("debuggerd: pid %d exited with status %d", rc, WEXITSTATUS(status));
      } else if (WIFSIGNALED(status)) {
        ALOGW("debuggerd: pid %d received signal %d", rc, WTERMSIG(status));
      } else if (WIFSTOPPED(status)) {
        ALOGW("debuggerd: pid %d stopped by signal %d", rc, WSTOPSIG(status));
      } else if (WIFCONTINUED(status)) {
        ALOGW("debuggerd: pid %d continued", rc);
      }

      kill_worker = true;
      kill_target = true;
      kill_self = true;
    } else if (WIFSIGNALED(status)) {
      ALOGE("debuggerd: worker process %d terminated due to signal %d", child_pid, WTERMSIG(status));
      kill_worker = false;
      kill_target = true;
    } else if (WIFSTOPPED(status)) {
      ALOGE("debuggerd: worker process %d stopped due to signal %d", child_pid, WSTOPSIG(status));
      kill_worker = true;
      kill_target = true;
    }
  } else {
    ALOGE("debuggerd: worker process %d timed out", child_pid);
    kill_worker = true;
    kill_target = true;
  }

  if (kill_worker) {
    // Something bad happened, kill the worker.
    if (kill(child_pid, SIGKILL) != 0) {
      ALOGE("debuggerd: failed to kill worker process %d: %s", child_pid, strerror(errno));
    } else {
      waitpid(child_pid, &status, 0);
    }
  }

  int exit_signal = SIGCONT;
  if (kill_target && request.action == DEBUGGER_ACTION_CRASH) {
    ALOGE("debuggerd: killing target %d", request.pid);
    exit_signal = SIGKILL;
  } else {
    ALOGW("debuggerd: resuming target %d", request.pid);
  }

  if (kill(request.pid, exit_signal) != 0) {
    ALOGE("debuggerd: failed to send signal %d to target: %s", exit_signal, strerror(errno));
  }

  if (kill_self) {
    stop_signal_sender();
    _exit(1);
  }
}

static void handle_request(int fd) {
  ALOGV("handle_request(%d)\n", fd);

  android::base::unique_fd closer(fd);
  debugger_request_t request;
  memset(&request, 0, sizeof(request));
  int status = read_request(fd, &request);
  if (status != 0) {
    return;
  }

  ALOGW("debuggerd: handling request: pid=%d uid=%d gid=%d tid=%d\n", request.pid, request.uid,
        request.gid, request.tid);

#if defined(__LP64__)
  // On 64 bit systems, requests to dump 32 bit and 64 bit tids come
  // to the 64 bit debuggerd. If the process is a 32 bit executable,
  // redirect the request to the 32 bit debuggerd.
  if (is32bit(request.tid)) {
    // Only dump backtrace and dump tombstone requests can be redirected.
    if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE ||
        request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
      redirect_to_32(fd, &request);
    } else {
      ALOGE("debuggerd: Not allowed to redirect action %d to 32 bit debuggerd\n", request.action);
    }
    return;
  }
#endif

  // Fork a child to handle the rest of the request.
  pid_t fork_pid = fork();
  if (fork_pid == -1) {
    ALOGE("debuggerd: failed to fork: %s\n", strerror(errno));
  } else if (fork_pid == 0) {
    worker_process(fd, request);
  } else {
    monitor_worker_process(fork_pid, request);
  }
}
Exemplo n.º 6
0
static void handle_child(pid_t childpid, int childstatus)
{
	unsigned int i;
	int slot;

	switch (childpid) {
	case 0:
		//debugf("[%d] Nothing changed. children:%d\n", getpid(), shm->running_childs);
		break;

	case -1:
		if (shm->exit_reason != STILL_RUNNING)
			return;

		if (errno == ECHILD) {
			debugf("[%d] All children exited!\n", getpid());
			for_each_pidslot(i) {
				if (shm->pids[i] != EMPTY_PIDSLOT) {
					if (pid_alive(shm->pids[i]) == -1) {
						debugf("[%d] Removing %d from pidmap\n", getpid(), shm->pids[i]);
						shm->pids[i] = EMPTY_PIDSLOT;
						shm->running_childs--;
					} else {
						debugf("[%d] %d looks still alive! ignoring.\n", getpid(), shm->pids[i]);
					}
				}
			}
			break;
		}
		output(0, "error! (%s)\n", strerror(errno));
		break;

	default:
		debugf("[%d] Something happened to pid %d\n", getpid(), childpid);

		if (WIFEXITED(childstatus)) {

			slot = find_pid_slot(childpid);
			if (slot == PIDSLOT_NOT_FOUND) {
				printf("[%d] ## Couldn't find pid slot for %d\n", getpid(), childpid);
				shm->exit_reason = EXIT_LOST_PID_SLOT;
				dump_pid_slots();
			} else {
				debugf("[%d] Child %d exited after %ld syscalls.\n", getpid(), childpid, shm->child_syscall_count[slot]);
				reap_child(childpid);
			}
			break;

		} else if (WIFSIGNALED(childstatus)) {

			switch (WTERMSIG(childstatus)) {
			case SIGALRM:
				debugf("[%d] got a alarm signal from pid %d\n", getpid(), childpid);
				break;
			case SIGFPE:
			case SIGSEGV:
			case SIGKILL:
			case SIGPIPE:
			case SIGABRT:
				debugf("[%d] got a signal from pid %d (%s)\n", getpid(), childpid, strsignal(WTERMSIG(childstatus)));
				reap_child(childpid);
				break;
			default:
				debugf("[%d] ** Child got an unhandled signal (%d)\n", getpid(), WTERMSIG(childstatus));
				break;
			}
			break;

		} else if (WIFSTOPPED(childstatus)) {

			switch (WSTOPSIG(childstatus)) {
			case SIGALRM:
				debugf("[%d] got an alarm signal from pid %d\n", getpid(), childpid);
				break;
			case SIGSTOP:
				debugf("[%d] Sending PTRACE_DETACH (and then KILL)\n", getpid());
				ptrace(PTRACE_DETACH, childpid, NULL, NULL);
				kill(childpid, SIGKILL);
				reap_child(childpid);
				break;
			case SIGFPE:
			case SIGSEGV:
			case SIGKILL:
			case SIGPIPE:
			case SIGABRT:
				debugf("[%d] Child %d was stopped by %s\n", getpid(), childpid, strsignal(WTERMSIG(childstatus)));
				reap_child(childpid);
				break;
			default:
				debugf("[%d] Child %d was stopped by unhandled signal (%s).\n", getpid(), childpid, strsignal(WSTOPSIG(childstatus)));
				break;
			}
			break;

		} else if (WIFCONTINUED(childstatus)) {
			break;
		} else {
			output(0, "erk, wtf\n");
		}
	}
Exemplo n.º 7
0
ni_bool_t
ni_process_continued(const ni_process_t *pi)
{
	return pi && WIFCONTINUED(pi->status);
}
Exemplo n.º 8
0
int
main (int argc, char *argv[])
{
  int var = 1;

  /* The fork system call is used by a process to request
     that the kernel create a new process.

     After fork has been called a new child process exists.
     Both the parent and the child then keep executing
     from the point right after the call to fork.
     Thus, both the parent and the child process both
     get a return value from fork.

     The child process gets a return value of 0, and
     the parent process gets a return value equal to the
     process ID of the newly created child.
   */
  int c1 = 0;
  c1 = fork ();
  if (c1 == 0)
    {

      /* we enter this block only if fork returns 0,
         which indicates that we are the child process */
      printf ("Value of var from child = %d\n", var);
      ++var;			// var is only incremented in the child process
    }
  else
    {

      // the parent process does not increment var; it sleeps instead
      int status;
      int retvalue = 0;
      while (retvalue != c1)

	{
	  status = 0;
	  retvalue = waitpid (c1, &status, 0);
	  if (retvalue < 0)

	    {
	      char buffer[256];
	      strerror_r (errno, buffer, 256);
	      printf ("error occured %s\n", buffer);
	      break;
	    }

	  else

	    {
	      printf ("state of process %d changed - ", retvalue);
	      if (WIFEXITED (status))
		{
		  printf ("exited, status=%d\n", WEXITSTATUS (status));
		}
	      else if (WIFSIGNALED (status))
		{
		  printf ("killed by signal %d\n", WTERMSIG (status));
		}
	      else if (WIFSTOPPED (status))
		{
		  printf ("stopped by signal %d\n", WSTOPSIG (status));
		}
	      else if (WIFCONTINUED (status))
		{
		  printf ("continued\n");
		}
	    }
	}
    }

  /* The line below will be executed twice: once from the
     child and once from the parent.

     Recall that the parent process and child process have
     separate address spaces; thus, because only the child
     incremented the value of var, only the child will
     print that the value of var is 2.
   */
  printf ("From process %d, value of var is %d.\n", getpid (), var);
  return 0;
}
Exemplo n.º 9
0
int main(int argc, char ** argv) {
	int option, nerror = 0, background = 0, quiet = 0, have_socket = 0;
	time_t pauselength = 0;
	char * proxy;
	opterr = 0;

	/* Create directories. */
	makercd();

	/* Load settings from ~/.shell-fm/shell-fm.rc. */
	settings(rcpath("shell-fm.rc"), !0);

	/* Enable discovery by default if it is set in configuration. */
	if(haskey(& rc, "discovery"))
		enable(DISCOVERY);

	/* Disable RTP if option "no-rtp" is set to something. */
	if(haskey(& rc, "no-rtp"))
		disable(RTP);

	/* If "daemon" is set in the configuration, enable daemon mode by default. */
	if(haskey(& rc, "daemon"))
		background = !0;

	/* If "quiet" is set in the configuration, enable quiet mode by default. */
	if(haskey(& rc, "quiet"))
		quiet = !0;

	/* Get proxy environment variable. */
	if((proxy = getenv("http_proxy")) != NULL)
		set(& rc, "proxy", proxy);


	/* Parse through command line options. */
	while(-1 != (option = getopt(argc, argv, ":dbhqi:p:D:y:Y:")))
		switch(option) {
			case 'd': /* Daemonize. */
				background = !background;
				break;

			case 'i': /* IP to bind network interface to. */
				set(& rc, "bind", optarg);
				break;

			case 'p': /* Port to listen on. */
				if(atoi(optarg))
					set(& rc, "port", optarg);
				else {
					fputs("Invalid port.\n", stderr);
					++nerror;
				}
				break;

			case 'b': /* Batch mode */
				batch = !0;
				break;

			case 'D': /* Path to audio device file. */
				set(& rc, "device", optarg);
				break;

			case 'y': /* Proxy address. */
				set(& rc, "proxy", optarg);
				break;

			case 'Y': /* SOCKS proxy address. */
				set(& rc, "socks-proxy", optarg);
				break;

			case 'q': /* Quiet mode. */
				quiet = !quiet;
				break;

			case 'h': /* Print help text and exit. */
				help(argv[0], 0);
				break;

			case ':':
				fprintf(stderr, "Missing argument for option -%c.\n\n", optopt);
				++nerror;
				break;

			case '?':
			default:
				fprintf(stderr, "Unknown option -%c.\n", optopt);
				++nerror;
				break;
		}

	/* The next argument, if present, is the lastfm:// URL we want to play. */
	if(optind > 0 && optind < argc && argv[optind]) {
		const char * station = argv[optind];

		set(& rc, "default-radio", station);
	}


	if(nerror)
		help(argv[0], EXIT_FAILURE);

#ifdef EXTERN_ONLY
	/* Abort if EXTERN_ONLY is defined and no extern command is present */
	if(!haskey(& rc, "extern")) {
		fputs("Can't continue without extern command.\n", stderr);
		exit(EXIT_FAILURE);
	}
#else
#ifndef LIBAO
	if(!haskey(& rc, "device"))
		set(& rc, "device", "/dev/audio");
#endif
#endif

	if(!background && !quiet) {
		puts("Shell.FM v" PACKAGE_VERSION ", (C) 2006-2012 by Jonas Kramer");
		puts("Published under the terms of the GNU General Public License (GPL).");

#ifndef TUXBOX
		puts("\nPress ? for help.\n");
#else
		puts("Compiled for the use with Shell.FM Wrapper.\n");
#endif
		fflush(stdout);
	}


	/* Open a port so Shell.FM can be controlled over network. */
	if(haskey(& rc, "bind")) {
		int port = 54311;

		if(haskey(& rc, "port"))
			port = atoi(value(& rc, "port"));

		if(tcpsock(value(& rc, "bind"), (unsigned short) port))
			have_socket = !0;
	}


	/* Open a UNIX socket for local "remote" control. */
	if(haskey(& rc, "unix") && unixsock(value(& rc, "unix")))
		have_socket = !0;


	/* We can't daemonize if there's no possibility left to control Shell.FM. */
	if(background && !have_socket) {
		fputs("Can't daemonize without control socket.\n", stderr);
		exit(EXIT_FAILURE);
	}

	memset(& data, 0, sizeof(struct hash));
	memset(& track, 0, sizeof(struct hash));
	memset(& playlist, 0, sizeof(struct playlist));

	/* Fork to background. */
	if(background) {
		int null;
		pid_t pid = fork();

		if(pid == -1) {
			fputs("Failed to daemonize.\n", stderr);
			exit(EXIT_FAILURE);
		} else if(pid) {
			exit(EXIT_SUCCESS);
		}

		enable(QUIET);

		/* Detach from TTY */
		setsid();
		pid = fork();

		if(pid > 0)
			exit(EXIT_SUCCESS);

		/* Close stdin out and err */
		close(0);
		close(1);
		close(2);

		/* Redirect  stdin and out to /dev/null */
		null = open("/dev/null", O_RDWR);
		dup(null);
		dup(null);
	}

	ppid = getpid();

	atexit(cleanup);
	load_queue();

	/* Set up signal handlers for communication with the playback process. */
	signal(SIGINT, forcequit);

	/* SIGUSR2 from playfork means it detected an error. */
	signal(SIGUSR2, playsig);

	/* Catch SIGTSTP to set pausetime when user suspends us with ^Z. */
	signal(SIGTSTP, stopsig);

	/* Authenticate to the Last.FM server. */
	create_session();

	if(!background) {
		struct input keyboard = { 0, KEYBOARD };
		register_handle(keyboard);
		canon(0);
		atexit(cleanup_term);
	}


	/* Play default radio, if specified. */
	if(haskey(& rc, "default-radio")) {
		if(!strcmp(value(& rc, "default-radio"), "last")) {
			char ** history = load_history(), * last = NULL, ** p;

			for(p = history; * p != NULL; ++p) {
				last = * p;
			}

			set(& rc, "default-radio", last);
			purge(history);
		}

		station(value(& rc, "default-radio"));
	}

	else if(!background)
		radioprompt("radio url> ");

	/* The main loop. */
	while(!0) {
		pid_t child;
		int status, playnext = 0;

		/* Check if anything died (submissions fork or playback fork). */
		while((child = waitpid(-1, & status, WNOHANG | WUNTRACED | WCONTINUED)) > 0) {
			if(child == subfork)
				subdead(WEXITSTATUS(status));
			else if(child == playfork) {
				if(WIFSTOPPED(status)) {
					/* time(& pausetime); */
				}
				else {
					if(WIFCONTINUED(status)) {
						signal(SIGTSTP, stopsig);
						if(pausetime != 0) {
							pauselength += time(NULL) - pausetime;
						}
					}
					else {
						playnext = !0;
						unlinknp();

						if(delayquit) {
							quit();
						}
					}
					pausetime = 0;
				}
			}
		}

		/*
			Check if the playback process died. If so, submit the data
			of the last played track. Then check if there are tracks left
			in the playlist; if not, try to refresh the list and stop the
			stream if there are no new tracks to fetch.
			Also handle user stopping the stream here.  We need to check for
			playnext != 0 before handling enabled(STOPPED) anyway, otherwise
			playfork would still be running.
		*/
		if(playnext) {
			playfork = 0;

			if(enabled(RTP)) {
				unsigned duration, played, minimum;

				duration = atoi(value(& track, "duration"));
				played = time(NULL) - change_time - pauselength;

				/* Allow user to specify minimum playback length (min. 50%). */
				if(haskey(& rc, "minimum")) {
					unsigned percent = atoi(value(& rc, "minimum"));
					if(percent < 50)
						percent = 50;
					minimum = duration * percent / 100;
				}
				else {
					minimum = duration / 2;
				}

				if(duration >= 30 && (played >= 240 || played > minimum)) {
					debug("adding track to scrobble queue\n");
					enqueue(& track);
				}
				else {
					debug("track too short (duration %d, played %d, minimum %d) - not scrobbling\n", duration, played, minimum);
				}
			}

			submit();

			/* Check if the user stopped the stream. */
			if(enabled(STOPPED) || error) {
				freelist(& playlist);
				empty(& track);

				if(error) {
					fputs("Playback stopped with an error.\n", stderr);
					error = 0;
				}

				disable(STOPPED);
				disable(CHANGED);

				continue;
			}

			shift(& playlist);
		}


		if(playnext || enabled(CHANGED)) {
			if(nextstation != NULL) {
				playnext = 0;
				disable(CHANGED);

				if(!station(nextstation))
					enable(STOPPED);

				free(nextstation);
				nextstation = NULL;
			}

			if(!enabled(STOPPED) && !playlist.left) {
				expand(& playlist);
				if(!playlist.left) {
					puts("No tracks left.");
					playnext = 0;
					disable(CHANGED);
					continue;
				}
			}

			if(!playfork) {
				/*
					If there was a track played before, and there is a gap
					configured, wait that many seconds before playing the next
					track.
				*/
				if(playnext && !enabled(INTERRUPTED) && haskey(& rc, "gap")) {
					int gap = atoi(value(& rc, "gap"));

					if(gap > 0)
						sleep(gap);
				}

				disable(INTERRUPTED);

				if(play(& playlist)) {
					time(& change_time);
					pauselength = 0;

					set(& track, "stationURL", current_station);

					/* Print what's currently played. (Ondrej Novy) */
					if(!background) {
						if(enabled(CHANGED) && playlist.left > 0) {
							puts(meta("Receiving %s.", M_COLORED, & track));
							disable(CHANGED);
						}

						if(haskey(& rc, "title-format"))
							printf("%s\n", meta(value(& rc, "title-format"), M_COLORED, & track));
						else
							printf("%s\n", meta("Now playing \"%t\" by %a.", M_COLORED, & track));
					}

					if(enabled(RTP)) {
						notify_now_playing(& track);
					}


					/* Write track data into a file. */
					if(haskey(& rc, "np-file") && haskey(& rc, "np-file-format")) {
						signed np;
						const char
							* file = value(& rc, "np-file"),
							* fmt = value(& rc, "np-file-format");

						unlink(file);
						if(-1 != (np = open(file, O_WRONLY | O_CREAT, 0644))) {
							const char * output = meta(fmt, 0, & track);
							if(output)
								write(np, output, strlen(output));
							close(np);
						}
					}


					if(haskey(& rc, "screen-format")) {
						const char * term = getenv("TERM");
						if(term != NULL && !strncmp(term, "screen", 6)) {
							const char * output =
								meta(value(& rc, "screen-format"), 0, & track);
							printf("\x1Bk%s\x1B\\", output);
						}
					}


					if(haskey(& rc, "term-format")) {
						const char * output =
							meta(value(& rc, "term-format"), 0, & track);
						printf("\x1B]2;%s\a", output);
					}


					/* Run a command with our track data. */
					if(haskey(& rc, "np-unescaped-cmd"))
						run(meta(value(& rc, "np-unescaped-cmd"), 0, & track));
					if(haskey(& rc, "np-cmd"))
						run(meta(value(& rc, "np-cmd"), M_SHELLESC, & track));
				} else
					change_time = 0;
			}

			if(banned(value(& track, "creator"))) {
				puts(meta("%a is banned.", M_COLORED, & track));
				rate(RATING_BAN);
				fflush(stdout);
			}
		}

		playnext = 0;

		if(playfork && change_time && haskey(& track, "duration") && !pausetime) {
			unsigned duration;
			signed remain;
			char remstr[32];

			duration = atoi(value(& track, "duration"));

			remain = (change_time + duration) - time(NULL) + pauselength;

			snprintf(remstr, sizeof(remstr), "%d", remain);
			set(& track, "remain", remstr);

			if(!background) {
				printf(
					"%s%c",
					meta("%r", M_COLORED, & track),
					// strdup(meta("%v", M_COLORED, & track)),
					batch ? '\n' : '\r'
				);
				fflush(stdout);
			}
		}

		handle_input(1000000);
	}

	return 0;
}
Exemplo n.º 10
0
//SIGPIPE是正常的信号,对端断开后本端协议栈在向对端传送数据时,对端会返回TCP RST,导致本端抛出SIGPIPE信号
void init_daemon(char* cmd) 
{ 
	int pid;  
    char *buf = "This is a Daemon, wcdj\n";  
    char path[FILEPATH_MAX];
    getRealPath(path);
    strcat(path,"/");
	strcat(path,"pushserver.lock");
	pid = readPidFile(path);
	if(pid != -1)
	{
    	printf("The server is start ...\n");    	
    }    	    
    if(strcmp(cmd,"stop") == 0 && pid != -1){
    	closeServer(pid,0);
    	int status;
    	int w;
    	 do {
            w = waitpid(pid, &status, WUNTRACED | WCONTINUED);
            if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); }

            if (WIFEXITED(status)) {
                printf("exited, status=%d/n", WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                printf("killed by signal %d/n", WTERMSIG(status));
            } else if (WIFSTOPPED(status)) {
                printf("stopped by signal %d/n", WSTOPSIG(status));
            } else if (WIFCONTINUED(status)) {
                printf("continued/n");
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    	exit(0);
    }    
    else if(strcmp(cmd,"restart") == 0 && pid != -1){
    	int status;
    	int w;
    	 do {
            w = waitpid(pid, &status, WUNTRACED | WCONTINUED);
            if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); }

            if (WIFEXITED(status)) {
                printf("exited, status=%d/n", WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                printf("killed by signal %d/n", WTERMSIG(status));
            } else if (WIFSTOPPED(status)) {
                printf("stopped by signal %d/n", WSTOPSIG(status));
            } else if (WIFCONTINUED(status)) {
                printf("continued/n");
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    	
    }else if(pid != -1){
    	printf("The server is start ...\n");   
    	exit(0);
    }
  	
    /* 屏蔽一些有关控制终端操作的信号 
     * 防止在守护进程没有正常运转起来时,因控制终端受到干扰退出或挂起 
     */  
    signal(SIGINT,  SIG_IGN);// 终端中断  
    signal(SIGHUP,  SIG_IGN);// 连接挂断  
    signal(SIGQUIT, SIG_IGN);// 终端退出  
    signal(SIGPIPE, SIG_IGN);// 向无读进程的管道写数据  
    signal(SIGTTOU, SIG_IGN);// 后台程序尝试写操作  
    signal(SIGTTIN, SIG_IGN);// 后台程序尝试读操作  
    signal(SIGTERM, SIG_IGN);// 终止  
    
    struct rlimit        rl;
 	if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
        printf("%s: can't get file limit", "pushserver");
        
	int i; 
	/*
	pid=fork();
	if(pid>0) 
		exit(0);//是父进程,结束父进程 
	else if(pid< 0) 
		exit(1);//fork失败,退出 
	//是第一子进程,后台继续执行 
	setsid();//第一子进程成为新的会话组长和进程组长 
	//并与控制终端分离 
	pid=fork();
	if(pid>0) 
		exit(0);//是第一子进程,结束第一子进程 
	else if(pid< 0) 
		exit(1);//fork失败,退出 
		*/
	if ((pid = fork()) < 0)
        printf("%s: can't fork", cmd);
    else if (pid != 0) /* parent */{
    	printf("tuichuzhu\n");
    	   exit(0);	
    }
    printf("jinlaile\n");
     
        
    setsid();
         
	//是第二子进程,继续 
	//第二子进程不再是会话组长 
	
	main_pid = getpid();     
	writePidFile(path);
	     
	for(i=3;i< NOFILE;++i)//关闭打开的文件描述符 MAXFILE 65536
		close(i); 
		     
	/*
	// [3] set current path  
    char szPath[1024];  
    if(getcwd(szPath, sizeof(szPath)) == NULL)  
    {  
        perror("getcwd");  
        exit(1);  
    }  
    else  
    {  
        chdir(szPath);  
        printf("set current path succ [%s]\n", szPath);  
    }  
    */     
	//chdir("/tmp");//改变工作目录到/tmp 
	umask(0);//重设文件创建掩模 
	 // [6] set termianl signal  
	     
 	signal(SIGTERM, wait_close); 
	signal(SIGHUP, restart_server);
	     
	/*
     * Close all open file descriptors.
     */
    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;
    for (i = 0; i < rl.rlim_max; i++)
        close(i);
     
    /*
     * Attach file descriptors 0, 1, and 2 to /dev/null.
     */     
    int fd0 = open("/dev/null", O_RDWR);
    int fd1 = dup(0);
    int fd2 = dup(0);
     
    /*
     * Initialize the log file.
     */     
    openlog("pushserver", LOG_CONS, LOG_DAEMON);
    if (fd0 != 0 || fd1 != 1 || fd2 != 2) {     
        syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2);
        exit(1);
    }     
    syslog(LOG_DEBUG, "daem ok ");
           
	return; 
} 
Exemplo n.º 11
0
/* Monitoring the subprocess end and get the return value */
static void *
monitor (void *arg)
{
  subprocess_t *p = arg;
  struct timespec start_time;

  /* Initializing the pipes () */
  int stdin_pipe[2];		/* '0' = child_read,  '1' = parent_write */
  int stdout_pipe[2];		/* '0' = parent_read, '1' = child_write */
  int stderr_pipe[2];		/* '0' = parent_read, '1' = child_write */

  CHECK_ERROR (((pipe (stdin_pipe) == -1) ||
		(pipe (stdout_pipe) == -1) ||
		(pipe (stderr_pipe) == -1)), "pipe initialization failed");

  /* We create a child process running the subprocess and we wait for
   * it to finish. If a timeout elapsed the child is killed. Waiting
   * is done using sigtimedwait(). Race condition is avoided by
   * blocking the SIGCHLD signal before fork() and storing it into the
   * buffer while starting the timer in a separate pthread. */

  /* Blocking SIGCHLD before forking */
  sigset_t mask;

  CHECK_ERROR ((sigemptyset (&mask) == -1), "sigemptyset failed");
  CHECK_ERROR ((sigaddset (&mask, SIGCHLD) == -1), "sigaddset failed");

  CHECK_ERROR ((sigprocmask (SIG_BLOCK, &mask, NULL) == -1),
	       "sigprocmask failed");

  /* Getting start time of the subprocess (profiling information) */
  CHECK_ERROR ((clock_gettime (CLOCK_MONOTONIC, &start_time) == -1),
	       "getting start time failed");

  /* Forking the process */
  CHECK_ERROR (((p->pid = fork ()) == -1), "fork failed");

  if (p->pid == 0)	/***** Child process *****/
    {
      /* TODO: What if the child_monitor fails miserably ? It should
       * be signaled in the parent stderr and not in the child
       * stderr. */
      CHECK_ERROR ((child_monitor (p,
				   stdin_pipe,
				   stdout_pipe,
				   stderr_pipe) == RETURN_FAILURE),
		   "child monitor failed");
    }
  else			    /***** Parent process *****/
    {
      int status;
      pthread_t watchdog_pthread, io_pthread;
      struct rusage usage;

      CHECK_ERROR ((close (stdin_pipe[0]) == -1), "close(stdin[0]) failed");
      CHECK_ERROR (((p->stdin = fdopen (stdin_pipe[1], "w")) == NULL),
		   "fdopen(stdin[1]) failed");

      CHECK_ERROR ((close (stdout_pipe[1]) == -1), "close(stdout[1]) failed");
      CHECK_ERROR (((p->stdout = fdopen (stdout_pipe[0], "r")) == NULL),
		   "fdopen(stdout[0]) failed");

      CHECK_ERROR ((close (stderr_pipe[1]) == -1), "close(stderr[1]) failed");
      CHECK_ERROR (((p->stderr = fdopen (stderr_pipe[0], "r")) == NULL),
		   "fdopen(stderr[0]) failed");

      /* Running a watchdog to timeout the subprocess */
      if ((p->limits) && (p->limits->timeout > 0))
	CHECK_ERROR ((pthread_create (&watchdog_pthread, NULL, watchdog, p) !=
		      0), "watchdog creation failed");

      /* Running the io monitor to watch stdout and stderr */
      CHECK_ERROR ((pthread_create (&io_pthread, NULL, io_monitor, p) != 0),
		   "io_monitor creation failed");

      p->status = RUNNING;

      /* Waiting for synchronization with monitored process */
      CHECK_ERROR (wait4 (p->pid, &status, 0, &usage) == -1, "wait failed");

      /* Filtering syscalls with ptrace */
      if ((p->limits != NULL) && (p->limits->syscalls[0] > 0))
	{
	  if (syscall_filter (p, &status, &usage) == RETURN_FAILURE)
	    goto fail;
	}

      /***** The subprocess is finished now *****/

      /* Getting end time of the subprocess (profiling information) */
      struct timespec tmp_time, end_time;

      CHECK_ERROR ((clock_gettime (CLOCK_MONOTONIC, &end_time) == -1),
		   "getting end time failed");
      tmp_time = timespec_diff (start_time, end_time);

      p->real_time_usec =
	(time_t) (tmp_time.tv_sec * 1000000 + tmp_time.tv_nsec / 1000);

      /* Finding out what the status and retval are really */
      if (WIFEXITED (status))
	{			/* Exited normally */
	  p->status = TERMINATED;
	  p->retval = WEXITSTATUS (status);	/* Return value */
	}
      else if (WIFSIGNALED (status))
	{
	  p->retval = WTERMSIG (status);	/* Kill signal */

	  if (p->status < TERMINATED)
	    {
	      /* Trying to guess why by looking at errno value */
	      switch (WTERMSIG (status))
		{
		case SIGSEGV:
		  p->status = MEMORYOUT;
		  break;

		default:
		  p->status = KILLED;
		}
	    }
	  /* FIXME: It may be interesting to store the termination signal
	   * into another variable and to 'p->retval = errno' */
	}
      else if (WIFSTOPPED (status))
	{
	  p->status = STOPPED;
	  p->retval = WSTOPSIG (status);	/* Stop signal */
	}
      else if (WIFCONTINUED (status))
	{
	  p->status = RUNNING;
	  p->retval = 0;	/* Process is still running */
	}

    fail:
      /* Cleaning the io_monitor */
      pthread_cancel (io_pthread);

      /* Cleaning the watchdog if not already exited */
      if ((p->limits) && (p->limits->timeout > 0))
	pthread_cancel (watchdog_pthread);

      /* Cleaning and setting the profile information */
      /* User time in us */
      p->user_time_usec =
	usage.ru_utime.tv_sec * 1000 + usage.ru_utime.tv_usec;

      /* System time in us */
      p->sys_time_usec =
	usage.ru_stime.tv_sec * 1000 + usage.ru_stime.tv_usec;

      /* Memory usage */
      p->memory_kbytes = usage.ru_maxrss;
    }

  return NULL;
}
Exemplo n.º 12
0
static int openInputDevice(lua_State *L) {
	const char* inputdevice = luaL_checkstring(L, 1);
#ifndef EMULATE_READER
	int fd;
	int childpid;
	fd = findFreeFdSlot();
	if(fd == -1) {
		return luaL_error(L, "no free slot for new input device <%s>", inputdevice);
	}
	if(!strcmp("fake_events", inputdevice)) {
		/* special case: the power slider */
		int pipefd[2];

		pipe(pipefd);
		if((childpid = fork()) == -1) {
			return luaL_error(L, "cannot fork() slider event listener");
		}
		if(childpid == 0) {
			// We send a SIGTERM to this child on exit, trap it to kill lipc properly.
			signal(SIGTERM, slider_handler);

			FILE *fp;
			char std_out[256];
			int status;
			struct input_event ev;
			__u16 key_code = 10000;

			close(pipefd[0]);

			ev.type = EV_KEY;
			ev.code = key_code;
			ev.value = 1;

			/* listen power slider events (listen for ever for multiple events) */
			char *argv[] = {"lipc-wait-event", "-m", "-s", "0", "com.lab126.powerd", "goingToScreenSaver,outOfScreenSaver,charging,notCharging", (char *) NULL};
			/* @TODO  07.06 2012 (houqp)
			*  plugin and out event can only be watched by:
				lipc-wait-event com.lab126.hal usbPlugOut,usbPlugIn
			*/

			fp = popen_noshell("lipc-wait-event", (const char * const *)argv, "r", &pclose_arg, 0);
			if (!fp) {
				err(EXIT_FAILURE, "popen_noshell()");
			}

			/* Flush to get rid of buffering issues? */
			fflush(fp);

			while(fgets(std_out, sizeof(std_out)-1, fp)) {
				if(std_out[0] == 'g') {
					ev.code = CODE_IN_SAVER;
				} else if(std_out[0] == 'o') {
					ev.code = CODE_OUT_SAVER;
				} else if((std_out[0] == 'u') && (std_out[7] == 'I')) {
					ev.code = CODE_USB_PLUG_IN;
				} else if((std_out[0] == 'u') && (std_out[7] == 'O')) {
					ev.code = CODE_USB_PLUG_OUT;
				} else if(std_out[0] == 'c') {
					ev.code = CODE_CHARGING;
				} else if(std_out[0] == 'n') {
					ev.code = CODE_NOT_CHARGING;
				} else {
					printf("Unrecognized event.\n");
				}
				/* fill event struct */
				gettimeofday(&ev.time, NULL);

				/* generate event */
				if(write(pipefd[1], &ev, sizeof(struct input_event)) == -1) {
					printf("Failed to generate event.\n");
				}
			}

			status = pclose_noshell(&pclose_arg);
			if (status == -1) {
				err(EXIT_FAILURE, "pclose_noshell()");
			} else {
				if (WIFEXITED(status)) {
					printf("lipc-wait-event exited normally with status: %d\n", WEXITSTATUS(status));
				} else if (WIFSIGNALED(status)) {
					printf("lipc-wait-event was killed by signal %d\n", WTERMSIG(status));
				} else if (WIFSTOPPED(status)) {
					printf("lipc-wait-event was stopped by signal %d\n", WSTOPSIG(status));
				} else if (WIFCONTINUED(status)) {
					printf("lipc-wait-event continued\n");
				}
			}

			// We're done, go away :).
			_exit(EXIT_SUCCESS);
		} else {
			close(pipefd[1]);
			inputfds[fd] = pipefd[0];
			slider_pid = childpid;
		}
	} else {
		inputfds[fd] = open(inputdevice, O_RDONLY | O_NONBLOCK, 0);
		if(inputfds[fd] != -1) {
			ioctl(inputfds[fd], EVIOCGRAB, 1);
			return 0;
		} else {
			return luaL_error(L, "error opening input device <%s>: %d", inputdevice, errno);
		}
	}
#else
	if(SDL_Init(SDL_INIT_VIDEO) < 0) {
		return luaL_error(L, "cannot initialize SDL.");
	}
	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
	/* we only use inputfds[0] in emu mode, because we only have one
	 * fake device so far. */
	inputfds[0] = open(inputdevice, O_RDWR | O_NONBLOCK);
	if (inputfds < 0) {
		return luaL_error(L, "error opening input device <%s>: %d", inputdevice, errno);
	}
#endif
	return 0;
}
Exemplo n.º 13
0
static void cgi_process_each(GSM_StateMachine *s, GSM_SMSMessage*sms) {
	int child_in[2];
	int child_out[2];
	int pid;
	int ret;
	int offset;
	int status;

	child_in[0] = child_in[1] = child_out[0] = child_out[1] = -1; /* invalid fd */

	DecodeUnicode(sms->Text, buffer);
	smprintf(s, CGI_ENGINE "<< [%s]\n", buffer);

	/* ----------------------------------------------------- now open the pipes */
	if (pipe(child_in)) {
		smprintf(s, CGI_ENGINE "Unable to open to pipe: %s\n", strerror(errno));
		goto error;
	}
	if (pipe(child_out)) {
		smprintf(s, CGI_ENGINE "Unable to open from pipe: %s\n", strerror(errno));
		goto error;
	}

	/* ------------------------- Block SIGHUP during the fork - prevents a race */
	//sigfillset(&signal_set);
	//pthread_sigmask(SIG_BLOCK, &signal_set, &old_set);
	//signal(SIGCHLD, cgi_child_end);


	/* ----------------------------------------------------------- fork the cgi */
	pid = fork();
	if(pid < 0) {
		smprintf(s, CGI_ENGINE "Could not fork: %s\n", strerror(errno));
		// pthread_sigmask(SIG_SETMASK, &old_set, NULL);
		goto error;
	}
	if(!pid) {
		/* -------------------------------------------------- child process */
		/* ------------------------------------ move stdout to child_out[1] */
		close(STDOUT_FILENO);
		dup2(child_out[1], STDOUT_FILENO);
		close(child_out[1]);
		close(child_out[0]);                       /* close unused read end */
		/* -------------------------------------- move stdin to child_in[0] */
		close(STDIN_FILENO);
		dup2(child_in[0], STDIN_FILENO);
		close(child_in[0]);
		close(child_in[1]);                       /* close unused write end */
		cgi_child(s);
	}
	/* --------------------------------------------------------- parent process */
	close(child_out[1]);                              /* close unused write end */
	close(child_in[0]);                                /* close unused read end */
	smprintf(s, CGI_ENGINE "Launched CGI script\n");

	/* ----------------------------------------------------------- send headers */
	DecodeUnicode(sms->Number, buffer2);
	cgi_write_header(s, child_in[1], "SMS_FROM", buffer2);
	DecodeUnicode(sms->Name, buffer2);
	cgi_write_header(s, child_in[1], "SMS_NAME", buffer2);
	cgi_write_header(s, child_in[1], "SMS_TIME", OSDate(sms->DateTime));

	/* -------------------------------------------- End headers with empty line */
	cgi_write_helper(s, child_in[1], "\r\n", sizeof("\r\n") - 1);

	/* ----------------------------------------------- now we write the command */
	cgi_write_helper(s, child_in[1], buffer, strlen(buffer));

	close(child_in[1]);                                             /* send EOF */

	/* ------------------------------------------------------------ now we read */
	smprintf(s, CGI_ENGINE ">>======== CGI Response ==========\n");
	buffer[0] = '\0';
	offset = 0;
	while((ret = read(child_out[0], buffer + offset, 1)) > 0) {
		offset += ret;
		*(buffer+offset) = '\0';
	}
	smprintf(s, CGI_ENGINE "%s", buffer);
	smprintf(s, "\n>>================================\n");

	do {
		/* ------------------------------------------------- wait for child to exit */
		if((ret = waitpid(pid, &status, WNOHANG)) == -1) {
			smprintf(s, CGI_ENGINE " waitpid failed :(\n");
			goto error;
		}
		if(!ret) {
			smprintf(s, CGI_ENGINE " Child is not dead yet ..\n");
		}
		if(!WIFEXITED(status)) {
			if(WIFSIGNALED(status)) {
				smprintf(s, CGI_ENGINE "killed by signal %d\n", WTERMSIG(status));
			} else if (WIFSTOPPED(status)) {
				smprintf(s, CGI_ENGINE "stopped by signal %d\n", WSTOPSIG(status));
			} else if (WIFCONTINUED(status)) {
				smprintf(s, CGI_ENGINE "continued\n");
			}
		}
	} while(!WIFEXITED(status) && !WIFSIGNALED(status));
	smprintf(s, CGI_ENGINE " Child process exited\n");

	if(buffer[0] != '\0') {
		/* ----------------------------------------------- prepare response */
		memset(&smsSendBuffer, 0, sizeof(smsSendBuffer));   /* reset memory */
		GSM_SetDefaultSMSData(&smsSendBuffer);
		smsSendBuffer.Location = 1;
		smsSendBuffer.Class = 1;
		smsSendBuffer.PDU = SMS_Submit;
		smsSendBuffer.Coding = SMS_Coding_Default_No_Compression;
		CopyUnicodeString(smsSendBuffer.Number, sms->Number);
		EncodeUnicode(smsSendBuffer.Text, buffer, strlen(buffer));
		/* -------------------------------------------------- send response */
		error = GSM_SendSMS(s, &smsSendBuffer);
	}

	error:
		close(child_in[0]);
		close(child_in[1]);
		close(child_out[0]);
		close(child_out[1]);

	GSM_DeleteSMS(s, sms);
	return;
}
Exemplo n.º 14
0
/*
 * wait for an event and start trying to figure out what to do with it.
 *
 * Returns R_DEBUG_REASON_*
 */
static RDebugReasonType r_debug_native_wait (RDebug *dbg, int pid) {
	int status = -1;
	RDebugReasonType reason = R_DEBUG_REASON_UNKNOWN;

#if __WINDOWS__ && !__CYGWIN__
	int mode = 0;
	status = w32_dbg_wait (dbg, pid);
	if (status == R_DEBUG_REASON_NEW_LIB) {
		mode = 'l';
	} else if (status == R_DEBUG_REASON_EXIT_LIB) {
		mode = 'u';
	} else {
		mode = 0;
	}
	if (mode) {
		RDebugInfo *r = r_debug_native_info (dbg, "");
		if (r && r->lib) {
			if (tracelib (dbg, mode=='l'? "load":"unload", r->lib))
				status = R_DEBUG_REASON_TRAP;
		} else {
			eprintf ("%soading unknown library.\n", mode?"L":"Unl");
		}
		r_debug_info_free (r);
	}
#else
	if (pid == -1) {
		eprintf ("r_debug_native_wait called with -1 pid!\n");
		return R_DEBUG_REASON_ERROR;
	}

#if __APPLE__
	// eprintf ("No waitpid here :D\n");
	reason = xnu_wait (dbg, pid);
	status = reason? 1: 0;
#else
	// XXX: this is blocking, ^C will be ignored
#ifdef WAIT_ON_ALL_CHILDREN
	//eprintf ("waiting on all children ...\n");
	int ret = waitpid (-1, &status, WAIT_ANY); //__WALL);
#else
	//eprintf ("waiting on pid %d ...\n", pid);
	int ret = waitpid (pid, &status, WAIT_ANY); //__WALL);
#endif // WAIT_ON_ALL_CHILDREN
	if (ret == -1) {
		r_sys_perror ("waitpid");
		return R_DEBUG_REASON_ERROR;
	}

	//eprintf ("r_debug_native_wait: status=%d (0x%x) (return=%d)\n", status, status, ret);

#ifdef WAIT_ON_ALL_CHILDREN
	if (ret != pid) {
		reason = R_DEBUG_REASON_NEW_PID;
		eprintf ("switching to pid %d\n", ret);
		r_debug_select(dbg, ret, ret);
	}
#endif // WAIT_ON_ALL_CHILDREN

	// TODO: switch status and handle reasons here
#if __linux__ && defined(PT_GETEVENTMSG)
	reason = linux_ptrace_event (dbg, pid, status);
#endif // __linux__

	/* propagate errors */
	if (reason == R_DEBUG_REASON_ERROR) {
		return reason;
	}

	/* we don't know what to do yet, let's try harder to figure it out. */
	if (reason == R_DEBUG_REASON_UNKNOWN) {
		if (WIFEXITED (status)) {
			eprintf ("child exited with status %d\n", WEXITSTATUS (status));
			reason = R_DEBUG_REASON_DEAD;
		} else if (WIFSIGNALED (status)) {
			eprintf ("child received signal %d\n", WTERMSIG (status));
			reason = R_DEBUG_REASON_SIGNAL;
		} else if (WIFSTOPPED (status)) {
			eprintf ("child stopped with signal %d\n", WSTOPSIG (status));

			/* this one might be good enough... */
			dbg->reason.signum = WSTOPSIG (status);

			/* the ptrace documentation says GETSIGINFO is only necessary for
			 * differentiating the various stops.
			 *
			 * this might modify dbg->reason.signum
			 */
			if (!r_debug_handle_signals (dbg))
				return R_DEBUG_REASON_ERROR;
			reason = dbg->reason.type;
		} else if (WIFCONTINUED (status)) {
			eprintf ("child continued...\n");
			reason = R_DEBUG_REASON_NONE;
		} else if (status == 1) {
			/* XXX(jjd): does this actually happen? */
			eprintf ("EEK DEAD DEBUGEE!\n");
			reason = R_DEBUG_REASON_DEAD;
		} else if (status == 0) {
			/* XXX(jjd): does this actually happen? */
			eprintf ("STATUS=0?!?!?!?\n");
			reason = R_DEBUG_REASON_DEAD;
		} else {
			if (ret != pid) {
				reason = R_DEBUG_REASON_NEW_PID;
			} else {
				/* ugh. still don't know :-/ */
				eprintf ("CRAP. returning from wait without knowing why...\n");
			}
		}
	}

	/* if we still don't know what to do, we have a problem... */
	if (reason == R_DEBUG_REASON_UNKNOWN) {
		eprintf ("%s: no idea what happened... wtf?!?!\n", __func__);
		reason = R_DEBUG_REASON_ERROR;
	}
#endif // __APPLE__
#endif // __WINDOWS__ && !__CYGWIN__

	dbg->reason.tid = pid;
	dbg->reason.type = reason;
	return reason;
}
Exemplo n.º 15
0
Arquivo: wait.c Projeto: 0day-ci/gcc
_Bool
Continued (uint32_t *w)
{
  return WIFCONTINUED (*w) != 0;
}
Exemplo n.º 16
0
void forkIt(int argc, char **argv)
{
    pid_t cpid, w;
    int status;
    char tmp[MAX];
    char **arg_list; // need to construct the parameters
    int j = 0;
    int i = 0;

    arg_list = (char **)malloc( MAX_COL * sizeof(char *));
    for(i = 0; i < MAX_COL; i++)
        arg_list[i]=(char *)malloc( MAX_ROW * sizeof(char));

    char str1[] = "ls";
    char str2[] = "-al";
    char str3[] = "/etc/passwd";


    ///// NOTE: must use pointers to the arg_list, not the content, so strcpy has a problem, need just assing
    ///// arg_list[0] = argv[0]; .....
    /*
       strcpy(arg_list[0], argv[0]);
       strcpy(arg_list[1], argv[1]);
       strcpy(arg_list[2], argv[2]); /// this must be const str3, not arg[2], but arg[2] is also /etc/passwd
       */
    i = 0;
    while(argv[argc-1][i] != '\n')
        i++;
    argv[argc-1][i] = 0;	// set an end to the array


    /* set the array parameter list */
    for(i = 0; i < argc; i++) {
        arg_list[i] = argv[i];
    }

    /*
       arg_list[0] = argv[0];
       arg_list[1] = argv[1];
       arg_list[2] = argv[2];
       */
    arg_list[argc]  = 0;
    //    printf("%d, %d, %d\n", argc, i, sizeof(str3));


    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (cpid == 0) {            /* Code executed by child, execute the command */
        printf("Child PID is %ld\n", (long) getpid());

        int result = 0;
        result = execvp(argv[0], arg_list); /// should be OK when constructed.

        /// NOTE: wrong state is handled by parent, here I keep it continue running, just comment exit,
        /// because the question require to continue inputting the commands
        if (result != 0)
            printf("Error when executing the command in child process!\n");
    } else {                    /* Code executed by parent, use waitpid */
        do {
            w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
            if (w == -1) {
                perror("waitpid");
                exit(EXIT_FAILURE);
            }

            /* could print necessary for debugging, these are important state */
            if (WIFEXITED(status)) {
                //printf("exited, status=%d\n", WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                //printf("killed by signal %d\n", WTERMSIG(status));
            } else if (WIFSTOPPED(status)) {
                //printf("stopped by signal %d\n", WSTOPSIG(status));
            } else if (WIFCONTINUED(status)) {
                //printf("continued\n");
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
        // exit(EXIT_SUCCESS);
    }

}// end forkIt
Exemplo n.º 17
0
static int
OUR_WAITID (idtype_t idtype, id_t id, siginfo_t *infop, int options)
{
  pid_t pid, child;
  int status;

  switch (idtype)
    {
    case P_PID:
      if(id <= 0)
	goto invalid;
      pid = (pid_t) id;
      break;
    case P_PGID:
      if (id < 0 || id == 1)
	goto invalid;
      pid = (pid_t) -id;
      break;
    case P_ALL:
      pid = -1;
      break;
    default:
    invalid:
      __set_errno (EINVAL);
      return -1;
    }

  /* Technically we're supposed to return EFAULT if infop is bogus,
     but that would involve mucking with signals, which is
     too much hassle.  User will have to deal with SIGSEGV/SIGBUS.
     We just check for a null pointer. */

  if (infop == NULL)
    {
      __set_errno (EFAULT);
      return -1;
    }

  /* This emulation using waitpid cannot support the waitid modes in which
     we do not reap the child, or match only stopped and not dead children.  */
  if (0
#ifdef WNOWAIT
      || (options & WNOWAIT)
#endif
#ifdef WEXITED
      || ((options & (WEXITED|WSTOPPED|WCONTINUED))
	  != (WEXITED | (options & WUNTRACED)))
#endif
      )
    {
      __set_errno (ENOTSUP);
      return -1;
    }

  /* Note the waitid() is a cancellation point.  But since we call
     waitpid() which itself is a cancellation point we do not have
     to do anything here.  */
  child = __waitpid (pid, &status,
		     options
#ifdef WEXITED
		     &~ WEXITED
#endif
		     );

  if (child == -1)
    /* `waitpid' set `errno' for us.  */
    return -1;

  if (child == 0)
    {
      /* The WHOHANG bit in OPTIONS is set and there are children available
	 but none has a status for us.  The XPG docs do not mention this
	 case so we clear the `siginfo_t' struct and return successfully.  */
      infop->si_signo = 0;
      infop->si_code = 0;
      return 0;
    }

  /* Decode the status field and set infop members... */
  infop->si_signo = SIGCHLD;
  infop->si_pid = child;
  infop->si_errno = 0;

  if (WIFEXITED (status))
    {
      infop->si_code = CLD_EXITED;
      infop->si_status = WEXITSTATUS (status);
    }
  else if (WIFSIGNALED (status))
    {
      infop->si_code = WCOREDUMP (status) ? CLD_DUMPED : CLD_KILLED;
      infop->si_status = WTERMSIG (status);
    }
  else if (WIFSTOPPED (status))
    {
      infop->si_code = CLD_STOPPED;
      infop->si_status = WSTOPSIG (status);
    }
#ifdef WIFCONTINUED
  else if (WIFCONTINUED (status))
    {
      infop->si_code = CLD_CONTINUED;
      infop->si_status = SIGCONT;
    }
#endif
  else
    /* Can't happen. */
    assert (! "What?");

  return 0;
}
Exemplo n.º 18
0
char*
ldap_lookup(config_t agent_config, const char *username, char *external_uid)
{
	LDAP		*ld;
	LDAPMessage	*result = (LDAPMessage *) 0;
	LDAPMessage	*e;
	BerElement	*ber;
	char		*a, *dn;
	char		*sane_username = malloc(strlen(username)*2);
	char		*p = sane_username;
	char		**vals = NULL;
	struct		timeval	ldaptimeout = {.tv_sec = BIND_TIMEOUT, .tv_usec = 0};
	int			i, rc=0, num_entries=0;
	char		*transcoded_query = NULL;
	char		*ldap_uri = NULL;
	char		*end_ptr;
	char		*ldap_host = _ds_read_attribute(agent_config, "ExtLookupServer");
	char		*port = _ds_read_attribute(agent_config, "ExtLookupPort");
	long		lldap_port;
	int			ldap_port = 389;
	char		*ldap_binddn = _ds_read_attribute(agent_config, "ExtLookupLogin");
	char		*ldap_passwd = _ds_read_attribute(agent_config, "ExtLookupPassword");
	char		*ldap_base = _ds_read_attribute(agent_config, "ExtLookupDB");
	char		*ldap_attrs[] = {_ds_read_attribute(agent_config, "ExtLookupLDAPAttribute"),0};
	char		*version = _ds_read_attribute(agent_config, "ExtLookupLDAPVersion");
	long		lldap_version;
	int			ldap_version = 3;
	char		*ldap_filter = _ds_read_attribute(agent_config, "ExtLookupQuery");
	int			ldap_scope;

	if (port != NULL) {
		errno=0;
		lldap_port = strtol(port, &end_ptr, 0);
		if ( (errno != 0) || (lldap_port < INT_MIN) || (lldap_port > INT_MAX) || (*end_ptr != '\0')) {
			LOG(LOG_ERR, "External Lookup: bad LDAP port number");
			return NULL;
		} else
			ldap_port = (int)lldap_port;
	}

	/* set ldap protocol version */
	if (version != NULL) {
		errno=0;
		lldap_version = strtol(version, &end_ptr, 0);
		if ((errno != 0) || (lldap_version < 1) || (lldap_version > 3) || (*end_ptr != '\0')) {
			LOG(LOG_ERR, "External Lookup: bad LDAP protocol version");
			return NULL;
		} else
			ldap_version = (int)lldap_version;
	}
		
	if (_ds_match_attribute(agent_config, "ExtLookupLDAPScope", "one"))
		ldap_scope = LDAP_SCOPE_ONELEVEL;
	else /* defaults to sub */
		ldap_scope = LDAP_SCOPE_SUBTREE;

	/* set alarm handler */
	signal(SIGALRM, sig_alrm);

	/* sanitize username for filter integration */
	for (; *username != '\0'; username++) {
		switch(*username) {
			case 0x2a: /* '*' */
			case 0x28: /* '(' */
			case 0x29: /* ')' */
			case 0x5c: /* '\' */
			case 0x00: /* NUL */
				*p++ = 0x5c; /* '\' */
				*p++ = *username;
				break;

			default:
				*p++ = *username;
				break;
		}
	}

	*p = '\0';

	LOGDEBUG("External Lookup: sanitized username is %s\n", sane_username);

	/* build proper LDAP filter*/
	transcoded_query = strdup(transcode_query(ldap_filter, sane_username, transcoded_query));
	free(sane_username);
	if (transcoded_query == NULL) {
		LOG(LOG_ERR, "External Lookup: %s", ERR_EXT_LOOKUP_MISCONFIGURED); 
		return NULL;
	}

	if( ldap_host != NULL || ldap_port ) {
	/* construct URL */
		LDAPURLDesc url;
		memset( &url, 0, sizeof(url));

		url.lud_scheme = "ldap";
		url.lud_host = ldap_host;
		url.lud_port = ldap_port;
		url.lud_scope = LDAP_SCOPE_SUBTREE;

		ldap_uri = ldap_url_desc2str( &url );
	}

	rc = ldap_initialize( &ld, ldap_uri );
	if( rc != LDAP_SUCCESS ) {
		LOG(LOG_ERR, "External Lookup: Could not create LDAP session handle for URI=%s (%d): %s\n", ldap_uri, rc, ldap_err2string(rc));
		return NULL;
	}

	if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version ) != LDAP_OPT_SUCCESS ) {
		LOG(LOG_ERR, "External Lookup: Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", ldap_version );
		return NULL;
	}

	/* use TLS if configured */
	if ( _ds_match_attribute(agent_config, "ExtLookupCrypto", "tls" )) {
		if (ldap_version != 3) {
			LOG(LOG_ERR, "External Lookup: TLS only supported with LDAP protocol version 3");
			return NULL;
		}
		if ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
			LOG(LOG_ERR, "External Lookup: %s: %s (%d)", ERR_EXT_LOOKUP_INIT_FAIL, strerror(errno), errno);
			return NULL;
		}
	}

	/* schedules alarm */
	alarm(BIND_TIMEOUT);
	
	/* authenticate to the directory */
	if ( (rc = ldap_simple_bind_s( ld, ldap_binddn, ldap_passwd )) != LDAP_SUCCESS ) {
		/* cancel alarms */
		alarm(0);
		
		LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_INIT_FAIL, ldap_err2string(rc) );
		ldap_unbind(ld);
		return NULL;
	}
	/* cancel alarms */
	alarm(0);
	
	/* search for all entries matching the filter */

	if ( (rc = ldap_search_st( ld, 
				   ldap_base, 
				   ldap_scope,
				   transcoded_query,
				   ldap_attrs, 
				   0,
				   &ldaptimeout, 
				   &result )) != LDAP_SUCCESS ) {

	free(transcoded_query);

	switch(rc) {
		case LDAP_TIMEOUT:
		case LDAP_BUSY:
		case LDAP_UNAVAILABLE:
		case LDAP_UNWILLING_TO_PERFORM:
		case LDAP_SERVER_DOWN:
		case LDAP_TIMELIMIT_EXCEEDED:
			LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) );
			ldap_unbind( ld );
			return NULL;
			break;
		case LDAP_FILTER_ERROR:
			LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) );
			ldap_unbind( ld );
			return NULL;
			break;
		case LDAP_SIZELIMIT_EXCEEDED:
			if ( result == NULL ) {
				LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) );
				ldap_unbind( ld );
				return NULL;
			}
			break;
		default:		       
			LOG(LOG_ERR, "External Lookup: %s: code=%d, %s", ERR_EXT_LOOKUP_SEARCH_FAIL, rc, ldap_err2string(ldap_result2error(ld, result, 1)) );
			ldap_unbind( ld );
			return NULL;
		}
	}

	num_entries=ldap_count_entries(ld,result);

	LOGDEBUG("External Lookup: found %d LDAP entries", num_entries);

    switch (num_entries) {
				case 1: /* only one entry, let's proceed */
					break;
					
				case -1: /* an error occured */
				    LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)));
					ldap_unbind( ld );
					return NULL ;
					
				case 0: /* no entries found */
					LOGDEBUG("External Lookup: %s: no entries found.", ERR_EXT_LOOKUP_SEARCH_FAIL);
					ldap_msgfree( result );
					ldap_unbind( ld );
					return NULL ;

				default: /* more than one entry returned */
					LOG(LOG_ERR, "External Lookup: %s: more than one entry returned.", ERR_EXT_LOOKUP_SEARCH_FAIL);
					ldap_msgfree( result );
					ldap_unbind( ld );
			    	return NULL;
	}

	/* for each entry print out name + all attrs and values */
	for ( e = ldap_first_entry( ld, result ); e != NULL;
	    e = ldap_next_entry( ld, e ) ) {
		if ( (dn = ldap_get_dn( ld, e )) != NULL ) {
		    ldap_memfree( dn );
		}
		for ( a = ldap_first_attribute( ld, e, &ber );
		    a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
			if ((vals = ldap_get_values( ld, e, a)) != NULL ) {
				for ( i = 0; vals[i] != NULL; i++ ) {
					external_uid = strdup(vals[i]);
				}
				ldap_value_free( vals );
			}
			ldap_memfree( a );
		}
		if ( ber != NULL ) {
			ber_free( ber, 0 );
		}
	}
	ldap_msgfree( result );
	ldap_unbind( ld );
	return external_uid;
}
#endif

char*
program_lookup(config_t agent_config, const char *username, char *external_uid)
{
	pid_t wstatus, pid;
	int i, status;
	int fd[2];
	char *output = malloc (1024);
	char **args = malloc (1024);
	char *token;
	char *saveptr;
	char *str;
	char *command_line = 0;
	
    /* build proper command line*/
	command_line = strdup(transcode_query(_ds_read_attribute(agent_config, "ExtLookupServer"), username, command_line));

	if (command_line == NULL) {
		LOG(LOG_ERR, ERR_EXT_LOOKUP_MISCONFIGURED);
		free(output);
		free(args);
		return NULL;
	}

	LOGDEBUG("command line is %s", command_line);
	
	/* break the command line into arguments */
	for (i = 0, str = command_line; ; i++, str = NULL) {
		token = strtok_r(str, " ", &saveptr);
		if (token == NULL)
			break;
		args[i] = token;
		LOGDEBUG("args[%d] = %s",i,token);
	}
	args[i] = (char *) 0;

	if (pipe(fd) == -1) {
		LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno));
		free(output);
		free(args);
		return NULL;
	}

	switch(pid=fork()) {

		case -1: /* couldn't fork - something went wrong */
			LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno));
			free(output);
			free(args);
			return NULL;

		case 0: /* execute the command and write to fd */
			close(fd[0]);
			dup2(fd[1], fileno(stdout));
			execve(args[0], args, 0);
			exit(EXIT_FAILURE);
			
		default: /* read from fd the first output line */
			do {
				wstatus = waitpid( pid, &status, WUNTRACED | WCONTINUED);
				if (wstatus == -1) {
					LOGDEBUG("waitpid() exited with an error: %s: errno=%i", strerror(errno), errno);
					free(output);
					free(args);
					return NULL;
				}
				if (WIFEXITED(status)) {
					LOGDEBUG("exited, status=%d\n", WEXITSTATUS(status));
					if (WEXITSTATUS(status)) {
						LOGDEBUG("Error running %s. Check path and permissions.\n", args[0]);
					}
				} else if (WIFSIGNALED(status)) {
					LOGDEBUG("killed by signal %d\n", WTERMSIG(status));
				} else if (WIFSTOPPED(status)) {
					LOGDEBUG("stopped by signal %d\n", WSTOPSIG(status));
				} else if (WIFCONTINUED(status)) {
					LOGDEBUG("continued\n");
				}
			} while (!WIFEXITED(status) && !WIFSIGNALED(status));
			close(fd[1]);
			/* just in case there's no line break at the end of the return... */
			memset(output, 0, 1024);
			if (read(fd[0], output, 1024) == -1) {
				LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno));
				free(output);
				free(args);
				return NULL;
			}
			close(fd[0]);
	}

	if (strlen(output) == 0) {
		free(output);
		free(args);
		return NULL;
	}
	
	/* terminate the output string at the first \n */
	token = strchr(output, '\n');
	if (token != NULL)
		*token = '\0';
	
	external_uid = strdup(output);
	free(output);
	free(command_line);
	free(args);
	return external_uid;
}
Exemplo n.º 19
0
void Jobs_colocaJobEmForeground (JobHeader *L, pid_t pid) {
	//Variáveis
	Job *jobAux;
	int estado;

	//Copia a lista
	jobAux = L->primeiroJob;
	//Rotina de pesquisa da Lista
	while (jobAux != NULL) {
		//Procura Job desejado
		if (jobAux->pid == pid) {
			//O Job já terminou			
			if(jobAux->statusExecucao == TERMINOU) {
				printf("Job ja terminou.\n");
				//Retorno
				return;
			}
			
			//O job já está em FOREGROUND
			if(jobAux->status == FOREGROUND) {
				printf("Job ja esta rodando em foreground.\n");
				//Retorno
				return;
			}

			//O job está RODANDO em BACKGROUND
			if(jobAux->statusExecucao == RODANDO && jobAux->status == BACKGROUND) {
				//Atualiza job
				jobAux->status = FOREGROUND;
				jobAux->statusExecucao = RODANDO;

				//Aguarda o filho responder
				waitpid(-1*(jobAux->pid),&estado,WUNTRACED);

				//A Job está PARADA (Comando digitado: Ctrl+Z)
				if (WIFSTOPPED(estado)) {
					//Atualiza status da Job
					jobAux->status = BACKGROUND;
					jobAux->statusExecucao = PAUSADO;
					return;
				}
				//Estado inatingível
				if(WIFCONTINUED(estado)) return;

				//A Job TERMINOU (Programa encerrado)
				jobAux->statusExecucao = TERMINOU;
				jobAux->status = BACKGROUND;

				//Retorno
				return;
			}

			//Atualiza job
			jobAux->status = FOREGROUND;
			jobAux->statusExecucao = RODANDO;

			//Continua a execução da Job
			kill(jobAux->pid,SIGCONT);

			//Retorno
			return;
		}
		//Percorre a lista
		jobAux = jobAux->prox;
	}
	//Job não encontrado
	printf("\nJob nao encontrado.\n");
}
int main()
{
    pid_t pid1,pid2;
    pid_t pid;
    int status;

    if((pid1 = fork()) < 0)
    {
        perror("Fail to fork");
        exit(EXIT_FAILURE);

    }else if(pid1 == 0){

        setpgrp(); // 自己创建一个组,PGID == PID
        printf("Create child process  pid1 (PID : %d  PGID : %d).\n",getpid(),getpgrp());
        while(1);

    }else{

        if((pid2 = fork()) < 0)
        {
            perror("Fail to fork");
            exit(EXIT_FAILURE);

        }else if(pid2 == 0){

            printf("Create child process pid2 (PID : %d  PGID : %d).\n",getpid(),getpgrp());
            while(1);
            //	printf("Child process (PID : %d  PGID :%d) exit.\n",getpid(),getpgrp());	

        }else{
            sleep(1);
            printf("Father PID : %d.\n",getpid());
            while(1)
            {
                printf("The father waitpid .\n");
                pid = waitpid(-1,&status,WUNTRACED | WCONTINUED | WNOHANG);

                if(pid == -1)
                    break;

                printf("CHILD PID : %d.\n",pid);

                if(WIFEXITED(status))
                {
                    printf("Normal exit.\n");

                }else if(WIFSIGNALED(status)){

                    printf("EXIT by signal(%d).\n",WTERMSIG(status));

                }else if(WIFSTOPPED(status)){

                    printf("Stop by signal(%d).\n",WSTOPSIG(status));
                }else if(WIFCONTINUED(status)){
                    printf("Continue bys SIGCONT.\n");

                }else{

                    printf("Unknown.\n");
                }

            }
        }

    }

    return 0;
}
Exemplo n.º 21
0
int main(int argc , char* argv[])
{
    char* fim = "fim"; 
    char** args;
    char argumentos[512];  
    int qntPipes,tmp_entrada,tmp_saida,bg=0; 
    char* prompt = "Quais são suas ordens ? ";
    pid_t processo,w;
    int fileOpen,status;

    fileOpen = open(argv[1],O_RDONLY);

    /* Open File For Standard Input */
    if( ( fileOpen ) == 0 ){
        printf( "Cannot Open File ") ;
        exit( 1 ) ;
    }

    if( fileOpen != 0 ){
        dup2( fileOpen, 0 ); /* Make fp stdin */
        close( fileOpen ) ; /* Close original fp */
    }

    //Valida o que for escrito pelo usuario
    printf("%s",prompt);

    while(fgets(argumentos,512,stdin) != NULL){

        strtok(argumentos,"\n");

        args = parseCommands(argumentos);

        localizaRedirecionamentos(args,&tmp_entrada,&tmp_saida,&bg);
        if(bg != 0){
            removeSimboloBackground(args,bg);
        }
        qntPipes = quantidadePipes(args); 

        processo = fork();
        if (processo == 0){
            if(bg != 0)printf("[1] %ld\n", (long) getpid());
            executarComandos(args,qntPipes);
            _exit(EXIT_SUCCESS);
        }else{
            if(bg != 0){
                do {
                    w = waitpid(processo, &status, WUNTRACED | WCONTINUED);
                    if (w == -1) {
                        perror("waitpid");
                        exit(EXIT_FAILURE);
                    }

                    if (WIFEXITED(status)) {
                        printf("Concluido status=%d\n", WEXITSTATUS(status));
                    } else if (WIFSIGNALED(status)) {
                        printf("killed by signal %d\n", WTERMSIG(status));
                    } else if (WIFSTOPPED(status)) {
                        printf("stopped by signal %d\n", WSTOPSIG(status));
                    } else if (WIFCONTINUED(status)) {
                        printf("continued\n");
                    }
                } while (!WIFEXITED(status) && !WIFSIGNALED(status));
            }else{
                wait(NULL);
                //exit(EXIT_SUCCESS);
            }
        }            
        

        if(strcmp(argumentos,fim) == 0) exit(EXIT_SUCCESS);
        printf("%s",prompt);

    }

    return 0;
}
Exemplo n.º 22
0
//=============================================================================
// METHOD     : SPELLprocess::run()
//=============================================================================
void SPELLprocess::run()
{
    DEBUG("[PRC] Starting process monitoring");
    if (!m_notChild)
    {
		m_status = 0;
		m_statusCode = PSTATUS_INITIAL;
		m_processPID = popen( m_command );

		DEBUG("[PRC] Waiting PID");
		waitpid( m_processPID, &m_status, WNOHANG);

		// First thing, check if the command has exited already at this point
		// if the return value is 127,
		if (WIFEXITED(m_status))
		{
			m_retValue = WEXITSTATUS(m_status);
			DEBUG("[PRC] Process exited before check loop");
			if ( m_retValue == SHELL_NOTFOUND )
			{
				DEBUG("[PRC] The process has failed (no shell)");
				m_retValue = -1;
				m_statusCode = PSTATUS_FAILED;
				m_pManager->fireProcessFailed( m_identifier );
				m_endEvent.set();
				return;
			}
			else if (m_retValue != 0)
			{
				DEBUG("[PRC] The process has failed (" + ISTR(m_retValue) + ")");
				m_statusCode = PSTATUS_FAILED;
				m_pManager->fireProcessFailed( m_identifier );
				m_endEvent.set();
				return;
			}
		}
		DEBUG("[PRC] The process has started, starting check");
	    m_statusCode = PSTATUS_RUNNING;
	    m_pManager->fireProcessStarted( m_identifier );

	    bool repeat = false;
	    do
	    {
	        m_status = 0;
	        repeat = false;
	        DEBUG("[PRC] Waiting child PID " + ISTR(m_processPID) );
	        int result = waitpid( m_processPID, &m_status, WUNTRACED );
	        DEBUG("[PRC] Child PID " + ISTR(m_processPID) + " exited");
	        if (result<0)
	        {
	            m_retValue = -1;
	            m_statusCode = PSTATUS_KILLED;
	            LOG_ERROR("The process " + ISTR(m_processPID) + " has been killed [1]");
	            m_pManager->fireProcessKilled( m_identifier );
	        }
	        else if (WIFEXITED(m_status))
	        {
	            m_retValue = WEXITSTATUS(m_status);
	            DEBUG("[PRC] The process " + ISTR(m_processPID) + " has finished with exit code " + ISTR(m_retValue));
	            if (m_retValue == SHELL_NOTFOUND )
	            {
	                DEBUG("[PRC] Command not found");
	            	m_retValue = -1;
	                m_statusCode = PSTATUS_FAILED;
	                m_pManager->fireProcessFailed( m_identifier );
	            }
	            else if (m_retValue == 0)
	            {
	                m_statusCode = PSTATUS_FINISHED;
	            	m_pManager->fireProcessFinished( m_identifier, m_retValue );
	            }
	            else
	            {
	                m_statusCode = PSTATUS_FAILED;
	            	m_pManager->fireProcessFailed( m_identifier );
	            }
	        }
	        else if (WIFSIGNALED(m_status))
	        {
	            m_retValue = -1;
	            m_statusCode = PSTATUS_KILLED;
	            DEBUG("[PRC] The process " + ISTR(m_processPID) + " has been killed [2]");
	            m_pManager->fireProcessKilled( m_identifier );
	        }
	        else if (WIFSTOPPED(m_status) || WIFCONTINUED(m_status))
	        {
	            // SPELLprocess can be stopped by a signal and can continue when SIGCONT
	            // is sent.
	            repeat = true;
	        }
	        else
	        {
	            m_retValue = -1;
	            m_statusCode = PSTATUS_KILLED;
	            DEBUG("[PRC] The process " + ISTR(m_processPID) + " has been killed [3]");
	            m_pManager->fireProcessKilled( m_identifier );
	        }
	    }
	    while(repeat == true);
    }
    else
    {
        DEBUG("[PRC] Attach to process " + ISTR(m_processPID) );
        m_statusCode = PSTATUS_RUNNING;
	    m_pManager->fireProcessStarted( m_identifier );

	    bool repeat = false;
	    do
	    {
	    	if ( !SPELLutils::pathExists( "/proc/" + ISTR(m_processPID) + "/stat" ) )
	    	{
	    		if (m_aboutToClose)
	    		{
	    			DEBUG("[PRC] The attached process " + ISTR(m_processPID) + " has finished");
	    			m_pManager->fireProcessFinished( m_identifier, 0 );
	    		}
	    		else
	    		{
	    			DEBUG("[PRC] The attached process " + ISTR(m_processPID) + " has been killed [4]");
	    			m_pManager->fireProcessKilled( m_identifier );
	    		}
    			repeat = false;

	    	}
	    	else
	    	{
		    	usleep(1000);
	    	}
	    }
	    while(repeat);
    }

    DEBUG("[PRC] Process monitoring finished");
    m_endEvent.set();
    DEBUG("[PRC] Exiting monitoring thread");
}
Exemplo n.º 23
0
static void handle_child(pid_t childpid, int childstatus)
{
	switch (childpid) {
	case 0:
		//debugf("Nothing changed. children:%d\n", shm->running_childs);
		break;

	case -1:
		if (shm->exit_reason != STILL_RUNNING)
			return;

		if (errno == ECHILD) {
			unsigned int i;
			bool seen = FALSE;

			debugf("All children exited!\n");

			for_each_child(i) {
				struct childdata *child;

				child = shm->children[i];

				if (child->pid != EMPTY_PIDSLOT) {
					if (pid_alive(child->pid) == -1) {
						debugf("Removing %d from pidmap\n", child->pid);
						child->pid = EMPTY_PIDSLOT;
						shm->running_childs--;
					} else {
						debugf("%d looks still alive! ignoring.\n", child->pid);
					}
					seen = TRUE;
				}
			}
			if (seen == FALSE)
				shm->running_childs = 0;
			break;
		}
		output(0, "error! (%s)\n", strerror(errno));
		break;

	default:
		debugf("Something happened to pid %d\n", childpid);

		if (WIFEXITED(childstatus)) {

			int childno;

			childno = find_childno(childpid);
			if (childno == CHILD_NOT_FOUND) {
				/* If we reaped it, it wouldn't show up, so check that. */
				if (shm->last_reaped != childpid) {
					outputerr("## Couldn't find %d in list of pids.\n", childpid);
					panic(EXIT_LOST_CHILD);
					dump_childnos();
				}
			} else {
				debugf("Child %d exited after %ld operations.\n",
					childpid, shm->children[childno]->syscall.op_nr);
				reap_child(childpid);
			}
			break;

		} else if (WIFSIGNALED(childstatus)) {
			handle_childsig(childpid, childstatus, FALSE);
		} else if (WIFSTOPPED(childstatus)) {
			handle_childsig(childpid, childstatus, TRUE);
		} else if (WIFCONTINUED(childstatus)) {
			break;
		} else {
			output(0, "erk, wtf\n");
		}
	}
Exemplo n.º 24
0
int main(int argc, char *argv[])
{
	enum __ptrace_request restart_how;
	int last_exit_status = -1;
	pid_t *pids = NULL;
	long status;
	int signal;
	pid_t pid;

	if (argc <= 1) {
		fprintf(stderr, "Usage: %s /path/to/exe [args]\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	pid = fork();
	switch(pid) {
	case -1:
		perror("fork()");
		exit(EXIT_FAILURE);

	case 0: /* child */
		status = ptrace(PTRACE_TRACEME, 0, NULL, NULL);
		if (status < 0) {
			perror("ptrace(TRACEME)");
			exit(EXIT_FAILURE);
		}

		/* Synchronize with the tracer's event loop.  */
		kill(getpid(), SIGSTOP);

		execvp(argv[1], &argv[1]);
		exit(EXIT_FAILURE);

	default: /* parent */
		break;
	}

	restart_how = (getenv("PTRACER_BEHAVIOR_1") == NULL
		? PTRACE_SYSCALL
		: PTRACE_CONT);

	pids = calloc(1, sizeof(pid_t));
	if (pids == NULL) {
		perror("calloc()");
		exit(EXIT_FAILURE);
	}

	signal = 0;
	while (1) {
		int tracee_status;
		pid_t pid;
		pid_t sid;
		int i;

		/* Wait for the next tracee's stop. */
		pid = waitpid(-1, &tracee_status, __WALL);
		if (pid < 0) {
			perror("waitpid()");
			if (errno != ECHILD)
				exit(EXIT_FAILURE);
			break;
		}

		sid = 0;
		for (i = 0; pids[i] != 0; i++) {
			if (pid == pids[i]) {
				sid = i + 1;
				break;
			}
		}
		if (sid == 0) {
			pids = realloc(pids, (i + 1 + 1) * sizeof(pid_t));
			if (pids == NULL) {
				perror("realloc()");
				exit(EXIT_FAILURE);
			}
			pids[i + 1] = 0;
			pids[i] = pid;
			sid = i + 1;
			fprintf(stderr, "sid %d -> pid %d\n", sid, pid);
		}

		if (WIFEXITED(tracee_status)) {
			fprintf(stderr, "sid %d: exited with status %d\n",
				sid, WEXITSTATUS(tracee_status));
			last_exit_status = WEXITSTATUS(tracee_status);
			continue; /* Skip the call to ptrace(SYSCALL). */
		}
		else if (WIFSIGNALED(tracee_status)) {
			fprintf(stderr, "sid %d: terminated with signal %d\n",
				sid, WTERMSIG(tracee_status));
			continue; /* Skip the call to ptrace(SYSCALL). */
		}
		else if (WIFCONTINUED(tracee_status)) {
			fprintf(stderr, "sid %d: continued\n", sid);
			signal = SIGCONT;
		}
		else if (WIFSTOPPED(tracee_status)) {
			struct user_regs_struct regs;

			/* Don't use WSTOPSIG() to extract the signal
			 * since it clears the PTRACE_EVENT_* bits. */
			signal = (tracee_status & 0xfff00) >> 8;

			switch (signal) {
				static bool skip_bare_sigtrap = false;
				long ptrace_options;

			case SIGTRAP:
				fprintf(stderr, "sid %d: SIGTRAP\n", sid);

				status = ptrace(PTRACE_GETREGS, pid, NULL, &regs);
				if (status < 0) {
					fprintf(stderr,
						"sigtrap: ?, ?\n");
				} else {
					fprintf(stderr, "sigtrap: %ld == 0 ? %d\n",
						REG(regs, SYSARG_NUM),
						REG(regs, SYSARG_RESULT) == 0);
				}

				/* PTRACER_BEHAVIOR_1 */
				if (restart_how != PTRACE_SYSCALL) {
					restart_how = PTRACE_SYSCALL;
					signal = 0;
					break;
				}

				/* Distinguish some events from others and
				 * automatically trace each new process with
				 * the same options.
				 *
				 * Note that only the first bare SIGTRAP is
				 * related to the tracing loop, others SIGTRAP
				 * carry tracing information because of
				 * TRACE*FORK/CLONE/EXEC.
				 */
				if (skip_bare_sigtrap) {
					signal = 0;
					break;
				}
				skip_bare_sigtrap = true;

				ptrace_options = PTRACE_O_TRACESYSGOOD
					| PTRACE_O_TRACEFORK
					| PTRACE_O_TRACEVFORK
					| PTRACE_O_TRACEVFORKDONE
					| PTRACE_O_TRACECLONE
					| PTRACE_O_TRACEEXIT;

				if (getenv("PTRACER_BEHAVIOR_2") == NULL)
					ptrace_options |= PTRACE_O_TRACEEXEC;

				status = ptrace(PTRACE_SETOPTIONS, pid, NULL, ptrace_options);
				if (status < 0) {
					perror("ptrace(PTRACE_SETOPTIONS)");
					exit(EXIT_FAILURE);
				}
				/* Fall through. */
			case SIGTRAP | 0x80:
				fprintf(stderr, "sid %d: PTRACE_EVENT_SYSGOOD\n", sid);
				signal = 0;

				status = ptrace(PTRACE_GETREGS, pid, NULL, &regs);
				if (status < 0) {
					fprintf(stderr,
						"syscall(?) = ?\n");
				} else {
					fprintf(stderr, "syscall(%ld) == 0 ? %d\n",
						REG(regs, SYSARG_NUM),
						REG(regs, SYSARG_RESULT) == 0);
				}
				break;

			case SIGTRAP | PTRACE_EVENT_VFORK << 8:
				fprintf(stderr, "sid %d: PTRACE_EVENT_VFORK\n", sid);
				signal = 0;
				break;

			case SIGTRAP | PTRACE_EVENT_VFORK_DONE << 8:
				fprintf(stderr, "sid %d: PTRACE_EVENT_VFORK\n", sid);
				signal = 0;
				break;

			case SIGTRAP | PTRACE_EVENT_FORK  << 8:
				fprintf(stderr, "sid %d: PTRACE_EVENT_FORK\n", sid);
				signal = 0;
				break;

			case SIGTRAP | PTRACE_EVENT_CLONE << 8:
				fprintf(stderr, "sid %d: PTRACE_EVENT_CLONE\n", sid);
				signal = 0;
				break;

			case SIGTRAP | PTRACE_EVENT_EXEC  << 8:
				fprintf(stderr, "sid %d: PTRACE_EVENT_EXEC\n", sid);
				signal = 0;
				break;

			case SIGTRAP | PTRACE_EVENT_EXIT  << 8:
				fprintf(stderr, "sid %d: PTRACE_EVENT_EXIT\n", sid);
				signal = 0;
				break;

			case SIGSTOP:
				fprintf(stderr, "sid %d: SIGSTOP\n", sid);
				signal = 0;
				break;

			default:
				break;
			}
		}
		else {
			fprintf(stderr, "sid %d: unknown trace event\n", sid);
			signal = 0;
		}

		/* Restart the tracee and stop it at the next entry or
		 * exit of a system call. */
		status = ptrace(restart_how, pid, NULL, signal);
		if (status < 0)
			fprintf(stderr, "ptrace(<restart_how>, %d, %d): %s\n", sid, signal, strerror(errno));
	}
Exemplo n.º 25
0
int main(int argc, char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "usage: %s bin_name [args...]\n", argv[0]);
        return -1;
    }

    char *bin_name = argv[1];

    printf("pid %ld, parent pid %ld\n", (long) getpid(), (long) getppid());

    pid_t child = fork();

    if (child == -1) {
        perror("fork");
        return -1;
    }

    if (child == 0) {
        /* Code executed by child */
        printf("child: pid %ld, parent pid %ld\n\n", (long) getpid(), (long) getppid());

        if (execvp(bin_name, argv + 1)) {
            perror("execvp");
            return -1;
        }

        printf("Child should never execute this...\n");
    }
    else {
        /* Code executed by parent */
        printf("parent: pid %ld\n", (long) getpid());

        int status;
        do {
            pid_t w;

            w = waitpid(child, &status, WUNTRACED | WCONTINUED);
            printf("\n");

            if (w < 0) {
                perror("waitpid");
                return -1;
            }

            if (WIFEXITED(status)) {
                int exitcode = WEXITSTATUS(status);
                printf("parent: child pid %ld exited normally with exit code %d\n", (long) w, exitcode);
            }
            else if (WIFSIGNALED(status)) {
                int termsig = WTERMSIG(status);
                printf("parent: child pid %ld was terminated by signal SIG%s (#%d)\n", (long) w, signal2str(termsig), termsig);
            }
            else if (WIFSTOPPED(status)) {
                int stopsig = WSTOPSIG(status);
                printf("parent: child pid %ld was stopped by signal SIG%s (#%d)\n", (long) w, signal2str(stopsig), stopsig);
            }
            else if (WIFCONTINUED(status)) {
                printf("parent: child pid %ld continued\n", (long) w);
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    }

    return 0;
}
Exemplo n.º 26
0
// TODO move this to a generic re-usable location
void startBackgroundWork(char *exec, char **pWorkUrl)
/* deal with forking off child for background work
 * and setting up the trash file for communicating
 * from the child to the browser */
{
char *workUrl = NULL;
char hgsid[64];
struct tempName tn;
safef(hgsid, sizeof(hgsid), "%s", cartSessionId(cart));
trashDirFile(&tn, "backGround", hgsid, ".tmp");
workUrl = cloneString(tn.forCgi);
fflush(stdout);
fflush(stderr);
// seems that we need to use the double-fork trick
// to create enough separation between the non-waiting parent
// and the grand-child process.  otherwise the OS and Apache are waiting on the child.

int pid = fork();
if (pid == -1)
    {   
    errAbort("can't fork, error %d", errno);
    }
if (pid == 0) // child
    {
    int pid2 = fork();
    if (pid2 == -1)
	{   
	errAbort("can't fork, error %d", errno);
	}
    if (pid2 == 0) // grand child
	{

	// we need to close or redup to open stdout, stderr, stdin
	// in order for apache to break ties with it.
	// Will the grandchild cgi still be able to function?

	// redirect stdout of child to the trash file for easier use of 
	// library functions that output html to stdout.
	int out = mustOpenFd(tn.forCgi, O_WRONLY | O_CREAT);
	fflush(stdout);
	dup2(out,STDOUT_FILENO);  /* closes STDOUT before setting it back to saved descriptor */
	close(out);

	// Unfortunately we must create our own stderr log file
	char errName[1024];
	safef(errName, sizeof errName, "%s.err", tn.forCgi);
	int err = mustOpenFd(errName, O_CREAT | O_WRONLY | O_APPEND);
	dup2(err, STDERR_FILENO);
	close(err);

	// stdin input is just empty
	int in = mustOpenFd("/dev/null", O_RDONLY);
	dup2(in, STDIN_FILENO);
	close(in);

	// execute so that we will be able to use database and other operations normally.
	char execPath[4096];
	safef(execPath, sizeof execPath, "%s hgsid=%s", exec, hgsid);
	char *args[10];
	int numArgs = chopString(execPath, " ", args, 10);
	args[numArgs] = NULL;
	// by creating a minimal environment and not inheriting from the parent,
	// it cause cgiSpoof to run,  picking up command-line params as cgi vars.
	char *newenviron[] = { "HGDB_CONF=hg.conf", NULL };
	int sleepSeconds = 1; // was 5
	sleep(sleepSeconds); // Give the foreground process time to write the cart.
	execve(args[0], args+1, newenviron);
	// SHOULD NOT GET HERE UNLESS EXEC FAILED.
	verbose(1,"execve failed for %s\n", exec);
	_exit(0); // exit without the usual cleanup which messes up parent's db connections etc.

	}
    else  // child
	{
	_exit(0); // exit without the usual cleanup which messes up parent's db connections etc.
	}
    }
else  // parent
    {
    *pWorkUrl = workUrl;
    // wait for the exiting child (not grandchild)
    int w, status;
    do {
	w = waitpid(pid, &status, WUNTRACED | WCONTINUED);
	if (w == -1) 
	    {
	    perror("waitpid");
	    exit(EXIT_FAILURE);
	    }

	if (WIFEXITED(status)) 
	    {
	    if (WEXITSTATUS(status) != 0)
		verbose(1, "exited, status=%d\n", WEXITSTATUS(status));
	    } 
	else if (WIFSIGNALED(status)) 
	    {
	    verbose(1, "killed by signal %d\n", WTERMSIG(status));
	    } 
	else if (WIFSTOPPED(status)) 
	    {
	    verbose(1, "stopped by signal %d\n", WSTOPSIG(status));
	    }
	else if (WIFCONTINUED(status)) 
	    {
	    verbose(1, "continued\n");
	    }
	} while (!WIFEXITED(status) && !WIFSIGNALED(status));

        // done waiting for child.

    }

}
Exemplo n.º 27
0
//--------------------------------------------------------------------------------------------------
proc_FaultAction_t proc_SigChildHandler
(
    proc_Ref_t procRef,             ///< [IN] The process reference.
    int procExitStatus              ///< [IN] The status of the process given by wait().
)
{
    proc_FaultAction_t faultAction = PROC_FAULT_ACTION_NO_FAULT;

    if (WIFSTOPPED(procExitStatus))
    {
        procRef->paused = true;

        LE_INFO("Process '%s' (PID: %d) has paused.", procRef->name, procRef->pid);
    }
    else if (WIFCONTINUED(procExitStatus))
    {
        procRef->paused = false;

        LE_INFO("Process '%s' (PID: %d) has been continued.", procRef->name, procRef->pid);
    }
    else
    {
        // The process died.

        if (WIFEXITED(procExitStatus))
        {
            LE_INFO("Process '%s' (PID: %d) has exited with exit code %d.",
                    procRef->name, procRef->pid, WEXITSTATUS(procExitStatus));

            if (WEXITSTATUS(procExitStatus) != EXIT_SUCCESS)
            {
                faultAction = GetFaultAction(procRef);
            }
        }
        else if (WIFSIGNALED(procExitStatus))
        {
            int sig = WTERMSIG(procExitStatus);

            // WARNING: strsignal() is non-reentrant.  We use it here because the Supervisor is
            //          single threaded.
            LE_INFO("Process '%s' (PID: %d) has exited due to signal %d (%s).",
                    procRef->name, procRef->pid, sig, strsignal(sig));

            faultAction = GetFaultAction(procRef);
        }

        // Check the fault action.  If it indicates that the process stopped due to an error, save
        // all relevant data for future diagnosis.
        if (faultAction != PROC_FAULT_ACTION_NO_FAULT)
        {
            // Check if we're rebooting.  If we are, this data needs to be saved in a more permanent
            // location.
            bool isRebooting = faultAction == PROC_FAULT_ACTION_REBOOT;
            CaptureDebugData(procRef, isRebooting);
        }

        procRef->pid = -1;
        procRef->paused = false;
    }

    return faultAction;
}
Exemplo n.º 28
0
int VMPI_WIFCONTINUED(int status)
{
    return WIFCONTINUED(status);
}
Exemplo n.º 29
0
/**
 * Parent watch child status
 */
int Watching()
{
	pid_t w;
	int status;

	openlog("pm_manager", LOG_PID, LOG_LOCAL0);

	do
	{
		child_pid = fork();
		if (child_pid == -1)
		{
			exit(EXIT_FAILURE);
		}

		if (child_pid == 0)
		{
			/**
			 * Child process
			 */
			signal(SIGINT, CSigHander);
			signal(SIGTERM, CSigHander);
			signal(SIGPIPE, SIG_IGN);
			return 0;
		}

		/**
		 * Parent process
		 */
		signal(SIGINT, PSigHander);
		signal(SIGTERM, PSigHander);
		signal(SIGHUP, PSigHander);
		signal(SIGPIPE, SIG_IGN);

		w = waitpid(child_pid, &status, WUNTRACED | WCONTINUED);
		closeMessage();
		if (w == -1)
		{
			perror("waitpid");
			exit(EXIT_FAILURE);
		}
		if (WIFEXITED(status))
		{
			_DBG("[Process] child exited, status=%d\n", WEXITSTATUS(status));
		}
		else if (WIFSIGNALED(status))
		{
			_DBG("[Process] child killed by signal %d\n", WTERMSIG(status));
		}
		else if (WIFSTOPPED(status))
		{
			_DBG("[Process] child stopped by signal %d\n", WSTOPSIG(status));
		}
		else if (WIFCONTINUED(status))
		{
			_DBG("[Process] continued\n");
		}
		sleep(3);
	}
	while (SIGTERM != WTERMSIG(status) && !flag);
	closelog();
	exit(EXIT_SUCCESS);
	return 1;
}
Exemplo n.º 30
0
int wait_process(child_process_t *process, int tmosec)
{
    int ec, flags = 0;
    time_t now, tmostamp;

    if (process->exited) {
        return 0;
    }
    if (tmosec < 0 || tmosec > 0) {
        flags |= WNOHANG;
    }
    now = time(NULL);

    /** Probably better logic for this */
    if (tmosec <= 0) {
        tmostamp = 0;
    } else {
        tmostamp = now + tmosec;
    }

    do {
        pid_t pidrv = waitpid(process->pid, &ec, flags);

        if (pidrv > 0) {
            if (WIFEXITED(ec)) {
                process->status = WEXITSTATUS(ec);
                process->exited = 1;

            } else if (WIFSIGNALED(ec)) {
                process->status = WTERMSIG(ec);
                process->exited = 1;

            } else if (WIFSTOPPED(ec) || WIFCONTINUED(ec)) {
                continue;

            } else {
                fprintf(stderr,
                        "Waitpid returned pid with neither EXITED or "
                        "SIGNALLED true. Assuming something else (0x%x)\n",
                        ec);
                process->status = -1;
                process->exited = 1;
            }

        } else if (pidrv == -1 && errno == ESRCH) {
            fprintf(stderr, "Process has already terminated. waitpid(%d) == ESRCH\n", process->pid);

            process->exited = 1;
        }

        if (process->exited) {
            return 0;
        }

        if (!tmostamp) {
            break;
        }
        usleep(500);
        now = time(NULL);
    } while (now < tmostamp);

    return -1;
}