[116751] trunk/base/src/port1.0/portutil.tcl

cal at macports.org cal at macports.org
Wed Feb 5 14:39:52 PST 2014


Revision: 116751
          https://trac.macports.org/changeset/116751
Author:   cal at macports.org
Date:     2014-02-05 14:39:52 -0800 (Wed, 05 Feb 2014)
Log Message:
-----------
portutil.tcl: make add{user,group} more robust, avoid stderr output causing failures, closes #42347

Modified Paths:
--------------
    trunk/base/src/port1.0/portutil.tcl

Modified: trunk/base/src/port1.0/portutil.tcl
===================================================================
--- trunk/base/src/port1.0/portutil.tcl	2014-02-05 22:35:42 UTC (rev 116750)
+++ trunk/base/src/port1.0/portutil.tcl	2014-02-05 22:39:52 UTC (rev 116751)
@@ -2363,22 +2363,74 @@
 
     if {${os.platform} eq "darwin"} {
         set dscl [findBinary dscl $portutil::autoconf::dscl_path]
-        exec $dscl . -create /Users/${name} UniqueID ${uid}
+        set failed? 0
+        try {
+            exec $dscl . -create /Users/${name} UniqueID ${uid} 2>@stderr
 
-        # These are implicitly added on Mac OSX Lion.  AuthenticationAuthority
-        # causes the user to be visible in the Users & Groups Preference Pane,
-        # and the others are just noise, so delete them.
-        # https://trac.macports.org/ticket/30168
-        exec $dscl . -delete /Users/${name} AuthenticationAuthority
-        exec $dscl . -delete /Users/${name} PasswordPolicyOptions
-        exec $dscl . -delete /Users/${name} dsAttrTypeNative:KerberosKeys
-        exec $dscl . -delete /Users/${name} dsAttrTypeNative:ShadowHashData
+            # These are implicitly added on Mac OSX Lion.  AuthenticationAuthority
+            # causes the user to be visible in the Users & Groups Preference Pane,
+            # and the others are just noise, so delete them.
+            # https://trac.macports.org/ticket/30168
+            exec $dscl . -delete /Users/${name} AuthenticationAuthority 2>@stderr
+            exec $dscl . -delete /Users/${name} PasswordPolicyOptions 2>@stderr
+            exec $dscl . -delete /Users/${name} dsAttrTypeNative:KerberosKeys 2>@stderr
+            exec $dscl . -delete /Users/${name} dsAttrTypeNative:ShadowHashData 2>@stderr
 
-        exec $dscl . -create /Users/${name} RealName ${realname}
-        exec $dscl . -create /Users/${name} Password ${passwd}
-        exec $dscl . -create /Users/${name} PrimaryGroupID ${gid}
-        exec $dscl . -create /Users/${name} NFSHomeDirectory ${home}
-        exec $dscl . -create /Users/${name} UserShell ${shell}
+            exec $dscl . -create /Users/${name} RealName ${realname} 2>@stderr
+            exec $dscl . -create /Users/${name} Password ${passwd} 2>@stderr
+            exec $dscl . -create /Users/${name} PrimaryGroupID ${gid} 2>@stderr
+            exec $dscl . -create /Users/${name} NFSHomeDirectory ${home} 2>@stderr
+            exec $dscl . -create /Users/${name} UserShell ${shell} 2>@stderr
+        } catch {{CHILDKILLED *} eCode eMessage} {
+            # the foreachs are a simple workaround for Tcl 8.4, which doesn't
+            # seem to have lassign
+            foreach {- pid sigName msg} $eCode {
+                ui_error "dscl($pid) was killed by $sigName: $msg"
+                ui_debug "dscl printed: $eMessage"
+            }
+
+            set failed? 1
+        } catch {{CHILDSTATUS *} eCode eMessage} {
+            foreach {- pid code} $eCode {
+                ui_error "dscl($pid) termined with an exit status of $code"
+                ui_debug "dscl printed: $eMessage"
+            }
+            
+            set failed? 1
+        } catch {{POSIX *} eCode eMessage} {
+            foreach {- errName msg} {
+                ui_error "failed to execute $dscl: $errName: $msg"
+                ui_debug "dscl printed: $eMessage"
+            }
+
+            set failed? 1
+        } finally {
+            if {${failed?}} {
+                # creating the user properly failed and we're bailing out
+                # anyway, try to delete the half-created user to revert to the
+                # state before the error
+                ui_debug "Attempting to clean up failed creation of user $name"
+                try {
+                    exec $dscl . -delete /Users/${name} 2>@stderr
+                } catch {{CHILDKILLED *} eCode eMessage} {
+                    foreach {- pid sigName msg} {
+                        ui_warn "dscl($pid) was killed by $sigName: $msg while trying to clean up failed creation of user $name."
+                        ui_debug "dscl printed: $eMessage"
+                    }
+                } catch {{CHILDSTATUS *} eCode eMessage} {
+                    # ignoring childstatus failure, because that probably means
+                    # the first call failed and the user wasn't even created
+                } catch {{POSIX *} eCode eMessage} {
+                    foreach {- errName msg} {
+                        ui_warn "failed to execute $dscl: $errName: $msg while trying to clean up failed creation of user $name."
+                        ui_debug "dscl printed: $eMessage"
+                    }
+                }
+
+                # and raise an error to abort
+                error "dscl failed to create required user $name."
+            }
+        }
     } else {
         # XXX adduser is only available for darwin, add more support here
         ui_warn "adduser is not implemented on ${os.platform}."
@@ -2419,11 +2471,63 @@
 
     if {${os.platform} eq "darwin"} {
         set dscl [findBinary dscl $portutil::autoconf::dscl_path]
-        exec $dscl . -create /Groups/${name} Password ${passwd}
-        exec $dscl . -create /Groups/${name} RealName ${realname}
-        exec $dscl . -create /Groups/${name} PrimaryGroupID ${gid}
-        if {${users} ne ""} {
-            exec $dscl . -create /Groups/${name} GroupMembership ${users}
+        set failed? 0
+        try {
+            exec $dscl . -create /Groups/${name} Password ${passwd}
+            exec $dscl . -create /Groups/${name} RealName ${realname}
+            exec $dscl . -create /Groups/${name} PrimaryGroupID ${gid}
+            if {${users} ne ""} {
+                exec $dscl . -create /Groups/${name} GroupMembership ${users}
+            }
+        } catch {{CHILDKILLED *} eCode eMessage} {
+            # the foreachs are a simple workaround for Tcl 8.4, which doesn't
+            # seem to have lassign
+            foreach {- pid sigName msg} $eCode {
+                ui_error "dscl($pid) was killed by $sigName: $msg"
+                ui_debug "dscl printed: $eMessage"
+            }
+
+            set failed? 1
+        } catch {{CHILDSTATUS *} eCode eMessage} {
+            foreach {- pid code} $eCode {
+                ui_error "dscl($pid) termined with an exit status of $code"
+                ui_debug "dscl printed: $eMessage"
+            }
+            
+            set failed? 1
+        } catch {{POSIX *} eCode eMessage} {
+            foreach {- errName msg} {
+                ui_error "failed to execute $dscl: $errName: $msg"
+                ui_debug "dscl printed: $eMessage"
+            }
+
+            set failed? 1
+        } finally {
+            if {${failed?}} {
+                # creating the user properly failed and we're bailing out
+                # anyway, try to delete the half-created user to revert to the
+                # state before the error
+                ui_debug "Attempting to clean up failed creation of group $name"
+                try {
+                    exec $dscl . -delete /Groups/${name} 2>@stderr
+                } catch {{CHILDKILLED *} eCode eMessage} {
+                    foreach {- pid sigName msg} {
+                        ui_warn "dscl($pid) was killed by $sigName: $msg while trying to clean up failed creation of group $name."
+                        ui_debug "dscl printed: $eMessage"
+                    }
+                } catch {{CHILDSTATUS *} eCode eMessage} {
+                    # ignoring childstatus failure, because that probably means
+                    # the first call failed and the user wasn't even created
+                } catch {{POSIX *} eCode eMessage} {
+                    foreach {- errName msg} {
+                        ui_warn "failed to execute $dscl: $errName: $msg while trying to clean up failed creation of group $name."
+                        ui_debug "dscl printed: $eMessage"
+                    }
+                }
+
+                # and raise an error to abort
+                error "dscl failed to create required group $name."
+            }
         }
     } else {
         # XXX addgroup is only available for darwin, add more support here
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20140205/3e0c4f51/attachment-0001.html>


More information about the macports-changes mailing list