Skip to content

Commit cbb47d6

Browse files
author
Alexander Scherbatiy
committed
8181571: printing to CUPS fails on mac sandbox app
Backport-of: 3d4be14eba60e21d5c10f2ad07a20c018329c563
1 parent a645c25 commit cbb47d6

File tree

2 files changed

+102
-9
lines changed

2 files changed

+102
-9
lines changed

src/java.desktop/unix/classes/sun/print/CUPSPrinter.java

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public class CUPSPrinter {
5454
private static native String getCupsServer();
5555
private static native int getCupsPort();
5656
private static native String getCupsDefaultPrinter();
57+
private static native String[] getCupsDefaultPrinters();
5758
private static native boolean canConnect(String server, int port);
5859
private static native boolean initIDs();
5960
// These functions need to be synchronized as
@@ -78,6 +79,7 @@ public class CUPSPrinter {
7879

7980
private static boolean libFound;
8081
private static String cupsServer = null;
82+
private static String domainSocketPathname = null;
8183
private static int cupsPort = 0;
8284

8385
static {
@@ -92,6 +94,13 @@ public Void run() {
9294
libFound = initIDs();
9395
if (libFound) {
9496
cupsServer = getCupsServer();
97+
// Is this a local domain socket pathname?
98+
if (cupsServer != null && cupsServer.startsWith("/")) {
99+
if (isSandboxedApp()) {
100+
domainSocketPathname = cupsServer;
101+
}
102+
cupsServer = "localhost";
103+
}
95104
cupsPort = getCupsPort();
96105
}
97106
}
@@ -376,6 +385,20 @@ public OutputStream run() {
376385
* Get list of all CUPS printers using IPP.
377386
*/
378387
static String[] getAllPrinters() {
388+
389+
if (getDomainSocketPathname() != null) {
390+
String[] printerNames = getCupsDefaultPrinters();
391+
if (printerNames != null && printerNames.length > 0) {
392+
String[] printerURIs = new String[printerNames.length];
393+
for (int i=0; i< printerNames.length; i++) {
394+
printerURIs[i] = String.format("ipp://%s:%d/printers/%s",
395+
getServer(), getPort(), printerNames[i]);
396+
}
397+
return printerURIs;
398+
}
399+
return null;
400+
}
401+
379402
try {
380403
URL url = new URL("http", getServer(), getPort(), "");
381404

@@ -458,15 +481,39 @@ public static int getPort() {
458481
return cupsPort;
459482
}
460483

484+
/**
485+
* Returns CUPS domain socket pathname.
486+
*/
487+
private static String getDomainSocketPathname() {
488+
return domainSocketPathname;
489+
}
490+
491+
@SuppressWarnings("removal")
492+
private static boolean isSandboxedApp() {
493+
if (PrintServiceLookupProvider.isMac()) {
494+
return java.security.AccessController
495+
.doPrivileged((java.security.PrivilegedAction<Boolean>) () ->
496+
System.getenv("APP_SANDBOX_CONTAINER_ID") != null);
497+
}
498+
return false;
499+
}
500+
501+
461502
/**
462503
* Detects if CUPS is running.
463504
*/
464505
public static boolean isCupsRunning() {
465506
IPPPrintService.debug_println(debugPrefix+"libFound "+libFound);
466507
if (libFound) {
467-
IPPPrintService.debug_println(debugPrefix+"CUPS server "+getServer()+
468-
" port "+getPort());
469-
return canConnect(getServer(), getPort());
508+
String server = getDomainSocketPathname() != null
509+
? getDomainSocketPathname()
510+
: getServer();
511+
IPPPrintService.debug_println(debugPrefix+"CUPS server "+server+
512+
" port "+getPort()+
513+
(getDomainSocketPathname() != null
514+
? " use domain socket pathname"
515+
: ""));
516+
return canConnect(server, getPort());
470517
} else {
471518
return false;
472519
}

src/java.desktop/unix/native/common/awt/CUPSfuncs.c

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,7 @@ Java_sun_print_CUPSPrinter_getCupsServer(JNIEnv *env,
172172
jstring cServer = NULL;
173173
const char* server = j2d_cupsServer();
174174
if (server != NULL) {
175-
// Is this a local domain socket?
176-
if (strncmp(server, "/", 1) == 0) {
177-
cServer = JNU_NewStringPlatform(env, "localhost");
178-
} else {
179-
cServer = JNU_NewStringPlatform(env, server);
180-
}
175+
cServer = JNU_NewStringPlatform(env, server);
181176
}
182177
return cServer;
183178
}
@@ -219,6 +214,57 @@ Java_sun_print_CUPSPrinter_getCupsDefaultPrinter(JNIEnv *env,
219214
return cDefPrinter;
220215
}
221216

217+
/*
218+
* Returns list of default local printers
219+
*/
220+
JNIEXPORT jobjectArray JNICALL
221+
Java_sun_print_CUPSPrinter_getCupsDefaultPrinters(JNIEnv *env,
222+
jobject printObj)
223+
{
224+
cups_dest_t *dests;
225+
int i, j, num_dests;
226+
jstring utf_str;
227+
jclass cls;
228+
jobjectArray nameArray = NULL;
229+
230+
cls = (*env)->FindClass(env, "java/lang/String");
231+
CHECK_NULL_RETURN(cls, NULL);
232+
233+
num_dests = j2d_cupsGetDests(&dests);
234+
235+
if (dests == NULL) {
236+
return NULL;
237+
}
238+
239+
nameArray = (*env)->NewObjectArray(env, num_dests, cls, NULL);
240+
if (nameArray == NULL) {
241+
j2d_cupsFreeDests(num_dests, dests);
242+
DPRINTF("CUPSfuncs::bad alloc new array\n", "")
243+
return NULL;
244+
}
245+
246+
for (i = 0; i < num_dests; i++) {
247+
utf_str = JNU_NewStringPlatform(env, dests[i].name);
248+
if (utf_str == NULL) {
249+
for (j = i - 1; j >= 0; j--) {
250+
utf_str = (*env)->GetObjectArrayElement(env, nameArray, j);
251+
(*env)->SetObjectArrayElement(env, nameArray, j, NULL);
252+
(*env)->DeleteLocalRef(env, utf_str);
253+
utf_str = NULL;
254+
}
255+
j2d_cupsFreeDests(num_dests, dests);
256+
(*env)->DeleteLocalRef(env, nameArray);
257+
DPRINTF("CUPSfuncs::bad alloc new string ->name\n", "")
258+
return NULL;
259+
}
260+
(*env)->SetObjectArrayElement(env, nameArray, i, utf_str);
261+
(*env)->DeleteLocalRef(env, utf_str);
262+
}
263+
264+
j2d_cupsFreeDests(num_dests, dests);
265+
return nameArray;
266+
}
267+
222268
/*
223269
* Checks if connection can be made to the server.
224270
*

0 commit comments

Comments
 (0)