Exemplo n.º 1
0
int				ft_ar_rgt(t_pipe **tmp, t_data *env)
{
	int		fd;
	int		ret;
	int		i;

	i = 1;
	ret = 0;
	fd = -1;
	if ((*tmp)->argv[1])
	{
		fd = open((*tmp)->argv[1], O_CREAT | O_WRONLY | O_TRUNC, 0644);
		if (fd == -1)
			ret = -1;
	}
	while ((*tmp)->argv[++i])
		ret = check_arg(tmp, i);
	if (ret > -1)
	{
		if ((ret = do_dup(fd, tmp, env)) < 0)
			return (ret);
	}
	if (ret < 0)
		return (ret);
	return (0);
}
Exemplo n.º 2
0
/*
17.6.1.2212 SLITERAL
STRING
Interpretation: Interpretation semantics for this word are undefined.
Compilation: ( c-addr1 u -- )
Append the run-time semantics given below to the current definition.
Run-time: ( -- c-addr2 u )
Return c-addr2u describing a string consisting of the characters specified by c-addr1 u
during compilation. A program shall not alter the returned string.
See: A.17.6.112.0 SLITERAL.
*/
static void do_sliteral(void)
{
/*
: sliteral ( c-addr u -- )
	postpone ahead rot rot
	( save a pointer to the string at runtime)
	here >r
	( copy string to data space)
	2dup here swap cmove
	dup allot align
	rot postpone then
	( compile runtime string address)
	r> postpone literal
	( compile runtime string length)
	postpone literal
	drop ( c-addr)
	; immediate

: str s" sample string" ;
str type cr cr
: stest [ str ] sliteral ;
: stest [ str ] sliteral 1- swap 1+ swap ." string is:" cr cr type cr cr ;

 */
do_ahead(); do_rot(); do_rot();
do_here(); do_to_r();
do_two_dup(); do_here(); do_swap(); do_cmove();
do_dup(); do_allot(); do_align();
do_rot(); do_then();
do_r_from(); do_literal();
do_literal();
do_drop();

}
Exemplo n.º 3
0
int				ft_ar_lft(t_pipe **tmp, t_data *env)
{
	int		fd;
	int		ret;

	fd = -1;
	ret = 0;
	if ((*tmp)->argv[1])
	{
		fd = open((*tmp)->argv[1], O_RDONLY);
		if (fd == -1)
		{
			ft_putstr((*tmp)->argv[1]);
			ft_putstr(" No such file or directory\n");
			ret = -1;
		}
		else
		{
			if ((ret = do_dup(fd, tmp, env)) < 0)
				return (ret);
		}
	}
	if (ret < 0)
		return (ret);
	return (0);
}
Exemplo n.º 4
0
static int sys_dup(int fd)
{
    int err;
    
    if ((err = do_dup(fd)) < 0) {
        curthr->kt_errno = -err;
        return -1;
    } else return err;
}
Exemplo n.º 5
0
/*
 * For backward compatibility.
 */
int
sys_cap_new(struct thread *td, struct cap_new_args *uap)
{
	struct filedesc *fdp;
	cap_rights_t rights;
	register_t newfd;
	int error, fd;

	fd = uap->fd;
	rights = uap->rights;

	AUDIT_ARG_FD(fd);
	AUDIT_ARG_RIGHTS(rights);

	if ((rights & ~CAP_ALL) != 0)
		return (EINVAL);

	fdp = td->td_proc->p_fd;
	FILEDESC_SLOCK(fdp);
	if (fget_locked(fdp, fd) == NULL) {
		FILEDESC_SUNLOCK(fdp);
		return (EBADF);
	}
	error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE);
	FILEDESC_SUNLOCK(fdp);
	if (error != 0)
		return (error);

	error = do_dup(td, 0, fd, 0, &newfd);
	if (error != 0)
		return (error);

	FILEDESC_XLOCK(fdp);
	/*
	 * We don't really care about the race between checking capability
	 * rights for the source descriptor and now. If capability rights
	 * were ok at that earlier point, the process had this descriptor
	 * with those rights, so we don't increase them in security sense,
	 * the process might have done the cap_new(2) a bit earlier to get
	 * the same effect.
	 */
	fdp->fd_ofiles[newfd].fde_rights = rights;
	if ((rights & CAP_IOCTL) == 0) {
		free(fdp->fd_ofiles[newfd].fde_ioctls, M_TEMP);
		fdp->fd_ofiles[newfd].fde_ioctls = NULL;
		fdp->fd_ofiles[newfd].fde_nioctls = 0;
	}
	if ((rights & CAP_FCNTL) == 0)
		fdp->fd_ofiles[newfd].fde_fcntls = 0;
	FILEDESC_XUNLOCK(fdp);

	td->td_retval[0] = newfd;

	return (0);
}
Exemplo n.º 6
0
bool msg_callback(void *buf, anvil_msginfo_t *msg_info)
{
    // Assume that we'll handle the msg
    bool handled = true;

    //anvil_syslog(0, "msg_callback\n");

    switch (msg_info->type & ~ANVIL_NAME_LOOKUP)
    {
        case ANVIL_OPEN:
            do_open(buf, msg_info);
            break;
        case ANVIL_CLOSE:
            do_close(buf, msg_info);
            break;
        case ANVIL_DUP:
            do_dup(buf, msg_info);
            break;
        case ANVIL_READ:
            do_read(buf, msg_info);
            break;
        case ANVIL_WRITE:
            do_write(buf, msg_info);
            break;
        case ANVIL_STAT:
            do_stat(buf, msg_info);
            break;
        case ANVIL_GETATTR:
            do_getattr(buf, msg_info);
            break;
        case ANVIL_SETATTR:
            do_setattr(buf, msg_info);
            break;
        case ANVIL_GETWINSZ:
            do_getwinsz(buf, msg_info);
            break;

        default:
            handled = false;
            anvil_syslog(0, "term-svr GOT UNKNOWN MSG %d\n", msg_info->type);
            break;
    }
    return handled;
}
Exemplo n.º 7
0
int vfs_selftest(kshell_t *kshell, int argc, char **argv)
{
  int fd1,fd2;
  char *y="/ab/fil";
  char x[2];
  int err;
  do_mkdir("/ab");
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  fd1=do_open("/ab/new",2);
  fd2=do_dup2(fd1,NFILES+1);
  if(fd2<0)
    {
      dbg(DBG_PRINT,"File not created\n");
    }
  do_mknod("/ab/notmade",4096,MKDEVID(1,1));
  do_mknod("/ab/new/not",S_IFCHR,MKDEVID(1,1));
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  do_mknod("", S_IFCHR,MKDEVID(1,1));

  /*do_close(fd1);*/
    for(fd2=1;fd2<35;fd2++)
    {
      sprintf(x,"%d",fd2);
      strcat(y,x);
      do_mknod(y,S_IFCHR,MKDEVID(1,0));
      err=do_open(y,2);
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
      
    }
do_mknod("/ab/new1", S_IFCHR,MKDEVID(1,1));
 err=do_dup(fd1);
  do_unlink("/ab/new/ab");
 do_unlink("/ab/new");
 do_close(fd1);
 for(fd2=NFILES-1;fd2>0;fd2--)
   {
     err=do_close(fd2);
     sprintf(x,"%d",fd2);
      strcat(y,x);
      do_unlink(y);  
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
   }
 do_link("/a","/dev");
 do_link("/dev","/a");
 do_link("/dev","/a");
 do_rmdir("/a");
 /* mkdir("/k");
    do_link("/ab","/k");*/
  do_rmdir("/ab");
  /*do_rmdir("/k");*/

 /*GS: SELF TESTS*/
    dbg(DBG_PRINT,"\n*************************************************************\n");
    dbg(DBG_PRINT,"\n\n\n\n(GRADING2C)(kmain.c)(selftest_proc_run) selftests begin\n");

    int retVal = 0;
    int i = 0;

    /* 1. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_stat)  strlen too long, return -ENAMETOOLONG\n");*/
    char longPath[1024 + 1] = {0};
    for(i = 0; i < 1025; i++)
        longPath[i] = 'a';
    struct stat buf;
    retVal = do_stat(longPath, &buf);
    retVal=do_chdir(longPath);

    /*2. dbg(DBG_PRINT, "(GRADING2B) ENOTDIR or ENOENT\n");*/
    retVal = do_stat("", &buf);

    /*3. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    struct dirent dirp;
    retVal = do_getdent(-1, &dirp);

    /*4. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    retVal = do_getdent(1, &dirp);

    /*5. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) File descriptor does not refer to a directory, return -ENOTDIR\n");*/
    do_mknod("/./file", S_IFCHR,MKDEVID(1,1));
    fd1 = do_open("/./file",2);
    retVal = do_getdent(fd1, &dirp);

    do_unlink("/./file");
    do_close(fd1);
    /*6. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) Both are valid names \n");*/
    /* and */
    /*7. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) error do_link, return error\n"); \n");*/
    retVal = do_rename("/./aaa", "/./bbb");


    dbg(DBG_PRINT,"\n\nretVal=%d",retVal);
    dbg(DBG_PRINT,"\n*************************************************************\n");
  return 0;
}
Exemplo n.º 8
0
void *extra_self_tests(int arg1, void *arg2)
{
        /* creating /test1/test2/ directories */
   dbg(DBG_ERROR | DBG_VFS,"TEST: Creating directories\n");        
                do_mkdir("dir");
                do_mkdir("dir/dir1");
                do_mkdir("dir/dir2");
                do_mkdir("dir/dir3");             
                do_mkdir("dir/dir4");  
   dbg(DBG_ERROR | DBG_VFS,"TEST: Directories are created\n");
        int fd;
        char *file2buf="File 2 write only test case";
        char *file1buf="Testing file_1 for write operation";
        char readbuf[150];

   dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir1\n");
        do_chdir("dir/dir1");

        /* file1.txt creation with O_CREAT|O_WRONLY  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Create file1.txt with O_CREAT|O_WRONLY flag in directory dir/dir1\n");
        fd = do_open("file1.txt", O_CREAT|O_WRONLY);
        do_write(fd, file1buf, strlen(file1buf));
        do_close(fd);
        
        /* file2.txt creation with O_CREAT|O_RDONLY  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir2\n");
        do_chdir("/dir/dir2");
        
   dbg(DBG_ERROR | DBG_VFS,"TEST: Create file2.txt with O_CREAT | O_RDONLY flag  in directory dir/dir2\n");
        fd = do_open("file2.txt", O_CREAT | O_RDONLY);
        do_close(fd);
        
         /* Write into file2.txt using O_WRONLY flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Write into file2.txt with O_WRONLY flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_WRONLY);
        do_write(fd, file2buf, strlen(file2buf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: written chars: \"%s\" in file2.txt\n",file2buf);
   
        char *appendbuf=" Appending for O_WRONLY|O_APPEND mode";
      /* Append into file2.txt using  O_WRONLY|O_APPEND  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_WRONLY|O_APPEND flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_WRONLY|O_APPEND);
        do_write(fd, appendbuf, strlen(appendbuf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",appendbuf);
        fd = do_open("file2.txt", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_read(fd,readbuf,strlen(file2buf)+strlen(appendbuf));
   dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf);

        char *append2buf=" Appending for O_RDWR|O_APPEND mode in file2";
      /* Append into file2.txt using  O_RDWR|O_APPEND  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_RDWR|O_APPEND flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_RDWR|O_APPEND);
        do_write(fd, append2buf, strlen(append2buf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",append2buf);
        fd = do_open("file2.txt", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_read(fd,readbuf,strlen(file2buf)+strlen(append2buf)+strlen(appendbuf));
   dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf);

   dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source directory => /dir/dir2, Destination directory => /dir/linkofdir2 \n");
        do_chdir("/");
        do_link("dir/dir2","dir/linkofdir2");

   dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source file => /dir/dir1/file1.txt, to the Destination => /dir/linkoffile1 \n");
        do_link("dir/dir1/file1.txt","dir/linkoffile1");
        
   dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming directory from dir/dir3 to dir/renamed \n");
        do_rename("dir/dir3","dir/renameddir3");

   dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming file from dir/dir1/file1.txt to dir/dir1/renamedfile1.txt \n");
        do_rename("dir/dir1/file1.txt","dir/dir1/renamedfile1.txt");

   dbg(DBG_ERROR | DBG_VFS,"TEST: Removing directory dir/dir4 \n");
        do_rmdir("dir/dir4");

   dbg(DBG_ERROR | DBG_VFS,"TEST: reading 18 chars from file: /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n");
        fd = do_open("dir/linkoffile2", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: read 18 chars: \"%s\" from file: /dir/linkoffile1\n",readbuf);
   
   dbg(DBG_ERROR | DBG_VFS,"TEST: reading file using lseek function on  /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n");
        memset(readbuf,0,sizeof(char)*150);
        fd = do_open("dir/linkoffile2", O_RDONLY);
        do_lseek(fd,-19,2);
        do_read(fd,readbuf,19);
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: read chars: \"%s\" using lseek from file: /dir/linkoffile1\n",readbuf);
   
   dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup()\n");
        fd = do_open("/dir/dir2/file2.txt", O_RDONLY);
    int fd2= do_dup(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: duplicate file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2);
             do_close(fd);        do_close(fd2);
                     
   dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup2()\n");    
        fd = do_open("/dir/dir2/file2.txt", O_RDONLY);
        fd2= do_dup2(fd,20);
   dbg(DBG_ERROR | DBG_VFS,"TEST: custom file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2);
                do_close(fd);        do_close(fd2);

        /*  Testing stat
        struct *statbuf;
   dbg(DBG_ERROR | DBG_VFS,"TEST: Testing the stat system call for directory dir\n");
        do_stat("dir",statbuf);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Output of stat for directory dir is :\"%s\" \n",statbuf);*/

        shellTest(); 

     return NULL;
}
Exemplo n.º 9
0
void
impl_exit_start(void)
{
    if( is_exiting == TRUE )
    {
        return;
    }

    /* We are now exiting.
     * After this point, all calls to various sockets,
     * (i.e. accept(), listen(), etc. will result in stalls.
     * We are just waiting until existing connections have 
     * finished and then we will be either exec()'ing a new
     * version or exiting this process. */
    is_exiting = TRUE;

    /* Get ready to restart.
     * We only proceed with actual restart actions
     * if we are the master process, otherwise we will
     * simply prepare to shutdown cleanly once all the
     * current active connections have finished. */
    if( master_pid == getpid() )
    {
        pid_t child;
        DEBUG("Exit started -- this is the master.");

        /* Unlink files (e.g. pidfile). */
        if( to_unlink != NULL && strlen(to_unlink) > 0 )
        {
            DEBUG("Unlinking '%s'...", to_unlink);
            unlink(to_unlink);
        }

        /* Neuter this process. */
        for( int fd = 0; fd < fd_limit(); fd += 1 )
        {
            fdinfo_t* info = fd_lookup(fd);
            if( exit_strategy == FORK &&
                info != NULL && info->type == SAVED )
            {
                /* Close initial files. Since these
                 * are now passed on to the child, we
                 * ensure that the parent won't mess 
                 * with them anymore. Note that we still
                 * have a copy as all SAVED descriptors. */
                if( info->saved.fd == 2 )
                {
                    /* We treat stderr special.
                     * Assuming logging will go here, we
                     * allow the parent process to continue
                     * writing to this file (and hope that
                     * it's open in APPEND mode, etc.). */
                    continue;
                }
                int nullfd = open("/dev/null", O_RDWR);
                do_dup2(nullfd, info->saved.fd);
                libc.close(nullfd);
            }
            if( info != NULL &&
                info->type == BOUND && !info->bound.is_ghost )
            {
                /* Change BOUND sockets to dummy sockets.
                 * This will allow select() and poll() to
                 * operate as you expect, and never give
                 * back new clients. */
                int newfd = do_dup(fd);
                if( newfd >= 0 )
                {
                    int dummy_server = impl_dummy_server();
                    if( dummy_server >= 0 )
                    {
                        /* Remove the descriptor in any epoll FDs. */
                        for( int efd = 0; efd < fd_limit(); efd += 1 )
                        {
                            fdinfo_t* einfo = fd_lookup(efd);
                            if( einfo != NULL && einfo->type == EPOLL )
                            {
                                struct epoll_event no_event;
                                epoll_ctl(efd, EPOLL_CTL_DEL, fd, &no_event);
                            }
                        }

                        info->bound.is_ghost = 1;
                        do_dup2(dummy_server, fd);
                        DEBUG("Replaced FD %d with dummy.", fd);
                    }
                    else
                    {
                        do_close(newfd);
                    }
                }
            }
        }

        switch( exit_strategy )
        {
            case FORK:
                /* Start the child process.
                 * We will exit gracefully when the tracked
                 * connection count reaches zero. */
                DEBUG("Exit strategy is fork.");
                child = libc.fork();
                if( child == 0 )
                {
                    DEBUG("I'm the child.");
                    impl_exec();
                }
                else
                {
                    DEBUG("I'm the parent.");
                }
                break;

            case EXEC:
                /* Nothing necessary beyond the above. */
                DEBUG("Exit strategy is exec.");
                break;
        }
    }
    else
    {
        /* Force our strategy to fork, though we haven't forked.
         * This will basically just have this process exit cleanly
         * once all the current active connections have finished. */
        DEBUG("Exit started -- this is the child.");
        exit_strategy = FORK;
    }
}
Exemplo n.º 10
0
void
impl_init(void)
{
    const char* mode_env = getenv("HUPTIME_MODE");
    const char* multi_env = getenv("HUPTIME_MULTI");
    const char* revive_env = getenv("HUPTIME_REVIVE");
    const char* debug_env = getenv("HUPTIME_DEBUG");
    const char* pipe_env = getenv("HUPTIME_PIPE");
    const char* wait_env = getenv("HUPTIME_WAIT");

    if( debug_env != NULL && strlen(debug_env) > 0 )
    {
        debug_enabled = !strcasecmp(debug_env, "true") ? TRUE: FALSE;
    }

    DEBUG("Initializing...");

    /* Initialize our lock. */
    impl_init_lock();

    /* Save this pid as our master pid.
     * This is done to handle processes that use
     * process pools. We remember the master pid and
     * will do the full fork()/exec() only when we are
     * the master. Otherwise, we will simply shutdown
     * gracefully, and all the master to restart. */
    master_pid = getpid();

    /* Grab our exit strategy. */
    if( mode_env != NULL && strlen(mode_env) > 0 )
    {
        if( !strcasecmp(mode_env, "fork") )
        {
            exit_strategy = FORK;
            DEBUG("Exit strategy is fork.");
        }
        else if( !strcasecmp(mode_env, "exec") )
        {
            exit_strategy = EXEC;
            DEBUG("Exit strategy is exec.");
        }
        else
        {
            fprintf(stderr, "Unknown exit strategy.");
            libc.exit(1);
        }
    }

    /* Check if we have something to unlink. */
    to_unlink = getenv("HUPTIME_UNLINK");
    if( to_unlink != NULL && strlen(to_unlink) > 0 )
    {
        DEBUG("Unlink is '%s'.", to_unlink);
    }

    /* Clear up any outstanding child processes.
     * Because we may have exited before the process
     * could do appropriate waitpid()'s, we try to
     * clean up children here. Note that we may have
     * some zombies that hang around during the life
     * of the program, but at every restart they will
     * be cleaned up (so at least they won't grow
     * without bound). */
    int status = 0;
    while( waitpid((pid_t)-1, &status, WNOHANG) > 0 );

    /* Check if we're in multi mode. */
    if( multi_env != NULL && strlen(multi_env) > 0 )
    {
        multi_mode = !strcasecmp(multi_env, "true") ? TRUE: FALSE;
    }
#ifndef SO_REUSEPORT
    if( multi_mode == TRUE )
    {
        fprintf(stderr, "WARNING: Multi mode not supported.\n");
        fprintf(stderr, "(Requires at least Linux 3.9 and recent headers).\n");
    } 
#endif

    /* Check if we're in revive mode. */
    if( revive_env != NULL && strlen(revive_env) > 0 )
    {
        revive_mode = !strcasecmp(revive_env, "true") ? TRUE : FALSE;
    }

    /* Check if we are in wait mode. */
    if( wait_env != NULL && strlen(wait_env) > 0 )
    {
        wait_mode = !strcasecmp(wait_env, "true") ? TRUE : FALSE;
    }

    /* Check if we're a respawn. */
    if( pipe_env != NULL && strlen(pipe_env) > 0 )
    {
        int fd = -1;
        fdinfo_t *info = NULL;
        int pipefd = strtol(pipe_env, NULL, 10);

        DEBUG("Loading all file descriptors.");

        /* Decode all passed information. */
        while( !info_decode(pipefd, &fd, &info) )
        {
            fd_save(fd, info);
            DEBUG("Decoded fd %d (type %d).", fd, info->type);
            info = NULL;
        }
        if( info != NULL )
        {
            dec_ref(info);
        }

        /* Finished with the pipe. */
        libc.close(pipefd);
        unsetenv("HUPTIME_PIPE");
        DEBUG("Finished decoding.");

        /* Close all non-encoded descriptors. */
        for( fd = 0; fd < fd_max(); fd += 1 )
        {
            info = fd_lookup(fd);
            if( info == NULL )
            {
                DEBUG("Closing fd %d.", fd);
                libc.close(fd);
            }
        }

        /* Restore all given file descriptors. */
        for( fd = 0; fd < fd_limit(); fd += 1 )
        {
            info = fd_lookup(fd);
            if( info != NULL && info->type == SAVED )
            {
                fdinfo_t *orig_info = fd_lookup(info->saved.fd);
                if( orig_info != NULL )
                {
                    /* Uh-oh, conflict. Move the original (best effort). */
                    do_dup(info->saved.fd);
                    do_close(info->saved.fd);
                }

                /* Return the offset (ignore failure). */
                if( info->saved.offset != (off_t)-1 )
                {
                    lseek(fd, info->saved.offset, SEEK_SET);
                }

                /* Move the SAVED fd back. */
                libc.dup2(fd, info->saved.fd);
                DEBUG("Restored fd %d.", info->saved.fd);
            }
        }
    }
    else
    {
        DEBUG("Saving all initial file descriptors.");

        /* Save all of our initial files. These are used
         * for re-execing the process. These are persisted
         * effectively forever, and on restarts we close
         * everything that is not a BOUND socket or a SAVED
         * file descriptor. */
        for( int fd = 0; fd < fd_max(); fd += 1 )
        {
            fdinfo_t *info = fd_lookup(fd);
            if( info != NULL )
            {
                /* Encoded earlier. */
                continue;
            }

            /* Make a new SAVED FD. */
            int newfd = libc.dup(fd);
            if( newfd >= 0 )
            {
                fdinfo_t *saved_info = alloc_info(SAVED);

                if( saved_info != NULL )
                {
                    saved_info->saved.fd = fd;
                    saved_info->saved.offset = lseek(fd, 0, SEEK_CUR);
                    fd_save(newfd, saved_info);
                    DEBUG("Saved fd %d (offset %lld).",
                        fd, (long long int)saved_info->saved.offset);
                }
            }
        }
    }

    /* Save the environment.
     *
     * NOTE: We reserve extra space in the environment
     * for our special start-up parameters, which will be added
     * in impl_exec() below. (The encoded BOUND/SAVED sockets).
     *
     * We also filter out the special variables above that were
     * used to pass in information about sockets that were bound. */
    free(environ_copy);
    environ_copy = (char**)read_nul_sep("/proc/self/environ");
    DEBUG("Saved environment.");

    /* Save the arguments. */
    free(args_copy);
    args_copy = (char**)read_nul_sep("/proc/self/cmdline");
    DEBUG("Saved args.");
    for( int i = 0; args_copy[i] != NULL; i += 1 )
    {
        DEBUG(" arg%d=%s", i, args_copy[i]);
    }

    /* Save the cwd & exe. */
    free(cwd_copy);
    cwd_copy = (char*)read_link("/proc/self/cwd");
    DEBUG("Saved cwd.");
    free(exe_copy);
    exe_copy = (char*)read_link("/proc/self/exe");
    DEBUG("Saved exe.");

    /* Install our signal handlers. */
    impl_install_sighandlers();

    /* Initialize our thread. */
    impl_init_thread();

    /* Unblock our signals.
     * Note that we have specifically masked the
     * signals prior to the exec() below, to cover
     * the race between program start and having
     * installed the appropriate handlers. */
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGHUP);
    sigprocmask(SIG_UNBLOCK, &set, NULL);

    /* Done. */
    DEBUG("Initialization complete.");
}
Exemplo n.º 11
0
void call_do_dup(){

	int a[] = {1, 3, 8, 2, 5, 7, 6, 7, 4};
	printf("\n\n\n----%s:[%d]----\n", __func__, __LINE__);
	do_dup(a, sizeof(a)/sizeof(a[0]));
}