Esempio n. 1
0
/*
 * Requires:
 *   "s" is a properly terminated string.
 *
 * Effects:
 *   Prints the string "s" to stdout using only functions that can be safely
 *   called by a signal handler, and exits the program.
 */
static void
sio_error(char s[])
{

	sio_puts(s);
	_exit(1);
}
Esempio n. 2
0
ssize_t sio_putl(long v) /* Put long */
{
    char s[128];
    
    sio_ltoa(v, s, 10); /* Based on K&R itoa() */  //line:csapp:sioltoa
    return sio_puts(s);
}
Esempio n. 3
0
ssize_t Sio_puts(char s[])
{
    ssize_t n;
  
    if ((n = sio_puts(s)) < 0)
	sio_error("Sio_puts error");
    return n;
}
Esempio n. 4
0
/*
 * Requires:
 *   None.
 *
 * Effects:
 *   Prints the long "v" to stdout using only functions that can be safely
 *   called by a signal handler, and returns either the number of characters
 *   printed or -1 if the long could not be printed.
 */
static ssize_t
sio_putl(long v)
{
	char s[128];
    
	sio_ltoa(v, s, 10);
	return (sio_puts(s));
}
Esempio n. 5
0
/* 
 * sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
 *     a child job terminates (becomes a zombie), or stops because it
 *     received a SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU signal. The 
 *     handler reaps all available zombie children, but doesn't wait 
 *     for any other currently running children to terminate.  
 */
void sigchld_handler(int sig) {

    int status;
    pid_t pid;
    int olderrno = errno; // store errno in handler

    /*
     * Reap child with the pid if the child is stopped or terminated
     * If a child is terminated normally, delete the child from the job list
     * If a child is stopped by a signal, set the job status as stopped
     * If a child is terminated by a signal that was not caught, delete the child from the job list
     */
    while ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0) {

        if (WIFEXITED(status)) {

            deletejob(job_list, pid); // the child ternimated normally

        } else if (WIFSTOPPED(status)) {

            /*
             * Avoid printf() in handler, use helper function to write the output to stdout
             */
            sio_puts("Job [");
            sio_putl(pid2jid(pid));
            sio_puts("] (");
            sio_putl(pid);
            sio_puts(") stopped by signal ");
            sio_putl(WSTOPSIG(status));
            sio_puts("\n");

            getjobpid(job_list, pid) -> state = ST; // the child was stopped by a signal 

        } else if (WIFSIGNALED(status)) { // the child was terminated by a signal that was not caught

            /*
             * Avoid printf() in handler, use helper function to write the output to stdout
             */
            sio_puts("Job [");
            sio_putl(pid2jid(pid));
            sio_puts("] (");
            sio_putl(pid);
            sio_puts(") terminated by signal ");
            sio_putl(WTERMSIG(status));
            sio_puts("\n");

			deletejob(job_list, pid);

        }

    }

    errno = olderrno;
    return;
}
Esempio n. 6
0
/* 
 * sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
 *  a child job terminates (becomes a zombie), or stops because it
 *  received a SIGSTOP or SIGTSTP signal.  The handler reaps all
 *  available zombie children, but doesn't wait for any other
 *  currently running children to terminate.  
 *
 * Requires:
 *   When a child job terminates or stops, it sends out signal successfully
 *
 * Effects:
 *   If the child job is stopped by a signal, change its state and print signal 
 *   information; if the child job is terminated by a signal, print signal 
 *   information and delete the child job; if the child job is terminated in 
 *   other ways, delete it. The handler reaps all available zombie children, 
 *   but doesn't wait for any currently running children to terminate. 
 */
static void
sigchld_handler(int signum)
{

	// Prevent an "unused parameter" warning.
	(void)signum;

	pid_t pid;
	int status;

	// Reap zombie children but doesn't wait for currently running children
	while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
		struct Job *pcurjob = getjobpid(jobs, pid);

		if (!pcurjob) {
			app_error("pcurjob in sigtstp_handler");
		}
		// If a child stops, change its state to ST and print the information
		if (WIFSTOPPED(status)) {
			pcurjob->state = ST;
			char *print;
			asprintf(&print, "Job [%d] (%d) stopped by signal SIGTSTP\n", pid2jid(pid), pid);
			sio_puts(print);
		} 
		// If a child terminates by signal, print the information and delete the job
		else if (WIFSIGNALED(status)) {
			char *print;
			asprintf(&print, "Job [%d] (%d) terminated by signal SIGINT\n", pcurjob->jid, pcurjob->pid);
		        sio_puts(print);
			deletejob(jobs, pid);
		}
		// Delete the job is the child terminates in any other way
		else {
			deletejob(jobs, pid);
		}
	}

	return;
}
Esempio n. 7
0
/**
 * Writes a character to the serial console.
 */
void sio_putchar( char ch ) {
	static char buf[2] = {'\0', '\0'};
	buf[0] = ch;
	sio_puts(buf);
}
Esempio n. 8
0
void sio_error(char s[]) /* Put error message and exit */
{
    sio_puts(s);
    _exit(1);                                      //line:csapp:sioexit
}
Esempio n. 9
0
static void * sior_rpc_server(u32 funcno, void * data, int size) {
    int res = 0, c;
    size_t s;
    char * p;
    struct init_arguments_t * i;
    switch(funcno) {
    case SIOR_INIT:
	i = (struct init_arguments_t *) data;
	sio_init(i->baudrate, i->lcr_ueps, i->lcr_upen, i->lcr_usbl, i->lcr_umode);
	break;
    case SIOR_PUTC:
	c = *((int *) data);
	res = sio_putc(c);
	break;
    case SIOR_GETC:
	res = sio_getc();
	break;
    case SIOR_GETCBLOCK:
	res = sio_getc_block();
	break;
    case SIOR_WRITE:
	p = *((char **) data) + IOP_MEM;
	s = *(((size_t *) data) + 1);
	DI();
	ee_kmode_enter();
	res = sio_write(p, s);
	ee_kmode_exit();
	EI();
	break;
    case SIOR_READ:
	p = *((char **) data) + IOP_MEM;
	s = *(((size_t *) data) + 1);
	DI();
	ee_kmode_enter();
	res = sio_read(p, s);
	ee_kmode_exit();
	EI();
	break;
    case SIOR_PUTS:
	p = *((char **) data) + IOP_MEM;
	DI();
	ee_kmode_enter();
	res = sio_puts(p);
	ee_kmode_exit();
	EI();
	break;
    case SIOR_PUTSN:
	p = *((char **) data) + IOP_MEM;
	DI();
	ee_kmode_enter();
	res = sio_putsn(p);
	ee_kmode_exit();
	EI();
	break;
    case SIOR_GETS:
	p = *((char **) data) + IOP_MEM;
	DI();
	ee_kmode_enter();
	(char*)res = sio_gets(p);
	ee_kmode_exit();
	EI();
	break;
    case SIOR_FLUSH:
	sio_flush();
	break;
    }

    *((int *) data) = res;

    return data;
}
Esempio n. 10
0
/*
 * Log - emits I/O safe logs whether global
 *      macro LOG is on or off
 */
void Log(char *msg, int len)
{
    sio_puts(msg, len & logger);
}