Example #1
0
	LaunchOptions::LaunchOptions()
		: wait(false),
#if defined(OS_WIN)
		start_hidden(false),
		handles_to_inherit(NULL),
		inherit_handles(false),
		as_user(NULL),
		empty_desktop_name(false),
		job_handle(NULL),
		stdin_handle(NULL),
		stdout_handle(NULL),
		stderr_handle(NULL),
		force_breakaway_from_job_(false)
#else
		clear_environ(false),
		fds_to_remap(NULL),
		maximize_rlimits(NULL),
		new_process_group(false)
#if defined(OS_LINUX)
		, clone_flags(0)
		, allow_new_privs(false)
#endif  // OS_LINUX
#if defined(OS_CHROMEOS)
		, ctrl_terminal_fd(-1)
#endif  // OS_CHROMEOS
#endif  // !defined(OS_WIN)
	{
	}

	LaunchOptions::~LaunchOptions() {
	}

	LaunchOptions LaunchOptionsForTest() {
		LaunchOptions options;
#if defined(OS_LINUX)
		// To prevent accidental privilege sharing to an untrusted child, processes
		// are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this
		// new child will be used for testing only.
		options.allow_new_privs = true;
#endif
		return options;
	}

}  // namespace base
Example #2
0
int
main(int argc, char **argv)
{
  int msgfd;
  struct stat statBuf;
  Port_t port;
  char *msg;
  int sockfd, newsockfd;
  socklen_t addrlen = 0;
  union sockaddr_u their_addr;

  if (argc != 3) {
    fprintf(stderr, "Usage: portmsg file port\n");
    return 1;
  }
  port = atoi(argv[2]);
  if (port == 0) {
    fprintf(stderr, "error: bad port number [%s]\n", argv[2]);
    return 1;
  }
  if ((msgfd = open(argv[1], O_RDONLY)) < 0) {
    fprintf(stderr, "error: cannot open message file [%s]: %s\n", argv[1],
            strerror(errno));
    return 1;
  }
  /* read the message */
  fstat(msgfd, &statBuf);
  if (statBuf.st_size <= 0) {
    fprintf(stderr, "error: message file [%s] is empty\n", argv[1]);
    return 1;
  }
  msg = (char *) malloc(statBuf.st_size);
  if (read(msgfd, msg, statBuf.st_size) != statBuf.st_size) {
    fprintf(stderr, "error: cannot read message file [%s]\n", argv[1]);
    return 1;
  }

  /* become a daemon */
  switch (fork()) {
  case -1:
    perror("can't fork");
    return 1;
  case 0:
    break;
  default:
    return 0;
  }
#ifdef HAVE_SETSID
  if (setsid() < 0)
    perror("Unable to create new session id (Harmless)");
#else
  if (new_process_group() < 0)
    perror("Unable to set new process group (Probably harmless)");
#endif

#ifdef USE_TIOCNOTTY
  if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
    ioctl(fd, TIOCNOTTY, NULL);
    close(fd);
  }
#endif

  install_sig_handler(SIGCHLD, wait_on_child);

  if ((sockfd = make_socket(port, SOCK_STREAM, NULL, NULL, host_ip)) < 0) {
    perror("can't make socket");
    return 1;
  }

main_again:
  if (connections > MAX_CONNECTIONS) {
    sleep(1);
    goto main_again;
  }
  addrlen = sizeof(their_addr);
  newsockfd = accept(sockfd, &their_addr.addr, &addrlen);
  if (newsockfd < 0) {
    if (errno == EINTR)
      goto main_again;
    perror("Couldn't accept connection");
    return 1;
  }
  connections++;
  switch (fork()) {
  case -1:
    perror("server can't fork");
    return 1;
  case 0:
    /* child process */
    install_sig_handler(SIGPIPE, lostconn);
    ignore_signal(SIGCHLD);
    send(newsockfd, msg, statBuf.st_size, 0);
    sleep(5);
    closesocket(newsockfd);
    break;
  default:
    closesocket(newsockfd);
    goto main_again;
  }

  return 0;
}
Example #3
0
int main(void) {
	char inputBuffer[MAX_LINE]; /** buffer to hold the command entered **/
	int background;             /** equals 1 if a command is followed by '&' **/
	int respawnable;			/** igual a 1 si al comando le sigue '#' **/
	char *args[MAX_LINE / 2];   /** command line (of 256) has max of 128 arguments **/

	// probably useful variables:
	int pid_fork, pid_wait; 		/** pid for created and waited process **/
	int status;             		/** status returned by wait **/
	enum status status_res; 		/** status processed by analyze_status() **/
	int info;						/** info processed by analyze_status() **/
	ignore_terminal_signals();	    /** Ignora las señales del terminal **/

	/** Asociamos el manejador a la señal SIGCHLD y creamos la lista de trabajos **/
	signal(SIGCHLD, manejador);
	lista_trabajos = new_list("Lista trabajos");

	/** Program terminates normally inside get_command() after ^D is typed **/
	while(1) {

		printf("\nCOMMAND->");
		fflush(stdout);
		/** get next command **/
		get_command(inputBuffer, MAX_LINE, args, &background, &respawnable);

		// if empty command
		if(args[0] == NULL) {
			continue;
		}

		/** Comando interno CD **/
		if(strcmp(args[0], "cd") == 0 && args[1] != NULL) {
			chdir(args[1]);
			continue;
		}

		/** Comando interno historial **/
		if(strcmp(args[0], "historial") == 0) {
			continue;
		}

		/** Comando interno JOBS (HECHO) **/
		if(strcmp(args[0], "jobs") == 0) {
			if(empty_list(lista_trabajos)) {
				printf("La lista de tareas está vacía\n");
			} else {
				print_job_list(lista_trabajos);
			}
			continue;
		}

		/** Comando interno BG (HECHO) **/
		if(strcmp(args[0], "bg") == 0) {
			if(args[1] == NULL) {
				printf("No le has pasado ningún argumento al comando \n");
			} else {
				int index = atoi(args[1]);   // Convertimos el indice pasado a un entero
				bgCommand(index);   // Invocamos al comando FG
			}
			continue;
		}

		/** Comando interno FG (HECHO) **/
		if(strcmp(args[0], "fg") == 0) {
			int index = 1;			// Por defecto a la primera tarea de la lista
			if(args[1] != NULL) {
				index = atoi(args[1]);	// Si no es nulo, lo aplicaremos al correspondiente
			}
			fgCommand(index);						// Invocamos al comando FG
			continue;
		}

		// the steps are:
		// (1) fork a child process using fork()
		pid_fork = fork();

		if(pid_fork < 0) {	// Caso de error
			printf("Error. The system wasn able to spawn a new process. Exiting...\n");
			exit(-1);

		} else if(pid_fork == 0) {	// Proceso hijo

			/** Nuevo identificador de grupo de procesos para el hijo, asociacion del terminal y señales a default **/
			pid_t mypid = getpid();
			new_process_group(mypid);	// Metemos al hijo en un nuevo grupo

			if(!background && !respawnable) {
				// Le asignamos el terminal
				set_terminal(mypid);
			}

			// Restauramos las señales que reciben del terminal
			restore_terminal_signals();

			// (2) the child process will invoke execvp()
			execvp(args[0], args);

			// Solo llegará aquí si no se ha producido el cambio de imagen
			printf("Error. Command not found: %s\n", args[0]);
			exit(-1);

		// Padre
		} else {

			/** Nuevo identificador de grupo de procesos para el hijo **/
			new_process_group(pid_fork);	// El padre se va a un nuevo grupo de trabajo

			/** Si el programa está en background o es respawnable **/
			if(background || respawnable) {

				/** BLoqueamos la señal SIGCHLD, añadimos el trabajo a la lista(background) y desbloqueamos la señal **/
				block_SIGCHLD();

				job *aux;

				// Creamos un nuevo nodo para agregarlo a la lista
				if(background) {
					aux = new_job(pid_fork, args[0], args, BACKGROUND);
				} else if(respawnable) {
					aux = new_job(pid_fork, args[0], args, RESPAWNABLE);
				}

				// Añadimos ese nodo a la lista creada anteriormente
				add_job(lista_trabajos, aux);
				unblock_SIGCHLD();

				printf("Background job running... pid: %d, command: %s. \n", pid_fork, args[0]);

			/** Si no, es por que está en foreground **/
			} else {
				/**
				 * Wait con detección de suspension y recuperación del terminal
				 * Con el WUNTRACED se comprueba también si el hijo se suspende
				 **/
				set_terminal(pid_fork);	// Redundante
				pid_t wait_pid = waitpid(pid_fork, &status, WUNTRACED);
				set_terminal(getpid());

				/**
				 * pid_fork = waitpid(pid_fork, &status, 0);
				 * esta instruccion ya no es necesaria porque hacemos el wait_pid
				 **/
				int info;
				// Le pasamos la variable "status" que nos acaba de pasar el wait
				enum status st = analyze_status(status, &info);

				/**
				 * Si sale del bloqueo debido a la suspensión del estado
				 * lo metemos en la lista de tareas para poder llevar un
				 * seguimiento de los procesos suspendidos
				 **/
				if(st == SUSPENDED) {
					/** BLoqueamos la señal SIGCHLD, añadimos el trabajo a la lista (suspendido) y desbloqueamos la señal **/
					block_SIGCHLD();
					// Creamos un nuevo nodo para agregarlo a la lista
					job *aux = new_job(pid_fork, args[0], args, STOPPED);
					// Añadimos ese nodo a la lista creada anteriormente
					add_job(lista_trabajos, aux);
					unblock_SIGCHLD();
				}

				// (4) Shell shows a status message for processed command
				printf("Foreground pid: %d, command: %s, status: %s, info: %d. \n", wait_pid, args[0], status_strings[st], info);

			}
		}

		// (5) loop returns to get_commnad() function

	} // end while
}