git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 5/5] convert: add filter.<driver>.process option

From
Lars Schneider <larsxschneider@gmail.com>
Date
Jul 29, 2016, 10:38 UTC
Message-ID
<64C7D52F-9030-460C-8F61-4076F5C1DDF6@gmail.com>
In-Reply-To
<20160727094102.GA31374@starla>
Show 10 quoted lines
> On 27 Jul 2016, at 11:41, Eric Wong <e@80x24.org> wrote:
> 
> larsxschneider@gmail.com wrote:
>> +static off_t multi_packet_read(struct strbuf *sb, const int fd, const size_t size)
> 
> I'm no expert in C, but this might be const-correctness taken
> too far.  I think basing this on the read(2) prototype is less
> surprising:
> 
>   static ssize_t multi_packet_read(int fd, struct strbuf *sb, size_t size)

Hm... ok. I like `const` because I think it is usually easier to read/understand functions that do not change their input variables. This way I can communicate my intention to future people modifying this function!

If this is frowned upon in the Git community then I will add a comment to the CodingGuidelines and remove the const :)

I agree with your reordering of the parameters, though!

Speaking of coding style... convert.c is already big and gets only bigger with this patch (1720 lines). Would it make sense to add a new file "convert-pipe-protocol.c" or something for my additions?

Show 8 quoted lines
> Also what Jeff said about off_t vs size_t, but my previous
> emails may have confused you w.r.t. off_t usage...
> 
>> +static int multi_packet_write(const char *src, size_t len, const int in, const int out)
> 
> Same comment about over const ints above.
> len can probably be off_t based on what is below; but you need
> to process the loop in ssize_t-friendly chunks.

I think I would prefer to keep it an size_t because that is the type we get from Git initially. The code will be more clear in v3.

Show 8 quoted lines
> 
>> +{
>> +	int ret = 1;
>> +	char header[4];
>> +	char buffer[8192];
>> +	off_t bytes_to_write;
> 
> What Jeff said, this should be ssize_t to match read(2) and xread
Agreed.
Show 27 quoted lines
> 
>> +	while (ret) {
>> +		if (in >= 0) {
>> +			bytes_to_write = xread(in, buffer, sizeof(buffer));
>> +			if (bytes_to_write < 0)
>> +				ret &= 0;
>> +			src = buffer;
>> +		} else {
>> +			bytes_to_write = len > LARGE_PACKET_MAX - 4 ? LARGE_PACKET_MAX - 4 : len;
>> +			len -= bytes_to_write;
>> +		}
>> +		if (!bytes_to_write)
>> +			break;
> 
> The whole ret &= .. style error handling is hard-to-follow and
> here, a source of bugs.  I think the expected convention on
> hitting errors is:
> 
> 	1) stop whatever you're doing
> 	2) cleanup
> 	3) propagate the error to callers
> 
> "goto" is an acceptable way of accomplishing this.
> 
> For example, byte_to_write may still be negative at this point
> (and interpreted as a really big number when cast to unsigned
> size_t) and src/buffer could be stack garbage.

I changed the implementation here so that the &= style is not necessary anymore. However, I will look into "goto" for the other areas!

Show 24 quoted lines
>> +		set_packet_header(header, bytes_to_write + 4);
>> +		ret &= write_in_full(out, &header, sizeof(header)) == sizeof(header);
>> +		ret &= write_in_full(out, src, bytes_to_write) == bytes_to_write;
>> +	}
>> +	ret &= write_in_full(out, "0000", 4) == 4;
>> +	return ret;
>> +}
>> +
> 
>> +static int apply_protocol_filter(const char *path, const char *src, size_t len,
>> +						int fd, struct strbuf *dst, const char *cmd,
>> +						const char *filter_type)
>> +{
> 
> <snip>
> 
>> +	if (fd >= 0 && !src) {
>> +		ret &= fstat(fd, &file_stat) != -1;
>> +		len = file_stat.st_size;
> 
> Same truncation bug I noticed earlier; what I originally meant
> is the `len' arg probably ought to be off_t, here, not size_t.
> 32-bit x86 Linux systems have 32-bit size_t (unsigned), but
> large file support means off_t is 64-bits (signed).
OK. Would it be OK to keep size_t for this patch series?
> Also, is it worth continuing this function if fstat fails?
No :-)
Show 15 quoted lines
>> +	}
>> +
>> +	sigchain_push(SIGPIPE, SIG_IGN);
>> +
>> +	packet_write(process->in, "%s\n", filter_type);
>> +	packet_write(process->in, "%s\n", path);
>> +	packet_write(process->in, "%zu\n", len);
> 
> I'm not sure if "%zu" is portable since we don't do C99 (yet?)
> For 64-bit signed off_t, you can probably do:
> 
> 	packet_write(process->in, "%"PRIuMAX"\n", (uintmax_t)len);
> 
> Since we don't have PRIiMAX or intmax_t, here, and a negative
> len would be a bug (probably from failed fstat) anyways.

OK. "%zu" is not used in the entire code base. I will go with your suggestion!

>> +	ret &= multi_packet_write(src, len, fd, process->in);
> 
> multi_packet_write will probably fail if fstat failed above...

Yes. The error handling is bogus... I thought bitwise "and" would act the same way as logical "and" (a bit embarrassing to admit that...).

> 
>> +	strbuf = packet_read_line(process->out, NULL);
> 
> And this may just block or timeout if multi_packet_write failed.

True, but unless there is anything easy to do I would leave that. Or do you think it is really necessary to introduce "select" and friends?

Thanks a lot for your review, Lars

Previous: Eric WongNext: Jakub Narębski
Message 51 of 77 in “Git filter protocol”
  1. 0/3 Git filter protocollarsxschneider@gmail.com, Jul 22, 2016
  2. 1/3 convert: quote filter names in error messageslarsxschneider@gmail.com, Jul 22, 2016
  3. 2/3 convert: modernize testslarsxschneider@gmail.com, Jul 22, 2016
  4. Remi Galan AlfonsoJul 26, 2016
  5. Junio C HamanoJul 26, 2016
  6. 3/3 convert: add filter.<driver>.useProtocol optionlarsxschneider@gmail.com, Jul 22, 2016
  7. Torsten BögershausenJul 22, 2016
  8. Lars SchneiderJul 24, 2016
  9. Ramsay JonesJul 22, 2016
  10. Ramsay JonesJul 22, 2016
  11. Lars SchneiderJul 24, 2016
  12. Ramsay JonesJul 24, 2016
  13. Jakub NarębskiJul 24, 2016
  14. Lars SchneiderJul 25, 2016
  15. Jakub NarębskiJul 26, 2016
  16. Lars SchneiderJul 25, 2016
  17. Jakub NarębskiJul 23, 2016
  18. Eric WongJul 23, 2016
  19. Jeff KingJul 26, 2016
  20. Lars SchneiderJul 24, 2016
  21. Jakub NarębskiJul 24, 2016
  22. Jakub NarębskiJul 24, 2016
  23. Lars SchneiderJul 25, 2016
  24. Jakub NarębskiJul 26, 2016
  25. Lars SchneiderJul 25, 2016
  26. Jakub NarębskiJul 26, 2016
  27. Eric WongJul 23, 2016
  28. Lars SchneiderJul 24, 2016
  29. Eric WongJul 25, 2016
  30. Duy NguyenJul 25, 2016
  31. Junio C HamanoJul 22, 2016
  32. Lars SchneiderJul 24, 2016
  33. Jeff KingJul 26, 2016
  34. 0/5 Git filter protocollarsxschneider@gmail.com, Jul 27, 2016
  35. 2/5 convert: modernize testslarsxschneider@gmail.com, Jul 27, 2016
  36. 3/5 pkt-line: extract and use `set_packet_header` functionlarsxschneider@gmail.com, Jul 27, 2016
  37. Junio C HamanoJul 27, 2016
  38. Lars SchneiderJul 27, 2016
  39. Junio C HamanoJul 27, 2016
  40. 4/5 convert: generate large test files only oncelarsxschneider@gmail.com, Jul 27, 2016
  41. Torsten BögershausenJul 27, 2016
  42. Jeff KingJul 27, 2016
  43. Lars SchneiderJul 27, 2016
  44. 5/5 convert: add filter.<driver>.process optionlarsxschneider@gmail.com, Jul 27, 2016
  45. Jeff KingJul 27, 2016
  46. Lars SchneiderJul 27, 2016
  47. Jeff KingJul 27, 2016
  48. Lars SchneiderJul 28, 2016
  49. Jeff KingJul 28, 2016
  50. Eric WongJul 27, 2016
  51. Lars SchneiderJul 29, 2016
  52. Jakub NarębskiJul 29, 2016
  53. Lars SchneiderJul 29, 2016
  54. Eric WongAug 5, 2016
  55. Lars SchneiderAug 5, 2016
  56. Eric WongAug 5, 2016
  57. Jakub NarębskiJul 27, 2016
  58. Lars SchneiderJul 29, 2016
  59. Junio C HamanoJul 29, 2016
  60. Jakub NarębskiJul 29, 2016
  61. Lars SchneiderJul 29, 2016
  62. Jakub NarębskiJul 30, 2016
  63. Torsten BögershausenJul 28, 2016
  64. 1/5 convert: quote filter names in error messageslarsxschneider@gmail.com, Jul 27, 2016
  65. Jakub NarębskiJul 27, 2016
  66. Lars SchneiderJul 28, 2016
  67. Jakub NarębskiJul 27, 2016
  68. Lars SchneiderJul 28, 2016
  69. Jakub NarębskiJul 28, 2016
  70. Jeff KingJul 28, 2016
  71. Jakub NarębskiJul 29, 2016
  72. Lars SchneiderJul 29, 2016
  73. Jeff KingJul 29, 2016
  74. Lars SchneiderJul 29, 2016
  75. Jeff KingJul 29, 2016
  76. Lars SchneiderJul 29, 2016
  77. Jeff KingJul 29, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.