+// find all offsets for currently open files and save them
+void
+Process::fix_file_offsets()
+{
+ Process::FdMap *fdo_stdin = &fd_map[STDIN_FILENO];
+ Process::FdMap *fdo_stdout = &fd_map[STDOUT_FILENO];
+ Process::FdMap *fdo_stderr = &fd_map[STDERR_FILENO];
+ string in = fdo_stdin->filename;
+ string out = fdo_stdout->filename;
+ string err = fdo_stderr->filename;
+
+ // initialize file descriptors to default: same as simulator
+ int stdin_fd, stdout_fd, stderr_fd;
+
+ if (in == "stdin" || in == "cin")
+ stdin_fd = STDIN_FILENO;
+ else if (in == "None")
+ stdin_fd = -1;
+ else {
+ // open standard in and seek to the right location
+ stdin_fd = Process::openInputFile(in);
+ if (lseek(stdin_fd, fdo_stdin->fileOffset, SEEK_SET) < 0)
+ panic("Unable to seek to correct location in file: %s", in);
+ }
+
+ if (out == "stdout" || out == "cout")
+ stdout_fd = STDOUT_FILENO;
+ else if (out == "stderr" || out == "cerr")
+ stdout_fd = STDERR_FILENO;
+ else if (out == "None")
+ stdout_fd = -1;
+ else {
+ stdout_fd = Process::openOutputFile(out);
+ if (lseek(stdout_fd, fdo_stdout->fileOffset, SEEK_SET) < 0)
+ panic("Unable to seek to correct location in file: %s", out);
+ }
+
+ if (err == "stdout" || err == "cout")
+ stderr_fd = STDOUT_FILENO;
+ else if (err == "stderr" || err == "cerr")
+ stderr_fd = STDERR_FILENO;
+ else if (err == "None")
+ stderr_fd = -1;
+ else if (err == out)
+ stderr_fd = stdout_fd;
+ else {
+ stderr_fd = Process::openOutputFile(err);
+ if (lseek(stderr_fd, fdo_stderr->fileOffset, SEEK_SET) < 0)
+ panic("Unable to seek to correct location in file: %s", err);
+ }
+
+ fdo_stdin->fd = stdin_fd;
+ fdo_stdout->fd = stdout_fd;
+ fdo_stderr->fd = stderr_fd;
+
+
+ for (int free_fd = 3; free_fd <= MAX_FD; ++free_fd) {
+ Process::FdMap *fdo = &fd_map[free_fd];
+ if (fdo->fd != -1) {
+ if (fdo->isPipe){
+ if (fdo->filename == "PIPE-WRITE")
+ continue;
+ else {
+ assert (fdo->filename == "PIPE-READ");
+ //create a new pipe
+ int fds[2];
+ int pipe_retval = pipe(fds);
+
+ if (pipe_retval < 0) {
+ // error
+ panic("Unable to create new pipe.");
+ }
+ fdo->fd = fds[0]; //set read pipe
+ Process::FdMap *fdo_write = &fd_map[fdo->readPipeSource];
+ if (fdo_write->filename != "PIPE-WRITE")
+ panic ("Couldn't find write end of the pipe");
+
+ fdo_write->fd = fds[1];//set write pipe
+ }
+ } else {
+ //Open file
+ int fd = open(fdo->filename.c_str(), fdo->flags, fdo->mode);
+
+ if (fd == -1)
+ panic("Unable to open file: %s", fdo->filename);
+ fdo->fd = fd;
+
+ //Seek to correct location before checkpoint
+ if (lseek(fd,fdo->fileOffset, SEEK_SET) < 0)
+ panic("Unable to seek to correct location in file: %s",
+ fdo->filename);
+ }
+ }
+ }
+}
+
+void
+Process::find_file_offsets()
+{
+ for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) {
+ Process::FdMap *fdo = &fd_map[free_fd];
+ if (fdo->fd != -1) {
+ fdo->fileOffset = lseek(fdo->fd, 0, SEEK_CUR);
+ } else {
+ fdo->filename = "NULL";
+ fdo->fileOffset = 0;
+ }
+ }
+}
+
+void
+Process::setReadPipeSource(int read_pipe_fd, int source_fd)
+{
+ Process::FdMap *fdo = &fd_map[read_pipe_fd];
+ fdo->readPipeSource = source_fd;
+}
+
+void
+Process::FdMap::serialize(std::ostream &os)
+{
+ SERIALIZE_SCALAR(fd);
+ SERIALIZE_SCALAR(isPipe);
+ SERIALIZE_SCALAR(filename);
+ SERIALIZE_SCALAR(flags);
+ SERIALIZE_SCALAR(readPipeSource);
+ SERIALIZE_SCALAR(fileOffset);
+}
+
+void
+Process::FdMap::unserialize(Checkpoint *cp, const std::string §ion)
+{
+ UNSERIALIZE_SCALAR(fd);
+ UNSERIALIZE_SCALAR(isPipe);
+ UNSERIALIZE_SCALAR(filename);
+ UNSERIALIZE_SCALAR(flags);
+ UNSERIALIZE_SCALAR(readPipeSource);
+ UNSERIALIZE_SCALAR(fileOffset);
+}
+