Ejemplo n.º 1
0
/*
 * Unshare file descriptor table if it is being shared
 */
static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp)
{
	struct files_struct *fd = current->files;
	int error = 0;

	if ((unshare_flags & CLONE_FILES) &&
	    (fd && atomic_read(&fd->count) > 1)) {
		*new_fdp = dup_fd(fd, &error);
		if (!*new_fdp)
			return error;
	}

	return 0;
}
Ejemplo n.º 2
0
pid_t pty_fork(int *ptrfdm, char** pts_name) {
    pid_t pid;
    char* name;
    int master_fd, pty_fd;

    if ((master_fd = ptm_open()) < 0) {
        err_sys("ERROR: ptm_open() failed [%d]\n", master_fd);
    }

    if ((name = ptsname(master_fd)) == NULL) {
        close(master_fd);
        return -1;
    }

    // Put values to the output params
    *pts_name = name;
    *ptrfdm = master_fd;

    if ((pid = fork()) < 0) {
        printf("FAILED");
        return (-1);
    }

    if (pid == 0) { /* child */
        if (setsid() < 0) {
            err_sys("setsid error");
        }

        if ((pty_fd = pts_open(master_fd)) < 0) {
            err_sys("can't open slave pty");
        }

        close(master_fd);
        dup_fd(pty_fd);

        return (0); /* child returns 0 just like fork() */
    } else { /* parent */
        return (pid); /* parent returns pid of child */
    }

}
Ejemplo n.º 3
0
static int copy_files(unsigned long clone_flags, struct task_struct *tsk)
{
	struct files_struct *oldf, *newf;
	int error = 0;

	oldf = current->files;
	if (!oldf)
		goto out;

	if (clone_flags & CLONE_FILES) {
		atomic_inc(&oldf->count);
		goto out;
	}

	newf = dup_fd(oldf, &error);
	if (!newf)
		goto out;

	tsk->files = newf;
	error = 0;
out:
	return error;
}
Ejemplo n.º 4
0
int
_user_dup(int fd)
{
	return dup_fd(fd, false);
}
Ejemplo n.º 5
0
int
_kern_dup(int fd)
{
	return dup_fd(fd, true);
}
Ejemplo n.º 6
0
/****** err_trace/shepherd_trace_init_intern() *******************************
*  NAME
*     shepherd_trace_init_intern() -- Initialize shepherd's tracing. 
*
*  SYNOPSIS
*     static FILE* shepherd_trace_init(char *trace_file_path,
*													char *trace_file_name)
*
*  FUNCTION
*     Opens the shepherd's trace file and sets the FD_CLOEXEC-flag so it will
*     be closed automatically in an exec()-call.
*     Must be called with euid=admin user to work properly!
*
*  INPUTS
*     char *trace_file_path - either the whole path of the trace file (including
*                             the file itself)
*                             or NULL to retrieve the file pointer of an already
*                             opened trace file.
*     char *trace_file_name - the name of the trace file itself. Ignored when
*                             *trace_file_path is NULL.
* 
*  RESULT
*     FILE* - If successfully opened, the file pointer of shepherd's trace file.
*           - Otherwise NULL.
*******************************************************************************/
static FILE* shepherd_trace_init_intern(st_shepherd_file_t shepherd_file)
{
   static char     path[SGE_PATH_MAX];
   static bool     called = false;
   SGE_STRUCT_STAT statbuf;
   dstring         ds;
   char            buffer[SGE_PATH_MAX+128];
   char            tmppath[SGE_PATH_MAX];
   int             fd       = -1;
   FILE            *fp      = NULL;
   int             do_chown = 0;

  	/* 
  	 *  after changing into the jobs cwd we need an 
  	 *  absolute path to the error/trace file 
  	 */
	if (called == false) { 
      getcwd(path, sizeof(path)); 
		called=true;
	}

  	snprintf(tmppath, SGE_PATH_MAX,"%s/%s",path, g_shepherd_file_name[shepherd_file]);
   sge_strlcpy(g_shepherd_file_path[shepherd_file], tmppath, SGE_PATH_MAX);

	/* If the file does not exist, create it. Otherwise just open it. */
	if (SGE_STAT(tmppath, &statbuf)) {
	  fd = SGE_OPEN3(tmppath, O_RDWR | O_CREAT | O_APPEND, 0644);
      if (fd<0) {
         sge_dstring_init(&ds, buffer, sizeof(buffer));
         sge_dstring_sprintf(&ds, "creat(%s) failed: %s", tmppath, strerror(errno));
         shepherd_panic(buffer);
      }

      if (getuid() == SGE_SUPERUSER_UID) {
         /* We must give the file to the job owner later */
			do_chown = 1;
		} else {
         /* We are not root, so we have to own all files anyway. */
         do_chown = 0;
		}
	} else {
      /* The file already exists. We get here when
       * a) a exec() failed or
       * b) after the execution of prolog/job, when the job/epilog
       * tries to init the error/exit status files.
       *
       * In a root system we can just open the file, because we are either
       * root or the job user who owns the file.
       * In a admin user system we must set our euid to root to open it, then
       * it is the same as the root system.
       * In a test user system we are the owner of the file and can open it.
       *
       * When we are root (masked or not), we gave this file to the
       * prolog user/job user right after its creation. But we can have
       * 3 different users for prolog, job and epilog, so we must give
       * the file here to the next user.
       * This must be done via shepherd_trace_chown() in the shepherd
       * before we switch to this user there.
       * It can't be done here because we don't know if we are in 
       * case a) (exec failed) or case b) (after execution of prolog/job).
       */
      int  old_euid = SGE_SUPERUSER_UID;

      /*
       * Work around for CR 6293411:
       * See shepherd_trace_exit() for details.
       */
      if (getuid() == SGE_SUPERUSER_UID) {
         old_euid = geteuid();
         seteuid(SGE_SUPERUSER_UID);
      }

      fd = SGE_OPEN2(tmppath, O_RDWR | O_APPEND);
      if (fd<0) {
         sge_dstring_init(&ds, buffer, sizeof(buffer));
         sge_dstring_sprintf(&ds, "open(%s) failed: %s",
                             tmppath, strerror(errno));
         shepherd_panic(buffer);
      }
      do_chown = 0;

      /*
       * Switch back to admin user?
       */
      if (old_euid != SGE_SUPERUSER_UID) {
         seteuid(old_euid);
      }
	}

	/* Something went wrong. */
	if (fd<0) {
		return NULL;
	}

	/* To avoid to block stdin, stdout or stderr, dup the fd until it is >= 3 */
	if (fd<3) {
		dup_fd(&fd);
	}

	/* Set FD_CLOEXEC flag to automatically close the file in an exec() */
	if (!set_cloexec(fd)) {
      shepherd_panic("set_cloexec() failed");
		return NULL;
	}

   /*
	 * Now open a FILE* from the file descriptor, so we can use fprintf().
    */
	fp = fdopen(fd, "a");
   if (!fp) {
      sge_dstring_init(&ds, buffer, sizeof(buffer));
      sge_dstring_sprintf(&ds, "can't open %s file \"%s\": %s\n",
				              g_shepherd_file_name[shepherd_file], tmppath, 
                          strerror(errno));
      shepherd_panic(buffer);
      return NULL;
   }
	if (do_chown && strlen(g_job_owner) > 0) {
		shepherd_trace_chown_intern(g_job_owner, fp, shepherd_file);
	}
	return fp;
}