Exemple #1
0
void	sig_handler(int sig)
{
  t_sh	*shell;

  shell = get_sh_info(NULL);
  SETFLAG(shell->signal, FLAGPOS(sig));
  if (sig == SIGINT)
    {
      my_putstr("\n", 1, -1);
      my_putstr(shell->param.str_prompt, 1, -1);
      if (shell->param.fallback == 1)
        {
          if (shell->param.cmd != NULL)
            shell->param.cmd[0] = '\0';
          shell->param.pos = 0;
          refresh_view(&(shell->param));
          view(shell->param.cmd, &(shell->param));
        }
    }
  if (sig == SIGWINCH && shell->param.fallback == 1)
    clear_cmd(shell->param.cmd, &(shell->param));
  if ((sig == SIGHUP) || (sig == SIGTERM) || (sig == SIGQUIT))
    {
      SETFLAG(shell->beepbeepexit, FLAGPOS(EXIT_F_POS));
      close(0);
    }
  init_sig(&sig_handler);
}
Exemple #2
0
void	builtin_fg(t_cmd *cmd, UNSEDP t_fds *fd, t_sh *shell)
{
  int	pgid;
  int	i;
  int	nb;

  i = 0;
  nb = 0;
  if (shell->process_group == NULL || !shell->jobcontrol)
    return ;
  if (cmd->argv[1] != NULL)
    nb = my_getnbr(cmd->argv[1]) - 1;
  while ((shell->process_group[i] != NULL) && (i < nb))
    i++;
  if (shell->process_group[i] != NULL)
    {
      pgid = shell->process_group[i]->pid.pgid;
      if (pgid != -1)
        {
          SETFLAG(shell->process_group[i]->flags, FLAGPOS(FGRP_FORGROUND));
          SETFLAG(shell->process_group[i]->flags, FLAGPOS(FGRP_RUNNING));
          if (set_forground_pgrp(pgid) == -1)
            set_forground_pgrp(shell->pid.pgid);
          kill(-pgid, SIGCONT);
        }
    }
}
Exemple #3
0
void	builtin_exit(t_cmd *cmd, UNSEDP t_fds *fd, t_sh *shell)
{
  if (cmd->argv[1] != NULL)
    shell->beepbeepexit = my_getnbr(cmd->argv[1]);
  else
    shell->beepbeepexit = 0;
  SETFLAG(shell->beepbeepexit, FLAGPOS(EXIT_F_POS));
  UNSETFLAG(shell->beepbeepexit, FLAGPOS(EXIT_FORK));
}
Exemple #4
0
void	no_fg_jobs_status(t_sh *shell)
{
  t_grp	*fg_grp;

  if ((fg_grp = get_forground_grp(shell)) != NULL)
    {
      UNSETFLAG(fg_grp->flags, FLAGPOS(FGRP_RUNNING));
      UNSETFLAG(fg_grp->flags, FLAGPOS(FGRP_FORGROUND));
      set_forground_pgrp(shell->pid.pgid);
    }
}
Exemple #5
0
int	exec_process(t_cmd *cmd, t_fds *fd, t_sh *shell,
                 int (*f)(char *cmd, char **argv, t_sh *shell))
{
  int	ret_exec;

  if ((cmd->pid.pid = check_perror("Fork", fork())) == 0)
    {
      if (cmd->pid.pgid != -1)
        {
          if (check_perror("Setpgid", setpgid(0, cmd->pid.pgid)) == -1)
            check_perror("Setpgid", setpgid(0, 0));
        }
      else
        check_perror("Setpgid", setpgid(0, 0));
      check_perror("Dup2", dup2(fd->stdin, 0));
      check_perror("Dup2", dup2(fd->stdout, 1));
      check_perror("Dup2", dup2(fd->stderr, 2));
      if ((ret_exec = f(cmd->cmd_fpath, cmd->argv, shell)) == -1)
        my_perror(cmd->cmd_fpath);
      my_exit(ret_exec);
      SETFLAG(shell->beepbeepexit, FLAGPOS(EXIT_FORK));
    }
  else if (cmd->pid.pid != -1)
    check_grp_set(cmd->pid.pid,
                  (cmd->pid.pgid == -1) ? cmd->pid.pid : cmd->pid.pgid);
  return (cmd->pid.pid);
}
t_grp	*get_forground_grp(t_sh *shell)
{
    int	i;
    t_grp	**pr_grp;
    t_grp	*tmp_grp;

    i = 0;
    pr_grp = shell->process_group;
    if (pr_grp == NULL)
        return (NULL);
    while ((tmp_grp = pr_grp[i]) != NULL)
    {
        if (GETFLAG(tmp_grp->flags, FLAGPOS(FGRP_FORGROUND))
                && !GETFLAG(tmp_grp->flags, FLAGPOS(FGRP_TERMINATED)))
            return (tmp_grp);
        i++;
    }
    return (NULL);
}
void	set_forground_process_g(t_sh *shell, t_grp *grp)
{
    int	i;
    t_grp	*tmp_grp;

    i = 0;
    if (shell->process_group == NULL)
        return ;
    while ((tmp_grp = shell->process_group[i]) != NULL)
    {
        if (tmp_grp == grp)
        {
            SETFLAG(tmp_grp->flags, FLAGPOS(FGRP_FORGROUND));
            if (set_forground_pgrp(grp->pid.pgid) == -1)
                set_forground_pgrp(shell->pid.pgid);
        }
        else
            UNSETFLAG(tmp_grp->flags, FLAGPOS(FGRP_FORGROUND));
        i++;
    }
}
int	exec_process_group(t_sh *shell, t_grp *grp)
{
  int	tmp;

  if (grp == NULL)
    return (-1);
  if ((tmp = (is_grp_exec(shell, grp) - 1)) != -1)
    tmp = open_redirection(grp, shell);
  if (MEXIT)
    return (0);
  if (tmp != -1)
    if ((exec_a_pipe(shell, grp) == -1) || (MEXIT))
      return (-1);
  shell->process_group = (t_grp**)add_ptr_t_tab((void**)shell->process_group,
                         (void*)grp);
  if (GETFLAG(grp->flags, FLAGPOS(FGRP_FORGROUND)) && (grp->pid.pgid != -1))
    set_forground_process_g(shell, grp);
  else
    UNSETFLAG(grp->flags, FLAGPOS(FGRP_FORGROUND));
  return (0);
}
Exemple #9
0
void	rm_all_terminated_grp(t_sh *shell)
{
  int	i;
  t_grp	*grp;

  i = 0;
  if (shell != NULL)
    while ((shell->process_group != NULL)
           && (grp = shell->process_group[i]) != NULL)
      {
        if (GETFLAG(grp->flags, FLAGPOS(FGRP_TERMINATED)))
          {
            i = 0;
            free_process_group(grp);
            rm_ptr_f_tab((void**)shell->process_group, (void*)grp);
          }
        i++;
      }
}
Exemple #10
0
void	builtin_bg(t_cmd *cmd, UNSEDP t_fds *fd, t_sh *shell)
{
  int	pgid;
  int	i;
  int	nb;

  i = 0;
  nb = 0;
  if (shell->process_group == NULL)
    return ;
  if (cmd->argv[1] != NULL)
    nb =  my_getnbr(cmd->argv[1]) - 1;
  while ((shell->process_group[i] != NULL) && (i < nb))
    i++;
  if (shell->process_group[i] != NULL)
    {
      pgid = shell->process_group[i]->pid.pgid;
      SETFLAG(shell->process_group[i]->flags, FLAGPOS(FGRP_RUNNING));
      kill(-pgid, SIGCONT);
    }
}
Exemple #11
0
void FastDup::Compare(FileReference *first, off_t filesize, DupeSetCallback callback)
{
	int blockcount = (int)ceil(filesize / BLOCKSIZE);

	int fcount = 0;
	for (FileReference *p = first; p; p = p->next)
		++fcount;
	
	bool progress = (Interactive && (filesize*fcount >= 3*1048576));
	int ipint = 0;
	if (progress)
	{
		ipint = (int)ceil(double(blockcount*fcount)/100);
		printf("Comparing %d files... \E[s0%%", fcount);
		fflush(stdout);
	}
	
	/* FDs */
	int ffd[fcount];
	/* File reference map, used afterwards to map back to the real file */
	FileReference *frmap[fcount];
	/* Data buffers */
	char *rrdbuf = new char[fcount * BLOCKSIZE];
	char *rdbuf[fcount];
	ssize_t rdbp = 0;
	/* Matchflag is 1 for each file pair that may still match, 0
	 * for pairs that cannot match, or 2 indicating that the current
	 * block of both files is known to match (which will be reset
	 * to 1 before the next block).
	 *
	 * To save space, a somewhat complex equation is used to calculate
	 * the positions of the flag for a given pair of files (i and j).
	 * The result of this equation is to map them so that, if there are
	 * 3 files total, [0] is 0 & 1, [1] is 0 & 2, [2] is 1 & 2, and
	 * no space is wasted.
	 *
	 * To calculate the position for files i and j with a maximum of f
	 * files, assuming that j > i, use:
	 *     int(((f-1)*i)-(i*(i/2.0-0.5))+(j-i)-1);
	 */
	char matchflag[(fcount*(fcount-1))/2];
#define FLAGPOS(i,j) int(((fcount-1)*(i))-((i)*((i)/2.0-0.5))+((j)-(i))-1)
	/* Holds the result for the matching of the current file (i) against
	 * all other TESTED files, by the index of the second file (j). Note
	 * that many parts of this may be left untouched due to other
	 * optimizations preventing a comparison. Use only when that
	 * information is known. Values are identical to the return of
	 * memcmp; -1 for i < j, 0 for i == j, 1 for i > j.
	 *
	 * Used to avoid comparisons by finding when two other files cannot
	 * match this block, or must match this block (i.e. i > j and i < k,
	 * or i == j and i == k).
	 */
	int mresult[fcount];
	/* Omit is true for files that have no possible matches left. These
	 * are not read or processed at all. */
	bool omit[fcount];
	/* Number of files omitted; used to end early if we run out of possible
	 * matches */
	int omitted = 0;
	/* Used to calculate omit, by keeping track of the number of comparisons
	 * with other files that have been skipped against this file. When this
	 * reaches fcount for a given file index, that file may be omitted. */
	int skipcount[fcount];
	
	memset(matchflag, 1, sizeof(matchflag));
	memset(omit, false, sizeof(omit));
	memset(skipcount, 0, sizeof(skipcount));
	
	int i = 0, j = 0;
	for (FileReference *p = first; p; p = p->next, ++i)
	{
		frmap[i] = p;
		const char *fn = p->FullPath();
		
		rdbuf[i] = rrdbuf + (BLOCKSIZE * i);
		
		if ((ffd[i] = open(fn, O_RDONLY)) < 0)
		{
			printf("Unable to open file '%s': %s\n", fn, strerror(errno));
			// Note: if handled in any other way, clean up open FDs and rrdbuf
			exit(EXIT_FAILURE);
		}
	}
	
	// Loop over blocks of the files, which will be compared
	int ti = 0;
	for (int block = 0;; ++block)
	{
		for (i = 0; i < fcount; i++)
		{
			if (omit[i])
				continue;
			
			rdbp = read(ffd[i], rdbuf[i], BLOCKSIZE);

			if (progress && (++ti == ipint))
			{
				ti = 0;
				fprintf(stdout, "\E[u%d%%", int((double((block+1)*(i+1))/(blockcount*fcount))*100));
				fflush(stdout);
			}
			
			if (rdbp < 0)
			{
				printf("%d: Read error: %s\n", i, strerror(errno));
				// Note: if handled in any other way, cleanup
				exit(EXIT_FAILURE);
			}
			else if (!rdbp)
			{
				// All files are assumed to be equal in size
				break;
			}
		}
		
		if (!rdbp)
			break;
		
		for (i = 0; i < fcount; i++)
		{
			if (omit[i])
				continue;
			
			for (j = i + 1; j < fcount; j++)
			{
				if (omit[j])
					continue;
				
				int flagpos = FLAGPOS(i, j);
				if (!matchflag[flagpos])
					continue;
				else if (matchflag[flagpos] == 2)
				{
					matchflag[flagpos] = 1;
					mresult[j] = 0;
				}
				else
					mresult[j] = memcmp(rdbuf[i], rdbuf[j], rdbp);
				
				for (int k = j - 1; k > i; --k)
				{
					if (omit[k])
						continue;
					
					int kflagpos = FLAGPOS(k, j);
					if (!matchflag[kflagpos])
						continue;
					
					if (mresult[k] != mresult[j])
					{
						matchflag[kflagpos] = 0;
						++skipcount[j];
						if (++skipcount[k] == fcount - 1)
						{
							omit[k] = true;
							close(ffd[k]);
							ffd[k] = -1;
							omitted++;
						}
					}
					else if (mresult[k] == 0 && mresult[j] == 0)
					{
						/* These will be equal, so we can avoid comparing them; signal this by setting
						 * matchflag to 2 for this block (it is one-shot, and will be reset before the
						 * next block). This is a huge saver when there is more than one duplicate of
						 * the same file. */
						matchflag[kflagpos] = 2;
					}
				}
				
				if (mresult[j] != 0)
				{
					matchflag[flagpos] = 0;
					skipcount[i]++;
					if (++skipcount[j] == fcount - 1)
					{
						omit[j] = true;
						close(ffd[j]);
						ffd[j] = -1;
						omitted++;
					}
				}
			}
			
			if (skipcount[i] == fcount - 1)
			{
				omit[i] = true;
				close(ffd[i]);
				ffd[i] = -1;
				if (++omitted == fcount)
					goto endscan;
			}
		}
	}