/** Make sure the fd used by this redirection is not used by i.e. a pipe. */ void free_fd( io_data_t *io, int fd ) { if( !io ) return; if( ( io->io_mode == IO_PIPE ) || ( io->io_mode == IO_BUFFER ) ) { int i; for( i=0; i<2; i++ ) { if(io->param1.pipe_fd[i] == fd ) { while(1) { if( (io->param1.pipe_fd[i] = dup(fd)) == -1) { if( errno != EINTR ) { debug( 1, FD_ERROR, fd ); wperror( L"dup" ); FATAL_EXIT(); } } else { break; } } } } } free_fd( io->next, fd ); }
int win32_spawn(int job_id, const char *cmd_line, const char **env, int env_count, const char *annotation, const char* echo_cmdline) { int result_code = 1; char buffer[8192]; char env_block[128*1024]; HANDLE output_handle; STARTUPINFO sinfo; PROCESS_INFORMATION pinfo; if (0 != make_env_block(env_block, sizeof(env_block) - 2, env, env_count)) { fprintf(stderr, "%d: env block error; too big?\n", job_id); return 1; } _snprintf(buffer, sizeof(buffer), "cmd.exe /c \"%s\"", cmd_line); output_handle = alloc_fd(job_id); memset(&pinfo, 0, sizeof(pinfo)); memset(&sinfo, 0, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); sinfo.hStdInput = NULL; sinfo.hStdOutput = sinfo.hStdError = output_handle; sinfo.dwFlags = STARTF_USESTDHANDLES; if (annotation) println_to_handle(output_handle, annotation); if (echo_cmdline) println_to_handle(output_handle, echo_cmdline); if (CreateProcess(NULL, buffer, NULL, NULL, TRUE, 0, env_block, NULL, &sinfo, &pinfo)) { DWORD result; CloseHandle(pinfo.hThread); while (WAIT_OBJECT_0 != WaitForSingleObject(pinfo.hProcess, INFINITE)) /* nop */; GetExitCodeProcess(pinfo.hProcess, &result); CloseHandle(pinfo.hProcess); result_code = (int) result; } else { fprintf(stderr, "%d: Couldn't launch process; Win32 error = %d\n", job_id, (int) GetLastError()); } free_fd(job_id, output_handle); return result_code; }
static int do_close(MESSAGE *message){ PROCESS *process=pid2process(message->source_pid); int fd=message->fd; if(process->file_descriptor[fd]!=NULL && process->file_descriptor[fd]->fd_inode!=NULL && process->file_descriptor[fd]->fd_inode->i_share_count>0 ){ free_inode(process->file_descriptor[fd]->fd_inode); free_fd(process->file_descriptor[fd]); process->file_descriptor[fd]=NULL; return 0; } else{ set_error_index(FILE_NOT_OPEN); return -1; } }
/** Set up a childs io redirections. Should only be called by setup_child_process(). Does the following: First it closes any open file descriptors not related to the child by calling close_unused_internal_pipes() and closing the universal variable server file descriptor. It then goes on to perform all the redirections described by \c io. \param io the list of IO redirections for the child \return 0 on sucess, -1 on failiure */ static int handle_child_io( io_data_t *io ) { close_unused_internal_pipes( io ); for( ; io; io=io->next ) { int tmp; if( io->io_mode == IO_FD && io->fd == io->param1.old_fd ) { continue; } if( io->fd > 2 ) { /* Make sure the fd used by this redirection is not used by e.g. a pipe. */ free_fd( io, io->fd ); } switch( io->io_mode ) { case IO_CLOSE: { if( close(io->fd) ) { debug( 0, _(L"Failed to close file descriptor %d"), io->fd ); wperror( L"close" ); } break; } case IO_FILE: { if( (tmp=wopen( io->param1.filename, io->param2.flags, OPEN_MASK ) )==-1 ) { if( ( io->param2.flags & O_EXCL ) && ( errno ==EEXIST ) ) { debug( 1, NOCLOB_ERROR, io->param1.filename ); } else { debug( 1, FILE_ERROR, io->param1.filename ); wperror( L"open" ); } return -1; } else if( tmp != io->fd) { /* This call will sometimes fail, but that is ok, this is just a precausion. */ close(io->fd); if(dup2( tmp, io->fd ) == -1 ) { debug( 1, FD_ERROR, io->fd ); wperror( L"dup2" ); return -1; } exec_close( tmp ); } break; } case IO_FD: { /* This call will sometimes fail, but that is ok, this is just a precausion. */ close(io->fd); if( dup2( io->param1.old_fd, io->fd ) == -1 ) { debug( 1, FD_ERROR, io->fd ); wperror( L"dup2" ); return -1; } break; } case IO_BUFFER: case IO_PIPE: { int write_pipe; write_pipe = !io->is_input; /* debug( 0, L"%ls %ls on fd %d (%d %d)", write_pipe?L"write":L"read", (io->io_mode == IO_BUFFER)?L"buffer":L"pipe", io->fd, io->param1.pipe_fd[0], io->param1.pipe_fd[1]); */ if( dup2( io->param1.pipe_fd[write_pipe], io->fd ) != io->fd ) { debug( 1, PIPE_ERROR ); wperror( L"dup2" ); return -1; } if( write_pipe ) { exec_close( io->param1.pipe_fd[0]); exec_close( io->param1.pipe_fd[1]); } else { exec_close( io->param1.pipe_fd[0] ); } break; } } } return 0; }
extern "C" int fs_open(FILE * fp, struct file_system * F, const char *filename, const char *mode) { //create file_descriptor and return to caller int i; struct file_descriptor *fd; struct directory dir; int r; int flag; int fd_num; int inode_num; int tmp; flag = 0; //read in current directory fseek(fp, F->inode_list[F->cur_idx].direct[0], SEEK_SET); fread(&dir, 1, sizeof(struct directory), fp); rewind(fp); //find first free file descriptor fd_num=get_fd(F); if(fd_num==-1) return -1; //go through files in directory and find file called filename for(i=0;i<MAX_SIZE_DIRECTORY;i++) { r=strcmp(filename,dir.files[i]); if(0==r) { //if found check to see if it is a regular file if( F->inode_list[dir.inodes[i]].file_type==0) { //use file descriptor found above to store information about found file F->fd[fd_num].in_use=1; F->fd[fd_num].in_offset=0; F->fd[fd_num].i= &(F->inode_list[dir.inodes[i]]); F->fd[fd_num].out_offset = F->inode_list[dir.inodes[i]].direct[0]; //set what mode file descriptor is in if(mode[0]=='r') { F->fd[fd_num].type=0; } else if(mode[0]=='w') { F->fd[fd_num].type=1; } } else { //file is directory so free file descriptor and return free_fd(F,fd_num); return -1; } flag=1; } } //if file not found than create a new file and use file descriptor from above if(flag==0) { if(mode[0]=='w') { F->fd[fd_num].in_use=1; F->fd[fd_num].type=1; F->fd[fd_num].in_offset=0; inode_num = get_inode(F); F->inode_list[inode_num].in_use=1; F->inode_list[inode_num].file_type=0; tmp=find_first_free_page(F); F->inode_list[inode_num].direct[0] = tmp; F->inode_list[inode_num].size=0; for(i=0;i<MAX_SIZE_DIRECTORY;i++) { if('\0'==dir.files[i][0]) { strcpy(dir.files[i],filename); dir.inodes[i]=inode_num; break; } } F->fd[fd_num].out_offset=F->inode_list[inode_num].direct[0]; F->fd[fd_num].i = &F->inode_list[inode_num]; //write current inode and directory back to disk fseek(fp, F->inode_list[F->cur_idx].direct[0], SEEK_SET); fwrite(&dir, sizeof(struct directory), 1, fp); rewind(fp); //change current working directory to dirname int ix; struct directory dirx; fseek(fp, F->inode_list[F->cur_idx].direct[0], SEEK_SET); fread(&dirx, 1, sizeof(struct directory), fp); rewind(fp); for(ix=0;ix<MAX_SIZE_DIRECTORY;ix++) { if(dirx.files[ix][0] != '\0') { printf("%s %d\n",dir.files[ix],dirx.inodes[ix]); } } } else { free_fd(F,fd_num); fd_num = -1; } } return fd_num; //use inode to get location of "file" in file hard drive and save the offset in offset in thefile_descriptor //save the inode that points to the file in the file_descriptor //save the file pointer to make for easier writing and reading }