[cvsnt] Exec failed: No such file or directory

Greg Lee glee-list at swspec.com
Wed Mar 22 15:55:04 GMT 2006

Community technical support mailing list was retired 2010 and replaced with a professional technical support team. For assistance please contact: Pre-sales Technical support via email to sales@march-hare.com.

> Please remember to provide both client and server platform information
> when reporting a problem.  I assume the client is Linux, based on
> various clues below.  I'll assume the server is also Linux, 
> for the sake of discussion.

You are correct, Linux is at both the client (kernel version 2.6.12) and server (kernel
version 2.4.21) ends.

> > I am having a problem when I commit changes to any file.  The 
> > client always returns a
> > message saying "Exec failed: No such file or directory" like this:
> >  
> > [glee at dev1 rcats-linux]$ cvs commit -m "testing"
> > glee at's password:
> > Checking in VersionHistory.txt;
> > /home/cvsroot/linux/VersionHistory.txt,v  <--  VersionHistory.txt
> > new revision: 1.28; previous revision: 1.27
> > done
> > Exec failed: No such file or directory
> > 
> > 
> > If I turn on tracing I see that cvsnt is trying to delete 
> > "CVS/Entries.Log", but it must not exist.
> I don't think so.  Unless something's been broken in the 2.5  stream, you
> should only get that message if an *exec* failed.  The "file or
> directory" that doesn't exist is a file that CVSNT is trying 
> to execute,
> or a directory in the path to that file, if CVSNT passed a pathname to
> one of the exec functions.  (In 2.0, CVSNT only ever passes a plain
> filename to exec.)
> > [glee at dev1 rcats-linux]$ cvs -t -t -t -t commit -m "testing"
> >  -> main loop with CVSROOT=glee at
> > <mailto:CVSROOT=glee at> 
> >  -> rename(CVS/Entries.Backup,CVS/Entries)
> >  -> unlink_file(CVS/Entries.Log)
> >  -> Starting server: /usr/bin/ssh -l glee cvs server
> > glee at's <mailto:glee at's>  password:
> >  -> Sending file `VersionHistory.txt' to server
> > Checking in VersionHistory.txt;
> > /home/cvsroot/linux/VersionHistory.txt,v  <--  VersionHistory.txt
> > new revision: 1.27; previous revision: 1.26
> > done
> >  -> unlink_file(CVS/Base/VersionHistory.txt)
> >  -> Register(VersionHistory.txt, 1.27, Wed Mar 22 01:21:41 
> > 2006, -kkv,  )
> >  -> rename(CVS/Entries.Backup,CVS/Entries)
> >  -> unlink_file(CVS/Entries.Log)
> > Exec failed: No such file or directory
> This just means that unlink_file was the last function to write a trace
> entry before the "Exec failed" message was written.  That doesn't tell
> you what might have happened between unlink_file's trace call and when
> the "Exec failed" was written.
> And in the case of this particular message, we actually don't even know
> when the message was generated relative to anything in the trace,
> because this message is generated by the child side of a fork.  (In 2.0,
> this happens in CRunFile::run in RunFile.cpp; I don't know if that's
> changed in 2.5.)  So there's a race here: the parent process does some
> stuff and forks at some point, and then the child process runs
> asynchronously, eventually tries to exec, calls perror, and exits.
> The child initially inherits stderr from the parent.  It appears that
> CVSNT generally (always?) redirects the child's I/O to a pipe and reads
> it in the parent.  In any case, eventually that message makes it to the
> parent, and then to you.  But there's no way to know when, after the
> fork, the child gets to run to the point where it generates that
> message, or when it gets to you from the child.
> (Oh, and the child uses exit() where it should use _exit(), BTW.  And it
> passes -1 to exit.  Both bad ideas.  Tony, should someone raise a bug
> for this?)
> >  -> Lock_Cleanup()
> > 
> > 
> > Does anyone know how to resolve this problem?
> Well, the thing to do is to figure out what CVSNT is trying to exec.
> diff, maybe (I don't know offhand when CVSNT uses the external diff).
> The mailer, if you have that configured.  Maybe other things.
> Offhand it appears that you should be getting more verbose logging of
> what CVSNT is trying to run; I'm not sure why you aren't, but it's late
> and I haven't looked at that part of the source.  In fact, with -tttt I
> get a *lot* more trace output from "cvs commit" than what you 
> show - did you remove part of the trace output?
> -- 
> Michael Wojcik
> Principal Software Systems Developer, Micro Focus

No, I did not remove part of the output.  I did use the form "-t -t -t -t" instead of
"-tttt", but I just tried "-tttt" and it returned the same results.

I determined that the error is coming from the server side so I added some code on the
server side to see what is being executed:

[glee at dev1 zzz]$ cvs -tttt commit -m "testing"
 -> main loop with CVSROOT=glee at
 -> Starting server: /usr/bin/ssh -l glee cvs server
glee at's password:
 -> Sending file `z.c' to server
Checking in z.c;
/home/cvsroot/zzz/z.c,v  <--  z.c
new revision: 1.17; previous revision: 1.16
 -> unlink_file(CVS/Base/z.c)
 -> Register(z.c, 1.17, Wed Mar 22 15:35:14 2006, ,  )
 -> rename(CVS/Entries.Backup,CVS/Entries)
 -> unlink_file(CVS/Entries.Log)
Exec failed ("(echo ; id; echo zzz z.c,1.16,1.17; date; cat) >>
/home/cvsroot/CVSROOT/commitlog "): No such file or directory
 -> Lock_Cleanup()
[glee at dev1 zzz]$ 

This is what I did to get this information:

--- cvsnt-   2006-03-22 10:34:54.000000000 -0500
+++ cvsnt-      2006-01-11 13:00:35.000000000
@@ -184,18 +184,8 @@

                char **myargv = (char**)m_args->toArgv();
                execvp (myargv[0], myargv);
-       char buf[2000] = "Exec failed (\"";
-       int i;
-       for(i=0; myargv[i] != NULL && i < 20; i++)
-       {
-               strcat(buf, myargv[i]);
-               strcat(buf, " ");
-       }
-       strcat(buf, "\")");
-               perror(buf);
+               perror("Exec failed");


So it looks like something in "(echo ; id; echo zzz z.c,1.16,1.17; date; cat)" is not
executing.  In fact, isn't execvp trying to execute the first argument in the list, i.e.
"(echo"?  "(echo" is not valid, the "(" is wrong.  "echo" is valid assuming it is in the
path.  Maybe the intent was to pass this string to a shell (sh, bash, etc)?

Greg Lee

More information about the cvsnt mailing list
Download the latest CVSNT, TortosieCVS, WinCVS etc. for Windows 8 etc.
@CVSNT on Twitter   CVSNT on Facebook