DrKLO/Telegram · error
%s: can't open %s for writing
Error message
%s: can't open %s for writing
What it means
jpegtran opens the output file with fopen(outfilename, WRITE_BINARY) at jpegtran.c:613. If fopen returns NULL, the output path is invalid: the parent directory doesn't exist, the process lacks write permission, or the disk is full. The program exits before writing any output.
Source
Thrown at TMessagesProj/jni/mozjpeg/jpegtran.c:614
&transformoption);
#else
dst_coef_arrays = src_coef_arrays;
#endif
/* Close input file, if we opened it.
* Note: we assume that jpeg_read_coefficients consumed all input
* until JPEG_REACHED_EOI, and that jpeg_finish_decompress will
* only consume more while (!cinfo->inputctl->eoi_reached).
* We cannot call jpeg_finish_decompress here since we still need the
* virtual arrays allocated from the source object for processing.
*/
if (fp != stdin)
fclose(fp);
/* Open the output file. */
if (outfilename != NULL) {
if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s for writing\n", progname,
outfilename);
exit(EXIT_FAILURE);
}
} else {
/* default output file is stdout */
fp = write_stdout();
}
/* Adjust default compression parameters by re-parsing the options */
file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);
/* Specify data destination for compression */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (jpeg_c_int_param_supported(&dstinfo, JINT_COMPRESS_PROFILE) &&
jpeg_c_get_int_param(&dstinfo, JINT_COMPRESS_PROFILE)
== JCP_MAX_COMPRESSION)
jpeg_mem_dest(&dstinfo, &outbuffer, &outsize);
elseView on GitHub (pinned to 45ab8f4308)
Solutions
- Ensure the parent directory exists: `mkdir -p $(dirname outpath)` before invoking
- Verify write permission: `access(dirname, W_OK) == 0`
- Use the app's internal storage (`getFilesDir()`) for output
- Check available disk space before writing large outputs
Example fix
// before jpegtran input.jpg -outfile /sdcard/output/out.jpg // after mkdir -p /sdcard/output jpegtran input.jpg -outfile /sdcard/output/out.jpg
Defensive patterns
Strategy: validation
Validate before calling
// Validate output path writability before invoking jpegtran
int validate_output_path(const char *path) {
char dir[4096];
strncpy(dir, path, sizeof(dir)-1); dir[sizeof(dir)-1] = '\0';
char *slash = strrchr(dir, '/');
if (slash) *slash = '\0';
else strcpy(dir, ".");
if (access(dir, W_OK) != 0) {
fprintf(stderr, "Output directory not writable: %s\n", dir);
return -1;
}
// check available space (at least 2x input size)
struct statvfs vfs;
if (statvfs(dir, &vfs) == 0) {
unsigned long long avail = (unsigned long long)vfs.f_bavail * vfs.f_bsize;
if (avail < 1024*1024) return -1; // less than 1MB free
}
return 0;
} Prevention
- Create the output directory before invoking jpegtran
- Verify write permission on the output directory with access(dir, W_OK)
- Use the app's internal storage for output to avoid permission issues
When it happens
Trigger: Output directory doesn't exist (e.g. /tmp/out/ when /tmp/out is missing). No write permission on the target directory (e.g. /system on Android). Disk full or quota exceeded. The output path is a directory, not a file.
Common situations: JNI caller passes an output path in a sandboxed directory that the native process can't write to. Output path to external storage on Android without WRITE_EXTERNAL_STORAGE permission. Path with a trailing slash interpreted as a directory.
Related errors
- Invalid path to YUV file!
- %s: can't open %s for reading
- %s: can't open %s
- %s: can't determine size of %s
- %s: can't read ICC profile from %s
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/0415790443184ff7.
Report an issue: GitHub.