# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: /home/qbproger/src/jruby/src/org
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and \n newlines.
# Above lines and this line are ignored by the patching process.
Index: jruby/RubyArgsFile.java
--- jruby/RubyArgsFile.java Base (BASE)
+++ jruby/RubyArgsFile.java Locally Modified (Based On LOCAL)
@@ -16,7 +16,7 @@
  * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
  * Copyright (C) 2007 Ola Bini <ola@ologix.com>
- * Copyright (C) 2008 Joseph LaFata <joe@quibb.org>
+ * Copyright (C) 2008-2009 Joseph LaFata <joe@quibb.org>
  * 
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -32,9 +32,13 @@
  ***** END LICENSE BLOCK *****/
 package org.jruby;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import static org.jruby.RubyEnumerator.enumeratorize;
 
 import org.jruby.anno.JRubyMethod;
+import org.jruby.ext.posix.FileStat;
 import org.jruby.runtime.Block;
 import org.jruby.runtime.ThreadContext;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -78,8 +82,62 @@
             if (filenameBytes.length() == 1 && filenameBytes.get(0) == '-') {
                 currentFile = runtime.getGlobalVariables().get("$stdin");
             } else {
-                currentFile = RubyFile.open(context, runtime.getFile(), 
+                currentFile = (RubyIO)RubyFile.open(context, runtime.getFile(),
                         new IRubyObject[] {filename.strDup(context.getRuntime())}, Block.NULL_BLOCK); 
+
+                if(runtime.getInstanceConfig().getInPlaceBackupExtention() != null) {
+                    FileStat stat1 = null;
+                    boolean windows = System.getProperty("os.name").toUpperCase().contains("WIN");
+
+                    String jfilename = filename.asJavaString();
+                    try {
+                        stat1 = runtime.getPosix().fstat(new FileInputStream(jfilename).getFD());
+                    } catch (IOException ex) {
+                        throw runtime.newIOErrorFromException(ex);
+                    }
+
+                    if(!runtime.getInstanceConfig().getInPlaceBackupExtention().equals("")) {
+
+                        String backup = jfilename + runtime.getInstanceConfig().getInPlaceBackupExtention();
+
+                        if(windows) { // we can't rename a file while it's open
+                            ((RubyIO)currentFile).close();
+                            new File(backup).delete();
+                            new File(jfilename).renameTo(new File(backup));
+                            currentFile = (RubyIO)RubyFile.open(context, runtime.getFile(),
+                                new IRubyObject[] {runtime.newString(backup)}, Block.NULL_BLOCK);
+                        } else {
+                            new File(jfilename).renameTo(new File(backup));
+                        }
+                        
+                    } else {
+
+                        if(windows) { // windows doesn't support inplace editing without a backup
+                            throw runtime.newIOError("Windows doesn't support inplace editing without a backup");
+                        } else {
+                            new File(jfilename).delete();
+                        }
+
+                    }
+
+                    File outputFile = new File(jfilename);
+                    try {
+                        outputFile.createNewFile();
+                    } catch (IOException ex) {
+                        throw runtime.newIOErrorFromException(ex);
+                    }
+
+                    if(!windows) { // chmod chown only on linux.
+                        runtime.getPosix().chmod(jfilename, stat1.mode());
+                        runtime.getPosix().chown(jfilename, stat1.uid(), stat1.gid());
+                    }
+
+                    runtime.getGlobalVariables().set("$stdout",
+                            (RubyIO) RubyFile.open(context, runtime.getFile(),
+                            new IRubyObject[] {filename.strDup(context.getRuntime()), runtime.newString("w")}, Block.NULL_BLOCK));
+
+                }
+
                 minLineNumber = currentLineNumber;
                 currentFile.callMethod(context, "lineno=", context.getRuntime().newFixnum(currentLineNumber));
             }
@@ -283,6 +341,9 @@
         if(data.currentFile == null && !data.nextArgsFile(context)) {
             return recv;
         }
+        if(((RubyIO)data.currentFile).closed_p(context).isFalse()) {
+            ((RubyIO)data.currentFile).close();
+        }
         data.currentFile = null;
         data.currentLineNumber = 0;
         return recv;
@@ -304,7 +365,8 @@
             throw context.getRuntime().newArgumentError("no stream");
         }
         
-        return ((RubyIO)data.currentFile).binmode();
+        ((RubyIO)data.currentFile).binmode();
+        return recv;
     }
 
     @JRubyMethod(name = "lineno")
Index: jruby/RubyInstanceConfig.java
--- jruby/RubyInstanceConfig.java Base (BASE)
+++ jruby/RubyInstanceConfig.java Locally Modified (Based On LOCAL)
@@ -12,6 +12,7 @@
  * rights and limitations under the License.
  *
  * Copyright (C) 2007, 2008 Nick Sieger <nicksieger@gmail.com>
+ * Copyright (C) 2009 Joseph LaFata <joe@quibb.org>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -168,6 +169,7 @@
     private boolean shouldCheckSyntax = false;
     private String inputFieldSeparator = null;
     private boolean managementEnabled = true;
+    private String inPlaceBackupExtension = null;
 
     private int safeLevel = 0;
 
@@ -351,7 +353,7 @@
                 .append("  -d              set debugging flags (set $DEBUG to true)\n")
                 .append("  -e 'command'    one line of script. Several -e's allowed. Omit [programfile]\n")
                 .append("  -Fpattern       split() pattern for autosplit (-a)\n")
-                //.append("  -i[extension]   edit ARGV files in place (make backup if extension supplied)\n")
+                .append("  -i[extension]   edit ARGV files in place (make backup if extension supplied)\n")
                 .append("  -Idirectory     specify $LOAD_PATH directory (may be used more than once)\n")
                 .append("  -J[java option] pass an option on to the JVM (e.g. -J-Xmx512m)\n")
                 .append("                    use --properties to list JRuby properties\n")
@@ -791,9 +793,12 @@
                     shouldPrintUsage = true;
                     shouldRunInterpreter = false;
                     break;
-                // FIXME: -i flag not supported
-//                    case 'i' :
-//                        break;
+                case 'i' :
+                    inPlaceBackupExtension = grabOptionalValue();
+                    if(inPlaceBackupExtension == null) {
+                        inPlaceBackupExtension = "";
+                    }
+                    break FOR;
                 case 'I':
                     String s = grabValue(getArgumentError("-I must be followed by a directory name to add to lib path"));
                     String[] ls = s.split(java.io.File.pathSeparator);
@@ -1208,6 +1213,10 @@
         return classCache;
     }
 
+    public String getInPlaceBackupExtention() {
+        return inPlaceBackupExtension;
+    }
+
     public void setClassCache(ClassCache classCache) {
         this.classCache = classCache;
     }

