getcwd.c (2219B)
1 /* 2 * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> 3 * Copyright (c) 2020 Stuart Henderson <stu@spacehopper.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * witH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/sysctl.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <unistd.h> 23 #include <vis.h> 24 #include <wchar.h> 25 26 void 27 mbswprint(const char *mbs) 28 { 29 char buf[5]; 30 wchar_t wc; 31 int len; /* length in bytes of UTF-8 encoded string */ 32 int width; /* display width of a single Unicode char */ 33 34 while (*mbs != '\0') { 35 len = mbtowc(&wc, mbs, MB_CUR_MAX); 36 if (len == -1) { 37 (void)mbtowc(NULL, NULL, MB_CUR_MAX); 38 len = 1; 39 } 40 if (len == 1) 41 width = vis(buf, mbs[0], 42 VIS_TAB | VIS_NL | VIS_CSTYLE, mbs[1]) - buf; 43 else if ((width = wcwidth(wc)) == -1) { 44 /* U+FFFD replacement character */ 45 memcpy(buf, "\357\277\275\0", 4); 46 width = 1; 47 } else { 48 memcpy(buf, mbs, len); 49 buf[len] = '\0'; 50 } 51 fputs(buf, stdout); 52 mbs += len; 53 } 54 fputs("\n", stdout); 55 } 56 57 void 58 curwd(pid_t pid) 59 { 60 int name[] = { CTL_KERN, KERN_PROC_CWD, pid }; 61 char path[PATH_MAX]; 62 size_t pathlen = sizeof path; 63 64 if (sysctl(name, 3, path, &pathlen, NULL, 0) != 0) 65 *path = '\0'; 66 67 mbswprint(path); 68 } 69 70 int 71 main(int argc, char *argv[]) 72 { 73 int pid; 74 const char *errstr; 75 76 pledge("stdio ps", NULL); 77 78 if (argc != 2) { 79 printf("usage: getcwd <pid>\n"); 80 return(1); 81 } 82 83 pid = strtonum(argv[1], 1, UINT_MAX, &errstr); 84 if (errstr != NULL) { 85 printf("pid is %s: %s\n", errstr, argv[0]); 86 return(1); 87 } 88 89 curwd(pid); 90 91 return 0; 92 }