david@ukma.UUCP (David Herron) (11/30/84)
Index: /usr/src/bin/dd.c 4.2BSD Problem: I had a bunch of ascii files that I was writing to a tape. A large number of them didn't have a carraige return at the end of the last line. I was writing these with dd(1) fixed length records of something like 128 columns, blocked at probably 10 records per block. Some of these files would hang on the tape drive at the end of file. Very strange. Diagnosis: This took a while. But I found that the last lines of these files were not being padded out. This was causing problems with the tape drive which were creating un-killable processes that were hogging the tape drive. (We still haven't decided if the problem is in the driver or the drive). Fix: See the comments in the diff below. Notes: I am not entirely certain that this is a proper fix as it changes the behavior of dd. With this change, using dd to block lines doesn't gaurantee that the file will be the same if you were to unblock it. If the last line were incomplete then it would be blocked, and when later unblocked would now have a new-line tacked on. I went ahead and did the patch because I decided that blocking/unblocking only makes sense with text files, and it doesn't make sense for text files to have incomplete lines in them. Repeat-by: Do this command: echo -n "This is an incomplete line" | dd of=file conv=block cbs=80 Look at "file" with od -c. You will see just a very short line. Cut out the following and run patch on it. (Beware the signature at the end of the file. Also that line numbers may vary with version and typing conditions.....) ----------------------------------->Cut Here<---------------------------- *** dd.c.orig Thu Nov 29 23:38:35 1984 --- dd.c Thu Nov 29 23:38:48 1984 *************** *** 1,9 static char *sccsid = "@(#)dd.c 4.3 (Berkeley) 4/29/83"; #include <stdio.h> #include <signal.h> #define BIG 2147483647 #define LCASE 01 #define UCASE 02 #define SWAB 04 #define NERR 010 --- 1,29 ----- static char *sccsid = "@(#)dd.c 4.3 (Berkeley) 4/29/83"; #include <stdio.h> #include <signal.h> + /* CHANGES + *--- 12-Jun-84 dsh: Problem: If a text file was ended with + * an incomplete line (the line lacked its' '\n'), then + * dd was not outputting an entire buffer for it, when conv==block. + * Since when you want things to be blocked, it is expected that + * the output file be an even multiple of the file size, this + * is wrong. This also lead to the discovery of an unexpected + * problem in the tape driver where it would not write very short + * blocks onto the tape, but would hang and leave an unkillable + * process lying around. + * Diagnosis: The problem lies in the copying loop in main(). + * EOF is handled fully within the "if (ibc==0 && --nfiles<=0)" + * statement. If a line is waiting to be blocked and readied + * for output, it won't be. All that gets called is flsh() + * which simply outputs the current buffer. + * Fix: If the conversion buffer is non-empty (and also not full), + * call block with '\n' for the argument. This forces the last + * buffer to get blocked. + */ + #define BIG 2147483647 #define LCASE 01 #define UCASE 02 #define SWAB 04 #define NERR 010 *************** *** 317,326 if(ibuf[c] != 0) ibc = c; stats(); } if(ibc == 0 && --files<=0) { flsh(); term(); } if(ibc != ibs) { nipr++; --- 337,351 ----- if(ibuf[c] != 0) ibc = c; stats(); } if(ibc == 0 && --files<=0) { + /* CHANGE 12-Jun-84 dsh: EOF was seen, with an incomplete buffer + * for output. complete it. + */ + if (conv==block && cbc>0 && cbc<cbs) + block('\n'); flsh(); term(); } if(ibc != ibs) { nipr++; ----------------------------------->Cut Here Also<----------------------- David Herron Arpa: "ukma!david"@ANL-MCS unmvax----\ /------- Arpa-Net research >---/----------------/----------- anlams!ukma!david boulder---/ decvax!ucbvax ---/ (or cbosgd!hasmed!qusavx!ukma!david)
david@ukma.uucp (12/09/84)
Problem: I had a bunch of ascii files that I was writing to a tape. A large number of them didn't have a carraige return at the end of the last line. I was writing these with dd(1) fixed length records of something like 128 columns, blocked at probably 10 records per block. Some of these files would hang on the tape drive at the end of file. Very strange. Diagnosis: This took a while. But I found that the last lines of these files were not being padded out. This was causing problems with the tape drive which were creating un-killable processes that were hogging the tape drive. (We still haven't decided if the problem is in the driver or the drive). Fix: See the comments in the diff below. Notes: I am not entirely certain that this is a proper fix as it changes the behavior of dd. With this change, using dd to block lines doesn't gaurantee that the file will be the same if you were to unblock it. If the last line were incomplete then it would be blocked, and when later unblocked would now have a new-line tacked on. I went ahead and did the patch because I decided that blocking/unblocking only makes sense with text files, and it doesn't make sense for text files to have incomplete lines in them. Repeat-by: Do this command: echo -n "This is an incomplete line" | dd of=file conv=block cbs=80 Look at "file" with od -c. You will see just a very short line. Cut out the following and run patch on it. (Beware the signature at the end of the file. Also that line numbers may vary with version and typing conditions.....) ----------------------------------->Cut Here<---------------------------- *** dd.c.orig Thu Nov 29 23:38:35 1984 --- dd.c Thu Nov 29 23:38:48 1984 *************** *** 1,9 static char *sccsid = "@(#)dd.c 4.3 (Berkeley) 4/29/83"; #include <stdio.h> #include <signal.h> #define BIG 2147483647 #define LCASE 01 #define UCASE 02 #define SWAB 04 #define NERR 010 --- 1,29 ----- static char *sccsid = "@(#)dd.c 4.3 (Berkeley) 4/29/83"; #include <stdio.h> #include <signal.h> + /* CHANGES + *--- 12-Jun-84 dsh: Problem: If a text file was ended with + * an incomplete line (the line lacked its' '\n'), then + * dd was not outputting an entire buffer for it, when conv==block. + * Since when you want things to be blocked, it is expected that + * the output file be an even multiple of the file size, this + * is wrong. This also lead to the discovery of an unexpected + * problem in the tape driver where it would not write very short + * blocks onto the tape, but would hang and leave an unkillable + * process lying around. + * Diagnosis: The problem lies in the copying loop in main(). + * EOF is handled fully within the "if (ibc==0 && --nfiles<=0)" + * statement. If a line is waiting to be blocked and readied + * for output, it won't be. All that gets called is flsh() + * which simply outputs the current buffer. + * Fix: If the conversion buffer is non-empty (and also not full), + * call block with '\n' for the argument. This forces the last + * buffer to get blocked. + */ + #define BIG 2147483647 #define LCASE 01 #define UCASE 02 #define SWAB 04 #define NERR 010 *************** *** 317,326 if(ibuf[c] != 0) ibc = c; stats(); } if(ibc == 0 && --files<=0) { flsh(); term(); } if(ibc != ibs) { nipr++; --- 337,351 ----- if(ibuf[c] != 0) ibc = c; stats(); } if(ibc == 0 && --files<=0) { + /* CHANGE 12-Jun-84 dsh: EOF was seen, with an incomplete buffer + * for output. complete it. + */ + if (conv==block && cbc>0 && cbc<cbs) + block('\n'); flsh(); term(); } if(ibc != ibs) { nipr++; ----------------------------------->Cut Here Also<----------------------- David Herron Arpa: "ukma!david"@ANL-MCS unmvax----\ /------- Arpa-Net research >---/----------------/----------- anlams!ukma!david boulder---/ decvax!ucbvax ---/ (or cbosgd!hasmed!qusavx!ukma!david)
marcus@pyuxt.UUCP (M. G. Hand) (12/12/84)
>No matter what change you propose to /dev/kmem, it is bound to break >ps, pstat, etc., access to crash dumps. About time ps was broken - its an applaling piece of code with its 2 byte malloc calls... Marcus Hand (pyuxt!marcus) -- Marcus Hand {ihnp4!}pyuxt!marcus