- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
There's no way this boss has programmed in anything other than QBasic.
I also suspect that the previous developer was just "uncooperative" rather than unskilled.
Admin
15) Same loop to wait for the database to return data is executed for deleting files.
16) "-i" <FONT color=#000000>is added with a separate strcat instead of being included in the original strcpy.</FONT>
<FONT color=#000000>17) Same three lines of code in Case 1 and Case 2. Failure to exploit leaving a break; out in this rare case when it actually would've helped.</FONT>
It's a classic Tufte WTF: the more you look at it, the more WTF it becomes.
--RA
Admin
Yeah, specially since he could sleep(n) to lock the process for n seconds at zero percent of CPU. Talk about efficency. And it's not compiler dependant!
What? Oh, yeah, he could have, of course, written the function so that it would need no delay whatsover...
What? He didn't need ANY delay AT ALL in the first place? Hummmm, not very experienced in maintaining low-end computers with low reliability SOs, right? (any cheap PC with a random Linux distribution will do) The operative system may be taking a few milliseconds to close the file, so this function would return, and another part of the program would attempt to open the file and get an error because the file is open.
As for my experience, restarting certain JSP server software in my web server needs a 5 seconds delay between stopping and starting the program, because Linux will take a pair of seconds at least to close the TCP port, and the JSP server will fail inmediatly instead of waiting until the port is cleared.
This is, of course, a different WTF, and won't be told here............
Admin
Well...
At least he didn't cast the return value of malloc(); that has to count for <i>something</i>...
Admin
Admin
Yeah, I was thinking that myself. The Ex-Programmer might have been the ONLY qualified guy around that place.
Six months from now, the boss will be talking to 'The Next New Guy', saying "You know, the last guy we had in here was a real ass-hat. But we're moving forward now..."
Admin
Quite. I can see how it could happen. I have sometimes pointed out bad consequences of an action, and my statement has not been popular. That does not stop the consequences from happening though.
"Look out for that train!" "Quit being so negative." SPLAT!
Sincerely,
Gene Wirchenko
Admin
WTF?? Linux does not keep open file handles around once you close them, and even if you forgot to close them opening the same files gives no error (unless you explicitly locked the file).
WTF again! No OS takes "a pair of seconds" just to close a TCP port.
Admin
I'm not sure what's worse, that code or that spelling of "rediculous".
Admin
Indeed, infinitely incrementing loops will delay execution quite well. Some might say a little too well.
Admin
twichs
God, its like some fratcal WTF. The more you look at it, the more WTFs become visable. Geez, I've got to look away before my brain goes splat! (although this WTF reminds me of the SQL Driver one from a few months back).
Admin
Losing 1K of memory every time you execute an SQL statement is nothing to call a "minor wtf"...
Also, i'm going to bet on hardcoded file names, so buffer overflows and quoting file names I don't think should be on the WTF list. In addition, since this is Windows code (or DOS?) and old, since its in C, I'd point out that the 'n' functions like strncat might not have been available, and that there may not have been any other way to execute queries other than the cmdline client. It may be possible that writing to files was the ONLY way to get this done.
Also, if it were DOS, then there is no possible way that a delay would be needed, since DOS was singlethreaded. So it was probably Win95 or Win3.1
Admin
You don't know if the rest of the code will open the file in read-write mode (as opposed to readonly mode), either for making changes to it or because of sheer dumbness. And then you'll get an error.
And, of course, the original WTF uses windows, since it's using the DEL command :)
Then, there are also those nice race-conditions (see below).
Well, my Redhat 9 box does. It "normally" takes much less than a second, so I initially set the delay to 2 seconds, just to be on the safe side. But once in a while it would take more than 2 seconds and I would find in the morning that the JSP server couldn't start because the port was binded to a different process (the older process).
I also thought about simply starting again and again until the port was opened but that had its own problems, namely race conditions between the two processes. They are mostly solved on version 3, but version 2 did this all the time.
Preliminary explanation: the JSP server uses a .pid file to see if other instances of it have been already started.
There are other non linux-specific errors. When I kill -9 the JSP server instead of using the perl script and it will refuse to start because the old .pid file is still there. Or when it failed to start but didn't delete the .pìd file. Fortunately, they seem to have solved most of these nuisances in newer versions.....
Admin
One note: this is probably worsened by the perl script probably throwing a signal to the process, then returning inmediately. This means that if I launch a new process as soon as the close script returns, the process may be still attempting to clear all reasources, closing files, and, of course, unbinding itself from TCP ports.
Even if the perl script waited until the process had finished, it is conceivable that returning from a perl script and automatically launching a new perl script may take less time than the OS clearing all resources from the process (or the perl script having been lucky in the CPU execution queue), and that the OS has not had enough physical time to unbind the TCP port in time for the second process because it was clearing other things first.
Final note: an OS may say that it has closed a process and cleared the resources, but behind the scenes it is still clearing resources. Think of this as a hard disk reporting that a file has been written, when it is actually still sitting in the disk cache. All this in the name of performance, of course.
Sooooo, to this, you add different combos of OS (windows NT,2000,2003,XP,SP1,SP2,SP3,Debian,Redhat 8,9, Fedora 1,2,3,4,5-test3, Linux Enterprise server), all the combinations of hard disk/motherboard/network card, and the use of different kernel versions (Redhat 9):
And a Fedora Core 2 server, where I also had some trouble with JSP server, is not better. I have used ALL of these along one year, one after the other:
Guess what, some of those versions will refuse to boot my server for no apparent reason. How many of those have TCP port closing bugs wihout me knowing?
Now, finally, compare this with a SUN server with Solaris, or some other enterprise level hardware-software combo, and check uptimes, reliability, etc. Of course, they also have race conditions and such, but they are free of some of the odities of "normal" OS.
Admin
I bet the boss claimed to have written that code because he was sick of some noob programmer whinging about the last guy.
Admin
....unless you make 'x' and 'z' volatile [:D]
Admin
ActionFlag! He's our hero!
ActionFlag!
Admin
Apparently, this guy is a 'boss' in the video game sense; i.e., some evil badass you have to overcome to reach your goal.
Admin
Good one. I guess the secret to beating him is to attack during the delay loop.
Admin
Most likely, they just hope it is, as they don't know any better. realloc(), anyone?
Admin
God. If I happen to read one more post containing the word goggles, or brillant, or brillance even, or first post,
im going to KILL MYSELF.
Die! you irritating F**KS[6]
I need coffee.
Admin
Bwahaha! A lot of guys say just that when crossing a railroad in their car. Guess their brain stops working once they start the engine...
Admin
Sorry for being not to specific on the terms, but.. after closing a socket, it will remain in (i don't remember what) state, and can not be reused again for a few seconds (os dependent), except with the SO_REUSEADDR socket option. Caused me a lot of trouble, when testing java server application, restarting it and it just could not bind to the same port. Fortunatelly we have solution, and we have the reason (i can not remember what is it, it was long time ago, getting old :))
Admin
Good compiler would probably optimize the empty loops away anyway.
Admin
It was probably because the compiler was smarter than the programmer and skipped over the 'dead' loops in a futile attempt to get the programmer to lookup the sleep() function.
Admin
I have looked at "man netstat", and the state is probably TIME_WAIT: "The socket is waiting after close to handle packets still in the network."
Other alternatives: CLOSE_WAIT "The remote end has shut down, waiting for the socket to close." CLOSING "Both sockets are shut down but we still don’t have all our data sent."
I guess that I was closing the server while it was handling some or other connection (translation: someone was downloading a page from the JSP server), and that's why it wouldn't close inmediately. In an inactive server (no visits at that time of the day) it closes inmediately. Of course I'm not going to test this in the production server that happens to have visits constantly. You know, stopping the JSP server mid-visit on purpose just to see in what interesing ways it breaks :)
Admin
In the first programming book I ever had.
Because many 8-bit computers did not have a BASIC command equivalent of sleep(1);, they recommended FOR I = 1 TO 1000: NEXT as a reasonable equivalent.
Obviously, it was a rather damaging programming habit, as many who had done that on 8-bit machines were in for a surprise when they started programming PC stuff on a 386SX-16 and upgraded to a 486DX-33 :)
Admin
Brillant! The goggles did something! And I got first post about it!
Seriously dude, lighten up. I hope the coffee helped..
Admin
I thought filename lengths were limited to 255 characters?
Unless the filenames also include the path, shouldn't 1024 be enough?
Admin
The filenames probably also included the path. And if this is a recent version of Windows, although there is a maximum filename+path limit of sorts, you can still create and access files with paths to the file longer than it (though a lot of software is upset by it, apparently).
Admin
An asshat with brillant pair of goggles 8-| made the first post. Now please, kill yourself
Sincerely,
Irritating Fuck (or Magic Duck, your choise)
Admin
Well, what prevents you from writing a shell/Perl/Python/whatever script that would check the state of the socket first and then perhaps sleep() for a while before launching the JSP server?
Admin
Well, you're absolutely right, it would the best option. But I had a few imponderables ot the time:
If I already knew Perl or Python, I could probably write a script that did such a thing. Currently, with my lowish and fragmented level of bash, I could do at most a call to netstat and do a grep on its output. Basically, when the server is active, I get this on netstat:
So I can do something like this in the restarting script (not checked code, this won't probably work, just to get the idea):
(notice how I have to execute netstat at two different places because bash does not have the do/while construct, so I have to use while/do. Either that, or GOTO. This is probably one of the few cases in programming where using GOTO is justified, which exemplifies how much what of a WTF bash becomes as soon as you attempt to do anything complicated. Using GOTO because of lacking do/while)
Here I execute netstat with a few options to get to see only the TCP ports and get the details. Then I pipe the output to a "grep" command to grep for the port 80 line (yes, I could get false positives, I know, it's just a hack). Then I look at the exit code of the grep command ("0" for having found matching line(s), "1" for not finding any line, "130" for control+c). Basically, this loops until the netstat output doesn't contain teh string ":::80".
Notice that sleep only lets me sleep in increments of one second. If I want to sleep less time, I could also run a loop like in the WTF, since bash will not optimize it :) Running the command continuosly is probably not an option, since it would take almost 100% CPU until killed if something went wrong.
I guess that maybe Perl or Python have some mechanism to interrogate the system about the state of a certain port, like a network library, or maybe, calling a C function :)
I could also hack the perl script that launches the server, altought this has the minor annoyance of having to update the script every time I upgrade the JSP server software, since the script is part of the software and it is distributed together.
Admin
To calculate the length the for loop needed to be in a (quikbasic) dos game ..
Admin
In the 90s, lots of old DOS programms crashed on new PCs because they were too fast... the programs try to calculate the length of the loop in that way, but eventually run into a division-by-zero error.
Admin
So, in this thread you've accused Linux of being a slow and unreliable OS, and sung the praises of Solaris - and only NOW do you admit that the problems you had with Linux were, in fact, not caused by anything to do with Linux, but with the fact that you yourself were too inexperienced to manage it properly.
There's a saying about which workmen are most inclined to blame their tools. How does it go again...
Admin
Ahh yes, the infamous Borland Pascal Runtime Error 200... That was an implementation bug, as Pascal's 'delay' function (equivalent of C's 'sleep') was using exactly this kind of busy spin loop. But I can't think of any other way to do it (DOS timer interrupt had insufficient time resolution). And after all, in a single-threaded environment it wasn't that important to conserve processor's time.
Admin
...and did you, too, discover the funny things that happen that way - specifically, how you actually may end up with fractional seconds? :) I also remember fondly some of my first experiences with sleep() and usleep() (as in "never rely on those to sleep exactly as long as you told them to")...
And guess why the DOS version of Ultima II doesn't work too well on a newish computer, let alone anything faster than a 286. You try to start the thing, it switches to 40-column mode, and you get "Division by Zero". (Not to even mention the fact that the most widespread PC versions these days have eff'd-up data files, but what else can you expect from Electronic Arts...)
Admin
Quite off-topic, but I did LOL at "DNS issues being 'resolved'". Nice touch, Alex :-)
Admin
You are being a bit of a troll on your message.... Anyways... I find that having to know about TCP port states and perl/python only to RESTART A FRIGGIN' JSP SERVER withouth the server failing to restart at seemingly random times is a bit of a wtf.
I'm now more experienced, and I still run into strange behaviours when going out of the already beaten paths. And experience just teached how to *avoid* those pits, not how to *solve* them. There is no current solution right now to my problem except sleeping until the OS frees the port. Either that, or edit the JSP server source code to change the way it opens the TCP port, and recompile...... which I find a teensy bit exaggerated for a minor problem, mind you.
You're right, however, in that two years ago I wouldn't have dared doing that change on source code, and now I would. So you could say it is my fault. But really, this still feels to me like having to modify my car engine by hand. I don't mean repairing/replacing, I mean changing slightly the way a certain motor piece interacts with the rest of the motor. Computers should "just work".
Notice that my university has a SPARC with SunOS, and that it is vastly more reliable than MY linux PC-based server, in spite of the SPARC being like a decade older. Distances are getting reduced with time and new advancements in linux and PCs, but still....
About Linux being slow and unreliable.... Well, Solaris is starting to feel older and older when compared to linux, but it still excels in Sun hardware when compared to Linux PCs: reliability, number of processes, etc.
Admin
Oh, and notice that I had to restart the JSP server at night, because backuping the whole server using either "cp" or "tar" happened to lock both the HTTPD and the JSP server while copying "/var" and maybe "/usr", I never got to learn exactly which ones...... Linux is so nice and reliable for enterprise level........
Admin
It's probably there to ensure the compiler doesn't optimise the loop out.
Admin
If you're talking about a listening port, then this is a normal part of TCP. TCP specifies that a recently closed port must not be reused for some amount of time (it's basically more than the timeout for senders that might still be sending data) to avoid the obvious problem. This state is called CLOSE_WAIT by netstat if you've seen that.
Admin
This was also a reason why for a while computers came with a "Turbo" button. (Really, it was a "slow down" button for such programs, of course).
Admin
Two problems with that notion:
1. This being a DOS or Windows machine (see use of "del" command), the return code from a program (aka ERRORLEVEL) is a number from 0-255. It cannot be negative.
2. Given that the same command is being used for both cases ("del" again), it seems highly unlikely that the command would have error return codes that would span from negative to positive to begin with. Generally speaking, programs tend to stick to one or the other, even in the unix world. This is not an absolute, I grant you, but it's usually the case.
Admin
however if you appended & to the end of either filename, you can run the delete calls as a background process, and then system will return instantly.....
Admin
This one is approaching the holy grail in terms of the WTF/line-of-code ratio: 1! Almost every single line of code is a WTF!
The only WTF I don't see is an SQL injection attack. Of course, it could still contain one if the caller of the function isn't careful with those filenames.
Admin
The real wtf is that you aren't using flock to create the pid file.
Admin
I didn't write that perl script, and flock is C function anyways. However, thanks for tip. I'll take that function into account if I ever need to lock a file.
Admin
I'm surprised more WTF readers aren't aware of this. An empty for loop was a very common method of creating a delay in BASIC. BASIC was still in pretty common usage as of 20 years ago.
The real WTF, which I guess is the very definition of a WTF, is that this aberration is in professional code. Code someone was paid to write.
I wish I could have joined the company for the boss's salary back when I was 14, because that's when I was writing code of this caliber.